Re: [eigen] Re: State of the problem with std::vector

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Benoit Jacob schrieb:
So if you
have MSVC and like this possible solution please tell us what other
methods of std::vector call resize...
Cheers,
Benoit

Still without a clear understanding of this threat. Nevertheless:

Microsoft Visual Studio 2008
Version 9.0.30729.1 SP

In the file "vector" (see attachment) scanning for "resize", i found three methods of std::vector<_Ty, _Ax> calling some form of resize().

two public, one protected

hope this help

Frank

// vector standard header
#pragma once
#ifndef _VECTOR_
#define _VECTOR_
#ifndef RC_INVOKED
#include <memory>
#include <stdexcept>

#ifdef _MSC_VER
 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma warning(disable: 4244)
#endif  /* _MSC_VER */

_STD_BEGIN
template<class _Ty,
	class _Ax = allocator<_Ty> >
	class vector;

		// TEMPLATE CLASS _Vector_const_iterator
template<class _Ty,
	class _Alloc>
	class _Vector_const_iterator
		: public _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 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;

#if _SECURE_SCL
	typedef _Range_checked_iterator_tag _Checked_iterator_category;
#endif

#if _SECURE_SCL && !_HAS_ITERATOR_DEBUGGING
	typedef pointer _Checked_iterator_base_type;

	_Checked_iterator_base_type _Checked_iterator_base() const
	{
		return _Myptr;
	}

	void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
	{
		this->_Myptr = const_cast<_Tptr>(_Base);
	}
#endif

	// Setting _Inner_type implies that the internal structure of vector is
	// an array of _Ty. This information is used in the copy and move algorithm.
	// The helper function _Ptr_cat will return _Scalar_ptr_iterator_tag if you
	// pass a vector iterator.
	typedef _Tptr _Inner_type;

	_Vector_const_iterator()
		{	// construct with null pointer
		_Myptr = 0;
		}

 #if _HAS_ITERATOR_DEBUGGING
	_Vector_const_iterator(_Tptr _Ptr, const _Container_base *_Pvector)
		{	// construct with pointer _Ptr
		_SCL_SECURE_VALIDATE(_Pvector == NULL || (((_Myvec *)_Pvector)->_Myfirst <= _Ptr && _Ptr <= ((_Myvec *)_Pvector)->_Mylast));
		this->_Adopt(_Pvector);
		_Myptr = _Ptr;
		}

 #elif _SECURE_SCL
	_Vector_const_iterator(_Tptr _Ptr, const _Container_base *_Pvector)
		{	// construct with pointer _Ptr
		_SCL_SECURE_VALIDATE(_Pvector != NULL && ((_Myvec *)_Pvector)->_Myfirst <= _Ptr && _Ptr <= ((_Myvec *)_Pvector)->_Mylast);
		this->_Set_container(_Pvector);
		_Myptr = _Ptr;
		}

 #else
	explicit _Vector_const_iterator(_Tptr _Ptr)
		{	// construct with pointer _Ptr
		_Myptr = _Ptr;
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	reference operator*() const
		{	// return designated object

 #if _HAS_ITERATOR_DEBUGGING
		if (this->_Mycont == 0
			|| _Myptr < ((_Myvec *)this->_Mycont)->_Myfirst
			|| ((_Myvec *)this->_Mycont)->_Mylast <= _Myptr)
			{
			_DEBUG_ERROR("vector iterator not dereferencable");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #else
 		_SCL_SECURE_VALIDATE(this->_Has_container());
		_SCL_SECURE_VALIDATE_RANGE(_Myptr < ((_Myvec *)(this->_Getmycont()))->_Mylast);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (*_Myptr);
		}

	pointer operator->() const
		{	// return pointer to class object
		return (&**this);
		}

	_Myt& operator++()
		{	// preincrement
		_SCL_SECURE_VALIDATE(this->_Has_container());
		_SCL_SECURE_VALIDATE_RANGE(_Myptr < ((_Myvec *)(this->_Getmycont()))->_Mylast);

 #if _HAS_ITERATOR_DEBUGGING
		if (this->_Mycont == 0
			|| ((_Myvec *)this->_Mycont)->_Mylast <= _Myptr)
			_DEBUG_ERROR("vector iterator not incrementable");
 #endif /* _HAS_ITERATOR_DEBUGGING */

		++_Myptr;
		return (*this);
		}

	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myt& operator--()
		{	// predecrement
		_SCL_SECURE_VALIDATE(this->_Has_container());
		_SCL_SECURE_VALIDATE_RANGE(_Myptr > ((_Myvec *)(this->_Getmycont()))->_Myfirst);

 #if _HAS_ITERATOR_DEBUGGING
		if (this->_Mycont == 0
			|| _Myptr == ((_Myvec *)this->_Mycont)->_Myfirst)
			_DEBUG_ERROR("vector iterator not decrementable");
 #endif /* _HAS_ITERATOR_DEBUGGING */

		--_Myptr;
		return (*this);
		}

	_Myt operator--(int)
		{	// postdecrement
		_Myt _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Myt& operator+=(difference_type _Off)
		{	// increment by integer
		_SCL_SECURE_VALIDATE(this->_Has_container());
		_SCL_SECURE_VALIDATE_RANGE(
			_Myptr + _Off <= ((_Myvec *)(this->_Getmycont()))->_Mylast &&
			_Myptr + _Off >= ((_Myvec *)(this->_Getmycont()))->_Myfirst);
		_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

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #else
		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (_Myptr - _Right._Myptr);
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

	bool operator==(const _Myt& _Right) const
		{	// test for iterator equality

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #else
		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
 #endif /* _HAS_ITERATOR_DEBUGGING */

		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

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #else
		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
 #endif /* _HAS_ITERATOR_DEBUGGING */

		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));
		}

 #if _HAS_ITERATOR_DEBUGGING
	void _Compat(const _Myt& _Right) const
		{	// test for compatible iterator pair
		if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)
			{
			_DEBUG_ERROR("vector iterators incompatible");
			_SCL_SECURE_INVALID_ARGUMENT;
			}
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	static void _Xlen()
		{	// report a length_error
		_THROW(length_error, "vector<T> too long");
		}

	static void _Xran()
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid vector<T> subscript");
		}

	static void _Xinvarg()
		{	// report an invalid_argument error
		_THROW(invalid_argument, "invalid vector<T> argument");
		}

	_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 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;

#if _SECURE_SCL && !_HAS_ITERATOR_DEBUGGING
	typedef pointer _Checked_iterator_base_type;

	_Checked_iterator_base_type _Checked_iterator_base() const
		{
		return (this->_Myptr);
		}

	void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
		{
		this->_Myptr = _Base;
		}
#endif

	_Vector_iterator()
		{	// construct with null vector pointer
		}

 #if _HAS_ITERATOR_DEBUGGING
	_Vector_iterator(pointer _Ptr, const _Container_base *_Pvector)
		: _Mybase(_Ptr, _Pvector)
		{	// construct with pointer _Ptr
		}

 #elif _SECURE_SCL
	_Vector_iterator(pointer _Ptr, const _Container_base *_Pvector)
		: _Mybase(_Ptr, _Pvector)
		{	// construct with pointer _Ptr
		}

 #else
	explicit _Vector_iterator(pointer _Ptr)
		: _Mybase(_Ptr)
		{	// construct with pointer _Ptr
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	reference operator*() const
		{	// return designated object
		return ((reference)**(_Mybase *)this);
		}

	pointer operator->() const
		{	// return pointer to class object
		return (&**this);
		}

	_Myt& operator++()
		{	// preincrement
		++(*(_Mybase *)this);
		return (*this);
		}

	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myt& operator--()
		{	// predecrement
		--(*(_Mybase *)this);
		return (*this);
		}

	_Myt operator--(int)
		{	// postdecrement
		_Myt _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Myt& operator+=(difference_type _Off)
		{	// increment by integer
		(*(_Mybase *)this) += _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);
	}

		// TEMPLATE CLASS _Vector_val
template<class _Ty,
	class _Alloc>
	class _Vector_val
		: public _CONTAINER_BASE_AUX_ALLOC<_Alloc>
	{	// base class for vector to hold allocator _Alval
protected:
	_Vector_val(_Alloc _Al = _Alloc())
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Al), _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;

  #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>;

	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, _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, _Iter_cat(_First));
		}

	template<class _Iter>
		void _Construct(_Iter _Count, _Iter _Val, _Int_iterator_tag)
		{	// initialize with _Count * _Val
		size_type _Size = (size_type)_Count;
		_Construct_n(_Size, (_Ty)_Val);
		}

	template<class _Iter>
		void _Construct(_Iter _First,
			_Iter _Last, 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 _HAS_ITERATOR_DEBUGGING
			this->_Orphan_all();
 #endif /* _HAS_ITERATOR_DEBUGGING */

			if (_Right.size() == 0)
				clear();	// new sequence empty, erase existing sequence
			else if (_Right.size() <= size())
				{	// enough elements, copy new and destroy old
				pointer _Ptr = _STDEXT unchecked_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();
				_STDEXT unchecked_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
			_Umove(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);
				}

 #if _HAS_ITERATOR_DEBUGGING
			this->_Orphan_all();
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_Myend = _Ptr + _Count;
			_Mylast = _Ptr + _Size;
			_Myfirst = _Ptr;
			}
		}

	size_type capacity() const
		{	// return current length of allocated storage
		return (_Myfirst == 0 ? 0 : _Myend - _Myfirst);
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (iterator(_Myfirst, this));
		}

	const_iterator begin() const
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(_Myfirst, this));
		}

	iterator end()
		{	// return iterator for end of mutable sequence
		return (iterator(_Mylast, this));
		}

	const_iterator end() const
		{	// return iterator for end of nonmutable sequence
		return (const_iterator(_Mylast, this));
		}

	iterator _Make_iter(const_iterator _Where) const
		{	// make iterator from const_iterator
		return (iterator(_Where._Myptr, this));
		}

 #else /* _HAS_ITERATOR_DEBUGGING */
	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));
		}

	iterator _Make_iter(const_iterator _Where) const
		{	// make iterator from const_iterator
		return (iterator(_Where._Myptr));
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	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 (_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

 #if _HAS_ITERATOR_DEBUGGING
		if (size() <= _Pos)
			{
			_DEBUG_ERROR("vector subscript out of range");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #endif /* _HAS_ITERATOR_DEBUGGING */
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());

		return (*(_Myfirst + _Pos));
		}

	reference operator[](size_type _Pos)
		{	// subscript mutable sequence

 #if _HAS_ITERATOR_DEBUGGING
		if (size() <= _Pos)
			{
			_DEBUG_ERROR("vector subscript out of range");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #endif /* _HAS_ITERATOR_DEBUGGING */
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());

		return (*(_Myfirst + _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())

 #if _HAS_ITERATOR_DEBUGGING
			{ // room at end, construct it there
			_Orphan_range(_Mylast, _Mylast);
			_Mylast = _Ufill(_Mylast, 1, _Val);
			}

 #else /* _HAS_ITERATOR_DEBUGGING */
			_Mylast = _Ufill(_Mylast, 1, _Val);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		else
			insert(end(), _Val);
		}

 #if _HAS_ITERATOR_DEBUGGING
	void pop_back()
		{	// erase element at end
		if (empty())
			_DEBUG_ERROR("vector empty before pop");
		else
			{	// erase last element
			_Orphan_range(_Mylast - 1, _Mylast);
			_Destroy(_Mylast - 1, _Mylast);
			--_Mylast;
			}
		}

 #else /* _HAS_ITERATOR_DEBUGGING */
	void pop_back()
		{	// erase element at end
		if (!empty())
			{	// erase last element
			_Destroy(_Mylast - 1, _Mylast);
			--_Mylast;
			}
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	template<class _Iter>
		void assign(_Iter _First, _Iter _Last)
		{	// assign [_First, _Last)
		_Assign(_First, _Last, _Iter_cat(_First));
		}

	template<class _Iter>
		void _Assign(_Iter _Count, _Iter _Val, _Int_iterator_tag)
		{	// assign _Count * _Val
		_Assign_n((size_type)_Count, (_Ty)_Val);
		}

	template<class _Iter>
		void _Assign(_Iter _First, _Iter _Last, 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(const_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(const_iterator _Where, size_type _Count, const _Ty& _Val)
		{	// insert _Count * _Val at _Where
		_Insert_n(_Where, _Count, _Val);
		}

	template<class _Iter>
		void insert(const_iterator _Where, _Iter _First, _Iter _Last)
		{	// insert [_First, _Last) at _Where
		_Insert(_Where, _First, _Last, _Iter_cat(_First));
		}

	template<class _Iter>
		void _Insert(const_iterator _Where, _Iter _First, _Iter _Last,
			_Int_iterator_tag)
		{	// insert _Count * _Val at _Where
		_Insert_n(_Where, (size_type)_First, (_Ty)_Last);
		}

	template<class _Iter>
		void _Insert(const_iterator _Where, _Iter _First, _Iter _Last,
			input_iterator_tag)
		{	// insert [_First, _Last) at _Where, input iterators

 #if _HAS_ITERATOR_DEBUGGING
		if (_Where._Mycont != this
			|| _Where._Myptr < _Myfirst || _Mylast < _Where._Myptr)
			_DEBUG_ERROR("vector insert iterator outside range");
 #endif /* _HAS_ITERATOR_DEBUGGING */

		if (_First != _Last)
			{	// worth doing, gather at end and rotate into place
			size_type _Oldsize = size();
			size_type _Whereoff = _Where._Myptr - _Myfirst;

			for (; _First != _Last; ++_First)
				_Insert_n(end(), (size_type)1, (value_type)*_First);

			_Reverse(_Myfirst + _Whereoff, _Myfirst + _Oldsize);
			_Reverse(_Myfirst + _Oldsize, _Mylast);
			_Reverse(_Myfirst + _Whereoff, _Mylast);
			}
		}

	template<class _Iter>
		void _Insert(const_iterator _Where,
			_Iter _First, _Iter _Last, forward_iterator_tag)
		{	// insert [_First, _Last) at _Where, forward iterators

 #if _HAS_ITERATOR_DEBUGGING
		if (_Where._Mycont != this
			|| _Where._Myptr < _Myfirst || _Mylast < _Where._Myptr)
			_DEBUG_ERROR("vector insert iterator outside range");
		_DEBUG_RANGE(_First, _Last);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		size_type _Count = 0;
		_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 = _Umove(_Myfirst, _VEC_ITER_BASE(_Where),
				_Newvec);	// copy prefix
			_Ptr = _Ucopy(_First, _Last, _Ptr);	// add new stuff
			_Umove(_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);
				}

 #if _HAS_ITERATOR_DEBUGGING
			this->_Orphan_all();
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_Myend = _Newvec + _Capacity;
			_Mylast = _Newvec + _Count;
			_Myfirst = _Newvec;
			}
		else
			{	// new stuff fits, append and rotate into place
			_Ucopy(_First, _Last, _Mylast);

			_Reverse(_Where._Myptr, _Mylast);
			_Reverse(_Mylast, _Mylast + _Count);
			_Reverse(_Where._Myptr, _Mylast + _Count);

			_Mylast += _Count;

 #if _HAS_ITERATOR_DEBUGGING
			_Orphan_range(_Where._Myptr, _Mylast);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			}
		}

 	void _Reverse(pointer _First, pointer _Last)
		{	// reverse a subrange
		for (; _First != _Last && _First != --_Last; ++_First)
			_STD _Swap_adl(*_First, *_Last);
		}

 #if _HAS_ITERATOR_DEBUGGING
	iterator erase(const_iterator _Where)
		{	// erase element at where
		if (_Where._Mycont != this
			|| _Where._Myptr < _Myfirst || _Mylast <= _Where._Myptr)
			_DEBUG_ERROR("vector erase iterator outside range");
		_STDEXT unchecked_copy(_Where._Myptr + 1, _Mylast, _Where._Myptr);
		_Destroy(_Mylast - 1, _Mylast);
		_Orphan_range(_Where._Myptr, _Mylast);
		--_Mylast;
		return (iterator(_Where._Myptr, this));
		}

 #else /* _HAS_ITERATOR_DEBUGGING */
	iterator erase(const_iterator _Where)
		{	// erase element at where
		_STDEXT unchecked_copy(_VEC_ITER_BASE(_Where) + 1, _Mylast,
			_VEC_ITER_BASE(_Where));
		_Destroy(_Mylast - 1, _Mylast);
		--_Mylast;
		return (_Make_iter(_Where));
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	iterator erase(const_iterator _First_arg,
		const_iterator _Last_arg)
		{	// erase [_First, _Last)
		iterator _First = _Make_iter(_First_arg);
		iterator _Last = _Make_iter(_Last_arg);

		if (_First != _Last)
			{	// worth doing, copy down over hole

 #if _HAS_ITERATOR_DEBUGGING
			if (_Last < _First || _First._Mycont != this
				|| _First._Myptr < _Myfirst || _Mylast < _Last._Myptr)
				_DEBUG_ERROR("vector erase iterator outside range");
			pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast,
				_VEC_ITER_BASE(_First));
			_Orphan_range(_First._Myptr, _Mylast);

 #else /* _HAS_ITERATOR_DEBUGGING */
			pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast,
				_VEC_ITER_BASE(_First));
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_Destroy(_Ptr, _Mylast);
			_Mylast = _Ptr;
			}
#if _HAS_ITERATOR_DEBUGGING
        return (iterator(_First._Myptr, this));
#else
		return (_First);
#endif
		}

	void clear()
		{	// erase all
		erase(begin(), end());
		}

	void swap(_Myt& _Right)
		{	// exchange contents with _Right
		if (this == &_Right)
			;	// same object, do nothing
		else if (this->_Alval == _Right._Alval)
			{	// same allocator, swap control information

 #if _HAS_ITERATOR_DEBUGGING
			this->_Swap_all(_Right);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			this->_Swap_aux(_Right);

			_STD swap(_Myfirst, _Right._Myfirst);
			_STD swap(_Mylast, _Right._Mylast);
			_STD swap(_Myend, _Right._Myend);
			}
		else
			{	// different allocator, do multiple assigns
			this->_Swap_aux(_Right);

			_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

 #if _HAS_ITERATOR_DEBUGGING
			this->_Orphan_all();
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_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 (_STDEXT unchecked_uninitialized_copy(_First, _Last,
			_Ptr, this->_Alval));
		}

	template<class _Iter>
		pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr)
		{	// move initializing [_First, _Last), using allocator
		return (_STDEXT _Unchecked_uninitialized_move(_First, _Last,
			_Ptr, this->_Alval));
		}

	void _Insert_n(const_iterator _Where,
		size_type _Count, const _Ty& _Val)
		{	// insert _Count * _Val at _Where

 #if _HAS_ITERATOR_DEBUGGING
		if (_Where._Mycont != this
			|| _Where._Myptr < _Myfirst || _Mylast < _Where._Myptr)
			_DEBUG_ERROR("vector insert iterator outside range");
 #endif /* _HAS_ITERATOR_DEBUGGING */

		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);
			size_type _Whereoff = _VEC_ITER_BASE(_Where) - _Myfirst;
			int _Ncopied = 0;

			_TRY_BEGIN
			_Ufill(_Newvec + _Whereoff, _Count, _Val);	// add new stuff
			++_Ncopied;
			_Umove(this->_Myfirst, _VEC_ITER_BASE(_Where),
				_Newvec);	// move prefix
			++_Ncopied;
			_Umove(_VEC_ITER_BASE(_Where), this->_Mylast,
				_Newvec + (_Whereoff + _Count));	// move suffix
			_CATCH_ALL
			if (1 < _Ncopied)
				_Destroy(_Newvec, _Newvec + _Whereoff);
			if (0 < _Ncopied)
				_Destroy(_Newvec + _Whereoff, _Newvec + _Whereoff + _Count);
			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);
				}

 #if _HAS_ITERATOR_DEBUGGING
			this->_Orphan_all();
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_Myend = _Newvec + _Capacity;
			_Mylast = _Newvec + _Count;
			_Myfirst = _Newvec;
			}
		else if ((size_type)(_Mylast - _VEC_ITER_BASE(_Where)) < _Count)
			{	// new stuff spills off end
			_Ty _Tmp = _Val;	// in case _Val is in sequence

			_Umove(_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;

 #if _HAS_ITERATOR_DEBUGGING
			_Orphan_range(_Where._Myptr, _Mylast);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			std::fill(_VEC_ITER_BASE(_Where), _Mylast - _Count,
				_Tmp);	// insert up to old end
			}
		else
			{	// new stuff can all be assigned
			_Ty _Tmp = _Val;	// in case _Val is in sequence

			pointer _Oldend = _Mylast;
			_Mylast = _Umove(_Oldend - _Count, _Oldend,
				_Mylast);	// copy suffix

 #if _HAS_ITERATOR_DEBUGGING
			_Orphan_range(_Where._Myptr, _Mylast);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			_STDEXT _Unchecked_move_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
		_STDEXT unchecked_uninitialized_fill_n(_Ptr, _Count, _Val, this->_Alval);
		return (_Ptr + _Count);
		}

	static void _Xlen()
		{	// report a length_error
		_THROW(length_error, "vector<T> too long");
		}

	static void _Xran()
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid vector<T> subscript");
		}

	static void _Xinvarg()
		{	// report an invalid_argument error
		_THROW(invalid_argument, "invalid vector<T> argument");
		}

 #if _HAS_ITERATOR_DEBUGGING
	void _Orphan_range(pointer _First, pointer _Last) const
		{	// orphan iterators within specified (inclusive) range
		_Lockit _Lock(_LOCK_DEBUG);
		const_iterator **_Pnext = (const_iterator **)&this->_Myfirstiter;
		while (*_Pnext != 0)
			if ((*_Pnext)->_Myptr < _First || _Last < (*_Pnext)->_Myptr)
				_Pnext = (const_iterator **)&(*_Pnext)->_Mynextiter;
			else
				{	// orphan the iterator
				(*_Pnext)->_Mycont = 0;
				*_Pnext = (const_iterator *)(*_Pnext)->_Mynextiter;
				}
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	pointer _Myfirst;	// pointer to beginning of array
	pointer _Mylast;	// pointer to current end of sequence
	pointer _Myend;	// pointer to end of array
	};

	// vector implements a performant swap
template <class _Ty, class _Ax>
	class _Move_operation_category<vector<_Ty, _Ax> >
	{
	public:
		typedef _Swap_move_tag _Move_cat;
	};

		// 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()
		&& 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 (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);
	}

//
// TEMPLATE CLASS vector<bool, Alloc> AND FRIENDS
//
typedef unsigned _Vbase;	// word type for vector<bool> representation
const int _VBITS = 8 * sizeof (_Vbase);	// at least CHAR_BITS bits per word

		// CLASS _Vb_iter_base
template<class _Sizet,
	class _Difft,
	class _MycontTy>
	class _Vb_iter_base
		: public _Ranit<_Bool, _Difft, bool *, bool>
	{	// store information common to reference and iterators
public:
#if _SECURE_SCL
	typedef _Range_checked_iterator_tag _Checked_iterator_category;
#endif

	_Vb_iter_base()
		: _Myptr(0), _Myoff(0)
		{	// construct with null pointer
		}

 #if _HAS_ITERATOR_DEBUGGING
	_Vb_iter_base(_Vbase *_Ptr, _Sizet _Off,
		const _Container_base *_Mypvbool)
		: _Myptr(_Ptr), _Myoff(_Off)
		{	// construct with offset and pointer
		_SCL_SECURE_VALIDATE(_Mypvbool != NULL);
		this->_Adopt(_Mypvbool);
		}

 #elif _SECURE_SCL
	_Vb_iter_base(_Vbase *_Ptr, _Sizet _Off,
		const _Container_base *_Mypvbool)
		: _Myptr(_Ptr), _Myoff(_Off)
		{	// construct with offset and pointer
		_SCL_SECURE_VALIDATE(_Mypvbool != NULL);
		this->_Set_container(_Mypvbool);
		}
 #else
	_Vb_iter_base(_Vbase *_Ptr, _Sizet _Off)
		: _Myptr(_Ptr), _Myoff(_Off)
		{	// construct with offset and pointer
		}
 #endif

	_Vbase *_Myptr;
	_Sizet _Myoff;

	static void _Xlen()
		{	// report a length_error
		_THROW(length_error, "vector<bool> too long");
			}

	static void _Xran()
		{	// report an out_of_range error
		_THROW(out_of_range, "invalid vector<bool> subscript");
		}

	static void _Xinvarg()
		{	// report an invalid_argument error
		_THROW(invalid_argument, "invalid vector<bool> argument");
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	_Vbase * _My_cont_begin() const
		{
		return (_VEC_ITER_BASE(((_MycontTy *)this->
			_Getmycont())->_Myvec.begin()));
		}

	_Sizet _My_actual_offset() const
		{
		_Sizet _Off = this->_Myoff;
		_Off += _VBITS * (this->_Myptr - _My_cont_begin());
		return (_Off);
		}
 #endif
	};

		// CLASS _Vb_reference
template<class _Sizet,
	class _Difft,
	class _MycontTy>
	class _Vb_reference
		: public _Vb_iter_base<_Sizet, _Difft, _MycontTy>
	{	// reference to a bit within a base word
public:
	typedef _Vb_iter_base<_Sizet, _Difft, _MycontTy> _Mybase;
	typedef _Vb_reference<_Sizet, _Difft, _MycontTy> _Mytype;

	_Vb_reference()
		{	// construct with null pointer
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	_Vb_reference(const _Mybase& _Right)
		: _Mybase(_Right._Myptr, _Right._Myoff, _Right._Getmycont())
		{	// construct with base
		}

 #else /* _HAS_ITERATOR_DEBUGGING */
	_Vb_reference(const _Mybase& _Right)
		: _Mybase(_Right._Myptr, _Right._Myoff)
		{	// construct with base
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	_Mytype& operator=(const _Mytype& _Right)
		{	// assign _Vb_reference _Right to bit
		return (*this = bool(_Right));
		}

	_Mytype& 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

 #if _HAS_ITERATOR_DEBUGGING
		if (this->_Mycont == 0 || this->_Myptr == 0)
			{
			_DEBUG_ERROR("vector<bool> iterator not dereferencable");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #else /* _HAS_ITERATOR_DEBUGGING */
 		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Myptr != NULL);
		_SCL_SECURE_VALIDATE_RANGE(this->_My_actual_offset() < ((_MycontTy *)this->_Getmycont())->_Mysize);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (this->_Myptr);
		}

protected:
	_Vbase _Mask() const
		{	// convert offset to mask
		return ((_Vbase)(1 << this->_Myoff));
		}
	};

template<class _Sizet,
	class _Difft,
	class _MycontTy>
	void swap(_Vb_reference<_Sizet, _Difft, _MycontTy> _Left,
		_Vb_reference<_Sizet, _Difft, _MycontTy> _Right)
	{	// swap _Left and _Right vector<bool> elements
	bool _Val = _Left;
	_Left = _Right;
	_Right = _Val;
	}

		// CLASS _Vb_const_iterator
template<class _Sizet,
	class _Difft,
	class _MycontTy>
	class _Vb_const_iterator
		: public _Vb_iter_base<_Sizet, _Difft, _MycontTy>
	{	// iterator for nonmutable vector<bool>
public:
	typedef _Vb_iter_base<_Sizet, _Difft, _MycontTy> _Mybase;
	typedef _Vb_const_iterator<_Sizet, _Difft, _MycontTy> _Mytype;

	typedef _Vb_reference<_Sizet, _Difft, _MycontTy> _Reft;
	typedef bool const_reference;

	typedef random_access_iterator_tag iterator_category;
	typedef _Bool value_type;
	typedef _Sizet size_type;
	typedef _Difft difference_type;
	typedef const_reference *pointer;
	typedef const_reference reference;

	_Vb_const_iterator()
		{	// construct with null reference
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	_Vb_const_iterator(const _Vbase *_Ptr, const _Container_base *_Mypvbool)
		: _Mybase((_Vbase *)_Ptr, 0, (_Container_base *)_Mypvbool)

 #else
	_Vb_const_iterator(const _Vbase *_Ptr)
		: _Mybase((_Vbase *)_Ptr, 0)

 #endif
		{	// construct with offset and pointer
		}

	const_reference operator*() const
		{	// return (reference to) designated object
		return (_Reft(*this));
		}

	_Mytype& operator++()
		{	// preincrement
		_Inc();
		return (*this);
		}

	_Mytype operator++(int)
		{	// postincrement
		_Mytype _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Mytype& operator--()
		{	// predecrement
		_Dec();
		return (*this);
		}

	_Mytype operator--(int)
		{	// postdecrement
		_Mytype _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Mytype& operator+=(difference_type _Off)
		{	// increment by integer
		if (_Off == 0)
			return (*this); // early out
		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Myptr != NULL);
		if (_Off < 0)
			{
			_SCL_SECURE_VALIDATE_RANGE(this->_My_actual_offset() >= ((size_type)-_Off));
			}
		else
			{
			_SCL_SECURE_VALIDATE_RANGE((this->_My_actual_offset() + _Off) <= ((_MycontTy *)this->_Getmycont())->_Mysize);
			}
		if (_Off < 0 && this->_Myoff < 0 - (size_type)_Off)
			{	/* add negative increment */
			this->_Myoff += _Off;
			this->_Myptr -= 1 + ((size_type)(-1) - this->_Myoff) / _VBITS;
			this->_Myoff %= _VBITS;
			}
		else
			{	/* add non-negative increment */
			this->_Myoff += _Off;
			this->_Myptr += this->_Myoff / _VBITS;
			this->_Myoff %= _VBITS;
			}
		return (*this);
		}

	_Mytype operator+(difference_type _Off) const
		{	// return this + integer
		_Mytype _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Mytype& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Mytype operator-(difference_type _Off) const
		{	// return this - integer
		_Mytype _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(
		const _Mytype& _Right) const
		{	// return difference of iterators

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		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 _Mytype& _Right) const
		{	// test for iterator equality

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (this->_Myptr == _Right._Myptr
			&& this->_Myoff == _Right._Myoff);
		}

	bool operator!=(const _Mytype& _Right) const
		{	// test for iterator inequality
		return (!(*this == _Right));
		}

	bool operator<(const _Mytype& _Right) const
		{	// test if this < _Right

 #if _HAS_ITERATOR_DEBUGGING
		_Compat(_Right);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (this->_Myptr < _Right._Myptr
			|| this->_Myptr == _Right._Myptr
				&& this->_Myoff < _Right._Myoff);
		}

	bool operator>(const _Mytype& _Right) const
		{	// test if this > _Right
		return (_Right < *this);
		}

	bool operator<=(const _Mytype& _Right) const
		{	// test if this <= _Right
		return (!(_Right < *this));
		}

	bool operator>=(const _Mytype& _Right) const
		{	// test if this >= _Right
		return (!(*this < _Right));
		}

protected:

 #if _HAS_ITERATOR_DEBUGGING
	void _Compat(const _Mytype& _Right) const
		{	// test for compatible iterator pair
		if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)
			_DEBUG_ERROR("vector<bool> iterators incompatible");
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	void _Dec()
		{	// decrement bit position
		if (this->_Myoff != 0)
			{
			--this->_Myoff;
			}
		else
			{
			_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Myptr != NULL);
			_SCL_SECURE_VALIDATE_RANGE(this->_Myptr > this->_My_cont_begin());
			--this->_Myptr;
			this->_Myoff = _VBITS - 1;
			}
		}

	void _Inc()
		{	// increment bit position
		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Myptr != NULL);
		_SCL_SECURE_VALIDATE_RANGE((this->_My_actual_offset() + 1) <= ((_MycontTy *)this->_Getmycont())->_Mysize);
		if (this->_Myoff < _VBITS - 1)
			++this->_Myoff;
		else
			this->_Myoff = 0, ++this->_Myptr;
		}
	};

template<class _Sizet,
	class _Difft,
	class _MycontTy>
	_Vb_const_iterator<_Sizet, _Difft, _MycontTy> operator+(_Difft _Off,
		_Vb_const_iterator<_Sizet, _Difft, _MycontTy> _Right)
		{	// return _Right + integer
		return (_Right += _Off);
		}

	// CLASS _Vb_iterator
template<class _Sizet,
	class _Difft,
	class _MycontTy>
	class _Vb_iterator
		: public _Vb_const_iterator<_Sizet, _Difft, _MycontTy>
	{	// iterator for mutable vector<bool>
public:
	typedef _Vb_const_iterator<_Sizet, _Difft, _MycontTy> _Mybase;
	typedef _Vb_iterator<_Sizet, _Difft, _MycontTy> _Mytype;

	typedef _Vb_reference<_Sizet, _Difft, _MycontTy> _Reft;
	typedef bool const_reference;

	typedef random_access_iterator_tag iterator_category;
	typedef _Bool value_type;
	typedef _Sizet size_type;
	typedef _Difft difference_type;
	typedef _Reft *pointer;
	typedef _Reft reference;

	_Vb_iterator()
		{	// construct with null reference
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	_Vb_iterator(_Vbase *_Ptr, _Container_base *_Mypvbool)
		: _Mybase(_Ptr, _Mypvbool)

 #else
	_Vb_iterator( _Vbase *_Ptr)
		: _Mybase(_Ptr)
 #endif /* _HAS_ITERATOR_DEBUGGING */

		{	// construct with offset and pointer
		}

	reference operator*() const
		{	// return (reference to) designated object
		return (_Reft(*this));
		}

	_Mytype& operator++()
		{	// preincrement
		++*(_Mybase *)this;
		return (*this);
		}

	_Mytype operator++(int)
		{	// postincrement
		_Mytype _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Mytype& operator--()
		{	// predecrement
		--*(_Mybase *)this;
		return (*this);
		}

	_Mytype operator--(int)
		{	// postdecrement
		_Mytype _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Mytype& operator+=(difference_type _Off)
		{	// increment by integer
		*(_Mybase *)this += _Off;
		return (*this);
		}

	_Mytype operator+(difference_type _Off) const
		{	// return this + integer
		_Mytype _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Mytype& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Mytype operator-(difference_type _Off) const
		{	// return this - integer
		_Mytype _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 _Sizet,
	class _Difft,
	class _MycontTy>
	_Vb_iterator<_Sizet, _Difft, _MycontTy> operator+(_Difft _Off,
		_Vb_iterator<_Sizet, _Difft, _MycontTy> _Right)
		{	// return _Right + integer
		return (_Right += _Off);
		}

		// CLASS vector_bool
template<class _Alloc>
	class vector<_Bool, _Alloc>
		: public _CONTAINER_BASE_AUX_ALLOC<_Alloc>
	{	// varying size array of bits
public:
	typedef typename _Alloc::size_type size_type;
	typedef typename _Alloc::difference_type _Dift;
	typedef std::vector<_Vbase,
		typename _Alloc::template rebind<_Vbase>::other>
			_Vbtype;
	typedef std::vector<_Bool, _Alloc> _Myt;


	typedef _Dift difference_type;
	typedef _Bool _Ty;
	typedef _Alloc allocator_type;

	typedef _Vb_reference<size_type, _Dift, _Myt> reference;
	typedef bool const_reference;
	typedef bool value_type;

	typedef reference _Reft;
	typedef _Vb_const_iterator<size_type, difference_type, _Myt> const_iterator;
	typedef _Vb_iterator<size_type, difference_type, _Myt> iterator;

	friend class _Vb_iter_base<size_type, difference_type, _Myt>;
	friend class _Vb_reference<size_type, difference_type, _Myt>;
	friend class _Vb_const_iterator<size_type, difference_type, _Myt>;
	friend class _Vb_iterator<size_type, difference_type, _Myt>;

	typedef iterator pointer;
	typedef const_iterator const_pointer;
	typedef std::reverse_iterator<iterator> reverse_iterator;
	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

	static const int _VBITS = std::_VBITS;

	vector()
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Alloc()), _Mysize(0), _Myvec()
		{	// construct empty vector
		}

	vector(const _Myt& _Right)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Right.get_allocator()), _Mysize(_Right._Mysize), _Myvec(_Right._Myvec)
		{	// copy construct vector; an implicitly defined copy constructor would not create an aux object.
		}

	explicit vector(const _Alloc& _Al)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Al), _Mysize(0), _Myvec(_Al)
		{	// construct empty vector, with allocator
		}

	explicit vector(size_type _Count, bool _Val = false)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Alloc()), _Mysize(0), _Myvec(_Nw(_Count), (_Vbase)(_Val ? -1 : 0))
		{	// construct from _Count * _Val
		_Trim(_Count);
		}

	vector(size_type _Count, bool _Val, const _Alloc& _Al)
		: _CONTAINER_BASE_AUX_ALLOC<_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)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Alloc()), _Mysize(0), _Myvec()
		{	// construct from [_First, _Last)
		_BConstruct(_First, _Last, _Iter_cat(_First));
		}

	template<class _Iter>
		vector(_Iter _First, _Iter _Last, const _Alloc& _Al)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Al), _Mysize(0), _Myvec(_Al)
		{	// construct from [_First, _Last), with allocator
		_BConstruct(_First, _Last, _Iter_cat(_First));
		}

	template<class _Iter>
		void _BConstruct(_Iter _Count, _Iter _Val, _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, 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);
		}

 #if _HAS_ITERATOR_DEBUGGING || _SECURE_SCL
	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (iterator(_VEC_ITER_BASE(_Myvec.begin()), this));
		}

	const_iterator begin() const
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(_VEC_ITER_BASE(_Myvec.begin()), this));
		}

 #else
	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())));
		}
 #endif

	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);
		}

	iterator _Make_iter(const_iterator _Where)
		{	// make iterator from const_iterator
		iterator _Tmp = begin();
		if (0 < _Mysize)
			_Tmp += _Where - begin();
		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
		// Work around a BE problem.
		_Alloc _Alret = _Myvec.get_allocator();
		return (_Alret);
		}

	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, _Iter_cat(_First));
		}

	template<class _Iter>
		void _Assign(_Iter _Count, _Iter _Val, _Int_iterator_tag)
		{	// assign _Count * _Val
		_Assign_n((size_type)_Count, (bool)_Val);
		}

	template<class _Iter>
		void _Assign(_Iter _First, _Iter _Last, 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(const_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(const_iterator _Where, size_type _Count, bool _Val)
		{	// insert _Count * _Val at _Where
		_Insert_n(_Where, _Count, _Val);
		}

	template<class _Iter>
		void insert(const_iterator _Where, _Iter _First, _Iter _Last)
		{	// insert [_First, _Last) at _Where
		_Insert(_Where, _First, _Last, _Iter_cat(_First));
		}

	template<class _Iter>
		void _Insert(const_iterator _Where, _Iter _Count, _Iter _Val,
			_Int_iterator_tag)
		{	// insert _Count * _Val at _Where
		_Insert_n(_Where, (size_type)_Count, (bool)_Val);
		}

	template<class _Iter>
		void _Insert(const_iterator _Where, _Iter _First, _Iter _Last,
			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(const_iterator _Where,
			_Iter _First, _Iter _Last,
			forward_iterator_tag)
		{	// insert [_First, _Last) at _Where, forward iterators

 #if _HAS_ITERATOR_DEBUGGING
		_DEBUG_RANGE(_First, _Last);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		size_type _Count = 0;
		_Distance(_First, _Last, _Count);

		size_type _Off = _Insert_x(_Where, _Count);
		std::copy(_First, _Last, begin() + _Off);
		}

	iterator erase(const_iterator _Where_arg)
		{	// erase element at _Where
		iterator _Where = _Make_iter(_Where_arg);
		size_type _Off = _Where - begin();

 #if _HAS_ITERATOR_DEBUGGING
		if (end() <= _Where)
			_DEBUG_ERROR("vector<bool> erase iterator outside range");
		std::copy(_Where + 1, end(), _Where);
		_Orphan_range(_Off, _Mysize);

 #else /* _HAS_ITERATOR_DEBUGGING */
		std::copy(_Where + 1, end(), _Where);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		_Trim(_Mysize - 1);
		return (begin() + _Off);
		}

	iterator erase(const_iterator _First_arg, const_iterator _Last_arg)
		{	// erase [_First, _Last)
		iterator _First = _Make_iter(_First_arg);
		iterator _Last = _Make_iter(_Last_arg);
		size_type _Off = _First - begin();

 #if _HAS_ITERATOR_DEBUGGING
		if (_Last < _First || end() < _Last)
			_DEBUG_ERROR("vector<bool> erase iterator outside range");
		iterator _Next = std::copy(_Last, end(), _First);
		size_type _Newsize = _Next - begin();
		_Orphan_range(_Newsize, _Mysize);
		_Trim(_Newsize);

 #else /* _HAS_ITERATOR_DEBUGGING */
		iterator _Next = std::copy(_Last, end(), _First);
		_Trim(_Next - begin());
 #endif /* _HAS_ITERATOR_DEBUGGING */

		return (begin() + _Off);
		}

	void clear()
		{	// erase all elements
		erase(begin(), end());
		}

	void flip()
		{	// toggle all elements
		for (_Vbtype::iterator _Next = _Myvec.begin();
			_Next != _Myvec.end(); ++_Next)
			*_Next = (_Vbase)~*_Next;
		_Trim(_Mysize);
		}

	void swap(_Myt& _Right)
		{	// exchange contents with right
		if (this != &_Right)
			{	// different, worth swapping

 #if _HAS_ITERATOR_DEBUGGING
			this->_Swap_all(_Right);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			this->_Swap_aux(_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(const_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(const_iterator _Where, size_type _Count)
		{	// make room to insert _Count elements at _Where
		size_type _Off = _Where - begin();

 #if _HAS_ITERATOR_DEBUGGING
		if (end() < _Where)
			_DEBUG_ERROR("vector<bool> insert iterator outside range");
		bool _Realloc = capacity() - size() < _Count;
 #endif /* _HAS_ITERATOR_DEBUGGING */

		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());
				}

 #if _HAS_ITERATOR_DEBUGGING
			_Orphan_range(_Realloc ? 0 : _Off, _Mysize);
 #endif /* _HAS_ITERATOR_DEBUGGING */

			}
		return (_Off);
		}

	static size_type _Nw(size_type _Count)
		{	// return number of base words from number of bits
		return ((_Count + _VBITS - 1) / _VBITS);
		}

 #if _HAS_ITERATOR_DEBUGGING
	void _Orphan_range(size_type _Offlo, size_type _Offhi) const
		{	// orphan iterators within specified (inclusive) range
		typedef _Vb_iter_base<size_type, difference_type, _Myt> _Myiterbase;

		_Lockit _Lock(_LOCK_DEBUG);
		_Vbase *_Base = (_Vbase *)_VEC_ITER_BASE(_Myvec.begin());

		_Myiterbase **_Pnext =
			(_Myiterbase **)&this->_Myfirstiter;
		while (*_Pnext != 0)
			{	// test offset from beginning of vector
			size_type _Off = _VBITS * ((*_Pnext)->_Myptr - _Base)
				+ (*_Pnext)->_Myoff;
			if (_Off < _Offlo || _Offhi < _Off)
				_Pnext = (_Myiterbase **)&(*_Pnext)->_Mynextiter;
			else
				{	// orphan the iterator
				(*_Pnext)->_Mycont = 0;
				*_Pnext = (_Myiterbase *)(*_Pnext)->_Mynextiter;
				}
			}
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

	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
		_THROW(length_error, "vector<bool> too long");
		}

	void _Xran() const
		{	// throw an out_of_range error
		_THROW(out_of_range, "invalid vector<bool> subscript");
		}

	size_type _Mysize;	// current length of sequence
	_Vbtype _Myvec;	// base vector of words
	};

typedef vector<bool, allocator<bool> > _Bvector;

#if _HAS_TRADITIONAL_STL
 typedef _Bvector bit_vector;
 #define __vector__	vector
#endif /* _HAS_TRADITIONAL_STL */

_STD_END

#ifdef _MSC_VER
 #pragma warning(default: 4244)
 #pragma warning(pop)
 #pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* RC_INVOKED */
#endif /* _VECTOR_ */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * 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) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.05:0009 */


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/