// -*- C++ -*- /*************************************************************************** * * vector - declarations for the Standard Library vector class * * $Id$ * *************************************************************************** * * 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. * *************************************************************************** * * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave * Software division. Licensed 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. * **************************************************************************/ #ifndef _RWSTD_VECTOR_INCLUDED #define _RWSTD_VECTOR_INCLUDED #include #include #include #include #include #include _RWSTD_NAMESPACE (std) { _EXPORT template ) > class vector; #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES # ifdef _RWSTD_NO_MEMBER_TEMPLATES // declarations of non-member function templates implementing // the functionality of vector member function templates _EXPORT template void __rw_assign_range (vector<_TypeT, _Allocator>*, _InputIter, _InputIter, input_iterator_tag); _EXPORT template void __rw_assign_range (vector<_TypeT, _Allocator>*, _FwdIter, _FwdIter, forward_iterator_tag); _EXPORT template void __rw_insert_range (vector<_TypeT, _Allocator>*, _VectorIter, _InputIter, _InputIter, input_iterator_tag); _EXPORT template void __rw_insert_range (vector<_TypeT, _Allocator>*, _VectorIter, _FwdIter, _FwdIter, forward_iterator_tag); # endif // _RWSTD_NO_MEMBER_TEMPLATES #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES _EXPORT template class vector: private _Allocator { 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; typedef _RWSTD_ALLOC_TYPE (allocator_type, value_type) _C_value_alloc_type; public: #ifndef _RWSTD_NO_DEBUG_ITER typedef _RW::__rw_debug_iter iterator; typedef _RW::__rw_debug_iter 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_reverse_iterator; typedef _STD::reverse_iterator reverse_iterator; #else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef _STD::reverse_iterator const_reverse_iterator; typedef _STD::reverse_iterator reverse_iterator; #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC public: _EXPLICIT vector (const allocator_type &__alloc = allocator_type ()) : allocator_type (__alloc), _C_begin (0), _C_end (0), _C_bufend (0) { } _EXPLICIT vector (size_type __n, const_reference __x = value_type (), const allocator_type &__alloc = allocator_type ()) : allocator_type (__alloc), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__n, __x); } #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES # if !defined (_MSC_VER) || _MSC_VER >= 1300 template vector (_InputIter __first, _InputIter __last, const allocator_type &__alloc = allocator_type ()) : allocator_type (__alloc), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__first, __last); } # else // if !MSVC || MSVC <= 6.0 // working around an MSVC 6.0 ICE (bug #554) template vector (_InputIter __first, _InputIter __last) : allocator_type (), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__first, __last); } template vector (_InputIter __first, _InputIter __last, const allocator_type &__alloc) : allocator_type (__alloc), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__first, __last); } # endif // MSVC <= 6.0 #else // defined _RWSTD_NO_INLINE_MEMBER_TEMPLATES vector (const_iterator __first, const_iterator __last, const _Allocator &__alloc = allocator_type ()) : allocator_type (__alloc), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__first, __last); } #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES vector (const vector &__rhs) : allocator_type (__rhs.get_allocator ()), _C_begin (0), _C_end (0), _C_bufend (0) { assign (__rhs.begin (), __rhs.end ()); } ~vector () { _C_destroy (begin (), end ()); _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, deallocate (_C_begin, _C_bufend - _C_begin)); } vector& operator= (const vector&); #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES template 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)); } #else // if defined (_RWSTD_NO_INLINE_MEMBER_TEMPLATES) void assign (const_iterator, const_iterator); # ifndef _RWSTD_NO_DEBUG_ITER // otherwise, const_pointer is the same as const_iterator void assign (const_pointer, const_pointer); # endif // _RWSTD_NO_DEBUG_ITER #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES void assign (size_type __n, const_reference __x) { _C_assign_n (__n, __x); } allocator_type get_allocator () const { return *this; } iterator begin () { return _C_make_iter (_C_begin); } const_iterator begin () const { return _C_make_iter (_C_begin); } iterator end () { return _C_make_iter (_C_end); } const_iterator end () const { return _C_make_iter (_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_end - _C_begin); } size_type max_size () const { return _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, max_size ()); } void resize (size_type, value_type = value_type ()); size_type capacity () const { return _C_bufend - _C_begin; } bool empty () const { return _C_begin == _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 ()); _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1)); --_C_end; } iterator insert (iterator, const_reference); #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES template void insert (iterator __it, _InputIter __first, _InputIter __last) { _C_insert (__it, __first, __last, _RWSTD_DISPATCH (_InputIter)); } #else // if defined (_RWSTD_NO_INLINE_MEMBER_TEMPLATES) void insert (iterator __it, const_iterator __first, const_iterator __last) { _RWSTD_INSERT_RANGE (__it, __first, __last); } #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES 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 () { erase (begin (), end ()); } 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); #ifndef _RWSTD_NO_MEMBER_TEMPLATES // implements range insert for ForwardIterators template void _C_insert_range (iterator, _FwdIter, _FwdIter, forward_iterator_tag); // implements range insert for InputIterators template void _C_insert_range (iterator, _InputIter, _InputIter, input_iterator_tag); #else // if defined (_RWSTD_NO_MEMBER_TEMPLATES) public: #endif // _RWSTD_NO_MEMBER_TEMPLATES #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES // implements range assign template 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 void _C_assign (_IntType __n, _IntType __x, int) { _C_assign_n (size_type (__n), __x); } // implements range insert for ForwardIterators template void _C_assign_range (_FwdIter, _FwdIter, forward_iterator_tag); // implements range insert for InputIterators template void _C_assign_range (_InputIter, _InputIter, input_iterator_tag); // implements range insert template 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 void _C_insert (const iterator &__it, _IntType __n, _IntType __x, int) { _C_insert_n (__it, size_type (__n), __x); } #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES void _C_realloc (size_type); void _C_construct (pointer __where, const_reference __what) { _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, construct (__where, __what)); } void _C_destroy (iterator __first, iterator __last) { for ( ; __first != __last; ++__first) _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, address (*__first)))); } pointer _C_begin; pointer _C_end; pointer _C_bufend; }; template 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 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 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 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 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 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 inline void vector<_TypeT, _Allocator>:: push_back (const_reference __x) { if (_C_end == _C_bufend) { _C_insert_1 (end (), __x); } else { _C_construct (_C_end, __x); ++_C_end; } } template inline _TYPENAME vector<_TypeT, _Allocator>::iterator vector<_TypeT, _Allocator>:: insert (iterator __it, const_reference __x) { const difference_type __off = __it - begin (); if (end () == __it) push_back (__x); else _C_insert_1 (__it, __x); return begin () + __off; } template inline _TYPENAME vector<_TypeT, _Allocator>::iterator vector<_TypeT, _Allocator>:: erase (iterator __it) { if (!empty ()) { if (__it + 1 != end ()) _STD::copy (__it + 1, end (), __it); _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1)); --_C_end; } return __it; } template inline _TYPENAME vector<_TypeT, _Allocator>::iterator vector<_TypeT, _Allocator>:: erase (iterator __first, iterator __last) { _RWSTD_ASSERT_RANGE (__first, __last); _RWSTD_ASSERT_RANGE (begin (), __first); const iterator __it = _STD::copy (__last, end (), __first); _C_destroy (__it, end ()); _C_end -= __last - __first; return __first; } template inline void vector<_TypeT, _Allocator>:: swap (vector &__other) { if (get_allocator () == __other.get_allocator ()) { _STD::swap (_C_begin, __other._C_begin); _STD::swap (_C_end, __other._C_end); _STD::swap (_C_bufend, __other._C_bufend); } else { // not exception-safe // avoid passing the whole object to other vector member // functions (i.e., assign()) in case they are implemented // in terms of swap(); use iterators instead vector __tmp (__other.get_allocator ()); // assert that the copy of the allocator compares equal // to the original (otherwise the swap() below will cause // a recursive call) _RWSTD_ASSERT (__tmp.get_allocator () == __other.get_allocator ()); __tmp.assign (begin (), end ()); __other.swap (__tmp); } } template 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 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 inline bool operator!= (const vector<_TypeT, _Allocator> &__x, const vector<_TypeT, _Allocator> &__y) { return !(__x == __y); } template inline bool operator> (const vector<_TypeT, _Allocator> &__x, const vector<_TypeT, _Allocator> &__y) { return __y < __x; } template inline bool operator>= (const vector<_TypeT, _Allocator> &__x, const vector<_TypeT, _Allocator> &__y) { return !(__x < __y); } template inline bool operator<= (const vector<_TypeT, _Allocator> &__x, const vector<_TypeT, _Allocator> &__y) { return !(__y < __x); } #ifndef _RWSTD_NO_PART_SPEC_OVERLOAD template 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 # define _VB_TYPENAME _TYPENAME _EXPORT template class #else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) # define _VB_TYPENAME // use a macro to mutate _Allocator into allocator # define _Allocator allocator _RWSTD_SPECIALIZED_CLASS class _RWSTD_EXPORT #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC vector: private _Allocator { typedef _RWSTD_REBIND(_Allocator, unsigned int) _C_value_alloc_type; typedef vector _C_self; public: typedef _Allocator allocator_type; typedef bool value_type; typedef _VB_TYPENAME allocator_type::size_type size_type; typedef _VB_TYPENAME allocator_type::difference_type difference_type; typedef _VB_TYPENAME _C_value_alloc_type::pointer pointer; typedef _VB_TYPENAME _C_value_alloc_type::const_pointer const_pointer; 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(0), _C_mask(0) {} 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; #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__) _C_iter (const _C_iter& __it) : _C_p (__it._C_p), _C_offset (__it._C_offset) {} #endif // __GNUG__ 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 { 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); } }; class const_iterator : public _C_iter, public _STD::iterator { 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); } }; #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC typedef _STD::reverse_iterator const_reverse_iterator; typedef _STD::reverse_iterator reverse_iterator; #else typedef _STD::reverse_iterator const_reverse_iterator; typedef _STD::reverse_iterator 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; } #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES template iterator _C_copy (_Iterator __first, _Iterator __last, iterator __res) { while (__first != __last) *__res++ = *__first++; return __res; } template iterator _C_copy_backward (_Iterator __first, _Iterator __last, iterator __res) { while (__first != __last) *--__res = *--__last; return __res; } #else iterator _C_copy (const_iterator __first, const_iterator __last, iterator __res) { while (__first != __last) *__res++ = *__first++; return __res; } iterator _C_copy (const bool* __first, const bool* __last, iterator __res) { while (__first != __last) *__res++ = *__first++; return __res; } iterator _C_copy_backward (const_iterator __first, const_iterator __last, iterator __res) { while (__first != __last) *--__res = *--__last; return __res; } iterator _C_copy_backward (const bool* __first, const bool* __last, iterator __res) { while (__first != __last) *--__res = *--__last; return __res; } #endif 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(0) { } #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(0) { _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 (0) { _C_init (__x.size ()); _C_copy (__x.begin (), __x.end (), _C_begin); } #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES template vector (_InputIter __first, _InputIter __last) : allocator_type (), _C_bufend(0) { size_type __n = _DISTANCE (__first, __last, size_type); _C_init(__n); _C_copy(__first, __last, _C_begin); } #else vector (const_iterator __first, const_iterator __last) : allocator_type (), _C_bufend(0) { size_type __n = _DISTANCE (__first, __last, size_type); _C_init(__n); _C_copy(__first, __last, _C_begin); } vector (const bool* __first, const bool* __last) : allocator_type (), _C_bufend(0) { size_type __n = _DISTANCE (__first, __last, size_type); _C_init(__n); _C_copy(__first, __last, _C_begin); } #endif ~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; } #ifndef _RWSTD_NO_INLINE_MEMBER_TEMPLATES template void assign (_InputIter __first, _InputIter __last) { erase (begin (), end ()); insert (begin (), __first, __last); } #else // if defined (_RWSTD_NO_INLINE_MEMBER_TEMPLATES) void assign (const_iterator __first, const_iterator __last) { erase (begin (), end ()); insert (begin (), __first, __last); } #endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES void assign (size_type __n, const bool& __x = bool()) { erase (begin (), end ()); 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::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::[](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::[](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::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::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); #ifndef _RWSTD_NO_MEMBER_TEMPLATES template void insert (iterator __it, _InputIter __first, _InputIter __last); #else void insert (iterator __it, const_iterator __first, const_iterator __last); #endif 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()); } }; #undef _Allocator #endif // _RWSTD_NO_BOOL #endif // _RWSTD_NO_VECTOR_BOOL } // namespace std #if defined (_RWSTD_NO_IMPLICIT_INCLUSION) # include #endif #ifndef _RWSTD_NO_STL_SPECIALIZATION #include "vector_spec.h" #endif // _RWSTD_NO_STL_SPECIALIZATION #endif // _RWSTD_VECTOR_INCLUDED