home *** CD-ROM | disk | FTP | other *** search
- // list standard header
-
- #if _MSC_VER > 1000
- #pragma once
- #endif
-
- #ifndef _LIST_
- #define _LIST_
- #include <cstddef>
- #include <functional>
- #include <iterator>
- #include <memory>
- #include <stdexcept>
- #include <xutility>
-
- #ifdef _MSC_VER
- #pragma pack(push,8)
- #endif /* _MSC_VER */
- _STD_BEGIN
- // TEMPLATE CLASS list
- template<class _Ty, class _A = allocator<_Ty> >
- class list {
- protected:
- struct _Node;
- friend struct _Node;
- typedef _POINTER_X(_Node, _A) _Nodeptr;
- struct _Node {
- _Nodeptr _Next, _Prev;
- _Ty _Value;
- };
- struct _Acc;
- friend struct _Acc;
- struct _Acc {
- typedef _REFERENCE_X(_Nodeptr, _A) _Nodepref;
- typedef _A::reference _Vref;
- static _Nodepref _Next(_Nodeptr _P)
- {return ((_Nodepref)(*_P)._Next); }
- static _Nodepref _Prev(_Nodeptr _P)
- {return ((_Nodepref)(*_P)._Prev); }
- static _Vref _Value(_Nodeptr _P)
- {return ((_Vref)(*_P)._Value); }
- };
- public:
- typedef list<_Ty, _A> _Myt;
- typedef _A allocator_type;
- typedef _A::size_type size_type;
- typedef _A::difference_type difference_type;
- typedef _A::pointer _Tptr;
- typedef _A::const_pointer _Ctptr;
- typedef _A::reference reference;
- typedef _A::const_reference const_reference;
- typedef _A::value_type value_type;
- // CLASS const_iterator
- class iterator;
- class const_iterator;
- friend class const_iterator;
- class const_iterator : public _Bidit<_Ty, difference_type> {
- public:
- const_iterator()
- {}
- const_iterator(_Nodeptr _P)
- : _Ptr(_P) {}
- const_iterator(const iterator& _X)
- : _Ptr(_X._Ptr) {}
- const_reference operator*() const
- {return (_Acc::_Value(_Ptr)); }
- _Ctptr operator->() const
- {return (&**this); }
- const_iterator& operator++()
- {_Ptr = _Acc::_Next(_Ptr);
- return (*this); }
- const_iterator operator++(int)
- {const_iterator _Tmp = *this;
- ++*this;
- return (_Tmp); }
- const_iterator& operator--()
- {_Ptr = _Acc::_Prev(_Ptr);
- return (*this); }
- const_iterator operator--(int)
- {const_iterator _Tmp = *this;
- --*this;
- return (_Tmp); }
- bool operator==(const const_iterator& _X) const
- {return (_Ptr == _X._Ptr); }
- bool operator!=(const const_iterator& _X) const
- {return (!(*this == _X)); }
- _Nodeptr _Mynode() const
- {return (_Ptr); }
- protected:
- _Nodeptr _Ptr;
- };
- // CLASS iterator
- friend class iterator;
- class iterator : public const_iterator {
- public:
- iterator()
- {}
- iterator(_Nodeptr _P)
- : const_iterator(_P) {}
- reference operator*() const
- {return (_Acc::_Value(_Ptr)); }
- _Tptr operator->() const
- {return (&**this); }
- iterator& operator++()
- {_Ptr = _Acc::_Next(_Ptr);
- return (*this); }
- iterator operator++(int)
- {iterator _Tmp = *this;
- ++*this;
- return (_Tmp); }
- iterator& operator--()
- {_Ptr = _Acc::_Prev(_Ptr);
- return (*this); }
- iterator operator--(int)
- {iterator _Tmp = *this;
- --*this;
- return (_Tmp); }
- bool operator==(const iterator& _X) const
- {return (_Ptr == _X._Ptr); }
- bool operator!=(const iterator& _X) const
- {return (!(*this == _X)); }
- };
- typedef reverse_bidirectional_iterator<iterator,
- value_type, reference, _Tptr, difference_type>
- reverse_iterator;
- typedef reverse_bidirectional_iterator<const_iterator,
- value_type, const_reference, _Ctptr, difference_type>
- const_reverse_iterator;
- explicit list(const _A& _Al = _A())
- : allocator(_Al),
- _Head(_Buynode()), _Size(0) {}
- explicit list(size_type _N, const _Ty& _V = _Ty(),
- const _A& _Al = _A())
- : allocator(_Al),
- _Head(_Buynode()), _Size(0)
- {insert(begin(), _N, _V); }
- list(const _Myt& _X)
- : allocator(_X.allocator),
- _Head(_Buynode()), _Size(0)
- {insert(begin(), _X.begin(), _X.end()); }
- list(const _Ty *_F, const _Ty *_L, const _A& _Al = _A())
- : allocator(_Al),
- _Head(_Buynode()), _Size(0)
- {insert(begin(), _F, _L); }
- typedef const_iterator _It;
- list(_It _F, _It _L, const _A& _Al = _A())
- : allocator(_Al),
- _Head(_Buynode()), _Size(0)
- {insert(begin(), _F, _L); }
- ~list()
- {erase(begin(), end());
- _Freenode(_Head);
- _Head = 0, _Size = 0; }
- _Myt& operator=(const _Myt& _X)
- {if (this != &_X)
- {iterator _F1 = begin();
- iterator _L1 = end();
- const_iterator _F2 = _X.begin();
- const_iterator _L2 = _X.end();
- for (; _F1 != _L1 && _F2 != _L2; ++_F1, ++_F2)
- *_F1 = *_F2;
- erase(_F1, _L1);
- insert(_L1, _F2, _L2); }
- return (*this); }
- iterator begin()
- {return (iterator(_Acc::_Next(_Head))); }
- const_iterator begin() const
- {return (const_iterator(_Acc::_Next(_Head))); }
- iterator end()
- {return (iterator(_Head)); }
- const_iterator end() const
- {return (const_iterator(_Head)); }
- reverse_iterator rbegin()
- {return (reverse_iterator(end())); }
- const_reverse_iterator rbegin() const
- {return (const_reverse_iterator(end())); }
- reverse_iterator rend()
- {return (reverse_iterator(begin())); }
- const_reverse_iterator rend() const
- {return (const_reverse_iterator(begin())); }
- void resize(size_type _N, _Ty _X = _Ty())
- {if (size() < _N)
- insert(end(), _N - size(), _X);
- else
- while (_N < size())
- pop_back(); }
- size_type size() const
- {return (_Size); }
- size_type max_size() const
- {return (allocator.max_size()); }
- bool empty() const
- {return (size() == 0); }
- _A get_allocator() const
- {return (allocator); }
- reference front()
- {return (*begin()); }
- const_reference front() const
- {return (*begin()); }
- reference back()
- {return (*(--end())); }
- const_reference back() const
- {return (*(--end())); }
- void push_front(const _Ty& _X)
- {insert(begin(), _X); }
- void pop_front()
- {erase(begin()); }
- void push_back(const _Ty& _X)
- {insert(end(), _X); }
- void pop_back()
- {erase(--end()); }
- void assign(_It _F, _It _L)
- {erase(begin(), end());
- insert(begin(), _F, _L); }
- void assign(size_type _N, const _Ty& _X = _Ty())
- {erase(begin(), end());
- insert(begin(), _N, _X); }
- iterator insert(iterator _P, const _Ty& _X = _Ty())
- {_Nodeptr _S = _P._Mynode();
- _Acc::_Prev(_S) = _Buynode(_S, _Acc::_Prev(_S));
- _S = _Acc::_Prev(_S);
- _Acc::_Next(_Acc::_Prev(_S)) = _S;
- allocator.construct(&_Acc::_Value(_S), _X);
- ++_Size;
- return (iterator(_S)); }
- void insert(iterator _P, size_type _M, const _Ty& _X)
- {for (; 0 < _M; --_M)
- insert(_P, _X); }
- void insert(iterator _P, const _Ty *_F, const _Ty *_L)
- {for (; _F != _L; ++_F)
- insert(_P, *_F); }
- void insert(iterator _P, _It _F, _It _L)
- {for (; _F != _L; ++_F)
- insert(_P, *_F); }
- iterator erase(iterator _P)
- {_Nodeptr _S = (_P++)._Mynode();
- _Acc::_Next(_Acc::_Prev(_S)) = _Acc::_Next(_S);
- _Acc::_Prev(_Acc::_Next(_S)) = _Acc::_Prev(_S);
- allocator.destroy(&_Acc::_Value(_S));
- _Freenode(_S);
- --_Size;
- return (_P); }
- iterator erase(iterator _F, iterator _L)
- {while (_F != _L)
- erase(_F++);
- return (_F); }
- void clear()
- {erase(begin(), end()); }
- void swap(_Myt& _X)
- {if (allocator == _X.allocator)
- {std::swap(_Head, _X._Head);
- std::swap(_Size, _X._Size); }
- else
- {iterator _P = begin();
- splice(_P, _X);
- _X.splice(_X.begin(), *this, _P, end()); }}
- friend void swap(_Myt& _X, _Myt& _Y)
- {_X.swap(_Y); }
- void splice(iterator _P, _Myt& _X)
- {if (!_X.empty())
- {_Splice(_P, _X, _X.begin(), _X.end());
- _Size += _X._Size;
- _X._Size = 0; }}
- void splice(iterator _P, _Myt& _X, iterator _F)
- {iterator _L = _F;
- if (_P != _F && _P != ++_L)
- {_Splice(_P, _X, _F, _L);
- ++_Size;
- --_X._Size; }}
- void splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
- {if (_F != _L)
- {if (&_X != this)
- {difference_type _N = 0;
- _Distance(_F, _L, _N);
- _Size += _N;
- _X._Size -= _N; }
- _Splice(_P, _X, _F, _L); }}
- void remove(const _Ty& _V)
- {iterator _L = end();
- for (iterator _F = begin(); _F != _L; )
- if (*_F == _V)
- erase(_F++);
- else
- ++_F; }
- typedef binder2nd<not_equal_to<_Ty> > _Pr1;
- void remove_if(_Pr1 _Pr)
- {iterator _L = end();
- for (iterator _F = begin(); _F != _L; )
- if (_Pr(*_F))
- erase(_F++);
- else
- ++_F; }
- void unique()
- {iterator _F = begin(), _L = end();
- if (_F != _L)
- for (iterator _M = _F; ++_M != _L; _M = _F)
- if (*_F == *_M)
- erase(_M);
- else
- _F = _M; }
- typedef not_equal_to<_Ty> _Pr2;
- void unique(_Pr2 _Pr)
- {iterator _F = begin(), _L = end();
- if (_F != _L)
- for (iterator _M = _F; ++_M != _L; _M = _F)
- if (_Pr(*_F, *_M))
- erase(_M);
- else
- _F = _M; }
- void merge(_Myt& _X)
- {if (&_X != this)
- {iterator _F1 = begin(), _L1 = end();
- iterator _F2 = _X.begin(), _L2 = _X.end();
- while (_F1 != _L1 && _F2 != _L2)
- if (*_F2 < *_F1)
- {iterator _Mid2 = _F2;
- _Splice(_F1, _X, _F2, ++_Mid2);
- _F2 = _Mid2; }
- else
- ++_F1;
- if (_F2 != _L2)
- _Splice(_L1, _X, _F2, _L2);
- _Size += _X._Size;
- _X._Size = 0; }}
- typedef greater<_Ty> _Pr3;
- void merge(_Myt& _X, _Pr3 _Pr)
- {if (&_X != this)
- {iterator _F1 = begin(), _L1 = end();
- iterator _F2 = _X.begin(), _L2 = _X.end();
- while (_F1 != _L1 && _F2 != _L2)
- if (_Pr(*_F2, *_F1))
- {iterator _Mid2 = _F2;
- _Splice(_F1, _X, _F2, ++_Mid2);
- _F2 = _Mid2; }
- else
- ++_F1;
- if (_F2 != _L2)
- _Splice(_L1, _X, _F2, _L2);
- _Size += _X._Size;
- _X._Size = 0; }}
- void sort()
- {if (2 <= size())
- {const size_t _MAXN = 15;
- _Myt _X(allocator), _A[_MAXN + 1];
- size_t _N = 0;
- while (!empty())
- {_X.splice(_X.begin(), *this, begin());
- size_t _I;
- for (_I = 0; _I < _N && !_A[_I].empty(); ++_I)
- {_A[_I].merge(_X);
- _A[_I].swap(_X); }
- if (_I == _MAXN)
- _A[_I].merge(_X);
- else
- {_A[_I].swap(_X);
- if (_I == _N)
- ++_N; }}
- while (0 < _N)
- merge(_A[--_N]); }}
- void sort(_Pr3 _Pr)
- {if (2 <= size())
- {const size_t _MAXN = 15;
- _Myt _X(allocator), _A[_MAXN + 1];
- size_t _N = 0;
- while (!empty())
- {_X.splice(_X.begin(), *this, begin());
- size_t _I;
- for (_I = 0; _I < _N && !_A[_I].empty(); ++_I)
- {_A[_I].merge(_X, _Pr);
- _A[_I].swap(_X); }
- if (_I == _MAXN)
- _A[_I].merge(_X, _Pr);
- else
- {_A[_I].swap(_X);
- if (_I == _N)
- ++_N; }}
- while (0 < _N)
- merge(_A[--_N], _Pr); }}
- void reverse()
- {if (2 <= size())
- {iterator _L = end();
- for (iterator _F = ++begin(); _F != _L; )
- {iterator _M = _F;
- _Splice(begin(), *this, _M, ++_F); }}}
- protected:
- _Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
- {_Nodeptr _S = (_Nodeptr)allocator._Charalloc(
- 1 * sizeof (_Node));
- _Acc::_Next(_S) = _Narg != 0 ? _Narg : _S;
- _Acc::_Prev(_S) = _Parg != 0 ? _Parg : _S;
- return (_S); }
- void _Freenode(_Nodeptr _S)
- {allocator.deallocate(_S, 1); }
- void _Splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
- {if (allocator == _X.allocator)
- {_Acc::_Next(_Acc::_Prev(_L._Mynode())) =
- _P._Mynode();
- _Acc::_Next(_Acc::_Prev(_F._Mynode())) =
- _L._Mynode();
- _Acc::_Next(_Acc::_Prev(_P._Mynode())) =
- _F._Mynode();
- _Nodeptr _S = _Acc::_Prev(_P._Mynode());
- _Acc::_Prev(_P._Mynode()) =
- _Acc::_Prev(_L._Mynode());
- _Acc::_Prev(_L._Mynode()) =
- _Acc::_Prev(_F._Mynode());
- _Acc::_Prev(_F._Mynode()) = _S; }
- else
- {insert(_P, _F, _L);
- _X.erase(_F, _L); }}
- void _Xran() const
- {_THROW(out_of_range, "invalid list<T> subscript"); }
- _A allocator;
- _Nodeptr _Head;
- size_type _Size;
- };
- // list TEMPLATE OPERATORS
- template<class _Ty, class _A> inline
- bool operator==(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (_X.size() == _Y.size()
- && equal(_X.begin(), _X.end(), _Y.begin())); }
- template<class _Ty, class _A> inline
- bool operator!=(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (!(_X == _Y)); }
- template<class _Ty, class _A> inline
- bool operator<(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (lexicographical_compare(_X.begin(), _X.end(),
- _Y.begin(), _Y.end())); }
- template<class _Ty, class _A> inline
- bool operator>(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (_Y < _X); }
- template<class _Ty, class _A> inline
- bool operator<=(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (!(_Y < _X)); }
- template<class _Ty, class _A> inline
- bool operator>=(const list<_Ty, _A>& _X,
- const list<_Ty, _A>& _Y)
- {return (!(_X < _Y)); }
- _STD_END
- #ifdef _MSC_VER
- #pragma pack(pop)
- #endif /* _MSC_VER */
-
- #endif /* _LIST_ */
-
- /*
- * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
- * Consult your license regarding permissions and restrictions.
- */
-
- /*
- * 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.
- */
-