📄 vector
字号:
_Cons_val(this->_Alval,
this->_Mylast,
_Val);
++this->_Mylast;
}
}
#if _ITERATOR_DEBUG_LEVEL == 2
void pop_back()
{ // erase element at end
if (empty())
_DEBUG_ERROR("vector empty before pop");
else
{ // erase last element
_Orphan_range(this->_Mylast - 1, this->_Mylast);
_Dest_val(this->_Alval,
this->_Mylast - 1);
--this->_Mylast;
}
}
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
void pop_back()
{ // erase element at end
if (!empty())
{ // erase last element
_Dest_val(this->_Alval,
this->_Mylast - 1);
--this->_Mylast;
}
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
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
size_type _Off = _VIPTR(_Where) - this->_Myfirst;
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() < _Off)
_DEBUG_ERROR("vector insert iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
if (_First != _Last)
{ // worth doing, gather at end and rotate into place
size_type _Oldsize = size();
_TRY_BEGIN
for (; _First != _Last; ++_First)
push_back(*_First); // append
_CATCH_ALL
erase(begin() + _Oldsize, end());
_RERAISE;
_CATCH_END
_STD rotate(begin() + _Off, begin() + _Oldsize, end());
}
}
template<class _Iter>
void _Insert(const_iterator _Where,
_Iter _First, _Iter _Last, forward_iterator_tag)
{ // insert [_First, _Last) at _Where, forward iterators
#if _ITERATOR_DEBUG_LEVEL == 2
if (_VICONT(_Where) != this
|| _VIPTR(_Where) < this->_Myfirst
|| this->_Mylast < _VIPTR(_Where))
_DEBUG_ERROR("vector insert iterator outside range");
_DEBUG_RANGE(_First, _Last);
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
size_type _Count = 0;
_Distance(_First, _Last, _Count);
if (_Count == 0)
;
else if (max_size() - size() < _Count)
_Xlen(); // result too long
else if (capacity() < size() + _Count)
{ // not enough room, reallocate
size_type _Capacity = _Grow_to(size() + _Count);
pointer _Newvec = this->_Alval.allocate(_Capacity);
pointer _Ptr = _Newvec;
_TRY_BEGIN
_Ptr = _Umove(this->_Myfirst, _VIPTR(_Where),
_Newvec); // copy prefix
_Ptr = _Ucopy(_First, _Last, _Ptr); // add new stuff
_Umove(_VIPTR(_Where), this->_Mylast,
_Ptr); // copy suffix
_CATCH_ALL
_Destroy(_Newvec, _Ptr);
this->_Alval.deallocate(_Newvec, _Capacity);
_RERAISE;
_CATCH_END
_Count += size();
if (this->_Myfirst != 0)
{ // destroy and deallocate old array
_Destroy(this->_Myfirst, this->_Mylast);
this->_Alval.deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);
}
this->_Orphan_all();
this->_Myend = _Newvec + _Capacity;
this->_Mylast = _Newvec + _Count;
this->_Myfirst = _Newvec;
}
else
{ // new stuff fits, append and rotate into place
_Ucopy(_First, _Last, this->_Mylast);
_STD rotate(_VIPTR(_Where), this->_Mylast,
this->_Mylast + _Count);
this->_Mylast += _Count;
_Orphan_range(_VIPTR(_Where), this->_Mylast);
}
}
#if _ITERATOR_DEBUG_LEVEL == 2
iterator erase(const_iterator _Where)
{ // erase element at where
if (_VICONT(_Where) != this
|| _VIPTR(_Where) < this->_Myfirst
|| this->_Mylast <= _VIPTR(_Where))
_DEBUG_ERROR("vector erase iterator outside range");
_Move(_VIPTR(_Where) + 1, this->_Mylast, _VIPTR(_Where));
_Destroy(this->_Mylast - 1, this->_Mylast);
_Orphan_range(_VIPTR(_Where), this->_Mylast);
--this->_Mylast;
return (_Make_iter(_Where));
}
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
iterator erase(const_iterator _Where)
{ // erase element at where
_Move(_VIPTR(_Where) + 1, this->_Mylast,
_VIPTR(_Where));
_Destroy(this->_Mylast - 1, this->_Mylast);
--this->_Mylast;
return (_Make_iter(_Where));
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
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 _ITERATOR_DEBUG_LEVEL == 2
if (_Last < _First || _VICONT(_First) != this
|| _VIPTR(_First) < this->_Myfirst
|| this->_Mylast < _VIPTR(_Last))
_DEBUG_ERROR("vector erase iterator outside range");
pointer _Ptr = _Move(_VIPTR(_Last), this->_Mylast,
_VIPTR(_First));
_Orphan_range(_VIPTR(_First), this->_Mylast);
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
pointer _Ptr = _Move(_VIPTR(_Last), this->_Mylast,
_VIPTR(_First));
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
_Destroy(_Ptr, this->_Mylast);
this->_Mylast = _Ptr;
}
return (_First);
}
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
this->_Swap_all(_Right);
_STD swap(this->_Myfirst, _Right._Myfirst);
_STD swap(this->_Mylast, _Right._Mylast);
_STD swap(this->_Myend, _Right._Myend);
}
else
{ // different allocator, do multiple assigns
_Myt _Ts = _Move(*this);
*this = _Move(_Right);
_Right = _Move(_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
this->_Myfirst = 0;
this->_Mylast = 0;
this->_Myend = 0;
if (_Capacity == 0)
return (false);
else if (max_size() < _Capacity)
_Xlen(); // result too long
else
{ // nonempty array, allocate storage
this->_Myfirst = this->_Alval.allocate(_Capacity);
this->_Mylast = this->_Myfirst;
this->_Myend = this->_Myfirst + _Capacity;
}
return (true);
}
void _Destroy(pointer _First, pointer _Last)
{ // destroy [_First, _Last) using allocator
_Destroy_range(_First, _Last, this->_Alval);
}
size_type _Grow_to(size_type _Count) const
{ // grow by 50% or at least to _Count
size_type _Capacity = capacity();
_Capacity = max_size() - _Capacity / 2 < _Capacity
? 0 : _Capacity + _Capacity / 2; // try to grow by 50%
if (_Capacity < _Count)
_Capacity = _Count;
return (_Capacity);
}
bool _Inside(const _Ty *_Ptr) const
{ // test if _Ptr points inside vector
return (_Ptr < this->_Mylast && this->_Myfirst <= _Ptr);
}
void _Reserve(size_type _Count)
{ // ensure room for _Count new elements, grow exponentially
size_type _Size = size();
if (max_size() - _Count < _Size)
_Xlen();
else if ((_Size += _Count) <= capacity())
;
else
reserve(_Grow_to(_Size));
}
void _Tidy()
{ // free all storage
if (this->_Myfirst != 0)
{ // something to free, destroy and deallocate it
this->_Orphan_all();
_Destroy(this->_Myfirst, this->_Mylast);
this->_Alval.deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);
}
this->_Myfirst = 0;
this->_Mylast = 0;
this->_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));
}
template<class _Iter>
pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr)
{ // move initializing [_First, _Last), using allocator
return (_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 _ITERATOR_DEBUG_LEVEL == 2
if (_VICONT(_Where) != this
|| _VIPTR(_Where) < this->_Myfirst
|| this->_Mylast < _VIPTR(_Where))
_DEBUG_ERROR("vector insert iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
if (_Count == 0)
;
else if (max_size() - size() < _Count)
_Xlen(); // result too long
else if (capacity() < size() + _Count)
{ // not enough room, reallocate
size_type _Capacity = _Grow_to(size() + _Count);
pointer _Newvec = this->_Alval.allocate(_Capacity);
size_type _Whereoff = _VIPTR(_Where) - this->_Myfirst;
int _Ncopied = 0;
_TRY_BEGIN
_Ufill(_Newvec + _Whereoff, _Count,
_STD addressof(_Val)); // add new stuff
++_Ncopied;
_Umove(this->_Myfirst, _VIPTR(_Where),
_Newvec); // copy prefix
++_Ncopied;
_Umove(_VIPTR(_Where), this->_Mylast,
_Newvec + (_Whereoff + _Count)); // copy 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 (this->_Myfirst != 0)
{ // destroy and deallocate old array
_Destroy(this->_Myfirst, this->_Mylast);
this->_Alval.deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);
}
this->_Orphan_all();
this->_Myend = _Newvec + _Capacity;
this->_Mylast = _Newvec + _Count;
this->_Myfirst = _Newvec;
}
else if ((size_type)(this->_Mylast - _VIPTR(_Where))
< _Count)
{ // new stuff spills off end
_Ty _Tmp = _Val; // in case _Val is in sequence
_Umove(_VIPTR(_Where), this->_Mylast,
_VIPTR(_Where) + _Count); // copy suffix
_TRY_BEGIN
_Ufill(this->_Mylast,
_Count - (this->_Mylast - _VIPTR(_Where)),
_STD addressof(_Tmp)); // insert new stuff off end
_CATCH_ALL
_Destroy(_VIPTR(_Where) + _Count,
this->_Mylast + _Count);
_RERAISE;
_CATCH_END
this->_Mylast += _Count;
_Orphan_range(_VIPTR(_Where), this->_Mylast);
_STD fill(_VIPTR(_Where), this->_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 = this->_Mylast;
this->_Mylast = _Umove(_Oldend - _Count, _Oldend,
this->_Mylast); // copy suffix
_Orphan_range(_VIPTR(_Where), this->_Mylast);
_STD _Copy_backward(_VIPTR(_Where), _Oldend - _Count,
_Oldend); // copy hole
_STD fill(_VIPTR(_Where),
_VIPTR(_Where) + _Count, _Tmp); // insert into hole
}
}
pointer _Ufill(pointer _Ptr, size_type _Count, const _Ty *_Pval)
{ // copy initializing _Count * _Val, using allocator
_Uninitialized_fill_n(_Ptr, _Count, _Pval, this->_Alval);
return (_Ptr + _Count);
}
__declspec(noreturn) void _Xlen() const
{ // report a length_error
_Xlength_error("vector<T> too long");
}
__declspec(noreturn) void _Xran() const
{ // report an out_of_range error
_Xout_of_range("invalid vector<T> subscript");
}
#if _VECTOR_ORPHAN_RANGE
void _Orphan_range(pointer _First, pointer _Last) const
{ // orphan iterators within specified (inclusive) range
_Lockit _Lock(_LOCK_DEBUG);
const_iterator **_Pnext = (const_iterator **)this->_Getpfirst();
if (_Pnext != 0)
while (*_Pnext != 0)
if ((*_Pnext)->_Ptr < _First || _Last < (*_Pnext)->_Ptr)
_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
else
{ // orphan the iterator
(*_Pnext)->_Clrcont();
*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
}
}
#else /* _VECTOR_ORPHAN_RANGE */
void _Orphan_range(pointer, pointer) const
{ // orphan iterators within specified (inclusive) range
}
#endif /* _VECTOR_ORPHAN_RANGE */
};
// vector TEMPLATE OPERATORS
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 _Ty,
class _Alloc> inline
void swap(vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>&& _Right)
{ // swap _Left and _Right vectors
typedef vector<_Ty, _Alloc> _Myt;
_Left.swap(_STD forward<_Myt>(_Right));
}
template<class _Ty,
class _Alloc> inline
void swap(vector<_Ty, _Alloc>&& _Left, vector<_Ty, _Alloc>& _Right)
{ // swap _Left and _Right vectors
typedef vector<_Ty, _Alloc> _Myt;
_Right.swap(_STD forward<_Myt>(_Left));
}
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()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -