#ifndef _VECTOR_ #define _VECTOR_ #include #include namespace RGL { //_STD_BEGIN template > class vector; #if _HAS_TRADITIONAL_ITERATORS #else /* _HAS_TRADITIONAL_ITERATORS */ // TEMPLATE CLASS _Vector_const_iterator template class _Vector_const_iterator : public ::std::_Ranit < _Ty, typename _Alloc::difference_type, typename _Alloc::const_pointer, typename _Alloc::const_reference > { // iterator for nonmutable vector public: typedef _Vector_const_iterator<_Ty, _Alloc> _Myt; typedef vector<_Ty, _Alloc> _Myvec; typedef typename _Alloc::pointer _Tptr; typedef ::std::random_access_iterator_tag iterator_category; typedef _Ty value_type; typedef typename _Alloc::difference_type difference_type; typedef typename _Alloc::const_pointer pointer; typedef typename _Alloc::const_reference reference; _Vector_const_iterator() { // construct with null pointer _Myptr = 0; } _Vector_const_iterator( _Tptr _Ptr ) { // construct with pointer _Ptr _Myptr = _Ptr; } reference operator*() const { // return designated object return ( *_Myptr ); } pointer operator->() const { // return pointer to class object return ( &**this ); } _Myt& operator++() { // preincrement ++_Myptr; return ( *this ); } _Myt operator++( int ) { // postincrement _Myt _Tmp = *this; ++*this; return ( _Tmp ); } _Myt& operator--() { // predecrement --_Myptr; return ( *this ); } _Myt operator--( int ) { // postdecrement _Myt _Tmp = *this; --*this; return ( _Tmp ); } _Myt& operator+=( difference_type _Off ) { // increment by integer _Myptr += _Off; return ( *this ); } _Myt operator+( difference_type _Off ) const { // return this + integer _Myt _Tmp = *this; return ( _Tmp += _Off ); } _Myt& operator-=( difference_type _Off ) { // decrement by integer return ( *this += -_Off ); } _Myt operator-( difference_type _Off ) const { // return this - integer _Myt _Tmp = *this; return ( _Tmp -= _Off ); } difference_type operator-( const _Myt& _Right ) const { // return difference of iterators return ( _Myptr - _Right._Myptr ); } reference operator[]( difference_type _Off ) const { // subscript return ( *( *this + _Off ) ); } bool operator==( const _Myt& _Right ) const { // test for iterator equality return ( _Myptr == _Right._Myptr ); } bool operator!=( const _Myt& _Right ) const { // test for iterator inequality return ( !( *this == _Right ) ); } bool operator<( const _Myt& _Right ) const { // test if this < _Right return ( _Myptr < _Right._Myptr ); } bool operator>( const _Myt& _Right ) const { // test if this > _Right return ( _Right < *this ); } bool operator<=( const _Myt& _Right ) const { // test if this <= _Right return ( !( _Right < *this ) ); } bool operator>=( const _Myt& _Right ) const { // test if this >= _Right return ( !( *this < _Right ) ); } _Tptr _Myptr; // offset of element in vector }; template inline _Vector_const_iterator<_Ty, _Alloc> operator+( typename _Vector_const_iterator<_Ty, _Alloc>::difference_type _Off, _Vector_const_iterator<_Ty, _Alloc> _Next ) { // add offset to iterator return ( _Next += _Off ); } // TEMPLATE CLASS _Vector_iterator template class _Vector_iterator : public _Vector_const_iterator<_Ty, _Alloc> { // iterator for mutable vector public: typedef _Vector_iterator<_Ty, _Alloc> _Myt; typedef _Vector_const_iterator<_Ty, _Alloc> _Mybase; typedef ::std::random_access_iterator_tag iterator_category; typedef _Ty value_type; typedef typename _Alloc::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::reference reference; _Vector_iterator() { // construct with null vector pointer } _Vector_iterator( pointer _Ptr ) : _Mybase( _Ptr ) { // construct with pointer _Ptr } reference operator*() const { // return designated object return (( reference )**( _Mybase * )this ); } pointer operator->() const { // return pointer to class object return ( &**this ); } _Myt& operator++() { // preincrement ++this->_Myptr; return ( *this ); } _Myt operator++( int ) { // postincrement _Myt _Tmp = *this; ++*this; return ( _Tmp ); } _Myt& operator--() { // predecrement --this->_Myptr; return ( *this ); } _Myt operator--( int ) { // postdecrement _Myt _Tmp = *this; --*this; return ( _Tmp ); } _Myt& operator+=( difference_type _Off ) { // increment by integer this->_Myptr += _Off; return ( *this ); } _Myt operator+( difference_type _Off ) const { // return this + integer _Myt _Tmp = *this; return ( _Tmp += _Off ); } _Myt& operator-=( difference_type _Off ) { // decrement by integer return ( *this += -_Off ); } _Myt operator-( difference_type _Off ) const { // return this - integer _Myt _Tmp = *this; return ( _Tmp -= _Off ); } difference_type operator-( const _Mybase& _Right ) const { // return difference of iterators return ( *( _Mybase * )this - _Right ); } reference operator[]( difference_type _Off ) const { // subscript return ( *( *this + _Off ) ); } }; template inline _Vector_iterator<_Ty, _Alloc> operator+( typename _Vector_iterator<_Ty, _Alloc>::difference_type _Off, _Vector_iterator<_Ty, _Alloc> _Next ) { // add offset to iterator return ( _Next += _Off ); } #endif /* _HAS_TRADITIONAL_ITERATORS */ // TEMPLATE CLASS _Vector_val template class _Vector_val : public ::std::_Container_base { // base class for vector to hold allocator _Alval protected: _Vector_val( _Alloc _Al = _Alloc() ) : _Alval( _Al ) { // construct allocator from _Al } typedef typename _Alloc::template rebind<_Ty>::other _Alty; _Alty _Alval; // allocator object for values }; // TEMPLATE CLASS vector template class vector : public _Vector_val<_Ty, _Ax> { // varying size array of values public: typedef vector<_Ty, _Ax> _Myt; typedef _Vector_val<_Ty, _Ax> _Mybase; typedef typename _Mybase::_Alty _Alloc; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type _Dift; typedef _Dift difference_type; typedef typename _Alloc::pointer _Tptr; typedef typename _Alloc::const_pointer _Ctptr; typedef _Tptr pointer; typedef _Ctptr const_pointer; typedef typename _Alloc::reference _Reft; typedef _Reft reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Alloc::value_type value_type; #if _HAS_TRADITIONAL_ITERATORS #define _VEC_ITER_BASE(it) (it) typedef pointer iterator; typedef const_pointer const_iterator; #else /* _HAS_TRADITIONAL_ITERATORS */ #define _VEC_ITER_BASE(it) (it)._Myptr typedef _Vector_iterator<_Ty, _Alloc> iterator; typedef _Vector_const_iterator<_Ty, _Alloc> const_iterator; // friend class _Vector_iterator<_Ty, _Alloc>; friend class _Vector_const_iterator<_Ty, _Alloc>; #endif /* _HAS_TRADITIONAL_ITERATORS */ typedef _STD reverse_iterator reverse_iterator; typedef _STD reverse_iterator const_reverse_iterator; vector() : _Mybase() { // construct empty vector _Buy( 0 ); } explicit vector( const _Alloc& _Al ) : _Mybase( _Al ) { // construct empty vector with allocator _Buy( 0 ); } explicit vector( size_type _Count ) : _Mybase() { // construct from _Count * _Ty() _Construct_n( _Count, _Ty() ); } vector( size_type _Count, const _Ty& _Val ) : _Mybase() { // construct from _Count * _Val _Construct_n( _Count, _Val ); } vector( size_type _Count, const _Ty& _Val, const _Alloc& _Al ) : _Mybase( _Al ) { // construct from _Count * _Val, with allocator _Construct_n( _Count, _Val ); } vector( const _Myt& _Right ) : _Mybase( _Right._Alval ) { // construct by copying _Right if ( _Buy( _Right.size() ) ) _TRY_BEGIN _Mylast = _Ucopy( _Right.begin(), _Right.end(), _Myfirst ); _CATCH_ALL _Tidy(); _RERAISE; _CATCH_END } template vector( _Iter _First, _Iter _Last ) : _Mybase() { // construct from [_First, _Last) _Construct( _First, _Last, _STD _Iter_cat( _First ) ); } template vector( _Iter _First, _Iter _Last, const _Alloc& _Al ) : _Mybase( _Al ) { // construct from [_First, _Last), with allocator _Construct( _First, _Last, _STD _Iter_cat( _First ) ); } template void _Construct( _Iter _Count, _Iter _Val, ::std::_Int_iterator_tag ) { // initialize with _Count * _Val size_type _Size = ( size_type )_Count; _Construct_n( _Size, _Val ); } template void _Construct( _Iter _First, _Iter _Last, ::std::input_iterator_tag ) { // initialize with [_First, _Last), input iterators _Buy( 0 ); _TRY_BEGIN insert( begin(), _First, _Last ); _CATCH_ALL _Tidy(); _RERAISE; _CATCH_END } void _Construct_n( size_type _Count, const _Ty& _Val ) { // construct from _Count * _Val if ( _Buy( _Count ) ) { // nonzero, fill it _TRY_BEGIN _Mylast = _Ufill( _Myfirst, _Count, _Val ); _CATCH_ALL _Tidy(); _RERAISE; _CATCH_END } } ~vector() { // destroy the object _Tidy(); } _Myt& operator=( const _Myt& _Right ) { // assign _Right if ( this != &_Right ) { // worth doing if ( _Right.size() == 0 ) clear(); // new sequence empty, free storage else if ( _Right.size() <= size() ) { // enough elements, copy new and destroy old pointer _Ptr = _STD copy( _Right._Myfirst, _Right._Mylast, _Myfirst ); // copy new _Destroy( _Ptr, _Mylast ); // destroy old _Mylast = _Myfirst + _Right.size(); } else if ( _Right.size() <= capacity() ) { // enough room, copy and construct new pointer _Ptr = _Right._Myfirst + size(); _STD copy( _Right._Myfirst, _Ptr, _Myfirst ); _Mylast = _Ucopy( _Ptr, _Right._Mylast, _Mylast ); } else { // not enough room, allocate new array and construct new if ( _Myfirst != 0 ) { // discard old array _Destroy( _Myfirst, _Mylast ); this->_Alval.deallocate( _Myfirst, _Myend - _Myfirst ); } if ( _Buy( _Right.size() ) ) _Mylast = _Ucopy( _Right._Myfirst, _Right._Mylast, _Myfirst ); } } return ( *this ); } void reserve( size_type _Count ) { // determine new minimum length of allocated storage if ( max_size() < _Count ) _Xlen(); // result too long else if ( capacity() < _Count ) { // not enough room, reallocate pointer _Ptr = this->_Alval.allocate( _Count ); _TRY_BEGIN _Ucopy( begin(), end(), _Ptr ); _CATCH_ALL this->_Alval.deallocate( _Ptr, _Count ); _RERAISE; _CATCH_END size_type _Size = size(); if ( _Myfirst != 0 ) { // destroy and deallocate old array _Destroy( _Myfirst, _Mylast ); this->_Alval.deallocate( _Myfirst, _Myend - _Myfirst ); } _Myend = _Ptr + _Count; _Mylast = _Ptr + _Size; _Myfirst = _Ptr; } } size_type capacity() const { // return current length of allocated storage return ( _Myfirst == 0 ? 0 : _Myend - _Myfirst ); } iterator begin() { // return iterator for beginning of mutable sequence return ( iterator( _Myfirst ) ); } const_iterator begin() const { // return iterator for beginning of nonmutable sequence return ( const_iterator( _Myfirst ) ); } iterator end() { // return iterator for end of mutable sequence return ( iterator( _Mylast ) ); } const_iterator end() const { // return iterator for end of nonmutable sequence return ( const_iterator( _Mylast ) ); } reverse_iterator rbegin() { // return iterator for beginning of reversed mutable sequence return ( reverse_iterator( end() ) ); } const_reverse_iterator rbegin() const { // return iterator for beginning of reversed nonmutable sequence return ( const_reverse_iterator( end() ) ); } reverse_iterator rend() { // return iterator for end of reversed mutable sequence return ( reverse_iterator( begin() ) ); } const_reverse_iterator rend() const { // return iterator for end of reversed nonmutable sequence return ( const_reverse_iterator( begin() ) ); } void resize( size_type _Newsize ) { // determine new length, padding with _Ty() elements as needed resize( _Newsize, _Ty() ); } void resize( size_type _Newsize, _Ty _Val ) { // determine new length, padding with _Val elements as needed if ( size() < _Newsize ) _Insert_n( end(), _Newsize - size(), _Val ); else if ( _Newsize < size() ) erase( begin() + _Newsize, end() ); } size_type size() const { // return length of sequence return ( _Myfirst == 0 ? 0 : _Mylast - _Myfirst ); } size_type max_size() const { // return maximum possible length of sequence return ( this->_Alval.max_size() ); } bool empty() const { // test if sequence is empty return ( size() == 0 ); } _Alloc get_allocator() const { // return allocator object for values return ( this->_Alval ); } const_reference at( size_type _Pos ) const { // subscript nonmutable sequence with checking if ( size() <= _Pos ) _Xran(); return ( *( begin() + _Pos ) ); } reference at( size_type _Pos ) { // subscript mutable sequence with checking if ( size() <= _Pos ) _Xran(); return ( *( begin() + _Pos ) ); } const_reference operator[]( size_type _Pos ) const { // subscript nonmutable sequence return ( *( begin() + _Pos ) ); } reference operator[]( size_type _Pos ) { // subscript mutable sequence return ( *( begin() + _Pos ) ); } reference front() { // return first element of mutable sequence return ( *begin() ); } const_reference front() const { // return first element of nonmutable sequence return ( *begin() ); } reference back() { // return last element of mutable sequence return ( *( end() - 1 ) ); } const_reference back() const { // return last element of nonmutable sequence return ( *( end() - 1 ) ); } void push_back( const _Ty& _Val ) { // insert element at end if ( size() < capacity() ) _Mylast = _Ufill( _Mylast, 1, _Val ); else insert( end(), _Val ); } void pop_back() { // erase element at end if ( !empty() ) { // erase last element _Destroy( _Mylast - 1, _Mylast ); --_Mylast; } } template void assign( _Iter _First, _Iter _Last ) { // assign [_First, _Last) _Assign( _First, _Last, _STD _Iter_cat( _First ) ); } template void _Assign( _Iter _Count, _Iter _Val, ::std::_Int_iterator_tag ) { // assign _Count * _Val _Assign_n(( size_type )_Count, ( _Ty )_Val ); } template void _Assign( _Iter _First, _Iter _Last, ::std::input_iterator_tag ) { // assign [_First, _Last), input iterators erase( begin(), end() ); insert( begin(), _First, _Last ); } void assign( size_type _Count, const _Ty& _Val ) { // assign _Count * _Val _Assign_n( _Count, _Val ); } iterator insert( iterator _Where, const _Ty& _Val ) { // insert _Val at _Where size_type _Off = size() == 0 ? 0 : _Where - begin(); _Insert_n( _Where, ( size_type )1, _Val ); return ( begin() + _Off ); } void insert( iterator _Where, size_type _Count, const _Ty& _Val ) { // insert _Count * _Val at _Where _Insert_n( _Where, _Count, _Val ); } template void insert( iterator _Where, _Iter _First, _Iter _Last ) { // insert [_First, _Last) at _Where _Insert( _Where, _First, _Last, _STD _Iter_cat( _First ) ); } template void _Insert( iterator _Where, _Iter _First, _Iter _Last, ::std::_Int_iterator_tag ) { // insert _Count * _Val at _Where _Insert_n( _Where, ( size_type )_First, ( _Ty )_Last ); } template void _Insert( iterator _Where, _Iter _First, _Iter _Last, ::std::input_iterator_tag ) { // insert [_First, _Last) at _Where, input iterators for ( ; _First != _Last; ++_First, ++_Where ) _Where = insert( _Where, *_First ); } template void _Insert( iterator _Where, _Iter _First, _Iter _Last, ::std::forward_iterator_tag ) { // insert [_First, _Last) at _Where, forward iterators size_type _Count = 0; _STD _Distance( _First, _Last, _Count ); size_type _Capacity = capacity(); if ( _Count == 0 ) ; else if ( max_size() - size() < _Count ) _Xlen(); // result too long else if ( _Capacity < size() + _Count ) { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50% if ( _Capacity < size() + _Count ) _Capacity = size() + _Count; pointer _Newvec = this->_Alval.allocate( _Capacity ); pointer _Ptr = _Newvec; _TRY_BEGIN _Ptr = _Ucopy( _Myfirst, _VEC_ITER_BASE( _Where ), _Newvec ); // copy prefix _Ptr = _Ucopy( _First, _Last, _Ptr ); // add new stuff _Ucopy( _VEC_ITER_BASE( _Where ), _Mylast, _Ptr ); // copy suffix _CATCH_ALL _Destroy( _Newvec, _Ptr ); this->_Alval.deallocate( _Newvec, _Capacity ); _RERAISE; _CATCH_END _Count += size(); if ( _Myfirst != 0 ) { // destroy and deallocate old array _Destroy( _Myfirst, _Mylast ); this->_Alval.deallocate( _Myfirst, _Myend - _Myfirst ); } _Myend = _Newvec + _Capacity; _Mylast = _Newvec + _Count; _Myfirst = _Newvec; } else if (( size_type )( end() - _Where ) < _Count ) { // new stuff spills off end _Ucopy( _VEC_ITER_BASE( _Where ), _Mylast, _VEC_ITER_BASE( _Where ) + _Count ); // copy suffix _Iter _Mid = _First; _STD advance( _Mid, end() - _Where ); _TRY_BEGIN _Ucopy( _Mid, _Last, _Mylast ); // insert new stuff off end _CATCH_ALL _Destroy( _VEC_ITER_BASE( _Where ) + _Count, _Mylast + _Count ); _RERAISE; _CATCH_END _Mylast += _Count; _STD copy( _First, _Mid, _VEC_ITER_BASE( _Where ) ); // insert to old end } else { // new stuff can all be assigned pointer _Oldend = _Mylast; _Mylast = _Ucopy( _Oldend - _Count, _Oldend, _Mylast ); // copy suffix _STD copy_backward( _VEC_ITER_BASE( _Where ), _Oldend - _Count, _Oldend ); // copy hole _STD copy( _First, _Last, _VEC_ITER_BASE( _Where ) ); // insert into hole } } iterator erase( iterator _Where ) { // erase element at where _STD copy( _VEC_ITER_BASE( _Where ) + 1, _Mylast, _VEC_ITER_BASE( _Where ) ); _Destroy( _Mylast - 1, _Mylast ); --_Mylast; return ( _Where ); } iterator erase( iterator _First, iterator _Last ) { // erase [_First, _Last) if ( _First != _Last ) { // worth doing, copy down over hole pointer _Ptr = _STD copy( _VEC_ITER_BASE( _Last ), _Mylast, _VEC_ITER_BASE( _First ) ); _Destroy( _Ptr, _Mylast ); _Mylast = _Ptr; } return ( _First ); } void clear() { // erase all _Tidy(); } void swap( _Myt& _Right ) { // exchange contents with _Right if ( this->_Alval == _Right._Alval ) { // same allocator, swap control information _STD swap( _Myfirst, _Right._Myfirst ); _STD swap( _Mylast, _Right._Mylast ); _STD swap( _Myend, _Right._Myend ); } else { // different allocator, do multiple assigns _Myt _Ts = *this; *this = _Right, _Right = _Ts; } } protected: void _Assign_n( size_type _Count, const _Ty& _Val ) { // assign _Count * _Val _Ty _Tmp = _Val; // in case _Val is in sequence erase( begin(), end() ); insert( begin(), _Count, _Tmp ); } bool _Buy( size_type _Capacity ) { // allocate array with _Capacity elements _Myfirst = 0, _Mylast = 0, _Myend = 0; if ( _Capacity == 0 ) return ( false ); else if ( max_size() < _Capacity ) _Xlen(); // result too long else { // nonempty array, allocate storage _Myfirst = this->_Alval.allocate( _Capacity ); _Mylast = _Myfirst; _Myend = _Myfirst + _Capacity; } return ( true ); } void _Destroy( pointer _First, pointer _Last ) { // destroy [_First, _Last) using allocator _Destroy_range( _First, _Last, this->_Alval ); } void _Tidy() { // free all storage if ( _Myfirst != 0 ) { // something to free, destroy and deallocate it _Destroy( _Myfirst, _Mylast ); this->_Alval.deallocate( _Myfirst, _Myend - _Myfirst ); } _Myfirst = 0, _Mylast = 0, _Myend = 0; } template pointer _Ucopy( _Iter _First, _Iter _Last, pointer _Ptr ) { // copy initializing [_First, _Last), using allocator return ( _Uninitialized_copy( _First, _Last, _Ptr, this->_Alval ) ); } void _Insert_n( iterator _Where, size_type _Count, const _Ty& _Val ) { // insert _Count * _Val at _Where _Ty _Tmp = _Val; // in case _Val is in sequence size_type _Capacity = capacity(); if ( _Count == 0 ) ; else if ( max_size() - size() < _Count ) _Xlen(); // result too long else if ( _Capacity < size() + _Count ) { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50% if ( _Capacity < size() + _Count ) _Capacity = size() + _Count; pointer _Newvec = this->_Alval.allocate( _Capacity ); pointer _Ptr = _Newvec; _TRY_BEGIN _Ptr = _Ucopy( _Myfirst, _VEC_ITER_BASE( _Where ), _Newvec ); // copy prefix _Ptr = _Ufill( _Ptr, _Count, _Tmp ); // add new stuff _Ucopy( _VEC_ITER_BASE( _Where ), _Mylast, _Ptr ); // copy suffix _CATCH_ALL _Destroy( _Newvec, _Ptr ); this->_Alval.deallocate( _Newvec, _Capacity ); _RERAISE; _CATCH_END _Count += size(); if ( _Myfirst != 0 ) { // destroy and deallocate old array _Destroy( _Myfirst, _Mylast ); this->_Alval.deallocate( _Myfirst, _Myend - _Myfirst ); } _Myend = _Newvec + _Capacity; _Mylast = _Newvec + _Count; _Myfirst = _Newvec; } else if (( size_type )( _Mylast - _VEC_ITER_BASE( _Where ) ) < _Count ) { // new stuff spills off end _Ucopy( _VEC_ITER_BASE( _Where ), _Mylast, _VEC_ITER_BASE( _Where ) + _Count ); // copy suffix _TRY_BEGIN _Ufill( _Mylast, _Count - ( _Mylast - _VEC_ITER_BASE( _Where ) ), _Tmp ); // insert new stuff off end _CATCH_ALL _Destroy( _VEC_ITER_BASE( _Where ) + _Count, _Mylast + _Count ); _RERAISE; _CATCH_END _Mylast += _Count; _STD fill( _VEC_ITER_BASE( _Where ), _Mylast - _Count, _Tmp ); // insert up to old end } else { // new stuff can all be assigned pointer _Oldend = _Mylast; _Mylast = _Ucopy( _Oldend - _Count, _Oldend, _Mylast ); // copy suffix _STD copy_backward( _VEC_ITER_BASE( _Where ), _Oldend - _Count, _Oldend ); // copy hole _STD fill( _VEC_ITER_BASE( _Where ), _VEC_ITER_BASE( _Where ) + _Count, _Tmp ); // insert into hole } } pointer _Ufill( pointer _Ptr, size_type _Count, const _Ty &_Val ) { // copy initializing _Count * _Val, using allocator _Uninitialized_fill_n( _Ptr, _Count, _Val, this->_Alval ); return ( _Ptr + _Count ); } void _Xlen() const { // report a length_error } void _Xran() const { // report an out_of_range error } pointer _Myfirst; // pointer to beginning of array pointer _Mylast; // pointer to current end of sequence pointer _Myend; // pointer to end of array }; // vector TEMPLATE FUNCTIONS template inline bool operator==( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test for vector equality return ( _Left.size() == _Right.size() && _STD equal( _Left.begin(), _Left.end(), _Right.begin() ) ); } template inline bool operator!=( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test for vector inequality return ( !( _Left == _Right ) ); } template inline bool operator<( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test if _Left < _Right for vectors return ( _STD lexicographical_compare( _Left.begin(), _Left.end(), _Right.begin(), _Right.end() ) ); } template inline bool operator>( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test if _Left > _Right for vectors return ( _Right < _Left ); } template inline bool operator<=( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test if _Left <= _Right for vectors return ( !( _Right < _Left ) ); } template inline bool operator>=( const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right ) { // test if _Left >= _Right for vectors return ( !( _Left < _Right ) ); } template inline void swap( vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right ) { // swap _Left and _Right vectors _Left.swap( _Right ); } // CLASS vector typedef unsigned _Vbase; // word type for vector representation const int _VBITS = 8 * sizeof( _Vbase ); // at least CHAR_BITS bits per word template class vector< ::std::_Bool, _Alloc> : public ::std::_Container_base { // varying size array of bits public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type _Dift; typedef vector < _Vbase, typename _Alloc::template rebind<_Vbase>::other > _Vbtype; typedef vector< _STD _Bool, _Alloc> _Myt; typedef _Dift difference_type; typedef _STD _Bool _Ty; typedef _Alloc allocator_type; typedef bool const_reference; typedef bool value_type; #define _VB_TYPENAME typename // CLASS _Vb_iter_base class _Vb_iter_base : public _STD _Ranit< _STD _Bool, _Dift, value_type *, value_type> { // store information common to reference and iterators public: _Vb_iter_base() : _Myoff( 0 ), _Myptr( 0 ) { // construct with null pointer } _Vb_iter_base( const _Vb_iter_base& _Right ) : _Myptr( _Right._Myptr ), _Myoff( _Right._Myoff ) { // construct with copy of _Right } _Vb_iter_base( _Vbase *_Ptr ) : _Myoff( 0 ), _Myptr( _Ptr ) { // construct with offset and pointer } size_type _Myoff; _Vbase *_Myptr; }; // CLASS reference class reference; friend class reference; class reference : public _Vb_iter_base { // reference to a bit within a base word public: reference() { // construct with null pointer } reference( const _Vb_iter_base& _Right ) : _Vb_iter_base( _Right ) { // construct with base } reference& operator=( const reference& _Right ) { // assign reference _Right to bit return ( *this = bool( _Right ) ); } reference& operator=( bool _Val ) { // assign _Val to bit if ( _Val ) *_Getptr() |= _Mask(); else *_Getptr() &= ~_Mask(); return ( *this ); } void flip() { // toggle the bit *_Getptr() ^= _Mask(); } bool operator~() const { // test if bit is reset return ( !bool( *this ) ); } operator bool() const { // test if bit is set return (( *_Getptr() & _Mask() ) != 0 ); } _Vbase *_Getptr() const { // get pointer to base word return ( this->_Myptr ); } protected: _Vbase _Mask() const { // convert offset to mask return (( _Vbase )( 1 << this->_Myoff ) ); } }; typedef reference _Reft; // CLASS const_iterator class const_iterator : public _Vb_iter_base { // iterator for nonmutable vector public: typedef _STD random_access_iterator_tag iterator_category; typedef _STD _Bool value_type; typedef _Dift difference_type; typedef const_reference *pointer; typedef const_reference reference; const_iterator() { // construct with null reference } const_iterator( const _Vbase *_Ptr ) : _Vb_iter_base(( _Vbase * )_Ptr ) { // construct with offset and pointer } const_reference operator*() const { // return (reference to) designated object return ( _Reft( *this ) ); } const_iterator& operator++() { // preincrement _Inc(); return ( *this ); } const_iterator operator++( int ) { // postincrement const_iterator _Tmp = *this; ++*this; return ( _Tmp ); } const_iterator& operator--() { // predecrement _Dec(); return ( *this ); } const_iterator operator--( int ) { // postdecrement const_iterator _Tmp = *this; --*this; return ( _Tmp ); } const_iterator& operator+=( difference_type _Off ) { // increment by integer if ( _Off < 0 && this->_Myoff < 0 - ( size_type )_Off ) { /* add negative increment */ difference_type _Nwords = ( 0 - this->_Myoff - ( size_type )_Off - 1 ) / _VBITS; this->_Myptr -= _Nwords + 1; this->_Myoff += _Nwords * _VBITS + _VBITS; } else { /* add non-negative increment */ this->_Myoff += _Off; this->_Myptr += this->_Myoff / _VBITS; this->_Myoff %= _VBITS; } return ( *this ); } const_iterator operator+( difference_type _Off ) const { // return this + integer const_iterator _Tmp = *this; return ( _Tmp += _Off ); } const_iterator& operator-=( difference_type _Off ) { // decrement by integer return ( *this += -_Off ); } const_iterator operator-( difference_type _Off ) const { // return this - integer const_iterator _Tmp = *this; return ( _Tmp -= _Off ); } difference_type operator-( const const_iterator _Right ) const { // return difference of iterators return ( _VBITS *( this->_Myptr - _Right._Myptr ) + ( difference_type )this->_Myoff - ( difference_type )_Right._Myoff ); } const_reference operator[]( difference_type _Off ) const { // subscript return ( *( *this + _Off ) ); } bool operator==( const const_iterator& _Right ) const { // test for iterator equality return ( this->_Myptr == _Right._Myptr && this->_Myoff == _Right._Myoff ); } bool operator!=( const const_iterator& _Right ) const { // test for iterator inequality return ( !( *this == _Right ) ); } bool operator<( const const_iterator& _Right ) const { // test if this < _Right return ( this->_Myptr < _Right._Myptr || this->_Myptr == _Right._Myptr && this->_Myoff < _Right._Myoff ); } bool operator>( const const_iterator& _Right ) const { // test if this > _Right return ( _Right < *this ); } bool operator<=( const const_iterator& _Right ) const { // test if this <= _Right return ( !( _Right < *this ) ); } bool operator>=( const const_iterator& _Right ) const { // test if this >= _Right return ( !( *this < _Right ) ); } protected: void _Dec() { // decrement bit position if ( this->_Myoff != 0 ) --this->_Myoff; else this->_Myoff = _VBITS - 1, --this->_Myptr; } void _Inc() { // increment bit position if ( this->_Myoff < _VBITS - 1 ) ++this->_Myoff; else this->_Myoff = 0, ++this->_Myptr; } }; // CLASS iterator class iterator : public const_iterator { // iterator for mutable vector public: typedef _STD random_access_iterator_tag iterator_category; typedef _STD _Bool value_type; typedef _Dift difference_type; typedef _Reft *pointer; typedef _Reft reference; iterator() { // construct with null reference } iterator( _Vbase *_Ptr ) : const_iterator( _Ptr ) { // construct with offset and pointer } reference operator*() const { // return (reference to) designated object return ( _Reft( *this ) ); } iterator& operator++() { // preincrement ++*( const_iterator * )this; return ( *this ); } iterator operator++( int ) { // postincrement iterator _Tmp = *this; ++*this; return ( _Tmp ); } iterator& operator--() { // predecrement --*( const_iterator * )this; return ( *this ); } iterator operator--( int ) { // postdecrement iterator _Tmp = *this; --*this; return ( _Tmp ); } iterator& operator+=( difference_type _Off ) { // increment by integer *( const_iterator * )this += _Off; return ( *this ); } iterator operator+( difference_type _Off ) const { // return this + integer iterator _Tmp = *this; return ( _Tmp += _Off ); } iterator& operator-=( difference_type _Off ) { // decrement by integer return ( *this += -_Off ); } iterator operator-( difference_type _Off ) const { // return this - integer iterator _Tmp = *this; return ( _Tmp -= _Off ); } difference_type operator-( const const_iterator _Right ) const { // return difference of iterators return ( *( const_iterator * )this - _Right ); } reference operator[]( difference_type _Off ) const { // subscript return ( *( *this + _Off ) ); } }; typedef iterator pointer; typedef const_iterator const_pointer; typedef _STD reverse_iterator reverse_iterator; typedef _STD reverse_iterator const_reverse_iterator; vector() : _Mysize( 0 ), _Myvec() { // construct empty vector } explicit vector( const _Alloc& _Al ) : _Mysize( 0 ), _Myvec( _Al ) { // construct empty vector, with allocator } explicit vector( size_type _Count, bool _Val = false ) : _Mysize( 0 ), _Myvec( _Nw( _Count ), ( _Vbase )( _Val ? -1 : 0 ) ) { // construct from _Count * _Val _Trim( _Count ); } vector( size_type _Count, bool _Val, const _Alloc& _Al ) : _Mysize( 0 ), _Myvec( _Nw( _Count ), ( _Vbase )( _Val ? -1 : 0 ), _Al ) { // construct from _Count * _Val, with allocator _Trim( _Count ); } template vector( _Iter _First, _Iter _Last ) : _Mysize( 0 ), _Myvec() { // construct from [_First, _Last) _BConstruct( _First, _Last, _STD _Iter_cat( _First ) ); } template vector( _Iter _First, _Iter _Last, const _Alloc& _Al ) : _Mysize( 0 ), _Myvec( _Al ) { // construct from [_First, _Last), with allocator _BConstruct( _First, _Last, _STD _Iter_cat( _First ) ); } template void _BConstruct( _Iter _Count, _Iter _Val, _STD _Int_iterator_tag ) { // initialize from _Count * _Val size_type _Num = ( size_type )_Count; _Myvec.assign( _Num, ( _Ty )_Val ? -1 : 0 ); _Trim( _Num ); } template void _BConstruct( _Iter _First, _Iter _Last, _STD input_iterator_tag ) { // initialize from [_First, _Last), input iterators insert( begin(), _First, _Last ); } ~vector() { // destroy the object _Mysize = 0; } void reserve( size_type _Count ) { // determine new minimum length of allocated storage _Myvec.reserve( _Nw( _Count ) ); } size_type capacity() const { // return current length of allocated storage return ( _Myvec.capacity() * _VBITS ); } iterator begin() { // return iterator for beginning of mutable sequence return ( iterator( _VEC_ITER_BASE( _Myvec.begin() ) ) ); } const_iterator begin() const { // return iterator for beginning of nonmutable sequence return ( const_iterator( _VEC_ITER_BASE( _Myvec.begin() ) ) ); } iterator end() { // return iterator for end of mutable sequence iterator _Tmp = begin(); if ( 0 < _Mysize ) _Tmp += _Mysize; return ( _Tmp ); } const_iterator end() const { // return iterator for end of nonmutable sequence const_iterator _Tmp = begin(); if ( 0 < _Mysize ) _Tmp += _Mysize; return ( _Tmp ); } reverse_iterator rbegin() { // return iterator for beginning of reversed mutable sequence return ( reverse_iterator( end() ) ); } const_reverse_iterator rbegin() const { // return iterator for beginning of reversed nonmutable sequence return ( const_reverse_iterator( end() ) ); } reverse_iterator rend() { // return iterator for end of reversed mutable sequence return ( reverse_iterator( begin() ) ); } const_reverse_iterator rend() const { // return iterator for end of reversed nonmutable sequence return ( const_reverse_iterator( begin() ) ); } void resize( size_type _Newsize, bool _Val = false ) { // determine new length, padding with _Val elements as needed if ( size() < _Newsize ) _Insert_n( end(), _Newsize - size(), _Val ); else if ( _Newsize < size() ) erase( begin() + _Newsize, end() ); } size_type size() const { // return length of sequence return ( _Mysize ); } size_type max_size() const { // return maximum possible length of sequence const size_type _Maxsize = _Myvec.max_size(); return ( _Maxsize < ( size_type )( -1 ) / _VBITS ? _Maxsize * _VBITS : ( size_type )( -1 ) ); } bool empty() const { // test if sequence is empty return ( size() == 0 ); } _Alloc get_allocator() const { // return allocator object for values return ( _Myvec.get_allocator() ); } const_reference at( size_type _Off ) const { // subscript nonmutable sequence with checking if ( size() <= _Off ) _Xran(); return ( *( begin() + _Off ) ); } reference at( size_type _Off ) { // subscript mutable sequence with checking if ( size() <= _Off ) _Xran(); return ( *( begin() + _Off ) ); } const_reference operator[]( size_type _Off ) const { // subscript nonmutable sequence return ( *( begin() + _Off ) ); } reference operator[]( size_type _Off ) { // subscript mutable sequence return ( *( begin() + _Off ) ); } reference front() { // return first element of mutable sequence return ( *begin() ); } const_reference front() const { // return first element of nonmutable sequence return ( *begin() ); } reference back() { // return last element of mutable sequence return ( *( end() - 1 ) ); } const_reference back() const { // return last element of nonmutable sequence return ( *( end() - 1 ) ); } void push_back( bool _Val ) { // insert element at end insert( end(), _Val ); } void pop_back() { // erase element at end if ( !empty() ) erase( end() - 1 ); } template void assign( _Iter _First, _Iter _Last ) { // assign [_First, _Last) _Assign( _First, _Last, _STD _Iter_cat( _First ) ); } template void _Assign( _Iter _Count, _Iter _Val, _STD _Int_iterator_tag ) { // assign _Count * _Val _Assign_n(( size_type )_Count, ( bool )_Val ); } template void _Assign( _Iter _First, _Iter _Last, _STD input_iterator_tag ) { // assign [_First, _Last), input iterators erase( begin(), end() ); insert( begin(), _First, _Last ); } void assign( size_type _Count, bool _Val ) { // assign _Count * _Val _Assign_n( _Count, _Val ); } iterator insert( iterator _Where, bool _Val ) { // insert _Val at _Where size_type _Off = _Where - begin(); _Insert_n( _Where, ( size_type )1, _Val ); return ( begin() + _Off ); } void insert( iterator _Where, size_type _Count, bool _Val ) { // insert _Count * _Val at _Where _Insert_n( _Where, _Count, _Val ); } template void insert( iterator _Where, _Iter _First, _Iter _Last ) { // insert [_First, _Last) at _Where _Insert( _Where, _First, _Last, _STD _Iter_cat( _First ) ); } template void _Insert( iterator _Where, _Iter _Count, _Iter _Val, _STD _Int_iterator_tag ) { // insert _Count * _Val at _Where _Insert_n( _Where, ( size_type )_Count, ( bool )_Val ); } template void _Insert( iterator _Where, _Iter _First, _Iter _Last, _STD input_iterator_tag ) { // insert [_First, _Last) at _Where, input iterators size_type _Off = _Where - begin(); for ( ; _First != _Last; ++_First, ++_Off ) insert( begin() + _Off, *_First ); } template void _Insert( iterator _Where, _Iter _First, _Iter _Last, _STD forward_iterator_tag ) { // insert [_First, _Last) at _Where, forward iterators size_type _Count = 0; _Distance( _First, _Last, _Count ); size_type _Off = _Insert_x( _Where, _Count ); copy( _First, _Last, begin() + _Off ); } iterator erase( iterator _Where ) { // erase element at _Where size_type _Off = _Where - begin(); copy( _Where + 1, end(), _Where ); _Trim( _Mysize - 1 ); return ( begin() + _Off ); } iterator erase( iterator _First, iterator _Last ) { // erase [_First, _Last) size_type _Off = _First - begin(); iterator _Next = copy( _Last, end(), _First ); _Trim( _Next - begin() ); return ( begin() + _Off ); } void clear() { // erase all elements erase( begin(), end() ); } void flip() { // toggle all elements for ( typename _Vbtype::iterator _Next = _Myvec.begin(); _Next != _Myvec.end(); ++_Next ) *_Next = ( _Vbase )~ * _Next; _Trim( _Mysize ); } void swap( _Myt& _Right ) { // exchange contents with right _STD swap( _Mysize, _Right._Mysize ); _Myvec.swap( _Right._Myvec ); } static void swap( reference _Left, reference _Right ) { // swap _Left and _Right vector elements bool _Val = _Left; _Left = _Right; _Right = _Val; } protected: void _Assign_n( size_type _Count, bool _Val ) { // assign _Count * _Val erase( begin(), end() ); _Insert_n( begin(), _Count, _Val ); } void _Insert_n( iterator _Where, size_type _Count, bool _Val ) { // insert _Count * _Val at _Where size_type _Off = _Insert_x( _Where, _Count ); _STD fill( begin() + _Off, begin() + ( _Off + _Count ), _Val ); } size_type _Insert_x( iterator _Where, size_type _Count ) { // make room to insert _Count elements at _Where size_type _Off = _Where - begin(); if ( _Count == 0 ) ; else if ( max_size() - size() < _Count ) _Xlen(); // result too long else { // worth doing _Myvec.resize( _Nw( size() + _Count ), 0 ); if ( size() == 0 ) _Mysize += _Count; else { // make room and copy down suffix iterator _Oldend = end(); _Mysize += _Count; _STD copy_backward( begin() + _Off, _Oldend, end() ); } } return ( _Off ); } static size_type _Nw( size_type _Count ) { // return number of base words from number of bits return (( _Count + _VBITS - 1 ) / _VBITS ); } void _Trim( size_type _Size ) { // trim base vector to exact length in bits if ( max_size() < _Size ) _Xlen(); // result too long size_type _Words = _Nw( _Size ); if ( _Words < _Myvec.size() ) _Myvec.erase( _Myvec.begin() + _Words, _Myvec.end() ); _Mysize = _Size; _Size %= _VBITS; if ( 0 < _Size ) _Myvec[_Words - 1] &= ( _Vbase )(( 1 << _Size ) - 1 ); } void _Xlen() const { // report a length_error } void _Xran() const { // throw an out_of_range error } size_type _Mysize; // current length of sequence _Vbtype _Myvec; // base vector of words }; typedef vector > _Bvector; #if _HAS_TRADITIONAL_STL typedef _Bvector bit_vector; #endif /* _HAS_TRADITIONAL_STL */ #if _HAS_TRADITIONAL_STL #define __vector__ vector #endif /* _HAS_TRADITIONAL_STL */ //_STD_END } #endif /* _VECTOR_ */