📄 forward_list
字号:
{ // delete an element
_Pnext = this->_Nextnode(_Pnode);
_Dest_val(this->_Alnod, _Pnode);
this->_Alnod.deallocate(_Pnode, 1);
}
}
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->_Myhead, _Right._Myhead);
}
else
{ // different allocator, do splices
_Myt _Tmp;
_Tmp.splice_after(_Tmp.before_begin(), _Right);
_Right.splice_after(_Right.before_begin(), *this);
splice_after(before_begin(), _Tmp);
}
}
void splice_after(const_iterator _Where, _Myt& _Right)
{ // splice all of _Right after _Where
if (this != &_Right && !_Right.empty())
{ // worth splicing, do it
_Splice_after(_Where, _Right,
_Right.before_begin(), _Right.end());
}
}
void splice_after(const_iterator _Where, _Myt& _Right,
const_iterator _First)
{ // splice _Right (_First, _First + 2) after _Where
const_iterator _After = _First;
if (_First == _Right.end() || ++_After == _Right.end())
_DEBUG_ERROR("forward_list splice_after iterator outside range");
else
{ // element exists, try splice
if (this != &_Right
|| (_Where != _First && _Where != _After))
_Splice_after(_Where, _Right, _First, ++_After);
}
}
void splice_after(const_iterator _Where,
_Myt& _Right, const_iterator _First, const_iterator _Last)
{ // splice _Right [_First, _Last) at _Where
const_iterator _After = _First;
if (_First == _Right.end())
_DEBUG_ERROR("forward_list splice_after iterator outside range");
else if (++_After != _Last && (this != &_Right || _Where != _First))
_Splice_after(_Where, _Right, _First, _Last);
}
void remove(const _Ty& _Val_arg)
{ // erase each element matching _Val
const _Ty _Val = _Val_arg; // in case it's removed along the way
iterator _Firstb = before_begin();
for (iterator _First = begin(); _First != end(); )
if (*_First == _Val)
_First = erase_after(_Firstb);
else
{ // advance iterators
++_Firstb;
++_First;
}
}
template<class _Pr1>
void remove_if(_Pr1 _Pred)
{ // erase each element satisfying _Pr1
iterator _Firstb = before_begin();
for (iterator _First = begin(); _First != end(); )
if (_Pred(*_First))
_First = erase_after(_Firstb);
else
{ // advance iterators
++_Firstb;
++_First;
}
}
void unique()
{ // erase each element matching previous
iterator _First = begin();
if (_First != end())
{ // worth doing
iterator _After = _First;
for (++_After; _After != end(); )
if (*_First == *_After)
_After = erase_after(_First);
else
_First = _After++;
}
}
template<class _Pr2>
void unique(_Pr2 _Pred)
{ // erase each element satisfying _Pred with previous
iterator _First = begin();
if (_First != end())
{ // worth doing
iterator _After = _First;
for (++_After; _After != end(); )
if (_Pred(*_First, *_After))
_After = erase_after(_First);
else
_First = _After++;
}
}
void merge(_Myt& _Right)
{ // merge in elements from _Right, both ordered by operator<
if (&_Right != this)
{ // safe to merge, do it
iterator _First1 = before_begin();
iterator _After1 = begin();
iterator _Last1 = end();
iterator _First2 = _Right.before_begin();
iterator _After2 = _Right.begin();
iterator _Last2 = _Right.end();
_DEBUG_ORDER(_After1, _Last1);
_DEBUG_ORDER(_After2, _Last2);
for (; _After1 != _Last1 && _After2 != _Last2; ++_First1)
if (_DEBUG_LT(*_After2, *_After1))
{ // splice in an element from _Right
iterator _Mid2 = _After2;
_Splice_after(_First1, _Right, _First2, ++_Mid2);
_After2 = _Mid2;
}
else
++_After1;
if (_After2 != _Last2)
_Splice_after(_First1, _Right, _First2,
_Last2); // splice remainder of _Right
}
}
template<class _Pr3>
void merge(_Myt& _Right, _Pr3 _Pred)
{ // merge in elements from _Right, both ordered by _Pred
if (&_Right != this)
{ // safe to merge, do it
iterator _First1 = before_begin();
iterator _After1 = begin();
iterator _Last1 = end();
iterator _First2 = _Right.before_begin();
iterator _After2 = _Right.begin();
iterator _Last2 = _Right.end();
_DEBUG_ORDER_PRED(_After1, _Last1, _Pred);
_DEBUG_ORDER_PRED(_After2, _Last2, _Pred);
for (; _After1 != _Last1 && _After2 != _Last2; ++_First1)
if (_DEBUG_LT_PRED(_Pred, *_After2, *_After1))
{ // splice in an element from _Right
iterator _Mid2 = _After2;
_Splice_after(_First1, _Right, _First2, ++_Mid2);
_After2 = _Mid2;
}
else
++_After1;
if (_After2 != _Last2)
_Splice_after(_First1, _Right, _First2,
_Last2); // splice remainder of _Right
}
}
void sort()
{ // order sequence, using operator<
iterator _First = begin();
if (_First != end() && ++_First != end())
{ // worth sorting, do it
const size_t _MAXBINS = 25;
_Myt _Templist(this->_Alval), _Binlist[_MAXBINS + 1];
size_t _Maxbin = 0;
while (!empty())
{ // sort another element, using bins
_Templist._Splice_same_after(_Templist.before_begin(), *this,
before_begin(), ++begin());
size_t _Bin;
for (_Bin = 0; _Bin < _Maxbin && !_Binlist[_Bin].empty();
++_Bin)
{ // merge into ever larger bins
_Binlist[_Bin].merge(_Templist);
_Binlist[_Bin].swap(_Templist);
}
if (_Bin == _MAXBINS)
_Binlist[_Bin - 1].merge(_Templist);
else
{ // spill to new bin, while they last
_Binlist[_Bin].swap(_Templist);
if (_Bin == _Maxbin)
++_Maxbin;
}
}
for (size_t _Bin = 1; _Bin < _Maxbin; ++_Bin)
_Binlist[_Bin].merge(_Binlist[_Bin - 1]); // merge up
splice_after(before_begin(),
_Binlist[_Maxbin - 1]); // result in last bin
}
}
template<class _Pr3>
void sort(_Pr3 _Pred)
{ // order sequence, using _Pred
iterator _First = begin();
if (_First != end() && ++_First != end())
{ // worth sorting, do it
const size_t _MAXBINS = 25;
_Myt _Templist(this->_Alval), _Binlist[_MAXBINS + 1];
size_t _Maxbin = 0;
while (!empty())
{ // sort another element, using bins
_Templist._Splice_same_after(_Templist.before_begin(), *this,
before_begin(), ++begin());
size_t _Bin;
for (_Bin = 0; _Bin < _Maxbin && !_Binlist[_Bin].empty();
++_Bin)
{ // merge into ever larger bins
_Binlist[_Bin].merge(_Templist, _Pred);
_Binlist[_Bin].swap(_Templist);
}
if (_Bin == _MAXBINS)
_Binlist[_Bin - 1].merge(_Templist, _Pred);
else
{ // spill to new bin, while they last
_Binlist[_Bin].swap(_Templist);
if (_Bin == _Maxbin)
++_Maxbin;
}
}
for (size_t _Bin = 1; _Bin < _Maxbin; ++_Bin)
_Binlist[_Bin].merge(_Binlist[_Bin - 1],
_Pred); // merge up
splice_after(before_begin(),
_Binlist[_Maxbin - 1]); // result in last bin
}
}
void reverse()
{ // reverse sequence
if (!empty())
{ // worth doing, move to back in reverse order
const_iterator _First = _Before_end();
for (; begin() != _First; )
_Splice_same_after(_First, *this, before_begin(), ++begin());
}
}
private:
size_type _Size() const
{ // get size by counting
size_type _Ans = 0;
for (const_iterator _Next = begin(); _Next != end(); ++_Next)
++_Ans;
return (_Ans);
}
const_iterator _Before_end() const
{ // get iterator just before end
const_iterator _Next = before_begin();
for (const_iterator _Nextp = _Next; ++_Nextp != end(); )
_Next = _Nextp;
return (_Next);
}
void _Splice_after(const_iterator _Where,
_Myt& _Right, const_iterator _First, const_iterator _Last)
{ // splice _Right (_First, _Last) just after _Where
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Where._Getcont() != this || _Where == end())
_DEBUG_ERROR("forward_list splice_after iterator outside range");
if (this->_Alval == _Right._Alval)
{ // same allocator, just relink
if (this != &_Right)
{ // transfer ownership of (_First, _Last)
const_iterator _Next = _First;
for (++_Next; _Next != _Last; )
{ // transfer ownership
const_iterator _Iter = _Next++;
_Orphan_ptr(_Right, _Iter._Ptr);
_Iter._Adopt(this);
}
}
_Splice_same_after(_Where, _Right, _First, _Last);
}
#else /* _ITERATOR_DEBUG_LEVEL == 2 */
if (this->_Alval == _Right._Alval)
_Splice_same_after(_Where, _Right, _First, _Last);
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
else
{ // different allocator, copy nodes then erase source
for (const_iterator _Next = _First; ++_Next != _Last; )
insert_after(_Where, (_Ty &&)*_Next);
_Right.erase_after(_First, _Last);
}
}
void _Splice_same_after(const_iterator _Where,
_Myt& _Right, const_iterator _First, const_iterator _Last)
{ // splice _Right (_First, _Last) just after _Where
const_iterator _Next = _First;
const_iterator _After = _Next;
for (++_After; _After != _Last; ++_Next, ++_After)
if (_After == _Right.end())
{ // find last element, and check for bad range
_DEBUG_ERROR("forward_list splice_after invalid range");
return;
}
this->_Nextnode(_Next._Mynode()) =
this->_Nextnode(_Where._Mynode()); // link last to new home
this->_Nextnode(_Where._Mynode()) =
this->_Nextnode(_First._Mynode()); // link first to new home
this->_Nextnode(_First._Mynode()) =
_Last._Mynode(); // drop range from old home
}
void _Assign_n(size_type _Count, const _Ty& _Val)
{ // assign _Count * _Val
_Ty _Tmp = _Val; // in case _Val is in sequence
clear();
_Insert_n_after(before_begin(), _Count, _Tmp);
}
void _Tidy()
{ // free all storage
clear();
}
void _Insert_n_after(const_iterator _Where,
size_type _Count, const _Ty& _Val)
{ // insert _Count * _Val after _Where
size_type _Countsave = _Count;
_TRY_BEGIN
for (; 0 < _Count; --_Count)
_Insert_after(_Where, _Val);
_CATCH_ALL
for (; _Count < _Countsave; ++_Count)
erase_after(_Where);
_RERAISE;
_CATCH_END
}
#if _ITERATOR_DEBUG_LEVEL == 2
void _Orphan_ptr(_Myt& _Cont, _Nodeptr _Ptr) const
{ // orphan iterators with specified node pointers
_Lockit _Lock(_LOCK_DEBUG);
const_iterator **_Pnext = (const_iterator **)_Cont._Getpfirst();
if (_Pnext != 0)
while (*_Pnext != 0)
if ((*_Pnext)->_Ptr == (_Nodeptr)&this->_Myhead
|| _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
else
{ // orphan the iterator
(*_Pnext)->_Clrcont();
*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
}
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
};
// forward_list TEMPLATE OPERATORS
template<class _Ty,
class _Alloc> inline
void swap(forward_list<_Ty, _Alloc>& _Left,
forward_list<_Ty, _Alloc>& _Right)
{ // swap _Left and _Right lists
_Left.swap(_Right);
}
template<class _Ty,
class _Alloc> inline
void swap(forward_list<_Ty, _Alloc>& _Left,
forward_list<_Ty, _Alloc>&& _Right)
{ // swap _Left and _Right lists
typedef forward_list<_Ty, _Alloc> _Myt;
_Left.swap(_STD forward<_Myt>(_Right));
}
template<class _Ty,
class _Alloc> inline
void swap(forward_list<_Ty, _Alloc>&& _Left,
forward_list<_Ty, _Alloc>& _Right)
{ // swap _Left and _Right lists
typedef forward_list<_Ty, _Alloc> _Myt;
_Right.swap(_STD forward<_Myt>(_Left));
}
template<class _Ty,
class _Alloc> inline
bool operator==(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test for list equality
typedef typename forward_list<_Ty, _Alloc>::const_iterator _Myit;
_Myit _First1 = _Left.begin();
_Myit _First2 = _Right.begin();
_Myit _Last1 = _Left.end();
_Myit _Last2 = _Right.end();
for (; ; ++_First1, ++_First2)
if (_First1 == _Last1)
return (_First2 == _Last2);
else if (_First2 == _Last2 || *_First1 != *_First2)
return (false);
}
template<class _Ty,
class _Alloc> inline
bool operator!=(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test for list inequality
return (!(_Left == _Right));
}
template<class _Ty,
class _Alloc> inline
bool operator<(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test if _Left < _Right for lists
return (lexicographical_compare(_Left.begin(), _Left.end(),
_Right.begin(), _Right.end()));
}
template<class _Ty,
class _Alloc> inline
bool operator>(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test if _Left > _Right for lists
return (_Right < _Left);
}
template<class _Ty,
class _Alloc> inline
bool operator<=(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test if _Left <= _Right for lists
return (!(_Right < _Left));
}
template<class _Ty,
class _Alloc> inline
bool operator>=(const forward_list<_Ty, _Alloc>& _Left,
const forward_list<_Ty, _Alloc>& _Right)
{ // test if _Left >= _Right for lists
return (!(_Left < _Right));
}
_STD_END
#pragma warning(pop)
#pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _FORWARD_LIST_ */
/*
* Copyright (c) 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.20:0009 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -