📄 forward_list
字号:
class _Ax = allocator<_Ty> >
class forward_list
: public _Flist_val<_Ty, _Ax>
{ // singly linked list
public:
typedef forward_list<_Ty, _Ax> _Myt;
typedef _Flist_val<_Ty, _Ax> _Mybase;
typedef typename _Mybase::_Alty _Alloc;
typedef typename _Mybase::_Node _Node;
typedef typename _Mybase::_Nodeptr _Nodeptr;
typedef _Alloc allocator_type;
typedef typename _Alloc::size_type size_type;
typedef typename _Alloc::difference_type difference_type;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
typedef typename _Alloc::reference reference;
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::value_type value_type;
typedef _Flist_const_iterator<_Mybase>
const_iterator;
typedef _Flist_iterator<_Mybase>
iterator;
forward_list()
: _Mybase()
{ // construct empty list
}
explicit forward_list(const _Alloc& _Al)
: _Mybase(_Al)
{ // construct empty list, allocator
}
explicit forward_list(size_type _Count)
: _Mybase()
{ // construct list from _Count * _Ty()
resize(_Count);
}
forward_list(size_type _Count, const _Ty& _Val)
: _Mybase()
{ // construct list from _Count * _Val
_Construct_n(_Count, _Val);
}
forward_list(size_type _Count, const _Ty& _Val, const _Alloc& _Al)
: _Mybase(_Al)
{ // construct list, allocator from _Count * _Val
_Construct_n(_Count, _Val);
}
forward_list(const _Myt& _Right)
: _Mybase(_Right._Alval)
{ // construct list by copying _Right
_TRY_BEGIN
insert_after(before_begin(), _Right.begin(), _Right.end());
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
template<class _Iter>
forward_list(_Iter _First, _Iter _Last)
: _Mybase()
{ // construct list from [_First, _Last)
_Construct(_First, _Last, _Iter_cat(_First));
}
template<class _Iter>
forward_list(_Iter _First, _Iter _Last, const _Alloc& _Al)
: _Mybase(_Al)
{ // construct list, allocator from [_First, _Last)
_Construct(_First, _Last, _Iter_cat(_First));
}
template<class _Iter>
void _Construct(_Iter _Count, _Iter _Val, _Int_iterator_tag)
{ // construct list from _Count * _Val
_Construct_n((size_type)_Count, (_Ty)_Val);
}
template<class _Iter>
void _Construct(_Iter _First,
_Iter _Last, input_iterator_tag)
{ // construct list from [_First, _Last), input iterators
_TRY_BEGIN
insert_after(before_begin(), _First, _Last);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
void _Construct_n(size_type _Count,
const _Ty& _Val)
{ // construct from _Count * _Val
_TRY_BEGIN
_Insert_n_after(before_begin(), _Count, _Val);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
forward_list(_Myt&& _Right)
: _Mybase(_Right._Alval)
{ // construct list by copying _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)
{ // clear this and steal from _Right
clear();
_Splice_after(before_begin(), _Right,
_Right.before_begin(), _Right.end());
}
}
void push_front(_Ty&& _Val)
{ // insert element at beginning
_Insert_after_rv(before_begin(), _STD forward<_Ty>(_Val));
}
template<class _Valty>
void emplace_front(_Valty&& _Val)
{ // insert element at beginning
_Insert_after_rv(before_begin(), _STD forward<_Valty>(_Val));
}
template<class _Valty>
iterator insert_after(const_iterator _Where, _Valty&& _Val)
{ // insert _Val at _Where
return (emplace_after(_Where, _STD forward<_Valty>(_Val)));
}
template<class _Valty>
iterator emplace_after(const_iterator _Where, _Valty&& _Val)
{ // insert _Val at _Where
_Insert_after_rv(_Where, _STD forward<_Valty>(_Val));
return (_Make_iter(++_Where));
}
template<class _Valty>
void _Insert_after_rv(const_iterator _Where,
_Valty&& _Val)
{ // insert _Val after _Where
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Where._Getcont() != this)
_DEBUG_ERROR("forward_list insert_after iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
_Nodeptr _Pnode = _Where._Mynode();
_Nodeptr _Newnode =
this->_Buynode(this->_Nextnode(_Pnode),
_STD forward<_Valty>(_Val));
this->_Nextnode(_Pnode) = _Newnode;
}
void swap(_Myt&& _Right)
{ // exchange contents with movable _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
~forward_list()
{ // destroy the object
_Tidy();
}
_Myt& operator=(const _Myt& _Right)
{ // assign _Right
if (this != &_Right)
assign(_Right.begin(), _Right.end());
return (*this);
}
iterator before_begin()
{ // return iterator before beginning of mutable sequence
return (iterator((_Nodeptr)&this->_Myhead, this));
}
const_iterator before_begin() const
{ // return iterator before beginning of mutable sequence
return (iterator((_Nodeptr)&this->_Myhead, this));
}
const_iterator cbefore_begin() const
{ // return iterator before beginning of mutable sequence
return (iterator((_Nodeptr)&this->_Myhead, this));
}
iterator begin()
{ // return iterator for beginning of mutable sequence
return (iterator(this->_Myhead, this));
}
const_iterator begin() const
{ // return iterator for beginning of nonmutable sequence
return (const_iterator(this->_Myhead, this));
}
iterator end()
{ // return iterator for end of mutable sequence
return (iterator(0, this));
}
const_iterator end() const
{ // return iterator for end of nonmutable sequence
return (const_iterator(0, this));
}
iterator _Make_iter(const_iterator _Where) const
{ // make iterator from const_iterator
return (iterator(_Where._Ptr, this));
}
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());
}
void resize(size_type _Newsize)
{ // determine new length, padding with _Ty() elements as needed
size_type _Cursize = _Size();
if (_Cursize < _Newsize)
{ // pad to make larger
const_iterator _Next = _Before_end();
_TRY_BEGIN
for (; _Cursize < _Newsize; ++_Cursize)
_Insert_after(_Next);
_CATCH_ALL
erase_after(_Next, end());
_RERAISE;
_CATCH_END
}
else if (_Newsize < _Cursize)
{ // erase all but _Newsize elements
iterator _Next = before_begin();
for (; 0 < _Newsize; --_Newsize)
++_Next;
erase_after(_Next, end());
}
}
void resize(size_type _Newsize, const _Ty& _Val)
{ // determine new length, padding with _Val elements as needed
size_type _Cursize = _Size();
if (_Cursize < _Newsize)
_Insert_n_after(_Before_end(), _Newsize - _Cursize, _Val);
else if (_Newsize < _Cursize)
{ // erase all but _Newsize elements
iterator _Next = before_begin();
for (; 0 < _Newsize; --_Newsize)
++_Next;
erase_after(_Next, end());
}
}
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 (begin() == end());
}
allocator_type get_allocator() const
{ // return allocator object for values
return (this->_Alval);
}
reference front()
{ // return first element of mutable sequence
return (*begin());
}
const_reference front() const
{ // return first element of nonmutable sequence
return (*begin());
}
void push_front(const _Ty& _Val)
{ // insert element at beginning
_Insert_after(before_begin(), _Val);
}
void pop_front()
{ // erase element at beginning
erase_after(before_begin());
}
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
clear();
insert_after(before_begin(), _First, _Last);
}
void assign(size_type _Count, const _Ty& _Val)
{ // assign _Count * _Val
_Assign_n(_Count, _Val);
}
iterator insert_after(const_iterator _Where, const _Ty& _Val)
{ // insert _Val at _Where
_Insert_after(_Where, _Val);
return (_Make_iter(++_Where));
}
void _Insert_after(const_iterator _Where,
const _Ty& _Val)
{ // insert _Val after _Where
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Where._Getcont() != this)
_DEBUG_ERROR("forward_list insert_after iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
_Nodeptr _Pnode = _Where._Mynode();
_Nodeptr _Newnode =
this->_Buynode(this->_Nextnode(_Pnode), _Val);
this->_Nextnode(_Pnode) = _Newnode;
}
void _Insert_after(const_iterator _Where)
{ // insert _Ty() after _Where
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Where._Getcont() != this)
_DEBUG_ERROR("forward_list insert_after iterator outside range");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
_Nodeptr _Pnode = _Where._Mynode();
_Nodeptr _Newnode =
this->_Buynode(this->_Nextnode(_Pnode));
this->_Nextnode(_Pnode) = _Newnode;
}
void insert_after(const_iterator _Where,
size_type _Count, const _Ty& _Val)
{ // insert _Count * _Val at _Where
_Insert_n_after(_Where, _Count, _Val);
}
template<class _Iter>
void insert_after(const_iterator _Where, _Iter _First, _Iter _Last)
{ // insert [_First, _Last) at _Where
_Insert_after(_Where, _First, _Last, _Iter_cat(_First));
}
template<class _Iter>
void _Insert_after(const_iterator _Where, _Iter _Count, _Iter _Val,
_Int_iterator_tag)
{ // insert _Count * _Val at _Where
_Insert_n_after(_Where, (size_type)_Count, (_Ty)_Val);
}
template<class _Iter>
void _Insert_after(const_iterator _Where,
_Iter _First, _Iter _Last, input_iterator_tag)
{ // insert [_First, _Last) after _Where, input iterators
size_type _Num = 0;
_TRY_BEGIN
for (const_iterator _After = _Where; _First != _Last;
++_After, ++_First, ++_Num)
_Insert_after(_After, *_First);
_CATCH_ALL
for (; 0 < _Num; --_Num)
erase_after(_Where);
_RERAISE;
_CATCH_END
}
template<class _Iter>
void _Insert_after(const_iterator _Where,
_Iter _First, _Iter _Last, forward_iterator_tag)
{ // insert [_First, _Last) after _Where, forward iterators
_DEBUG_RANGE(_First, _Last);
_Iter _Next = _First;
_TRY_BEGIN
for (const_iterator _After = _Where; _First != _Last;
++_After, ++_First)
_Insert_after(_After, *_First);
_CATCH_ALL
for (; _Next != _First; ++_Next)
erase_after(_Where);
_RERAISE;
_CATCH_END
}
iterator erase_after(const_iterator _Where)
{ // erase element after _Where
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Where._Getcont() != this
|| _Where == end())
_DEBUG_ERROR("forward_list erase_after iterator outside range");
_Nodeptr _Pnodeb = _Where._Mynode();
_Orphan_ptr(*this, this->_Nextnode(_Pnodeb));
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
_Nodeptr _Pnodeb = _Where._Mynode();
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
if (++_Where == end())
_DEBUG_ERROR("forward_list erase_after iterator outside range");
else
{ // node exists, erase it
_Nodeptr _Pnode = _Where._Mynode(); // subject node
++_Where; // point past subject node
this->_Nextnode(_Pnodeb) = this->_Nextnode(_Pnode); // link past it
_Dest_val(this->_Alnod, _Pnode);
this->_Alnod.deallocate(_Pnode, 1);
}
return (_Make_iter(_Where));
}
iterator erase_after(const_iterator _First,
const_iterator _Last)
{ // erase (_First, _Last)
if (_First == before_begin() && _Last == end())
{ // erase all and return fresh iterator
clear();
return (end());
}
else
{ // erase subrange
if (_First == end() || _First == _Last)
_DEBUG_ERROR("forward_list invalid erase_after range");
else
{ // range not awful, try it
const_iterator _After = _First;
++_After;
_DEBUG_RANGE(_After, _Last);
while (_After != _Last)
_After = erase_after(_First);
}
return (_Make_iter(_Last));
}
}
void clear()
{ // erase all
#if _ITERATOR_DEBUG_LEVEL == 2
this->_Orphan_ptr(*this, 0);
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
_Nodeptr _Pnext;
_Nodeptr _Pnode = this->_Myhead;
this->_Myhead = 0;
for (; _Pnode != 0; _Pnode = _Pnext)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -