📄 vector
字号:
#define _VIPTR(it) (it)._Ptr
typedef _Vector_iterator<_Mybase> iterator;
typedef _Vector_const_iterator<_Mybase> const_iterator;
typedef _STD reverse_iterator<iterator> reverse_iterator;
typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;
vector()
: _Mybase()
{ // construct empty vector
}
explicit vector(const _Alloc& _Al)
: _Mybase(_Al)
{ // construct empty vector with allocator
}
explicit vector(size_type _Count)
: _Mybase()
{ // construct from _Count * _Ty()
resize(_Count);
}
vector(size_type _Count, const _Ty& _Val)
: _Mybase()
{ // construct from _Count * _Val
_Construct_n(_Count, _STD addressof(_Val));
}
vector(size_type _Count, const _Ty& _Val, const _Alloc& _Al)
: _Mybase(_Al)
{ // construct from _Count * _Val, with allocator
_Construct_n(_Count, _STD addressof(_Val));
}
vector(const _Myt& _Right)
: _Mybase(_Right._Alval)
{ // construct by copying _Right
if (_Buy(_Right.size()))
_TRY_BEGIN
this->_Mylast = _Ucopy(_Right.begin(), _Right.end(),
this->_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;
_Ty _Newval = (_Ty)_Val;
_Construct_n(_Size, _STD addressof(_Newval));
}
template<class _Iter>
void _Construct(_Iter _First,
_Iter _Last, input_iterator_tag)
{ // initialize with [_First, _Last), input iterators
_TRY_BEGIN
insert(begin(), _First, _Last);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
void _Construct_n(size_type _Count, const _Ty *_Pval)
{ // construct from _Count * *_Pval
if (_Buy(_Count))
{ // nonzero, fill it
_TRY_BEGIN
this->_Mylast = _Ufill(this->_Myfirst, _Count, _Pval);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
}
vector(_Myt&& _Right)
: _Mybase(_Right._Alval)
{ // construct by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
_Myt& operator=(_Myt&& _Right)
{ // assign by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
return (*this);
}
void _Assign_rv(_Myt&& _Right)
{ // assign by moving _Right
if (this == &_Right)
;
else if (get_allocator() != _Right.get_allocator())
{ // move construct a copy
clear();
for (iterator _Next = _Right.begin(); _Next != _Right.end();
++_Next)
push_back(_STD forward<_Ty>(*_Next));
}
else
{ // clear this and steal from _Right
_Tidy();
this->_Swap_all((_Myt&)_Right);
this->_Myfirst = _Right._Myfirst;
this->_Mylast = _Right._Mylast;
this->_Myend = _Right._Myend;
_Right._Myfirst = 0;
_Right._Mylast = 0;
_Right._Myend = 0;
}
}
void push_back(_Ty&& _Val)
{ // insert element at end
if (_Inside(_STD addressof(_Val)))
{ // push back an element
size_type _Idx = _STD addressof(_Val) - this->_Myfirst;
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
_STD forward<_Ty>(this->_Myfirst[_Idx]));
++this->_Mylast;
}
else
{ // push back a non-element
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
_STD forward<_Ty>(_Val));
++this->_Mylast;
}
}
void emplace_back(_Ty&& _Val)
{ // insert element at end
push_back(_STD forward<_Ty>(_Val));
}
template<class _Valty>
void emplace_back(_Valty&& _Val)
{ // insert element at end
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
_STD forward<_Valty>(_Val));
++this->_Mylast;
}
template<class _Valty>
iterator insert(const_iterator _Where, _Valty&& _Val)
{ // insert _Val at _Where
return (emplace(_Where, _STD forward<_Valty>(_Val)));
}
template<class _Valty>
iterator emplace(const_iterator _Where, _Valty&& _Val)
{ // insert _Val at _Where
size_type _Off = _VIPTR(_Where) - this->_Myfirst;
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() < _Off)
_DEBUG_ERROR("vector emplace iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
emplace_back(_STD forward<_Valty>(_Val));
_STD rotate(begin() + _Off, end() - 1, end());
return (begin() + _Off);
}
void swap(_Myt&& _Right)
{ // exchange contents with movable _Right
if (this != &_Right)
{ // swap with emptied container
clear();
this->_Swap_all((_Myt&)_Right);
_Assign_rv(_STD forward<_Myt>(_Right));
}
}
~vector()
{ // destroy the object
_Tidy();
}
_Myt& operator=(const _Myt& _Right)
{ // assign _Right
if (this != &_Right)
{ // worth doing
this->_Orphan_all();
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 = _STD _Copy_impl(_Right._Myfirst, _Right._Mylast,
this->_Myfirst); // copy new
_Destroy(_Ptr, this->_Mylast); // destroy old
this->_Mylast = this->_Myfirst + _Right.size();
}
else if (_Right.size() <= capacity())
{ // enough room, copy and construct new
pointer _Ptr = _Right._Myfirst + size();
_STD _Copy_impl(_Right._Myfirst, _Ptr, this->_Myfirst);
this->_Mylast = _Ucopy(_Ptr, _Right._Mylast, this->_Mylast);
}
else
{ // not enough room, allocate new array and construct new
if (this->_Myfirst != 0)
{ // discard old array
_Destroy(this->_Myfirst, this->_Mylast);
this->_Alval.deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);
}
if (_Buy(_Right.size()))
this->_Mylast = _Ucopy(_Right._Myfirst, _Right._Mylast,
this->_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(this->_Myfirst, this->_Mylast, _Ptr);
_CATCH_ALL
this->_Alval.deallocate(_Ptr, _Count);
_RERAISE;
_CATCH_END
size_type _Size = 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 = _Ptr + _Count;
this->_Mylast = _Ptr + _Size;
this->_Myfirst = _Ptr;
}
}
size_type capacity() const
{ // return current length of allocated storage
return (this->_Myend - this->_Myfirst);
}
iterator begin()
{ // return iterator for beginning of mutable sequence
return (iterator(this->_Myfirst, this));
}
const_iterator begin() const
{ // return iterator for beginning of nonmutable sequence
return (const_iterator(this->_Myfirst, this));
}
iterator end()
{ // return iterator for end of mutable sequence
return (iterator(this->_Mylast, this));
}
const_iterator end() const
{ // return iterator for end of nonmutable sequence
return (const_iterator(this->_Mylast, this));
}
iterator _Make_iter(const_iterator _Where) const
{ // make iterator from const_iterator
return (iterator(_Where._Ptr, this));
}
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()));
}
#if _HAS_CPP0X
const_iterator cbegin() const
{ // return iterator for beginning of nonmutable sequence
return (((const _Myt *)this)->begin());
}
const_iterator cend() const
{ // return iterator for end of nonmutable sequence
return (((const _Myt *)this)->end());
}
const_reverse_iterator crbegin() const
{ // return iterator for beginning of reversed nonmutable sequence
return (((const _Myt *)this)->rbegin());
}
const_reverse_iterator crend() const
{ // return iterator for ebd of reversed nonmutable sequence
return (((const _Myt *)this)->rend());
}
void shrink_to_fit()
{ // reduce capacity
if (size() < capacity())
{ // worth shrinking, do it
_Myt _Tmp(*this);
swap(_Tmp);
}
}
#endif /* _HAS_CPP0X */
void resize(size_type _Newsize)
{ // determine new length, padding with _Ty() elements as needed
if (_Newsize < size())
erase(begin() + _Newsize, end());
else if (size() < _Newsize)
{ // pad as needed
_Reserve(_Newsize - size());
_Uninitialized_default_fill_n(this->_Mylast, _Newsize - size(),
(_Ty *)0, this->_Alval);
this->_Mylast += _Newsize - size();
}
}
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 (this->_Mylast - this->_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 (this->_Myfirst == this->_Mylast);
}
_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 (*(this->_Myfirst + _Pos));
}
reference at(size_type _Pos)
{ // subscript mutable sequence with checking
if (size() <= _Pos)
_Xran();
return (*(this->_Myfirst + _Pos));
}
const_reference operator[](size_type _Pos) const
{ // subscript nonmutable sequence
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() <= _Pos)
{ // report error
_DEBUG_ERROR("vector subscript out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
#endif /* _ITERATOR_DEBUG_LEVEL */
return (*(this->_Myfirst + _Pos));
}
reference operator[](size_type _Pos)
{ // subscript mutable sequence
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() <= _Pos)
{ // report error
_DEBUG_ERROR("vector subscript out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
#endif /* _ITERATOR_DEBUG_LEVEL */
return (*(this->_Myfirst + _Pos));
}
#if _HAS_CPP0X
pointer data()
{ // return address of first element
return (this->_Myfirst);
}
const_pointer data() const
{ // return address of first element
return (this->_Myfirst);
}
#endif /* _HAS_CPP0X */
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 (_Inside(_STD addressof(_Val)))
{ // push back an element
size_type _Idx = _STD addressof(_Val) - this->_Myfirst;
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
this->_Myfirst[_Idx]);
++this->_Mylast;
}
else
{ // push back a non-element
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -