|
|
#pragma once
#ifndef _STLLIST_H_
#define _STLLIST_H_
//#include <cstddef>
//#include <functional>
//#include <iterator>
//#include <memory>
//#include <stdexcept>
//#include <xutility>
#include <stlxstdd.h>
#include <stlfunc.h>
#include <stliter.h>
#include <stlmem.h>
#include <stlxutil.h>
#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: typedef _POINTER_X(void, _A) _Genptr; struct _Node; friend struct _Node; struct _Node { _Genptr _Next, _Prev; _Ty _Value; }; typedef _POINTER_X(_Node, _A) _Nodeptr; 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 iterator
class iterator; friend class iterator; class iterator : public _Bidit<_Ty, difference_type> { public: iterator() {
} iterator(_Nodeptr _P) : _Ptr(_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)); } _Nodeptr _Mynode() const { return (_Ptr); } protected: _Nodeptr _Ptr; }; // CLASS const_iterator
class const_iterator; friend class const_iterator; class const_iterator : public iterator { public: const_iterator() {
} const_iterator(_Nodeptr _P) : iterator(_P) {
} const_iterator(const iterator& _X) : iterator(_X) {
} 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) { iterator _Tmp = *this; ++*this; return (_Tmp); } const_iterator& operator--() { _Ptr = _Acc::_Prev(_Ptr); return (*this); } const_iterator operator--(int) { 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)); } }; 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()); } 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) { size_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 /* _STLLIST_H_ */
/*
* 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. */
|