RetroArch/console/rgl/ps3/vector
2012-05-06 03:47:35 +02:00

1740 lines
51 KiB
Plaintext

// vector standard header
#ifndef _VECTOR_
#define _VECTOR_
#define RGL_STD_VECTOR
#include <memory>
#include <stdexcept>
#define STL_NAMESPACE ::RGL::
namespace RGL
{
//_STD_BEGIN
template<class _Ty, class _Ax = ::std::allocator<_Ty> > class vector;
#if _HAS_TRADITIONAL_ITERATORS
#else /* _HAS_TRADITIONAL_ITERATORS */
// TEMPLATE CLASS _Vector_const_iterator
template<class _Ty, class _Alloc>
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<class _Ty, class _Alloc>
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 _Ty, class _Alloc>
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<class _Ty, class _Alloc>
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 _Ty, class _Alloc>
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 _Ty, class _Ax>
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<iterator> reverse_iterator;
typedef _STD reverse_iterator<const_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<class _Iter>
vector( _Iter _First, _Iter _Last )
: _Mybase()
{ // construct from [_First, _Last)
_Construct( _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
vector( _Iter _First, _Iter _Last, const _Alloc& _Al )
: _Mybase( _Al )
{ // construct from [_First, _Last), with allocator
_Construct( _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
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<class _Iter>
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<class _Iter>
void assign( _Iter _First, _Iter _Last )
{ // assign [_First, _Last)
_Assign( _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
void _Assign( _Iter _Count, _Iter _Val, ::std::_Int_iterator_tag )
{ // assign _Count * _Val
_Assign_n(( size_type )_Count, ( _Ty )_Val );
}
template<class _Iter>
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<class _Iter>
void insert( iterator _Where, _Iter _First, _Iter _Last )
{ // insert [_First, _Last) at _Where
_Insert( _Where, _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
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<class _Iter>
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<class _Iter>
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<class _Iter>
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<class _Ty, class _Alloc>
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<class _Ty, class _Alloc>
inline bool operator!=( const vector<_Ty, _Alloc>& _Left,
const vector<_Ty, _Alloc>& _Right )
{ // test for vector inequality
return ( !( _Left == _Right ) );
}
template<class _Ty, class _Alloc>
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<class _Ty, class _Alloc>
inline bool operator>( const vector<_Ty, _Alloc>& _Left,
const vector<_Ty, _Alloc>& _Right )
{ // test if _Left > _Right for vectors
return ( _Right < _Left );
}
template<class _Ty, class _Alloc>
inline bool operator<=( const vector<_Ty, _Alloc>& _Left,
const vector<_Ty, _Alloc>& _Right )
{ // test if _Left <= _Right for vectors
return ( !( _Right < _Left ) );
}
template<class _Ty, class _Alloc>
inline bool operator>=( const vector<_Ty, _Alloc>& _Left,
const vector<_Ty, _Alloc>& _Right )
{ // test if _Left >= _Right for vectors
return ( !( _Left < _Right ) );
}
template<class _Ty, class _Alloc>
inline void swap( vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right )
{ // swap _Left and _Right vectors
_Left.swap( _Right );
}
// CLASS vector<bool>
typedef unsigned _Vbase; // word type for vector<bool> representation
const int _VBITS = 8 * sizeof( _Vbase ); // at least CHAR_BITS bits per word
template<class _Alloc>
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<bool>
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<bool>
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<iterator> reverse_iterator;
typedef _STD reverse_iterator<const_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<class _Iter>
vector( _Iter _First, _Iter _Last )
: _Mysize( 0 ), _Myvec()
{ // construct from [_First, _Last)
_BConstruct( _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
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<class _Iter>
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<class _Iter>
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<class _Iter>
void assign( _Iter _First, _Iter _Last )
{ // assign [_First, _Last)
_Assign( _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
void _Assign( _Iter _Count, _Iter _Val, _STD _Int_iterator_tag )
{ // assign _Count * _Val
_Assign_n(( size_type )_Count, ( bool )_Val );
}
template<class _Iter>
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<class _Iter>
void insert( iterator _Where, _Iter _First, _Iter _Last )
{ // insert [_First, _Last) at _Where
_Insert( _Where, _First, _Last, _STD _Iter_cat( _First ) );
}
template<class _Iter>
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<class _Iter>
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<class _Iter>
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<bool> 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<bool, _STD allocator<bool> > _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_ */