Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 <bits/concept_check.h>
  35.  
  36. namespace std
  37. {
  38.  
  39. struct _List_node_base {
  40.   _List_node_base* _M_next;
  41.   _List_node_base* _M_prev;
  42. };
  43.  
  44. template <class _Tp>
  45. struct _List_node : public _List_node_base {
  46.   _Tp _M_data;
  47. };
  48.  
  49. struct _List_iterator_base {
  50.   typedef size_t                     size_type;
  51.   typedef ptrdiff_t                  difference_type;
  52.   typedef bidirectional_iterator_tag iterator_category;
  53.  
  54.   _List_node_base* _M_node;
  55.  
  56.   _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
  57.   _List_iterator_base() {}
  58.  
  59.   void _M_incr() { _M_node = _M_node->_M_next; }
  60.   void _M_decr() { _M_node = _M_node->_M_prev; }
  61.  
  62.   bool operator==(const _List_iterator_base& __x) const {
  63.     return _M_node == __x._M_node;
  64.   }
  65.   bool operator!=(const _List_iterator_base& __x) const {
  66.     return _M_node != __x._M_node;
  67.   }
  68. };  
  69.  
  70. template<class _Tp, class _Ref, class _Ptr>
  71. struct _List_iterator : public _List_iterator_base {
  72.   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
  73.   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  74.   typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;
  75.  
  76.   typedef _Tp value_type;
  77.   typedef _Ptr pointer;
  78.   typedef _Ref reference;
  79.   typedef _List_node<_Tp> _Node;
  80.  
  81.   _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
  82.   _List_iterator() {}
  83.   _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}
  84.  
  85.   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
  86.   pointer operator->() const { return &(operator*()); }
  87.  
  88.   _Self& operator++() {
  89.     this->_M_incr();
  90.     return *this;
  91.   }
  92.   _Self operator++(int) {
  93.     _Self __tmp = *this;
  94.     this->_M_incr();
  95.     return __tmp;
  96.   }
  97.   _Self& operator--() {
  98.     this->_M_decr();
  99.     return *this;
  100.   }
  101.   _Self operator--(int) {
  102.     _Self __tmp = *this;
  103.     this->_M_decr();
  104.     return __tmp;
  105.   }
  106. };
  107.  
  108.  
  109. // Base class that encapsulates details of allocators.  Three cases:
  110. // an ordinary standard-conforming allocator, a standard-conforming
  111. // allocator with no non-static data, and an SGI-style allocator.
  112. // This complexity is necessary only because we're worrying about backward
  113. // compatibility and because we want to avoid wasting storage on an
  114. // allocator instance if it isn't necessary.
  115.  
  116.  
  117. // Base for general standard-conforming allocators.
  118. template <class _Tp, class _Allocator, bool _IsStatic>
  119. class _List_alloc_base {
  120. public:
  121.   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
  122.           allocator_type;
  123.   allocator_type get_allocator() const { return _Node_allocator; }
  124.  
  125.   _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {}
  126.  
  127. protected:
  128.   _List_node<_Tp>* _M_get_node()
  129.    { return _Node_allocator.allocate(1); }
  130.   void _M_put_node(_List_node<_Tp>* __p)
  131.     { _Node_allocator.deallocate(__p, 1); }
  132.  
  133. protected:
  134.   typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
  135.            _Node_allocator;
  136.   _List_node<_Tp>* _M_node;
  137. };
  138.  
  139. // Specialization for instanceless allocators.
  140.  
  141. template <class _Tp, class _Allocator>
  142. class _List_alloc_base<_Tp, _Allocator, true> {
  143. public:
  144.   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
  145.           allocator_type;
  146.   allocator_type get_allocator() const { return allocator_type(); }
  147.  
  148.   _List_alloc_base(const allocator_type&) {}
  149.  
  150. protected:
  151.   typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
  152.           _Alloc_type;
  153.   _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
  154.   void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
  155.  
  156. protected:
  157.   _List_node<_Tp>* _M_node;
  158. };
  159.  
  160. template <class _Tp, class _Alloc>
  161. class _List_base
  162.   : public _List_alloc_base<_Tp, _Alloc,
  163.                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
  164. {
  165. public:
  166.   typedef _List_alloc_base<_Tp, _Alloc,
  167.                            _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
  168.           _Base;
  169.   typedef typename _Base::allocator_type allocator_type;
  170.  
  171.   _List_base(const allocator_type& __a) : _Base(__a) {
  172.     _M_node = _M_get_node();
  173.     _M_node->_M_next = _M_node;
  174.     _M_node->_M_prev = _M_node;
  175.   }
  176.   ~_List_base() {
  177.     clear();
  178.     _M_put_node(_M_node);
  179.   }
  180.  
  181.   void clear();
  182. };
  183.  
  184.  
  185. template <class _Tp, class _Alloc>
  186. void
  187. _List_base<_Tp,_Alloc>::clear()
  188. {
  189.   _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next;
  190.   while (__cur != _M_node) {
  191.     _List_node<_Tp>* __tmp = __cur;
  192.     __cur = (_List_node<_Tp>*) __cur->_M_next;
  193.     _Destroy(&__tmp->_M_data);
  194.     _M_put_node(__tmp);
  195.   }
  196.   _M_node->_M_next = _M_node;
  197.   _M_node->_M_prev = _M_node;
  198. }
  199.  
  200. template <class _Tp, class _Alloc = allocator<_Tp> >
  201. class list : protected _List_base<_Tp, _Alloc>
  202. {
  203.   // concept requirements
  204.   __glibcpp_class_requires(_Tp, _SGIAssignableConcept);
  205.  
  206.   typedef _List_base<_Tp, _Alloc> _Base;
  207. protected:
  208.   typedef void* _Void_pointer;
  209.  
  210. public:      
  211.   typedef _Tp value_type;
  212.   typedef value_type* pointer;
  213.   typedef const value_type* const_pointer;
  214.   typedef value_type& reference;
  215.   typedef const value_type& const_reference;
  216.   typedef _List_node<_Tp> _Node;
  217.   typedef size_t size_type;
  218.   typedef ptrdiff_t difference_type;
  219.  
  220.   typedef typename _Base::allocator_type allocator_type;
  221.   allocator_type get_allocator() const { return _Base::get_allocator(); }
  222.  
  223. public:
  224.   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
  225.   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  226.  
  227.   typedef reverse_iterator<const_iterator> const_reverse_iterator;
  228.   typedef reverse_iterator<iterator>       reverse_iterator;
  229.  
  230. protected:
  231.   using _Base::_M_node;
  232.   using _Base::_M_put_node;
  233.   using _Base::_M_get_node;
  234.  
  235. protected:
  236.   _Node* _M_create_node(const _Tp& __x)
  237.   {
  238.     _Node* __p = _M_get_node();
  239.     __STL_TRY {
  240.       _Construct(&__p->_M_data, __x);
  241.     }
  242.     __STL_UNWIND(_M_put_node(__p));
  243.     return __p;
  244.   }
  245.  
  246.   _Node* _M_create_node()
  247.   {
  248.     _Node* __p = _M_get_node();
  249.     __STL_TRY {
  250.       _Construct(&__p->_M_data);
  251.     }
  252.     __STL_UNWIND(_M_put_node(__p));
  253.     return __p;
  254.   }
  255.  
  256. public:
  257.   explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {}
  258.  
  259.   iterator begin()             { return (_Node*)(_M_node->_M_next); }
  260.   const_iterator begin() const { return (_Node*)(_M_node->_M_next); }
  261.  
  262.   iterator end()             { return _M_node; }
  263.   const_iterator end() const { return _M_node; }
  264.  
  265.   reverse_iterator rbegin()
  266.     { return reverse_iterator(end()); }
  267.   const_reverse_iterator rbegin() const
  268.     { return const_reverse_iterator(end()); }
  269.  
  270.   reverse_iterator rend()
  271.     { return reverse_iterator(begin()); }
  272.   const_reverse_iterator rend() const
  273.     { return const_reverse_iterator(begin()); }
  274.  
  275.   bool empty() const { return _M_node->_M_next == _M_node; }
  276.   size_type size() const {
  277.     size_type __result = 0;
  278.     distance(begin(), end(), __result);
  279.     return __result;
  280.   }
  281.   size_type max_size() const { return size_type(-1); }
  282.  
  283.   reference front() { return *begin(); }
  284.   const_reference front() const { return *begin(); }
  285.   reference back() { return *(--end()); }
  286.   const_reference back() const { return *(--end()); }
  287.  
  288.   void swap(list<_Tp, _Alloc>& __x) { std::swap(_M_node, __x._M_node); }
  289.  
  290.   iterator insert(iterator __position, const _Tp& __x) {
  291.     _Node* __tmp = _M_create_node(__x);
  292.     __tmp->_M_next = __position._M_node;
  293.     __tmp->_M_prev = __position._M_node->_M_prev;
  294.     __position._M_node->_M_prev->_M_next = __tmp;
  295.     __position._M_node->_M_prev = __tmp;
  296.     return __tmp;
  297.   }
  298.   iterator insert(iterator __position) { return insert(__position, _Tp()); }
  299.  
  300.   // Check whether it's an integral type.  If so, it's not an iterator.
  301.   template<class _Integer>
  302.   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
  303.                           __true_type) {
  304.     _M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
  305.   }
  306.  
  307.   template <class _InputIterator>
  308.   void _M_insert_dispatch(iterator __pos,
  309.                           _InputIterator __first, _InputIterator __last,
  310.                           __false_type);
  311.  
  312.   template <class _InputIterator>
  313.   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
  314.     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
  315.     _M_insert_dispatch(__pos, __first, __last, _Integral());
  316.   }
  317.  
  318.   void insert(iterator __pos, size_type __n, const _Tp& __x)
  319.     { _M_fill_insert(__pos, __n, __x); }
  320.   void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
  321.  
  322.   void push_front(const _Tp& __x) { insert(begin(), __x); }
  323.   void push_front() {insert(begin());}
  324.   void push_back(const _Tp& __x) { insert(end(), __x); }
  325.   void push_back() {insert(end());}
  326.  
  327.   iterator erase(iterator __position) {
  328.     _List_node_base* __next_node = __position._M_node->_M_next;
  329.     _List_node_base* __prev_node = __position._M_node->_M_prev;
  330.     _Node* __n = (_Node*) __position._M_node;
  331.     __prev_node->_M_next = __next_node;
  332.     __next_node->_M_prev = __prev_node;
  333.     _Destroy(&__n->_M_data);
  334.     _M_put_node(__n);
  335.     return iterator((_Node*) __next_node);
  336.   }
  337.   iterator erase(iterator __first, iterator __last);
  338.   void clear() { _Base::clear(); }
  339.  
  340.   void resize(size_type __new_size, const _Tp& __x);
  341.   void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
  342.  
  343.   void pop_front() { erase(begin()); }
  344.   void pop_back() {
  345.     iterator __tmp = end();
  346.     erase(--__tmp);
  347.   }
  348.   list(size_type __n, const _Tp& __value,
  349.        const allocator_type& __a = allocator_type())
  350.     : _Base(__a)
  351.     { insert(begin(), __n, __value); }
  352.   explicit list(size_type __n)
  353.     : _Base(allocator_type())
  354.     { insert(begin(), __n, _Tp()); }
  355.  
  356.   // We don't need any dispatching tricks here, because insert does all of
  357.   // that anyway.  
  358.   template <class _InputIterator>
  359.   list(_InputIterator __first, _InputIterator __last,
  360.        const allocator_type& __a = allocator_type())
  361.     : _Base(__a)
  362.     { insert(begin(), __first, __last); }
  363.  
  364.   list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator())
  365.     { insert(begin(), __x.begin(), __x.end()); }
  366.  
  367.   ~list() { }
  368.  
  369.   list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x);
  370.  
  371. public:
  372.   // assign(), a generalized assignment member function.  Two
  373.   // versions: one that takes a count, and one that takes a range.
  374.   // The range version is a member template, so we dispatch on whether
  375.   // or not the type is an integer.
  376.  
  377.   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
  378.  
  379.   void _M_fill_assign(size_type __n, const _Tp& __val);
  380.  
  381.   template <class _InputIterator>
  382.   void assign(_InputIterator __first, _InputIterator __last) {
  383.     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
  384.     _M_assign_dispatch(__first, __last, _Integral());
  385.   }
  386.  
  387.   template <class _Integer>
  388.   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
  389.     { _M_fill_assign((size_type) __n, (_Tp) __val); }
  390.  
  391.   template <class _InputIterator>
  392.   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
  393.                           __false_type);
  394.  
  395. protected:
  396.   void transfer(iterator __position, iterator __first, iterator __last) {
  397.     if (__position != __last) {
  398.       // Remove [first, last) from its old position.
  399.       __last._M_node->_M_prev->_M_next     = __position._M_node;
  400.       __first._M_node->_M_prev->_M_next    = __last._M_node;
  401.       __position._M_node->_M_prev->_M_next = __first._M_node;
  402.  
  403.       // Splice [first, last) into its new position.
  404.       _List_node_base* __tmp      = __position._M_node->_M_prev;
  405.       __position._M_node->_M_prev = __last._M_node->_M_prev;
  406.       __last._M_node->_M_prev     = __first._M_node->_M_prev;
  407.       __first._M_node->_M_prev    = __tmp;
  408.     }
  409.   }
  410.  
  411. public:
  412.   void splice(iterator __position, list& __x) {
  413.     if (!__x.empty())
  414.       this->transfer(__position, __x.begin(), __x.end());
  415.   }
  416.   void splice(iterator __position, list&, iterator __i) {
  417.     iterator __j = __i;
  418.     ++__j;
  419.     if (__position == __i || __position == __j) return;
  420.     this->transfer(__position, __i, __j);
  421.   }
  422.   void splice(iterator __position, list&, iterator __first, iterator __last) {
  423.     if (__first != __last)
  424.       this->transfer(__position, __first, __last);
  425.   }
  426.   void remove(const _Tp& __value);
  427.   void unique();
  428.   void merge(list& __x);
  429.   void reverse();
  430.   void sort();
  431.  
  432.   template <class _Predicate> void remove_if(_Predicate);
  433.   template <class _BinaryPredicate> void unique(_BinaryPredicate);
  434.   template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering);
  435.   template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering);
  436. };
  437.  
  438. template <class _Tp, class _Alloc>
  439. inline bool
  440. operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
  441. {
  442.   typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
  443.   const_iterator __end1 = __x.end();
  444.   const_iterator __end2 = __y.end();
  445.  
  446.   const_iterator __i1 = __x.begin();
  447.   const_iterator __i2 = __y.begin();
  448.   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
  449.     ++__i1;
  450.     ++__i2;
  451.   }
  452.   return __i1 == __end1 && __i2 == __end2;
  453. }
  454.  
  455. template <class _Tp, class _Alloc>
  456. inline bool operator<(const list<_Tp,_Alloc>& __x,
  457.                       const list<_Tp,_Alloc>& __y)
  458. {
  459.   return lexicographical_compare(__x.begin(), __x.end(),
  460.                                  __y.begin(), __y.end());
  461. }
  462.  
  463. template <class _Tp, class _Alloc>
  464. inline bool operator!=(const list<_Tp,_Alloc>& __x,
  465.                        const list<_Tp,_Alloc>& __y) {
  466.   return !(__x == __y);
  467. }
  468.  
  469. template <class _Tp, class _Alloc>
  470. inline bool operator>(const list<_Tp,_Alloc>& __x,
  471.                       const list<_Tp,_Alloc>& __y) {
  472.   return __y < __x;
  473. }
  474.  
  475. template <class _Tp, class _Alloc>
  476. inline bool operator<=(const list<_Tp,_Alloc>& __x,
  477.                        const list<_Tp,_Alloc>& __y) {
  478.   return !(__y < __x);
  479. }
  480.  
  481. template <class _Tp, class _Alloc>
  482. inline bool operator>=(const list<_Tp,_Alloc>& __x,
  483.                        const list<_Tp,_Alloc>& __y) {
  484.   return !(__x < __y);
  485. }
  486.  
  487. template <class _Tp, class _Alloc>
  488. inline void
  489. swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
  490. {
  491.   __x.swap(__y);
  492. }
  493.  
  494. template <class _Tp, class _Alloc> template <class _InputIter>
  495. void
  496. list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position,
  497.                                       _InputIter __first, _InputIter __last,
  498.                                       __false_type)
  499. {
  500.   for ( ; __first != __last; ++__first)
  501.     insert(__position, *__first);
  502. }
  503.  
  504. template <class _Tp, class _Alloc>
  505. void
  506. list<_Tp, _Alloc>::_M_fill_insert(iterator __position,
  507.                                   size_type __n, const _Tp& __x)
  508. {
  509.   for ( ; __n > 0; --__n)
  510.     insert(__position, __x);
  511. }
  512.  
  513. template <class _Tp, class _Alloc>
  514. typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first,
  515.                                                              iterator __last)
  516. {
  517.   while (__first != __last)
  518.     erase(__first++);
  519.   return __last;
  520. }
  521.  
  522. template <class _Tp, class _Alloc>
  523. void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
  524. {
  525.   iterator __i = begin();
  526.   size_type __len = 0;
  527.   for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
  528.     ;
  529.   if (__len == __new_size)
  530.     erase(__i, end());
  531.   else                          // __i == end()
  532.     insert(end(), __new_size - __len, __x);
  533. }
  534.  
  535. template <class _Tp, class _Alloc>
  536. list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x)
  537. {
  538.   if (this != &__x) {
  539.     iterator __first1 = begin();
  540.     iterator __last1 = end();
  541.     const_iterator __first2 = __x.begin();
  542.     const_iterator __last2 = __x.end();
  543.     while (__first1 != __last1 && __first2 != __last2)
  544.       *__first1++ = *__first2++;
  545.     if (__first2 == __last2)
  546.       erase(__first1, __last1);
  547.     else
  548.       insert(__last1, __first2, __last2);
  549.   }
  550.   return *this;
  551. }
  552.  
  553. template <class _Tp, class _Alloc>
  554. void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
  555.   iterator __i = begin();
  556.   for ( ; __i != end() && __n > 0; ++__i, --__n)
  557.     *__i = __val;
  558.   if (__n > 0)
  559.     insert(end(), __n, __val);
  560.   else
  561.     erase(__i, end());
  562. }
  563.  
  564. template <class _Tp, class _Alloc> template <class _InputIter>
  565. void
  566. list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2,
  567.                                       __false_type)
  568. {
  569.   iterator __first1 = begin();
  570.   iterator __last1 = end();
  571.   for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
  572.     *__first1 = *__first2;
  573.   if (__first2 == __last2)
  574.     erase(__first1, __last1);
  575.   else
  576.     insert(__last1, __first2, __last2);
  577. }
  578.  
  579. template <class _Tp, class _Alloc>
  580. void list<_Tp, _Alloc>::remove(const _Tp& __value)
  581. {
  582.   iterator __first = begin();
  583.   iterator __last = end();
  584.   while (__first != __last) {
  585.     iterator __next = __first;
  586.     ++__next;
  587.     if (*__first == __value) erase(__first);
  588.     __first = __next;
  589.   }
  590. }
  591.  
  592. template <class _Tp, class _Alloc>
  593. void list<_Tp, _Alloc>::unique()
  594. {
  595.   iterator __first = begin();
  596.   iterator __last = end();
  597.   if (__first == __last) return;
  598.   iterator __next = __first;
  599.   while (++__next != __last) {
  600.     if (*__first == *__next)
  601.       erase(__next);
  602.     else
  603.       __first = __next;
  604.     __next = __first;
  605.   }
  606. }
  607.  
  608. template <class _Tp, class _Alloc>
  609. void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)
  610. {
  611.   iterator __first1 = begin();
  612.   iterator __last1 = end();
  613.   iterator __first2 = __x.begin();
  614.   iterator __last2 = __x.end();
  615.   while (__first1 != __last1 && __first2 != __last2)
  616.     if (*__first2 < *__first1) {
  617.       iterator __next = __first2;
  618.       transfer(__first1, __first2, ++__next);
  619.       __first2 = __next;
  620.     }
  621.     else
  622.       ++__first1;
  623.   if (__first2 != __last2) transfer(__last1, __first2, __last2);
  624. }
  625.  
  626. inline void __List_base_reverse(_List_node_base* __p)
  627. {
  628.   _List_node_base* __tmp = __p;
  629.   do {
  630.     std::swap(__tmp->_M_next, __tmp->_M_prev);
  631.     __tmp = __tmp->_M_prev;     // Old next node is now prev.
  632.   } while (__tmp != __p);
  633. }
  634.  
  635. template <class _Tp, class _Alloc>
  636. inline void list<_Tp, _Alloc>::reverse()
  637. {
  638.   __List_base_reverse(this->_M_node);
  639. }    
  640.  
  641. template <class _Tp, class _Alloc>
  642. void list<_Tp, _Alloc>::sort()
  643. {
  644.   // Do nothing if the list has length 0 or 1.
  645.   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
  646.     list<_Tp, _Alloc> __carry;
  647.     list<_Tp, _Alloc> __counter[64];
  648.     int __fill = 0;
  649.     while (!empty()) {
  650.       __carry.splice(__carry.begin(), *this, begin());
  651.       int __i = 0;
  652.       while(__i < __fill && !__counter[__i].empty()) {
  653.         __counter[__i].merge(__carry);
  654.         __carry.swap(__counter[__i++]);
  655.       }
  656.       __carry.swap(__counter[__i]);        
  657.       if (__i == __fill) ++__fill;
  658.     }
  659.  
  660.     for (int __i = 1; __i < __fill; ++__i)
  661.       __counter[__i].merge(__counter[__i-1]);
  662.     swap(__counter[__fill-1]);
  663.   }
  664. }
  665.  
  666. template <class _Tp, class _Alloc> template <class _Predicate>
  667. void list<_Tp, _Alloc>::remove_if(_Predicate __pred)
  668. {
  669.   iterator __first = begin();
  670.   iterator __last = end();
  671.   while (__first != __last) {
  672.     iterator __next = __first;
  673.     ++__next;
  674.     if (__pred(*__first)) erase(__first);
  675.     __first = __next;
  676.   }
  677. }
  678.  
  679. template <class _Tp, class _Alloc> template <class _BinaryPredicate>
  680. void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
  681. {
  682.   iterator __first = begin();
  683.   iterator __last = end();
  684.   if (__first == __last) return;
  685.   iterator __next = __first;
  686.   while (++__next != __last) {
  687.     if (__binary_pred(*__first, *__next))
  688.       erase(__next);
  689.     else
  690.       __first = __next;
  691.     __next = __first;
  692.   }
  693. }
  694.  
  695. template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
  696. void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x,
  697.                               _StrictWeakOrdering __comp)
  698. {
  699.   iterator __first1 = begin();
  700.   iterator __last1 = end();
  701.   iterator __first2 = __x.begin();
  702.   iterator __last2 = __x.end();
  703.   while (__first1 != __last1 && __first2 != __last2)
  704.     if (__comp(*__first2, *__first1)) {
  705.       iterator __next = __first2;
  706.       transfer(__first1, __first2, ++__next);
  707.       __first2 = __next;
  708.     }
  709.     else
  710.       ++__first1;
  711.   if (__first2 != __last2) transfer(__last1, __first2, __last2);
  712. }
  713.  
  714. template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
  715. void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
  716. {
  717.   // Do nothing if the list has length 0 or 1.
  718.   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
  719.     list<_Tp, _Alloc> __carry;
  720.     list<_Tp, _Alloc> __counter[64];
  721.     int __fill = 0;
  722.     while (!empty()) {
  723.       __carry.splice(__carry.begin(), *this, begin());
  724.       int __i = 0;
  725.       while(__i < __fill && !__counter[__i].empty()) {
  726.         __counter[__i].merge(__carry, __comp);
  727.         __carry.swap(__counter[__i++]);
  728.       }
  729.       __carry.swap(__counter[__i]);        
  730.       if (__i == __fill) ++__fill;
  731.     }
  732.  
  733.     for (int __i = 1; __i < __fill; ++__i)
  734.       __counter[__i].merge(__counter[__i-1], __comp);
  735.     swap(__counter[__fill-1]);
  736.   }
  737. }
  738.  
  739. } // namespace std
  740.  
  741. #endif /* __SGI_STL_INTERNAL_LIST_H */
  742.  
  743. // Local Variables:
  744. // mode:C++
  745. // End:
  746.