stl_slist.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:28k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute and sell this software
  6.  * and its documentation for any purpose is hereby granted without fee,
  7.  * provided that the above copyright notice appear in all copies and
  8.  * that both that copyright notice and this permission notice appear
  9.  * in supporting documentation.  Silicon Graphics makes no
  10.  * representations about the suitability of this software for any
  11.  * purpose.  It is provided "as is" without express or implied warranty.
  12.  *
  13.  */
  14. /* NOTE: This is an internal header file, included by other STL headers.
  15.  *   You should not attempt to use it directly.
  16.  */
  17. #ifndef __SGI_STL_INTERNAL_SLIST_H
  18. #define __SGI_STL_INTERNAL_SLIST_H
  19. __STL_BEGIN_NAMESPACE 
  20. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  21. #pragma set woff 1174
  22. #pragma set woff 1375
  23. #endif
  24. struct _Slist_node_base
  25. {
  26.   _Slist_node_base* _M_next;
  27. };
  28. inline _Slist_node_base*
  29. __slist_make_link(_Slist_node_base* __prev_node,
  30.                   _Slist_node_base* __new_node)
  31. {
  32.   __new_node->_M_next = __prev_node->_M_next;
  33.   __prev_node->_M_next = __new_node;
  34.   return __new_node;
  35. }
  36. inline _Slist_node_base* 
  37. __slist_previous(_Slist_node_base* __head,
  38.                  const _Slist_node_base* __node)
  39. {
  40.   while (__head && __head->_M_next != __node)
  41.     __head = __head->_M_next;
  42.   return __head;
  43. }
  44. inline const _Slist_node_base* 
  45. __slist_previous(const _Slist_node_base* __head,
  46.                  const _Slist_node_base* __node)
  47. {
  48.   while (__head && __head->_M_next != __node)
  49.     __head = __head->_M_next;
  50.   return __head;
  51. }
  52. inline void __slist_splice_after(_Slist_node_base* __pos,
  53.                                  _Slist_node_base* __before_first,
  54.                                  _Slist_node_base* __before_last)
  55. {
  56.   if (__pos != __before_first && __pos != __before_last) {
  57.     _Slist_node_base* __first = __before_first->_M_next;
  58.     _Slist_node_base* __after = __pos->_M_next;
  59.     __before_first->_M_next = __before_last->_M_next;
  60.     __pos->_M_next = __first;
  61.     __before_last->_M_next = __after;
  62.   }
  63. }
  64. inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node)
  65. {
  66.   _Slist_node_base* __result = __node;
  67.   __node = __node->_M_next;
  68.   __result->_M_next = 0;
  69.   while(__node) {
  70.     _Slist_node_base* __next = __node->_M_next;
  71.     __node->_M_next = __result;
  72.     __result = __node;
  73.     __node = __next;
  74.   }
  75.   return __result;
  76. }
  77. inline size_t __slist_size(_Slist_node_base* __node)
  78. {
  79.   size_t __result = 0;
  80.   for ( ; __node != 0; __node = __node->_M_next)
  81.     ++__result;
  82.   return __result;
  83. }
  84. template <class _T>
  85. struct _Slist_node : public _Slist_node_base
  86. {
  87.   _T _M_data;
  88. };
  89. struct _Slist_iterator_base
  90. {
  91.   typedef size_t               size_type;
  92.   typedef ptrdiff_t            difference_type;
  93.   typedef forward_iterator_tag iterator_category;
  94.   _Slist_node_base* _M_node;
  95.   _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {}
  96.   void _M_incr() { _M_node = _M_node->_M_next; }
  97.   bool operator==(const _Slist_iterator_base& __x) const {
  98.     return _M_node == __x._M_node;
  99.   }
  100.   bool operator!=(const _Slist_iterator_base& __x) const {
  101.     return _M_node != __x._M_node;
  102.   }
  103. };
  104. template <class _T, class _Ref, class _Ptr>
  105. struct _Slist_iterator : public _Slist_iterator_base
  106. {
  107.   typedef _Slist_iterator<_T, _T&, _T*>             iterator;
  108.   typedef _Slist_iterator<_T, const _T&, const _T*> const_iterator;
  109.   typedef _Slist_iterator<_T, _Ref, _Ptr>           _Self;
  110.   typedef _T              value_type;
  111.   typedef _Ptr            pointer;
  112.   typedef _Ref            reference;
  113.   typedef _Slist_node<_T> _Node;
  114.   _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {}
  115.   _Slist_iterator() : _Slist_iterator_base(0) {}
  116.   _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
  117.   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
  118. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  119.   pointer operator->() const { return &(operator*()); }
  120. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  121.   _Self& operator++()
  122.   {
  123.     _M_incr();
  124.     return *this;
  125.   }
  126.   _Self operator++(int)
  127.   {
  128.     _Self __tmp = *this;
  129.     _M_incr();
  130.     return __tmp;
  131.   }
  132. };
  133. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  134. inline ptrdiff_t* distance_type(const _Slist_iterator_base&) {
  135.   return 0;
  136. }
  137. inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) {
  138.   return forward_iterator_tag();
  139. }
  140. template <class _T, class _Ref, class _Ptr> 
  141. inline _T* value_type(const _Slist_iterator<_T, _Ref, _Ptr>&) {
  142.   return 0;
  143. }
  144. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  145. // Base class that encapsulates details of allocators.  Three cases:
  146. // an ordinary standard-conforming allocator, a standard-conforming
  147. // allocator with no non-static data, and an SGI-style allocator.
  148. // This complexity is necessary only because we're worrying about backward
  149. // compatibility and because we want to avoid wasting storage on an 
  150. // allocator instance if it isn't necessary.
  151. #ifdef __STL_USE_STD_ALLOCATORS
  152. // Base for general standard-conforming allocators.
  153. template <class _T, class _Allocator, bool _IsStatic>
  154. class _Slist_alloc_base {
  155. public:
  156.   typedef typename _Alloc_traits<_T,_Allocator>::allocator_type
  157.           allocator_type;
  158.   allocator_type get_allocator() const { return _M_node_allocator; }
  159.   _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {}
  160. protected:
  161.   _Slist_node<_T>* _M_get_node() 
  162.     { return _M_node_allocator.allocate(1); }
  163.   void _M_put_node(_Slist_node<_T>* __p) 
  164.     { _M_node_allocator.deallocate(__p, 1); }
  165. protected:
  166.   typename _Alloc_traits<_Slist_node<_T>,_Allocator>::allocator_type
  167.            _M_node_allocator;
  168.   _Slist_node_base _M_head;
  169. };
  170. // Specialization for instanceless allocators.
  171. template <class _T, class _Allocator>
  172. class _Slist_alloc_base<_T,_Allocator, true> {
  173. public:
  174.   typedef typename _Alloc_traits<_T,_Allocator>::allocator_type
  175.           allocator_type;
  176.   allocator_type get_allocator() const { return allocator_type(); }
  177.   _Slist_alloc_base(const allocator_type&) {}
  178. protected:
  179.   typedef typename _Alloc_traits<_Slist_node<_T>, _Allocator>::_Alloc_type
  180.           _Alloc_type;
  181.   _Slist_node<_T>* _M_get_node() { return _Alloc_type::allocate(1); }
  182.   void _M_put_node(_Slist_node<_T>* __p) { _Alloc_type::deallocate(__p, 1); }
  183. protected:
  184.   _Slist_node_base _M_head;
  185. };
  186. template <class _T, class _Alloc>
  187. struct _Slist_base
  188.   : public _Slist_alloc_base<_T, _Alloc,
  189.                              _Alloc_traits<_T, _Alloc>::_S_instanceless>
  190. {
  191.   typedef _Slist_alloc_base<_T, _Alloc,
  192.                             _Alloc_traits<_T, _Alloc>::_S_instanceless>
  193.           _Base;
  194.   typedef typename _Base::allocator_type allocator_type;
  195.   _Slist_base(const allocator_type& __a) : _Base(__a) { _M_head._M_next = 0; }
  196.   ~_Slist_base() { _M_erase_after(&_M_head, 0); }
  197. protected:
  198.   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
  199.   {
  200.     _Slist_node<_T>* __next = (_Slist_node<_T>*) (__pos->_M_next);
  201.     _Slist_node_base* __next_next = __next->_M_next;
  202.     __pos->_M_next = __next_next;
  203.     destroy(&__next->_M_data);
  204.     _M_put_node(__next);
  205.     return __next_next;
  206.   }
  207.   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
  208. };
  209. #else /* __STL_USE_STD_ALLOCATORS */
  210. template <class _T, class _Alloc> 
  211. struct _Slist_base {
  212.   typedef _Alloc allocator_type;
  213.   allocator_type get_allocator() const { return allocator_type(); }
  214.   _Slist_base(const allocator_type&) { _M_head._M_next = 0; }
  215.   ~_Slist_base() { _M_erase_after(&_M_head, 0); }
  216. protected:
  217.   typedef simple_alloc<_Slist_node<_T>, _Alloc> _Alloc_type;
  218.   _Slist_node<_T>* _M_get_node() { return _Alloc_type::allocate(1); }
  219.   void _M_put_node(_Slist_node<_T>* __p) { _Alloc_type::deallocate(__p, 1); }
  220.   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
  221.   {
  222.     _Slist_node<_T>* __next = (_Slist_node<_T>*) (__pos->_M_next);
  223.     _Slist_node_base* __next_next = __next->_M_next;
  224.     __pos->_M_next = __next_next;
  225.     destroy(&__next->_M_data);
  226.     _M_put_node(__next);
  227.     return __next_next;
  228.   }
  229.   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
  230. protected:
  231.   _Slist_node_base _M_head;
  232. };  
  233. #endif /* __STL_USE_STD_ALLOCATORS */
  234. template <class _T, class _Alloc> 
  235. _Slist_node_base*
  236. _Slist_base<_T,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
  237.                                        _Slist_node_base* __last_node) {
  238.   _Slist_node<_T>* __cur = (_Slist_node<_T>*) (__before_first->_M_next);
  239.   while (__cur != __last_node) {
  240.     _Slist_node<_T>* __tmp = __cur;
  241.     __cur = (_Slist_node<_T>*) __cur->_M_next;
  242.     destroy(&__tmp->_M_data);
  243.     _M_put_node(__tmp);
  244.   }
  245.   __before_first->_M_next = __last_node;
  246.   return __last_node;
  247. }
  248. template <class _T, class _Alloc = __STL_DEFAULT_ALLOCATOR(_T) >
  249. class slist : private _Slist_base<_T,_Alloc>
  250. {
  251. private:
  252.   typedef _Slist_base<_T,_Alloc> _Base;
  253. public:
  254.   typedef _T                value_type;
  255.   typedef value_type*       pointer;
  256.   typedef const value_type* const_pointer;
  257.   typedef value_type&       reference;
  258.   typedef const value_type& const_reference;
  259.   typedef size_t            size_type;
  260.   typedef ptrdiff_t         difference_type;
  261.   typedef _Slist_iterator<_T, _T&, _T*>             iterator;
  262.   typedef _Slist_iterator<_T, const _T&, const _T*> const_iterator;
  263.   typedef typename _Base::allocator_type allocator_type;
  264.   allocator_type get_allocator() const { return _Base::get_allocator(); }
  265. private:
  266.   typedef _Slist_node<_T>      _Node;
  267.   typedef _Slist_node_base     _Node_base;
  268.   typedef _Slist_iterator_base _Iterator_base;
  269.   _Node* _M_create_node(const value_type& __x) {
  270.     _Node* __node = _M_get_node();
  271.     __STL_TRY {
  272.       construct(&__node->_M_data, __x);
  273.       __node->_M_next = 0;
  274.     }
  275.     __STL_UNWIND(_M_put_node(__node));
  276.     return __node;
  277.   }
  278.   
  279.   _Node* _M_create_node() {
  280.     _Node* __node = _M_get_node();
  281.     __STL_TRY {
  282.       construct(&__node->_M_data);
  283.       __node->_M_next = 0;
  284.     }
  285.     __STL_UNWIND(_M_put_node(__node));
  286.     return __node;
  287.   }
  288. private:
  289. #ifdef __STL_USE_NAMESPACES  
  290.   using _Base::_M_get_node;
  291.   using _Base::_M_put_node;
  292.   using _Base::_M_erase_after;
  293.   using _Base::_M_head;
  294. #endif /* __STL_USE_NAMESPACES */
  295. public:
  296.   explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {}
  297.   slist(size_type __n, const value_type& __x,
  298.         const allocator_type& __a =  allocator_type()) : _Base(__a)
  299.     { _M_insert_after_fill(&_M_head, __n, __x); }
  300.   explicit slist(size_type __n) : _Base(allocator_type())
  301.     { _M_insert_after_fill(&_M_head, __n, value_type()); }
  302. #ifdef __STL_MEMBER_TEMPLATES
  303.   // We don't need any dispatching tricks here, because _M_insert_after_range
  304.   // already does them.
  305.   template <class _InputIterator>
  306.   slist(_InputIterator __first, _InputIterator __last,
  307.         const allocator_type& __a =  allocator_type()) : _Base(__a)
  308.     { _M_insert_after_range(&_M_head, __first, __last); }
  309. #else /* __STL_MEMBER_TEMPLATES */
  310.   slist(const_iterator __first, const_iterator __last,
  311.         const allocator_type& __a =  allocator_type()) : _Base(__a)
  312.     { _M_insert_after_range(&_M_head, __first, __last); }
  313.   slist(const value_type* __first, const value_type* __last,
  314.         const allocator_type& __a =  allocator_type()) : _Base(__a)
  315.     { _M_insert_after_range(&_M_head, __first, __last); }
  316. #endif /* __STL_MEMBER_TEMPLATES */
  317.   slist(const slist& __x) : _Base(__x.get_allocator())
  318.     { _M_insert_after_range(&_M_head, __x.begin(), __x.end()); }
  319.   slist& operator= (const slist& __x);
  320.   ~slist() {}
  321. public:
  322.   // assign(), a generalized assignment member function.  Two
  323.   // versions: one that takes a count, and one that takes a range.
  324.   // The range version is a member template, so we dispatch on whether
  325.   // or not the type is an integer.
  326.   void assign(size_type __n, const _T& __val);
  327. #ifdef __STL_MEMBER_TEMPLATES
  328.   template <class _InputIterator>
  329.   void assign(_InputIterator __first, _InputIterator __last) {
  330.     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
  331.     _M_assign_dispatch(__first, __last, _Integral());
  332.   }
  333.   template <class _Integer>
  334.   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
  335.     { assign((size_type) __n, (_T) __val); }
  336.   template <class _InputIterator>
  337.   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
  338.                           __false_type);
  339. #endif /* __STL_MEMBER_TEMPLATES */
  340. public:
  341.   iterator begin() { return iterator((_Node*)_M_head._M_next); }
  342.   const_iterator begin() const 
  343.     { return const_iterator((_Node*)_M_head._M_next);}
  344.   iterator end() { return iterator(0); }
  345.   const_iterator end() const { return const_iterator(0); }
  346.   size_type size() const { return __slist_size(_M_head._M_next); }
  347.   
  348.   size_type max_size() const { return size_type(-1); }
  349.   bool empty() const { return _M_head._M_next == 0; }
  350.   void swap(slist& __x) { __STD::swap(_M_head._M_next, __x._M_head._M_next); }
  351. public:
  352.   friend bool operator== __STL_NULL_TMPL_ARGS (const slist<_T,_Alloc>& _SL1,
  353.                                                const slist<_T,_Alloc>& _SL2);
  354. public:
  355.   reference front() { return ((_Node*) _M_head._M_next)->_M_data; }
  356.   const_reference front() const 
  357.     { return ((_Node*) _M_head._M_next)->_M_data; }
  358.   void push_front(const value_type& __x)   {
  359.     __slist_make_link(&_M_head, _M_create_node(__x));
  360.   }
  361.   void push_front() { __slist_make_link(&_M_head, _M_create_node());}
  362.   void pop_front() {
  363.     _Node* __node = (_Node*) _M_head._M_next;
  364.     _M_head._M_next = __node->_M_next;
  365.     destroy(&__node->_M_data);
  366.     _M_put_node(__node);
  367.   }
  368.   iterator previous(const_iterator __pos) {
  369.     return iterator((_Node*) __slist_previous(&_M_head, __pos._M_node));
  370.   }
  371.   const_iterator previous(const_iterator __pos) const {
  372.     return const_iterator((_Node*) __slist_previous(&_M_head, __pos._M_node));
  373.   }
  374. private:
  375.   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
  376.     return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
  377.   }
  378.   _Node* _M_insert_after(_Node_base* __pos) {
  379.     return (_Node*) (__slist_make_link(__pos, _M_create_node()));
  380.   }
  381.   void _M_insert_after_fill(_Node_base* __pos,
  382.                             size_type __n, const value_type& __x) {
  383.     for (size_type __i = 0; __i < __n; ++__i)
  384.       __pos = __slist_make_link(__pos, _M_create_node(__x));
  385.   }
  386. #ifdef __STL_MEMBER_TEMPLATES
  387.   // Check whether it's an integral type.  If so, it's not an iterator.
  388.   template <class _InIter>
  389.   void _M_insert_after_range(_Node_base* __pos, 
  390.                              _InIter __first, _InIter __last) {
  391.     typedef typename _Is_integer<_InIter>::_Integral _Integral;
  392.     _M_insert_after_range(__pos, __first, __last, _Integral());
  393.   }
  394.   template <class _Integer>
  395.   void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
  396.                              __true_type) {
  397.     _M_insert_after_fill(__pos, __n, __x);
  398.   }
  399.   template <class _InIter>
  400.   void _M_insert_after_range(_Node_base* __pos,
  401.                              _InIter __first, _InIter __last,
  402.                              __false_type) {
  403.     while (__first != __last) {
  404.       __pos = __slist_make_link(__pos, _M_create_node(*__first));
  405.       ++__first;
  406.     }
  407.   }
  408. #else /* __STL_MEMBER_TEMPLATES */
  409.   void _M_insert_after_range(_Node_base* __pos,
  410.                              const_iterator __first, const_iterator __last) {
  411.     while (__first != __last) {
  412.       __pos = __slist_make_link(__pos, _M_create_node(*__first));
  413.       ++__first;
  414.     }
  415.   }
  416.   void _M_insert_after_range(_Node_base* __pos,
  417.                              const value_type* __first,
  418.                              const value_type* __last) {
  419.     while (__first != __last) {
  420.       __pos = __slist_make_link(__pos, _M_create_node(*__first));
  421.       ++__first;
  422.     }
  423.   }
  424. #endif /* __STL_MEMBER_TEMPLATES */
  425. public:
  426.   iterator insert_after(iterator __pos, const value_type& __x) {
  427.     return iterator(_M_insert_after(__pos._M_node, __x));
  428.   }
  429.   iterator insert_after(iterator __pos) {
  430.     return insert_after(__pos, value_type());
  431.   }
  432.   void insert_after(iterator __pos, size_type __n, const value_type& __x) {
  433.     _M_insert_after_fill(__pos._M_node, __n, __x);
  434.   }
  435. #ifdef __STL_MEMBER_TEMPLATES
  436.   // We don't need any dispatching tricks here, because _M_insert_after_range
  437.   // already does them.
  438.   template <class _InIter>
  439.   void insert_after(iterator __pos, _InIter __first, _InIter __last) {
  440.     _M_insert_after_range(__pos._M_node, __first, __last);
  441.   }
  442. #else /* __STL_MEMBER_TEMPLATES */
  443.   void insert_after(iterator __pos,
  444.                     const_iterator __first, const_iterator __last) {
  445.     _M_insert_after_range(__pos._M_node, __first, __last);
  446.   }
  447.   void insert_after(iterator __pos,
  448.                     const value_type* __first, const value_type* __last) {
  449.     _M_insert_after_range(__pos._M_node, __first, __last);
  450.   }
  451. #endif /* __STL_MEMBER_TEMPLATES */
  452.   iterator insert(iterator __pos, const value_type& __x) {
  453.     return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node),
  454.                     __x));
  455.   }
  456.   iterator insert(iterator __pos) {
  457.     return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node),
  458.                                     value_type()));
  459.   }
  460.   void insert(iterator __pos, size_type __n, const value_type& __x) {
  461.     _M_insert_after_fill(__slist_previous(&_M_head, __pos._M_node), __n, __x);
  462.   } 
  463.     
  464. #ifdef __STL_MEMBER_TEMPLATES
  465.   // We don't need any dispatching tricks here, because _M_insert_after_range
  466.   // already does them.
  467.   template <class _InIter>
  468.   void insert(iterator __pos, _InIter __first, _InIter __last) {
  469.     _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), 
  470.                           __first, __last);
  471.   }
  472. #else /* __STL_MEMBER_TEMPLATES */
  473.   void insert(iterator __pos, const_iterator __first, const_iterator __last) {
  474.     _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), 
  475.                           __first, __last);
  476.   }
  477.   void insert(iterator __pos, const value_type* __first, 
  478.                               const value_type* __last) {
  479.     _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), 
  480.                           __first, __last);
  481.   }
  482. #endif /* __STL_MEMBER_TEMPLATES */
  483. public:
  484.   iterator erase_after(iterator __pos) {
  485.     return iterator((_Node*) _M_erase_after(__pos._M_node));
  486.   }
  487.   iterator erase_after(iterator __before_first, iterator __last) {
  488.     return iterator((_Node*) _M_erase_after(__before_first._M_node, 
  489.                                             __last._M_node));
  490.   } 
  491.   iterator erase(iterator __pos) {
  492.     return (_Node*) _M_erase_after(__slist_previous(&_M_head, 
  493.                                                     __pos._M_node));
  494.   }
  495.   iterator erase(iterator __first, iterator __last) {
  496.     return (_Node*) _M_erase_after(
  497.       __slist_previous(&_M_head, __first._M_node), __last._M_node);
  498.   }
  499.   void resize(size_type new_size, const _T& __x);
  500.   void resize(size_type new_size) { resize(new_size, _T()); }
  501.   void clear() { _M_erase_after(&_M_head, 0); }
  502. public:
  503.   // Moves the range [__before_first + 1, __before_last + 1) to *this,
  504.   //  inserting it immediately after __pos.  This is constant time.
  505.   void splice_after(iterator __pos, 
  506.                     iterator __before_first, iterator __before_last)
  507.   {
  508.     if (__before_first != __before_last) 
  509.       __slist_splice_after(__pos._M_node, __before_first._M_node, 
  510.                            __before_last._M_node);
  511.   }
  512.   // Moves the element that follows __prev to *this, inserting it immediately
  513.   //  after __pos.  This is constant time.
  514.   void splice_after(iterator __pos, iterator __prev)
  515.   {
  516.     __slist_splice_after(__pos._M_node, __prev._M_node, __prev._M_node->_M_next);
  517.   }
  518.   // Linear in distance(begin(), __pos), and linear in __x.size().
  519.   void splice(iterator __pos, slist& __x) {
  520.     if (__x._M_head._M_next)
  521.       __slist_splice_after(__slist_previous(&_M_head, __pos._M_node),
  522.                            &__x._M_head, __slist_previous(&__x._M_head, 0));
  523.   }
  524.   // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
  525.   void splice(iterator __pos, slist& __x, iterator __i) {
  526.     __slist_splice_after(__slist_previous(&_M_head, __pos._M_node),
  527.                          __slist_previous(&__x._M_head, __i._M_node),
  528.                          __i._M_node);
  529.   }
  530.   // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
  531.   // and in distance(__first, __last).
  532.   void splice(iterator __pos, slist& __x, iterator __first, iterator __last)
  533.   {
  534.     if (__first != __last)
  535.       __slist_splice_after(__slist_previous(&_M_head, __pos._M_node),
  536.                            __slist_previous(&__x._M_head, __first._M_node),
  537.                            __slist_previous(__first._M_node, __last._M_node));
  538.   }
  539. public:
  540.   void reverse() { 
  541.     if (_M_head._M_next)
  542.       _M_head._M_next = __slist_reverse(_M_head._M_next);
  543.   }
  544.   void remove(const _T& __val); 
  545.   void unique(); 
  546.   void merge(slist& __x);
  547.   void sort();     
  548. #ifdef __STL_MEMBER_TEMPLATES
  549.   template <class _Predicate> 
  550.   void remove_if(_Predicate __pred);
  551.   template <class _BinaryPredicate> 
  552.   void unique(_BinaryPredicate __pred); 
  553.   template <class _StrictWeakOrdering> 
  554.   void merge(slist&, _StrictWeakOrdering);
  555.   template <class _StrictWeakOrdering> 
  556.   void sort(_StrictWeakOrdering __comp); 
  557. #endif /* __STL_MEMBER_TEMPLATES */
  558. };
  559. template <class _T, class _Alloc>
  560. slist<_T,_Alloc>& slist<_T,_Alloc>::operator=(const slist<_T,_Alloc>& __x)
  561. {
  562.   if (&__x != this) {
  563.     _Node_base* __p1 = &_M_head;
  564.     _Node* __n1 = (_Node*) _M_head._M_next;
  565.     const _Node* __n2 = (const _Node*) __x._M_head._M_next;
  566.     while (__n1 && __n2) {
  567.       __n1->_M_data = __n2->_M_data;
  568.       __p1 = __n1;
  569.       __n1 = (_Node*) __n1->_M_next;
  570.       __n2 = (const _Node*) __n2->_M_next;
  571.     }
  572.     if (__n2 == 0)
  573.       _M_erase_after(__p1, 0);
  574.     else
  575.       _M_insert_after_range(__p1, const_iterator((_Node*)__n2), 
  576.                                   const_iterator(0));
  577.   }
  578.   return *this;
  579. }
  580. template <class _T, class _Alloc>
  581. void slist<_T, _Alloc>::assign(size_type __n, const _T& __val) {
  582.   _Node_base* __prev = &_M_head;
  583.   _Node* __node = (_Node*) _M_head._M_next;
  584.   for ( ; __node != 0 && __n > 0 ; --__n) {
  585.     __node->_M_data = __val;
  586.     __prev = __node;
  587.     __node = (_Node*) __node->_M_next;
  588.   }
  589.   if (__n > 0)
  590.     _M_insert_after_fill(__prev, __n, __val);
  591.   else
  592.     _M_erase_after(__prev, 0);
  593. }
  594. #ifdef __STL_MEMBER_TEMPLATES
  595. template <class _T, class _Alloc> template <class _InputIter>
  596. void
  597. slist<_T, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last,
  598.                                       __false_type)
  599. {
  600.   _Node_base* __prev = &_M_head;
  601.   _Node* __node = (_Node*) _M_head._M_next;
  602.   while (__node != 0 && __first != __last) {
  603.     __node->_M_data = *__first;
  604.     __prev = __node;
  605.     __node = (_Node*) __node->_M_next;
  606.     ++__first;
  607.   }
  608.   if (__first != __last)
  609.     _M_insert_after_range(__prev, __first, __last);
  610.   else
  611.     _M_erase_after(__prev, 0);
  612. }
  613. #endif /* __STL_MEMBER_TEMPLATES */
  614. template <class _T, class _Alloc>
  615. bool operator==(const slist<_T,_Alloc>& _SL1, const slist<_T,_Alloc>& _SL2)
  616. {
  617.   typedef typename slist<_T,_Alloc>::_Node _Node;
  618.   _Node* __n1 = (_Node*) _SL1._M_head._M_next;
  619.   _Node* __n2 = (_Node*) _SL2._M_head._M_next;
  620.   while (__n1 && __n2 && __n1->_M_data == __n2->_M_data) {
  621.     __n1 = (_Node*) __n1->_M_next;
  622.     __n2 = (_Node*) __n2->_M_next;
  623.   }
  624.   return __n1 == 0 && __n2 == 0;
  625. }
  626. template <class _T, class _Alloc>
  627. inline bool operator<(const slist<_T,_Alloc>& _SL1,
  628.                       const slist<_T,_Alloc>& _SL2)
  629. {
  630.   return lexicographical_compare(_SL1.begin(), _SL1.end(), 
  631.                                  _SL2.begin(), _SL2.end());
  632. }
  633. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  634. template <class _T, class _Alloc>
  635. inline void swap(slist<_T,_Alloc>& __x, slist<_T,_Alloc>& __y) {
  636.   __x.swap(__y);
  637. }
  638. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  639. template <class _T, class _Alloc>
  640. void slist<_T,_Alloc>::resize(size_type __len, const _T& __x)
  641. {
  642.   _Node_base* __cur = &_M_head;
  643.   while (__cur->_M_next != 0 && __len > 0) {
  644.     --__len;
  645.     __cur = __cur->_M_next;
  646.   }
  647.   if (__cur->_M_next) 
  648.     _M_erase_after(__cur, 0);
  649.   else
  650.     _M_insert_after_fill(__cur, __len, __x);
  651. }
  652. template <class _T, class _Alloc>
  653. void slist<_T,_Alloc>::remove(const _T& __val)
  654. {
  655.   _Node_base* __cur = &_M_head;
  656.   while (__cur && __cur->_M_next) {
  657.     if (((_Node*) __cur->_M_next)->_M_data == __val)
  658.       _M_erase_after(__cur);
  659.     else
  660.       __cur = __cur->_M_next;
  661.   }
  662. }
  663. template <class _T, class _Alloc> 
  664. void slist<_T,_Alloc>::unique()
  665. {
  666.   _Node_base* __cur = _M_head._M_next;
  667.   if (__cur) {
  668.     while (__cur->_M_next) {
  669.       if (((_Node*)__cur)->_M_data == 
  670.           ((_Node*)(__cur->_M_next))->_M_data)
  671.         _M_erase_after(__cur);
  672.       else
  673.         __cur = __cur->_M_next;
  674.     }
  675.   }
  676. }
  677. template <class _T, class _Alloc>
  678. void slist<_T,_Alloc>::merge(slist<_T,_Alloc>& __x)
  679. {
  680.   _Node_base* __n1 = &_M_head;
  681.   while (__n1->_M_next && __x._M_head._M_next) {
  682.     if (((_Node*) __x._M_head._M_next)->_M_data < 
  683.         ((_Node*)       __n1->_M_next)->_M_data) 
  684.       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
  685.     __n1 = __n1->_M_next;
  686.   }
  687.   if (__x._M_head._M_next) {
  688.     __n1->_M_next = __x._M_head._M_next;
  689.     __x._M_head._M_next = 0;
  690.   }
  691. }
  692. template <class _T, class _Alloc>
  693. void slist<_T,_Alloc>::sort()
  694. {
  695.   if (_M_head._M_next && _M_head._M_next->_M_next) {
  696.     slist __carry;
  697.     slist __counter[64];
  698.     int __fill = 0;
  699.     while (!empty()) {
  700.       __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next);
  701.       int __i = 0;
  702.       while (__i < __fill && !__counter[__i].empty()) {
  703.         __counter[__i].merge(__carry);
  704.         __carry.swap(__counter[__i]);
  705.         ++__i;
  706.       }
  707.       __carry.swap(__counter[__i]);
  708.       if (__i == __fill)
  709.         ++__fill;
  710.     }
  711.     for (int __i = 1; __i < __fill; ++__i)
  712.       __counter[__i].merge(__counter[__i-1]);
  713.     this->swap(__counter[__fill-1]);
  714.   }
  715. }
  716. #ifdef __STL_MEMBER_TEMPLATES
  717. template <class _T, class _Alloc> 
  718. template <class _Predicate>
  719. void slist<_T,_Alloc>::remove_if(_Predicate __pred)
  720. {
  721.   _Node_base* __cur = &_M_head;
  722.   while (__cur->_M_next) {
  723.     if (__pred(((_Node*) __cur->_M_next)->_M_data))
  724.       _M_erase_after(__cur);
  725.     else
  726.       __cur = __cur->_M_next;
  727.   }
  728. }
  729. template <class _T, class _Alloc> template <class _BinaryPredicate> 
  730. void slist<_T,_Alloc>::unique(_BinaryPredicate __pred)
  731. {
  732.   _Node* __cur = (_Node*) _M_head._M_next;
  733.   if (__cur) {
  734.     while (__cur->_M_next) {
  735.       if (__pred(((_Node*)__cur)->_M_data, 
  736.                  ((_Node*)(__cur->_M_next))->_M_data))
  737.         _M_erase_after(__cur);
  738.       else
  739.         __cur = (_Node*) __cur->_M_next;
  740.     }
  741.   }
  742. }
  743. template <class _T, class _Alloc> template <class _StrictWeakOrdering>
  744. void slist<_T,_Alloc>::merge(slist<_T,_Alloc>& __x,
  745.                              _StrictWeakOrdering __comp)
  746. {
  747.   _Node_base* __n1 = &_M_head;
  748.   while (__n1->_M_next && __x._M_head._M_next) {
  749.     if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
  750.                ((_Node*)       __n1->_M_next)->_M_data))
  751.       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
  752.     __n1 = __n1->_M_next;
  753.   }
  754.   if (__x._M_head._M_next) {
  755.     __n1->_M_next = __x._M_head._M_next;
  756.     __x._M_head._M_next = 0;
  757.   }
  758. }
  759. template <class _T, class _Alloc> template <class _StrictWeakOrdering> 
  760. void slist<_T,_Alloc>::sort(_StrictWeakOrdering __comp)
  761. {
  762.   if (_M_head._M_next && _M_head._M_next->_M_next) {
  763.     slist __carry;
  764.     slist __counter[64];
  765.     int __fill = 0;
  766.     while (!empty()) {
  767.       __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next);
  768.       int __i = 0;
  769.       while (__i < __fill && !__counter[__i].empty()) {
  770.         __counter[__i].merge(__carry, __comp);
  771.         __carry.swap(__counter[__i]);
  772.         ++__i;
  773.       }
  774.       __carry.swap(__counter[__i]);
  775.       if (__i == __fill)
  776.         ++__fill;
  777.     }
  778.     for (int __i = 1; __i < __fill; ++__i)
  779.       __counter[__i].merge(__counter[__i-1], __comp);
  780.     this->swap(__counter[__fill-1]);
  781.   }
  782. }
  783. #endif /* __STL_MEMBER_TEMPLATES */
  784. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  785. #pragma reset woff 1174
  786. #pragma reset woff 1375
  787. #endif
  788. __STL_END_NAMESPACE 
  789. #endif /* __SGI_STL_INTERNAL_SLIST_H */
  790. // Local Variables:
  791. // mode:C++
  792. // End: