home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Compilers / digital marsC compier / dm / stl / stl_list.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-08  |  25.3 KB  |  886 lines

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