| // -*- C++ -*- |
| /*************************************************************************** |
| * |
| * <vector> - dfefinition of the C++ Standard Library vector class template |
| * |
| * $Id$ |
| * |
| *************************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. See the License for the specific language governing |
| * permissions and limitations under the License. |
| * |
| * Copyright 1994-2007 Rogue Wave Software, Inc. |
| * |
| *************************************************************************** |
| * |
| * Copyright (c) 1994 |
| * Hewlett-Packard Company |
| * |
| * Permission to use, copy, modify, distribute and sell this software |
| * and its documentation for any purpose is hereby granted without fee, |
| * provided that the above copyright notice appear in all copies and |
| * that both that copyright notice and this permission notice appear |
| * in supporting documentation. Hewlett-Packard Company makes no |
| * representations about the suitability of this software for any |
| * purpose. It is provided "as is" without express or implied warranty. |
| * |
| **************************************************************************/ |
| |
| #ifndef _RWSTD_VECTOR_INCLUDED |
| #define _RWSTD_VECTOR_INCLUDED |
| |
| |
| #include <rw/_algobase.h> |
| #include <rw/_allocator.h> |
| #include <rw/_error.h> |
| #include <rw/_iterator.h> |
| #include <rw/_select.h> |
| #include <rw/_defs.h> |
| |
| |
| _RWSTD_NAMESPACE (std) { |
| |
| _EXPORT |
| template <class _TypeT, class _Allocator = allocator<_TypeT> > |
| class vector; |
| |
| |
| _EXPORT |
| template <class _TypeT, class _Allocator> |
| class vector |
| { |
| public: |
| |
| typedef _TypeT value_type; |
| typedef _Allocator allocator_type; |
| typedef typename allocator_type::size_type size_type; |
| typedef typename allocator_type::difference_type difference_type; |
| typedef typename allocator_type::reference reference; |
| typedef typename allocator_type::const_reference const_reference; |
| typedef typename allocator_type::pointer pointer; |
| typedef typename allocator_type::const_pointer const_pointer; |
| |
| public: |
| |
| #ifndef _RWSTD_NO_DEBUG_ITER |
| |
| typedef _RW::__rw_debug_iter <vector, pointer, pointer> iterator; |
| |
| typedef _RW::__rw_debug_iter <vector, const_pointer, pointer> |
| const_iterator; |
| |
| iterator _C_make_iter (pointer __ptr) { |
| return iterator (*this, __ptr); |
| } |
| |
| const_iterator _C_make_iter (pointer __ptr) const { |
| return const_iterator (*this, __ptr); |
| } |
| |
| #else // if defined (_RWSTD_NO_DEBUG_ITER) |
| |
| typedef pointer iterator; |
| typedef const_pointer const_iterator; |
| |
| iterator _C_make_iter (pointer __ptr) { |
| return __ptr; |
| } |
| |
| const_iterator _C_make_iter (const_pointer __ptr) const { |
| return __ptr; |
| } |
| |
| #endif // _RWSTD_NO_DEBUG_ITER |
| |
| #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator; |
| typedef _STD::reverse_iterator<iterator> reverse_iterator; |
| |
| #else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) |
| |
| typedef _STD::reverse_iterator<const_iterator, |
| random_access_iterator_tag, value_type, |
| const_reference, const_pointer, difference_type> |
| const_reverse_iterator; |
| |
| typedef _STD::reverse_iterator<iterator, |
| random_access_iterator_tag, value_type, |
| reference, pointer, difference_type> |
| reverse_iterator; |
| |
| #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| public: |
| |
| explicit |
| vector (const allocator_type &__alloc = allocator_type ()) |
| : _C_alloc (__alloc) { } |
| |
| explicit |
| vector (size_type __n, const_reference __x = value_type (), |
| const allocator_type &__alloc = allocator_type ()) |
| : _C_alloc (__alloc) { |
| assign (__n, __x); |
| } |
| |
| template <class _InputIter> |
| vector (_InputIter __first, _InputIter __last, |
| const allocator_type &__alloc = allocator_type ()) |
| : _C_alloc (__alloc) { |
| assign (__first, __last); |
| } |
| |
| vector (const vector &__rhs) |
| : _C_alloc (__rhs.get_allocator ()) { |
| assign (__rhs.begin (), __rhs.end ()); |
| } |
| |
| |
| ~vector () { |
| _C_destroy (begin ()); |
| _C_alloc.deallocate (_C_alloc._C_begin, |
| _C_alloc._C_bufend - _C_alloc._C_begin); |
| } |
| |
| vector& operator= (const vector&); |
| |
| template <class _InputIter> |
| void assign (_InputIter __first, _InputIter __last) { |
| // dispatch either to a range assign or to an assign with repetition |
| _C_assign (__first, __last, _RWSTD_DISPATCH (_InputIter)); |
| } |
| |
| void assign (size_type __n, const_reference __x) { |
| _C_assign_n (__n, __x); |
| } |
| |
| allocator_type get_allocator () const { |
| return _C_alloc; |
| } |
| |
| iterator begin () { |
| return _C_make_iter (_C_alloc._C_begin); |
| } |
| |
| const_iterator begin () const { |
| return _C_make_iter (_C_alloc._C_begin); |
| } |
| |
| iterator end () { |
| return _C_make_iter (_C_alloc._C_end); |
| } |
| |
| const_iterator end () const { |
| return _C_make_iter (_C_alloc._C_end); |
| } |
| |
| reverse_iterator rbegin () { |
| return reverse_iterator (end ()); |
| } |
| |
| const_reverse_iterator rbegin () const { |
| return const_reverse_iterator (end ()); |
| } |
| |
| reverse_iterator rend () { |
| return reverse_iterator (begin ()); |
| } |
| |
| const_reverse_iterator rend () const { |
| return const_reverse_iterator (begin ()); |
| } |
| |
| size_type size () const { |
| return size_type (_C_alloc._C_end - _C_alloc._C_begin); |
| } |
| |
| size_type max_size () const { |
| return _C_alloc.max_size (); |
| } |
| |
| void resize (size_type, value_type = value_type ()); |
| |
| size_type capacity () const { |
| return _C_alloc._C_bufend - _C_alloc._C_begin; |
| } |
| |
| bool empty () const { |
| return _C_alloc._C_begin == _C_alloc._C_end; |
| } |
| |
| void reserve (size_type); |
| |
| reference operator[] (size_type); |
| |
| const_reference operator[] (size_type) const; |
| |
| reference at (size_type); |
| |
| const_reference at (size_type __n) const; |
| |
| reference front () { |
| _RWSTD_ASSERT (!empty ()); |
| return *begin (); |
| } |
| |
| const_reference front () const { |
| _RWSTD_ASSERT (!empty ()); |
| return *begin (); |
| } |
| |
| reference back () { |
| _RWSTD_ASSERT (!empty ()); |
| return *(end () - 1); |
| } |
| |
| const_reference back () const { |
| _RWSTD_ASSERT (!empty ()); |
| return *(end () - 1); |
| } |
| |
| void push_back (const_reference); |
| |
| void pop_back () { |
| _RWSTD_ASSERT (!empty ()); |
| _C_alloc.destroy (_C_alloc._C_end - 1); |
| --_C_alloc._C_end; |
| } |
| |
| iterator insert (iterator, const_reference); |
| |
| template <class _InputIter> |
| void insert (iterator __it, _InputIter __first, _InputIter __last) { |
| _C_insert (__it, __first, __last, _RWSTD_DISPATCH (_InputIter)); |
| } |
| |
| void insert (iterator __it, size_type __n, const_reference __x) { |
| _C_insert_n (__it, __n, __x); |
| } |
| |
| iterator erase (iterator); |
| |
| iterator erase (iterator, iterator); |
| |
| void swap (vector&); |
| |
| void clear (); |
| |
| #ifdef _RWSTD_NO_PART_SPEC_OVERLOAD |
| |
| friend void swap (vector& __lhs, vector& __rhs) { |
| __lhs.swap (__rhs); |
| } |
| |
| #endif // _RWSTD_NO_PART_SPEC_OVERLOAD |
| |
| private: |
| |
| // implements assign with repetition |
| void _C_assign_n (size_type, const_reference); |
| |
| // implements a single-element insert |
| void _C_insert_1 (const iterator&, const_reference); |
| |
| // implements insert with repetition |
| void _C_insert_n (const iterator&, size_type, const_reference); |
| |
| // implements range insert for ForwardIterators |
| template <class _FwdIter> |
| void _C_insert_range (iterator, _FwdIter, _FwdIter, |
| forward_iterator_tag); |
| |
| // implements range insert for InputIterators |
| template <class _InputIter> |
| void _C_insert_range (iterator, _InputIter, _InputIter, |
| input_iterator_tag); |
| |
| // implements range assign |
| template <class _InputIter> |
| void _C_assign (_InputIter __first, _InputIter __last, void*) { |
| _RWSTD_ASSERT_RANGE (__first, __last); |
| |
| // dispatch to an assign suitable for the category of InputIter |
| _RWSTD_ASSIGN_RANGE (__first, __last, |
| _RWSTD_ITERATOR_CATEGORY (_InputIter, __first)); |
| } |
| |
| // implements assign with repetition if value_type == size_type |
| template <class _IntType> |
| void _C_assign (_IntType __n, _IntType __x, int) { |
| _C_assign_n (size_type (__n), __x); |
| } |
| |
| // implements range insert for ForwardIterators |
| template <class _FwdIter> |
| void _C_assign_range (_FwdIter, _FwdIter, forward_iterator_tag); |
| |
| // implements range insert for InputIterators |
| template <class _InputIter> |
| void _C_assign_range (_InputIter, _InputIter, input_iterator_tag); |
| |
| // implements range insert |
| template <class _InputIter> |
| void _C_insert (const iterator &__it, |
| _InputIter __first, _InputIter __last, void*) { |
| _RWSTD_ASSERT_RANGE (begin (), __it); |
| _RWSTD_ASSERT_RANGE (__first, __last); |
| |
| // dispatch to an insert suitable for the category of InputIter |
| _RWSTD_INSERT_RANGE (__it, __first, __last, |
| _RWSTD_ITERATOR_CATEGORY (_InputIter, __first)); |
| } |
| |
| // implements insert with repetition if value_type == size_type |
| template <class _IntType> |
| void _C_insert (const iterator &__it, |
| _IntType __n, _IntType __x, int) { |
| _C_insert_n (__it, size_type (__n), __x); |
| } |
| |
| void _C_realloc (size_type); |
| |
| // constructs a copy at the end and grows the size of container |
| void _C_push_back (const_reference __x) { |
| _RWSTD_ASSERT (_C_alloc._C_end != _C_alloc._C_bufend); |
| _C_alloc.construct (_C_alloc._C_end, __x); |
| ++_C_alloc._C_end; |
| } |
| |
| // destroys elements from the iterator to the end of the vector |
| // and resets end() to point to the iterator |
| void _C_destroy (iterator); |
| |
| // implements swap for objects with unequal allocator |
| void _C_unsafe_swap (vector&); |
| |
| struct _C_VectorAlloc: allocator_type { |
| |
| _C_VectorAlloc (const allocator_type &__alloc) |
| : allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend () |
| { /* empty */} |
| |
| pointer _C_begin; |
| pointer _C_end; |
| pointer _C_bufend; |
| } _C_alloc; |
| }; |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::reference |
| vector<_TypeT, _Allocator>:: |
| operator[] (size_type __n) |
| { |
| #ifdef _RWSTD_BOUNDS_CHECKING |
| |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_OUT_OF_RANGE, |
| _RWSTD_FUNC ("vector::operator[](size_type)"), |
| __n, size ())); |
| |
| #endif // _RWSTD_BOUNDS_CHECKING |
| |
| return *(begin () + __n); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::const_reference |
| vector<_TypeT, _Allocator>:: |
| operator[] (size_type __n) const |
| { |
| #ifdef _RWSTD_BOUNDS_CHECKING |
| |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_OUT_OF_RANGE, |
| _RWSTD_FUNC ("vector::operator[](size_type) const"), |
| __n, size ())); |
| |
| #endif // _RWSTD_BOUNDS_CHECKING |
| |
| return *(begin () + __n); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::reference |
| vector<_TypeT, _Allocator>:: |
| at (size_type __n) |
| { |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_OUT_OF_RANGE, |
| _RWSTD_FUNC ("vector::at (size_type)"), |
| __n, size ())); |
| return *(begin () + __n); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::const_reference |
| vector<_TypeT, _Allocator>:: |
| at (size_type __n) const |
| { |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_OUT_OF_RANGE, |
| _RWSTD_FUNC ("vector::at(size_type) const"), |
| __n, size ())); |
| return *(begin () + __n); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| vector<_TypeT, _Allocator>:: |
| resize (size_type __new_size, value_type __x /* = value_type () */) |
| { |
| if (size () < __new_size) |
| insert (end (), __new_size - size (), __x); |
| else if (__new_size < size ()) |
| erase (begin () + __new_size, end ()); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| vector<_TypeT, _Allocator>:: |
| reserve (size_type __n) |
| { |
| _RWSTD_REQUIRES (__n <= max_size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector::reserve(size_type)"), |
| __n, max_size ())); |
| |
| if (capacity () < __n) |
| _C_realloc (__n); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| vector<_TypeT, _Allocator>:: |
| push_back (const_reference __x) |
| { |
| if (_C_alloc._C_end == _C_alloc._C_bufend) |
| _C_insert_1 (end (), __x); |
| else |
| _C_push_back (__x); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::iterator |
| vector<_TypeT, _Allocator>:: |
| insert (iterator __it, const_reference __x) |
| { |
| _RWSTD_ASSERT_RANGE (__it, end ()); |
| |
| const difference_type __off = __it - begin (); |
| |
| if (end () == __it) |
| push_back (__x); |
| else |
| _C_insert_1 (__it, __x); |
| |
| return begin () + __off; |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::iterator |
| vector<_TypeT, _Allocator>:: |
| erase (iterator __it) |
| { |
| _RWSTD_ASSERT_RANGE (__it, end ()); |
| _RWSTD_ASSERT (__it < end ()); // `it' must be dereferenceable |
| |
| const iterator __next = __it + 1; |
| |
| if (__next != end ()) |
| _STD::copy (__next, end (), __it); |
| |
| _C_alloc.destroy (_C_alloc._C_end - 1); |
| --_C_alloc._C_end; |
| |
| return __it; |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline typename vector<_TypeT, _Allocator>::iterator |
| vector<_TypeT, _Allocator>:: |
| erase (iterator __first, iterator __last) |
| { |
| _RWSTD_ASSERT_RANGE (__first, __last); |
| _RWSTD_ASSERT_RANGE (begin (), __first); |
| |
| _C_destroy (_STD::copy (__last, end (), __first)); |
| |
| return __first; |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| vector<_TypeT, _Allocator>:: |
| clear () |
| { |
| if (!empty ()) |
| _C_destroy (begin ()); |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| vector<_TypeT, _Allocator>:: |
| swap (vector &__other) |
| { |
| if (get_allocator () == __other.get_allocator ()) { |
| pointer __tmp = _C_alloc._C_begin; |
| _C_alloc._C_begin = __other._C_alloc._C_begin; |
| __other._C_alloc._C_begin = __tmp; |
| __tmp = _C_alloc._C_end; |
| _C_alloc._C_end = __other._C_alloc._C_end; |
| __other._C_alloc._C_end = __tmp; |
| __tmp = _C_alloc._C_bufend; |
| _C_alloc._C_bufend = __other._C_alloc._C_bufend; |
| __other._C_alloc._C_bufend = __tmp; |
| } |
| else { |
| // not exception-safe |
| _C_unsafe_swap (__other); |
| } |
| } |
| |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator== (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return __x.size () == __y.size () |
| && _STD::equal(__x.begin (), __x.end (), __y.begin ()); |
| } |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator< (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return _STD::lexicographical_compare (__x.begin (), __x.end (), |
| __y.begin (), __y.end ()); |
| } |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator!= (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return !(__x == __y); |
| } |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator> (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return __y < __x; |
| } |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator>= (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return !(__x < __y); |
| } |
| |
| template <class _TypeT, class _Allocator> |
| inline bool |
| operator<= (const vector<_TypeT, _Allocator> &__x, |
| const vector<_TypeT, _Allocator> &__y) |
| { |
| return !(__y < __x); |
| } |
| |
| #ifndef _RWSTD_NO_PART_SPEC_OVERLOAD |
| |
| template <class _TypeT, class _Allocator> |
| inline void |
| swap (vector<_TypeT, _Allocator> &__x, vector<_TypeT, _Allocator> &__y) |
| { |
| __x.swap (__y); |
| } |
| |
| #endif // _RWSTD_NO_PART_SPEC_OVERLOAD |
| |
| /***************************************************************************/ |
| |
| #ifndef _RWSTD_NO_VECTOR_BOOL |
| |
| #ifndef _RWSTD_NO_BOOL |
| |
| // number of bits in a machine word |
| # define _RWSTD_WORD_BIT (int (_RWSTD_CHAR_BIT * sizeof (unsigned int))) |
| |
| |
| #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| _EXPORT |
| template <class _Allocator> |
| class |
| |
| #else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) |
| |
| // use a macro to mutate _Allocator into allocator<bool> |
| # define _Allocator allocator<bool> |
| |
| _RWSTD_SPECIALIZED_CLASS |
| class _RWSTD_EXPORT |
| |
| #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| vector<bool, _Allocator >: private _Allocator |
| { |
| #if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) |
| // clear typename |
| # undef typename |
| # define typename |
| #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| typedef _RWSTD_REBIND(_Allocator, unsigned int) _C_value_alloc_type; |
| typedef vector _C_self; |
| public: |
| |
| typedef _Allocator allocator_type; |
| typedef bool value_type; |
| |
| typedef typename allocator_type::size_type size_type; |
| typedef typename allocator_type::difference_type difference_type; |
| typedef typename _C_value_alloc_type::pointer pointer; |
| typedef typename _C_value_alloc_type::const_pointer const_pointer; |
| |
| #if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) |
| // restore typename |
| # undef typename |
| # define typename typename |
| #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| class iterator; |
| class const_iterator; |
| |
| class reference { |
| |
| #if !defined (__INTEL_COMPILER) || !defined (_MSC_VER) |
| // avoid MSVC 6.0 bug 576 |
| friend class iterator; |
| #else // if Intel C++ 8.1 with MSVC |
| // work around Intel C++ 8.1 bug 575 |
| friend class _C_self::iterator; |
| #endif // Intel C++ with MSVC |
| |
| friend class const_iterator; |
| |
| private: |
| |
| unsigned int* _C_p; |
| unsigned int _C_mask; |
| reference (unsigned int* __x, unsigned int __y) |
| : _C_p (__x), _C_mask (__y) { } |
| public: |
| |
| reference () : _C_p (), _C_mask () {} |
| |
| operator bool () const { |
| return !!(*_C_p & _C_mask); |
| } |
| |
| reference& operator= (bool __x) { |
| if (__x) |
| *_C_p |= _C_mask; |
| else |
| *_C_p &= ~_C_mask; |
| return *this; |
| } |
| |
| reference& operator= (const reference& __x) { |
| return *this = bool(__x); |
| } |
| |
| #ifndef _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS |
| |
| bool operator== (const reference& __x) const { |
| return bool(*this) == bool(__x); |
| } |
| |
| bool operator< (const reference& __x) const { |
| #ifndef _MSC_VER |
| return bool(*this) < bool(__x); |
| #else |
| return int(*this) < int(__x); |
| #endif |
| } |
| |
| bool operator!= (const reference& __x) const { |
| return !(*this == __x); |
| } |
| |
| bool operator> (const reference& __x) const { |
| return __x < *this; |
| } |
| |
| bool operator>= (const reference& __x) const { |
| return !(*this < __x); |
| } |
| |
| bool operator<= (const reference& __x) const { |
| return !(*this > __x); |
| } |
| |
| #endif // _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS |
| |
| void flip () { |
| *_C_p ^= _C_mask; |
| } |
| }; |
| |
| typedef bool const_reference; |
| |
| // hacks working around bogus g++ 2.95.2 warnings coming out of |
| // iterators below as well as what's probably an MSVC 6.0 bug |
| typedef reference _C_ref; |
| typedef const_reference _C_const_ref; |
| typedef difference_type _C_diff_t; |
| |
| class _C_iter { |
| friend class iterator; |
| friend class const_iterator; |
| |
| private: |
| |
| #if defined (__GNUG__) |
| // gcc 3.0.1 and prior take 14.5.3, p9 literally |
| public: |
| #elif defined (_MSC_VER) && _MSC_VER <= 1300 || defined (__APOGEE__) |
| friend class vector<bool, _Allocator>; |
| #else |
| friend class vector; |
| #endif |
| unsigned int* _C_p; // pointer to the current word |
| unsigned int _C_offset; // number of the pointed-to bit |
| |
| _C_iter (unsigned int* __x = 0, unsigned int __y = 0) |
| : _C_p (__x), _C_offset (__y) { } |
| |
| // On Sun, gcc 3.1 does generate an incorrect copy constructor |
| // that has as an effect an incompletely/incorrectly initialized |
| // iterator. |
| #if defined (__sun__) && defined (__GNUG__) \ |
| || defined (__SUNPRO_CC) && defined (__amd64__) |
| |
| // working around a gcc 3.1 bug on Solaris where the compiler |
| // generates bad code for the implicitly defined copy ctor |
| // also working around a Sun C++ 5.9 optimizer ICE on x86_64 |
| // in wide (64-bit) mode (see STDCXX-551) |
| |
| _C_iter (const _C_iter& __it) |
| : _C_p (__it._C_p), _C_offset (__it._C_offset) {} |
| #endif // gcc 3.1/Solaris || Sun C++ 5.9/x86_64 |
| |
| void operator++ () { |
| if (_C_offset++ == _RWSTD_WORD_BIT - 1) { |
| _C_offset = 0; |
| ++_C_p; |
| } |
| } |
| |
| void operator-- () { |
| if (_C_offset-- == 0) { |
| _C_offset = _RWSTD_WORD_BIT - 1; |
| --_C_p; |
| } |
| } |
| |
| void operator+= (difference_type __i) { |
| difference_type __n = __i + _C_offset; |
| _C_p += __n / _RWSTD_WORD_BIT; |
| __n = __n % _RWSTD_WORD_BIT; |
| if (__n < 0) { |
| _C_offset = _RWSTD_STATIC_CAST (unsigned int, |
| __n + _RWSTD_WORD_BIT); |
| --_C_p; |
| } |
| else |
| _C_offset = _RWSTD_STATIC_CAST (unsigned int,__n); |
| } |
| |
| public: |
| |
| bool operator== (const _C_iter& __x) const { |
| return _C_p == __x._C_p && _C_offset == __x._C_offset; |
| } |
| |
| bool operator< (const _C_iter& __x) const { |
| return _C_p < __x._C_p || |
| (_C_p == __x._C_p && _C_offset < __x._C_offset); |
| } |
| |
| bool operator!= (const _C_iter& __x) const { |
| return !(*this == __x); |
| } |
| |
| bool operator> (const _C_iter& __x) const { |
| return __x < *this; |
| } |
| |
| bool operator>= (const _C_iter& __x) const { |
| return !(*this < __x); |
| } |
| |
| bool operator<= (const _C_iter& __x) const { |
| return !(*this > __x); |
| } |
| }; |
| |
| class iterator |
| : public _C_iter, |
| public _STD::iterator<random_access_iterator_tag, |
| value_type, _C_diff_t, |
| pointer, _C_ref> { |
| public: |
| |
| // bring names used in declarations below into scope |
| // (dependent base members not visible without qualification) |
| typedef _C_ref reference; |
| typedef _C_diff_t difference_type; |
| |
| iterator (unsigned int *__x = 0, unsigned int __y = 0) |
| : _C_iter (__x, __y) { } |
| |
| reference operator* () const { |
| return reference (this->_C_p, 1U << this->_C_offset); |
| } |
| |
| iterator& operator++ () { |
| return _C_iter::operator++(), *this; |
| } |
| |
| iterator operator++ (int) { |
| iterator __tmp = *this; |
| ++*this; |
| return __tmp; |
| } |
| |
| iterator& operator-- () { |
| return _C_iter::operator--(), *this; |
| } |
| |
| iterator operator-- (int) { |
| iterator __tmp = *this; |
| --*this; |
| return __tmp; |
| } |
| |
| iterator& operator+= (difference_type __i) { |
| return _C_iter::operator+= (__i), *this; |
| } |
| |
| iterator& operator-= (difference_type __i) { |
| *this += -__i; |
| return *this; |
| } |
| |
| iterator operator+ (difference_type __i) const { |
| iterator __tmp = *this; |
| return __tmp += __i; |
| } |
| |
| iterator operator- (difference_type __i) const { |
| iterator __tmp = *this; |
| return __tmp -= __i; |
| } |
| |
| difference_type operator- (iterator __x) const { |
| return _RWSTD_WORD_BIT * (this->_C_p - __x._C_p) |
| + this->_C_offset - __x._C_offset; |
| } |
| |
| reference operator[] (difference_type __i) { |
| return *(*this + __i); |
| } |
| |
| friend iterator operator+ (difference_type __i, |
| const iterator &__x) { |
| return __x + __i; |
| } |
| }; |
| |
| class const_iterator |
| : public _C_iter, |
| public _STD::iterator<random_access_iterator_tag, |
| value_type, _C_diff_t, |
| const_pointer, _C_const_ref> { |
| public: |
| |
| // bring names used in declarations below into scope |
| // (dependent base members not visible without qualification) |
| typedef _C_const_ref const_reference; |
| typedef _C_diff_t difference_type; |
| |
| const_iterator (unsigned int *__x = 0, unsigned int __y = 0) |
| : _C_iter (__x, __y) { } |
| |
| const_iterator (const _C_iter &__x) |
| : _C_iter (__x) { } |
| |
| const_reference operator* () const { |
| return _C_ref (this->_C_p, 1U << this->_C_offset); |
| } |
| |
| const_iterator& operator++ () { |
| return _C_iter::operator++(), *this; |
| } |
| |
| const_iterator operator++ (int) { |
| const_iterator __tmp = *this; |
| ++*this; |
| return __tmp; |
| } |
| |
| const_iterator& operator-- () { |
| return _C_iter::operator--(), *this; |
| } |
| |
| const_iterator operator-- (int) { |
| const_iterator __tmp = *this; |
| --*this; |
| return __tmp; |
| } |
| |
| const_iterator& operator+= (difference_type __i) { |
| return _C_iter::operator+= (__i), *this; |
| } |
| |
| const_iterator& operator-= (difference_type __i) { |
| return *this += -__i; |
| } |
| |
| const_iterator |
| operator+ (difference_type __i) const { |
| return const_iterator (*this) += __i; |
| } |
| |
| const_iterator operator- (difference_type __i) const { |
| return const_iterator (*this) -= __i; |
| } |
| |
| difference_type operator- (const_iterator __x) const { |
| return _RWSTD_WORD_BIT * (this->_C_p - __x._C_p) |
| + this->_C_offset - __x._C_offset; |
| } |
| |
| const_reference operator[] (difference_type __i) { |
| return *(*this + __i); |
| } |
| |
| friend const_iterator operator+ (difference_type __i, |
| const const_iterator &__x) { |
| return __x + __i; |
| } |
| }; |
| |
| #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator; |
| typedef _STD::reverse_iterator<iterator> reverse_iterator; |
| |
| #else |
| |
| typedef _STD::reverse_iterator<const_iterator, |
| random_access_iterator_tag, value_type, |
| const_reference, const_pointer, difference_type> |
| const_reverse_iterator; |
| |
| typedef _STD::reverse_iterator<iterator, |
| random_access_iterator_tag, value_type, |
| reference, pointer, difference_type> |
| reverse_iterator; |
| |
| #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC |
| |
| private: |
| // |
| // These private functions are replicas of generic algorithms. |
| // We provide them here to avoid putting instantiations of |
| // the generic algorithms into an archive or shared library. |
| // This gives you full flexibilty in deciding where you want |
| // to put particular instantiations of the generic |
| // algorithms. |
| // |
| |
| void _C_fill (iterator __first, iterator __last, bool __val) { |
| while (__first != __last) *__first++ = __val; |
| } |
| |
| void _C_fill_n (iterator __first, size_type __n, bool __val) { |
| while (__n-- > 0) *__first++ = __val; |
| } |
| |
| template <class _Iterator> |
| iterator _C_copy (_Iterator __first, _Iterator __last, iterator __res) { |
| while (__first != __last) |
| *__res++ = *__first++; |
| return __res; |
| } |
| |
| template <class _Iterator> |
| iterator |
| _C_copy_backward (_Iterator __first, _Iterator __last, iterator __res) { |
| while (__first != __last) *--__res = *--__last; |
| return __res; |
| } |
| |
| private: |
| |
| iterator _C_begin; |
| iterator _C_end; |
| unsigned int * _C_bufend; |
| |
| unsigned int* _C_bit_alloc (size_type __n) { |
| return _C_value_alloc_type(*this). |
| allocate ((__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT, |
| pointer(_C_begin._C_p)); |
| } |
| |
| void _C_init (size_type __n) { |
| unsigned int* __q = _C_bit_alloc(__n); |
| _C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT; |
| _C_begin = iterator(__q, 0); |
| _C_end = _C_begin + __n; |
| } |
| |
| void _C_insert (iterator, bool); |
| |
| public: |
| |
| vector (const _Allocator& __alloc = allocator_type ()) |
| : allocator_type (__alloc), _C_begin(iterator()), _C_end(iterator()), |
| _C_bufend () { } |
| |
| #if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530 |
| // working around a SunPro 5.3 bug (see PR #25962) |
| explicit |
| #endif // SunPro > 5.3 |
| vector (size_type __n, bool __val = bool (), |
| const _Allocator& __alloc = allocator_type ()) |
| : allocator_type (__alloc), _C_bufend () { |
| _C_init(__n); |
| unsigned int * __first = _C_begin._C_p; |
| size_type __m = (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT; |
| while (__m-- > 0) *__first++ = __val ? ~0 : 0; |
| } |
| |
| vector (const _C_self &__x) |
| : allocator_type (__x.get_allocator ()), _C_bufend () { |
| _C_init (__x.size ()); |
| _C_copy (__x.begin (), __x.end (), _C_begin); |
| } |
| |
| template<class _InputIter> |
| vector (_InputIter __first, _InputIter __last) |
| : allocator_type (), _C_bufend () |
| { |
| size_type __n = _DISTANCE (__first, __last, size_type); |
| _C_init(__n); |
| _C_copy(__first, __last, _C_begin); |
| } |
| |
| ~vector () { |
| _C_value_alloc_type(*this).deallocate(_C_begin._C_p, |
| _C_bufend - _C_begin._C_p); |
| } |
| _C_self& operator= (const _C_self& __x) |
| { |
| if (&__x == this) return *this; |
| if (__x.size() > capacity()) |
| { |
| _C_value_alloc_type(*this).deallocate(_C_begin._C_p, |
| _C_bufend - _C_begin._C_p); |
| _C_init(__x.size()); |
| } |
| _C_copy(__x.begin(), __x.end(), begin()); |
| _C_end = begin() + __x.size(); |
| return *this; |
| } |
| |
| template<class _InputIter> |
| void assign (_InputIter __first, _InputIter __last) { |
| clear (); |
| insert (begin (), __first, __last); |
| } |
| |
| void assign (size_type __n, const bool& __x = bool()) { |
| clear (); |
| insert (begin (), __n, __x); |
| } |
| |
| allocator_type get_allocator() const { |
| return *this; |
| } |
| |
| // |
| // iterators |
| // |
| iterator begin () { return _C_begin; } |
| const_iterator begin () const |
| { return const_iterator(_C_begin._C_p,_C_begin._C_offset); } |
| iterator end () { return _C_end; } |
| const_iterator end () const |
| { return const_iterator(_C_end._C_p,_C_end._C_offset); } |
| |
| reverse_iterator rbegin () { return reverse_iterator(end()); } |
| const_reverse_iterator rbegin () const |
| { |
| return const_reverse_iterator(end()); |
| } |
| reverse_iterator rend () { return reverse_iterator(begin()); } |
| const_reverse_iterator rend () const |
| { |
| return const_reverse_iterator(begin()); |
| } |
| |
| // |
| // capacity |
| // |
| size_type size () const { return size_type(end() - begin()); } |
| size_type max_size () const { |
| return _C_value_alloc_type(*this).max_size(); |
| } |
| void resize (size_type __new_size, bool __c = false); |
| size_type capacity () const |
| { |
| return size_type(const_iterator(_C_bufend, 0) - begin()); |
| } |
| bool empty () const { return begin() == end(); } |
| void reserve (size_type __n) |
| { |
| _RWSTD_REQUIRES (__n <= max_size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector<bool>::reserve (size_type)"), |
| __n, max_size ())); |
| |
| if (capacity() < __n) |
| { |
| unsigned int* __q = _C_bit_alloc(__n); |
| _C_end = _C_copy(begin(), end(), iterator(__q, 0)); |
| _C_value_alloc_type(*this).deallocate(_C_begin._C_p, |
| _C_bufend - _C_begin._C_p); |
| _C_begin = iterator(__q, 0); |
| _C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT; |
| } |
| } |
| |
| // |
| // element access |
| // |
| reference operator[] (size_type __n) |
| { |
| #ifdef _RWSTD_BOUNDS_CHECKING |
| |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector<bool>::[](size_type)"), |
| __n, size ())); |
| |
| #endif // _RWSTD_BOUNDS_CHECKING |
| |
| return *(begin() + __n); |
| } |
| const_reference operator[] (size_type __n) const |
| { |
| #ifdef _RWSTD_BOUNDS_CHECKING |
| |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector<bool>::[](size_type)"), |
| __n, size ())); |
| |
| #endif // _RWSTD_BOUNDS_CHECKING |
| |
| return *(begin() + __n); |
| } |
| reference at (size_type __n) |
| { |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector<bool>::at(size_type)"), |
| __n, size ())); |
| return *(begin() + __n); |
| } |
| const_reference at (size_type __n) const |
| { |
| _RWSTD_REQUIRES (__n < size (), |
| (_RWSTD_ERROR_LENGTH_ERROR, |
| _RWSTD_FUNC ("vector<bool>::at(size_type) const"), |
| __n, size ())); |
| |
| return *(begin() + __n); |
| } |
| reference front () { return *begin(); } |
| const_reference front () const { return *begin(); } |
| reference back () { return *(end() - 1); } |
| const_reference back () const { return *(end() - 1); } |
| |
| // |
| // modifiers |
| // |
| void push_back (const bool& __x) |
| { |
| if (_C_end._C_p != _C_bufend) { |
| ++_C_end; |
| *(_C_end-1) = __x; |
| } |
| else |
| _C_insert(end(), __x); |
| } |
| |
| void pop_back () { --_C_end; } |
| |
| iterator insert (iterator __it, const bool& __x = bool()) |
| { |
| size_type __n = __it - begin(); |
| if (_C_end._C_p != _C_bufend && __it == end()) { |
| ++_C_end; |
| *(_C_end-1) = __x; |
| } |
| else |
| _C_insert(__it, __x); |
| return begin() + __n; |
| } |
| |
| void insert (iterator __it, size_type __n, const bool& __x); |
| |
| template<class _InputIter> |
| void insert (iterator __it, _InputIter __first, |
| _InputIter __last); |
| |
| iterator erase (iterator __it) |
| { |
| if (!(__it + 1 == end())) |
| _C_copy(__it + 1, end(), __it); |
| --_C_end; |
| return __it; |
| } |
| |
| iterator erase(iterator __first, iterator __last) |
| { |
| _C_end = _C_copy(__last, end(), __first); |
| return __first; |
| } |
| |
| void swap (_C_self& __x) |
| { |
| if((_C_value_alloc_type)*this == (_C_value_alloc_type)__x) |
| { |
| _STD::swap (_C_begin, __x._C_begin); |
| _STD::swap (_C_end, __x._C_end); |
| _STD::swap (_C_bufend, __x._C_bufend); |
| } |
| else |
| { |
| _C_self _x = *this; |
| *this = __x; |
| __x=_x; |
| } |
| } |
| |
| static void swap(reference __x, reference __y); |
| |
| void flip (); |
| |
| void clear() |
| { |
| erase(begin(),end()); |
| } |
| |
| #if defined (_RWSTD_NO_PART_SPEC_OVERLOAD) |
| friend void swap (vector& __lhs, vector& __rhs) { |
| __lhs.swap (__rhs); |
| } |
| #endif |
| |
| }; |
| |
| #undef _Allocator |
| |
| #endif // _RWSTD_NO_BOOL |
| |
| #endif // _RWSTD_NO_VECTOR_BOOL |
| |
| } // namespace std |
| |
| |
| #if defined (_RWSTD_NO_IMPLICIT_INCLUSION) |
| # include <vector.cc> |
| #endif |
| |
| |
| #endif // _RWSTD_VECTOR_INCLUDED |