Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

stl_list.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Permission to use, copy, modify, distribute and sell this software
00007  * and its documentation for any purpose is hereby granted without fee,
00008  * provided that the above copyright notice appear in all copies and
00009  * that both that copyright notice and this permission notice appear
00010  * in supporting documentation.  Hewlett-Packard Company makes no
00011  * representations about the suitability of this software for any
00012  * purpose.  It is provided "as is" without express or implied warranty.
00013  *
00014  *
00015  * Copyright (c) 1996,1997
00016  * Silicon Graphics Computer Systems, Inc.
00017  *
00018  * Permission to use, copy, modify, distribute and sell this software
00019  * and its documentation for any purpose is hereby granted without fee,
00020  * provided that the above copyright notice appear in all copies and
00021  * that both that copyright notice and this permission notice appear
00022  * in supporting documentation.  Silicon Graphics makes no
00023  * representations about the suitability of this software for any
00024  * purpose.  It is provided "as is" without express or implied warranty.
00025  */
00026 
00027 /* NOTE: This is an internal header file, included by other STL headers.
00028  *   You should not attempt to use it directly.
00029  */
00030 
00031 #ifndef __SGI_STL_INTERNAL_LIST_H
00032 #define __SGI_STL_INTERNAL_LIST_H
00033 
00034 #include <bits/concept_check.h>
00035 
00036 namespace std
00037 {
00038 
00039 struct _List_node_base {
00040   _List_node_base* _M_next;
00041   _List_node_base* _M_prev;
00042 };
00043 
00044 template <class _Tp>
00045 struct _List_node : public _List_node_base {
00046   _Tp _M_data;
00047 };
00048 
00049 struct _List_iterator_base {
00050   typedef size_t                     size_type;
00051   typedef ptrdiff_t                  difference_type;
00052   typedef bidirectional_iterator_tag iterator_category;
00053 
00054   _List_node_base* _M_node;
00055 
00056   _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
00057   _List_iterator_base() {}
00058 
00059   void _M_incr() { _M_node = _M_node->_M_next; }
00060   void _M_decr() { _M_node = _M_node->_M_prev; }
00061 
00062   bool operator==(const _List_iterator_base& __x) const {
00063     return _M_node == __x._M_node;
00064   }
00065   bool operator!=(const _List_iterator_base& __x) const {
00066     return _M_node != __x._M_node;
00067   }
00068 };  
00069 
00070 template<class _Tp, class _Ref, class _Ptr>
00071 struct _List_iterator : public _List_iterator_base {
00072   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
00073   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00074   typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;
00075 
00076   typedef _Tp value_type;
00077   typedef _Ptr pointer;
00078   typedef _Ref reference;
00079   typedef _List_node<_Tp> _Node;
00080 
00081   _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
00082   _List_iterator() {}
00083   _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}
00084 
00085   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
00086   pointer operator->() const { return &(operator*()); }
00087 
00088   _Self& operator++() { 
00089     this->_M_incr();
00090     return *this;
00091   }
00092   _Self operator++(int) { 
00093     _Self __tmp = *this;
00094     this->_M_incr();
00095     return __tmp;
00096   }
00097   _Self& operator--() { 
00098     this->_M_decr();
00099     return *this;
00100   }
00101   _Self operator--(int) { 
00102     _Self __tmp = *this;
00103     this->_M_decr();
00104     return __tmp;
00105   }
00106 };
00107 
00108 
00109 // Base class that encapsulates details of allocators.  Three cases:
00110 // an ordinary standard-conforming allocator, a standard-conforming
00111 // allocator with no non-static data, and an SGI-style allocator.
00112 // This complexity is necessary only because we're worrying about backward
00113 // compatibility and because we want to avoid wasting storage on an 
00114 // allocator instance if it isn't necessary.
00115 
00116 
00117 // Base for general standard-conforming allocators.
00118 template <class _Tp, class _Allocator, bool _IsStatic>
00119 class _List_alloc_base {
00120 public:
00121   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00122           allocator_type;
00123   allocator_type get_allocator() const { return _Node_allocator; }
00124 
00125   _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {}
00126 
00127 protected:
00128   _List_node<_Tp>* _M_get_node()
00129    { return _Node_allocator.allocate(1); }
00130   void _M_put_node(_List_node<_Tp>* __p)
00131     { _Node_allocator.deallocate(__p, 1); }
00132 
00133 protected:
00134   typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
00135            _Node_allocator;
00136   _List_node<_Tp>* _M_node;
00137 };
00138 
00139 // Specialization for instanceless allocators.
00140 
00141 template <class _Tp, class _Allocator>
00142 class _List_alloc_base<_Tp, _Allocator, true> {
00143 public:
00144   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00145           allocator_type;
00146   allocator_type get_allocator() const { return allocator_type(); }
00147 
00148   _List_alloc_base(const allocator_type&) {}
00149 
00150 protected:
00151   typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
00152           _Alloc_type;
00153   _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
00154   void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
00155 
00156 protected:
00157   _List_node<_Tp>* _M_node;
00158 };
00159 
00160 template <class _Tp, class _Alloc>
00161 class _List_base 
00162   : public _List_alloc_base<_Tp, _Alloc,
00163                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00164 {
00165 public:
00166   typedef _List_alloc_base<_Tp, _Alloc,
00167                            _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00168           _Base; 
00169   typedef typename _Base::allocator_type allocator_type;
00170 
00171   _List_base(const allocator_type& __a) : _Base(__a) {
00172     _M_node = _M_get_node();
00173     _M_node->_M_next = _M_node;
00174     _M_node->_M_prev = _M_node;
00175   }
00176   ~_List_base() {
00177     clear();
00178     _M_put_node(_M_node);
00179   }
00180 
00181   void clear();
00182 };
00183 
00184 
00185 template <class _Tp, class _Alloc>
00186 void 
00187 _List_base<_Tp,_Alloc>::clear() 
00188 {
00189   _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next;
00190   while (__cur != _M_node) {
00191     _List_node<_Tp>* __tmp = __cur;
00192     __cur = (_List_node<_Tp>*) __cur->_M_next;
00193     _Destroy(&__tmp->_M_data);
00194     _M_put_node(__tmp);
00195   }
00196   _M_node->_M_next = _M_node;
00197   _M_node->_M_prev = _M_node;
00198 }
00199 
00200 template <class _Tp, class _Alloc = allocator<_Tp> >
00201 class list : protected _List_base<_Tp, _Alloc>
00202 {
00203   // concept requirements
00204   __glibcpp_class_requires(_Tp, _SGIAssignableConcept);
00205 
00206   typedef _List_base<_Tp, _Alloc> _Base;
00207 protected:
00208   typedef void* _Void_pointer;
00209 
00210 public:      
00211   typedef _Tp value_type;
00212   typedef value_type* pointer;
00213   typedef const value_type* const_pointer;
00214   typedef value_type& reference;
00215   typedef const value_type& const_reference;
00216   typedef _List_node<_Tp> _Node;
00217   typedef size_t size_type;
00218   typedef ptrdiff_t difference_type;
00219 
00220   typedef typename _Base::allocator_type allocator_type;
00221   allocator_type get_allocator() const { return _Base::get_allocator(); }
00222 
00223 public:
00224   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
00225   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00226 
00227   typedef reverse_iterator<const_iterator> const_reverse_iterator;
00228   typedef reverse_iterator<iterator>       reverse_iterator;
00229 
00230 protected:
00231   using _Base::_M_node;
00232   using _Base::_M_put_node;
00233   using _Base::_M_get_node;
00234 
00235 protected:
00236   _Node* _M_create_node(const _Tp& __x)
00237   {
00238     _Node* __p = _M_get_node();
00239     __STL_TRY {
00240       _Construct(&__p->_M_data, __x);
00241     }
00242     __STL_UNWIND(_M_put_node(__p));
00243     return __p;
00244   }
00245 
00246   _Node* _M_create_node()
00247   {
00248     _Node* __p = _M_get_node();
00249     __STL_TRY {
00250       _Construct(&__p->_M_data);
00251     }
00252     __STL_UNWIND(_M_put_node(__p));
00253     return __p;
00254   }
00255 
00256 public:
00257   explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {}
00258 
00259   iterator begin()             { return (_Node*)(_M_node->_M_next); }
00260   const_iterator begin() const { return (_Node*)(_M_node->_M_next); }
00261 
00262   iterator end()             { return _M_node; }
00263   const_iterator end() const { return _M_node; }
00264 
00265   reverse_iterator rbegin() 
00266     { return reverse_iterator(end()); }
00267   const_reverse_iterator rbegin() const 
00268     { return const_reverse_iterator(end()); }
00269 
00270   reverse_iterator rend()
00271     { return reverse_iterator(begin()); }
00272   const_reverse_iterator rend() const
00273     { return const_reverse_iterator(begin()); }
00274 
00275   bool empty() const { return _M_node->_M_next == _M_node; }
00276   size_type size() const {
00277     size_type __result = 0;
00278     distance(begin(), end(), __result);
00279     return __result;
00280   }
00281   size_type max_size() const { return size_type(-1); }
00282 
00283   reference front() { return *begin(); }
00284   const_reference front() const { return *begin(); }
00285   reference back() { return *(--end()); }
00286   const_reference back() const { return *(--end()); }
00287 
00288   void swap(list<_Tp, _Alloc>& __x) { std::swap(_M_node, __x._M_node); }
00289 
00290   iterator insert(iterator __position, const _Tp& __x) {
00291     _Node* __tmp = _M_create_node(__x);
00292     __tmp->_M_next = __position._M_node;
00293     __tmp->_M_prev = __position._M_node->_M_prev;
00294     __position._M_node->_M_prev->_M_next = __tmp;
00295     __position._M_node->_M_prev = __tmp;
00296     return __tmp;
00297   }
00298   iterator insert(iterator __position) { return insert(__position, _Tp()); }
00299 
00300   // Check whether it's an integral type.  If so, it's not an iterator.
00301   template<class _Integer>
00302   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00303                           __true_type) {
00304     _M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
00305   }
00306 
00307   template <class _InputIterator>
00308   void _M_insert_dispatch(iterator __pos,
00309                           _InputIterator __first, _InputIterator __last,
00310                           __false_type);
00311 
00312   template <class _InputIterator>
00313   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00314     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00315     _M_insert_dispatch(__pos, __first, __last, _Integral());
00316   }
00317 
00318   void insert(iterator __pos, size_type __n, const _Tp& __x)
00319     { _M_fill_insert(__pos, __n, __x); }
00320   void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x); 
00321 
00322   void push_front(const _Tp& __x) { insert(begin(), __x); }
00323   void push_front() {insert(begin());}
00324   void push_back(const _Tp& __x) { insert(end(), __x); }
00325   void push_back() {insert(end());}
00326 
00327   iterator erase(iterator __position) {
00328     _List_node_base* __next_node = __position._M_node->_M_next;
00329     _List_node_base* __prev_node = __position._M_node->_M_prev;
00330     _Node* __n = (_Node*) __position._M_node;
00331     __prev_node->_M_next = __next_node;
00332     __next_node->_M_prev = __prev_node;
00333     _Destroy(&__n->_M_data);
00334     _M_put_node(__n);
00335     return iterator((_Node*) __next_node);
00336   }
00337   iterator erase(iterator __first, iterator __last);
00338   void clear() { _Base::clear(); }
00339 
00340   void resize(size_type __new_size, const _Tp& __x);
00341   void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
00342 
00343   void pop_front() { erase(begin()); }
00344   void pop_back() { 
00345     iterator __tmp = end();
00346     erase(--__tmp);
00347   }
00348   list(size_type __n, const _Tp& __value,
00349        const allocator_type& __a = allocator_type())
00350     : _Base(__a)
00351     { insert(begin(), __n, __value); }
00352   explicit list(size_type __n)
00353     : _Base(allocator_type())
00354     { insert(begin(), __n, _Tp()); }
00355 
00356   // We don't need any dispatching tricks here, because insert does all of
00357   // that anyway.  
00358   template <class _InputIterator>
00359   list(_InputIterator __first, _InputIterator __last,
00360        const allocator_type& __a = allocator_type())
00361     : _Base(__a)
00362     { insert(begin(), __first, __last); }
00363 
00364   list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator())
00365     { insert(begin(), __x.begin(), __x.end()); }
00366 
00367   ~list() { }
00368 
00369   list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x);
00370 
00371 public:
00372   // assign(), a generalized assignment member function.  Two
00373   // versions: one that takes a count, and one that takes a range.
00374   // The range version is a member template, so we dispatch on whether
00375   // or not the type is an integer.
00376 
00377   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00378 
00379   void _M_fill_assign(size_type __n, const _Tp& __val);
00380 
00381   template <class _InputIterator>
00382   void assign(_InputIterator __first, _InputIterator __last) {
00383     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00384     _M_assign_dispatch(__first, __last, _Integral());
00385   }
00386 
00387   template <class _Integer>
00388   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00389     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00390 
00391   template <class _InputIterator>
00392   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00393                           __false_type);
00394 
00395 protected:
00396   void transfer(iterator __position, iterator __first, iterator __last) {
00397     if (__position != __last) {
00398       // Remove [first, last) from its old position.
00399       __last._M_node->_M_prev->_M_next     = __position._M_node;
00400       __first._M_node->_M_prev->_M_next    = __last._M_node;
00401       __position._M_node->_M_prev->_M_next = __first._M_node; 
00402 
00403       // Splice [first, last) into its new position.
00404       _List_node_base* __tmp      = __position._M_node->_M_prev;
00405       __position._M_node->_M_prev = __last._M_node->_M_prev;
00406       __last._M_node->_M_prev     = __first._M_node->_M_prev; 
00407       __first._M_node->_M_prev    = __tmp;
00408     }
00409   }
00410 
00411 public:
00412   void splice(iterator __position, list& __x) {
00413     if (!__x.empty()) 
00414       this->transfer(__position, __x.begin(), __x.end());
00415   }
00416   void splice(iterator __position, list&, iterator __i) {
00417     iterator __j = __i;
00418     ++__j;
00419     if (__position == __i || __position == __j) return;
00420     this->transfer(__position, __i, __j);
00421   }
00422   void splice(iterator __position, list&, iterator __first, iterator __last) {
00423     if (__first != __last) 
00424       this->transfer(__position, __first, __last);
00425   }
00426   void remove(const _Tp& __value);
00427   void unique();
00428   void merge(list& __x);
00429   void reverse();
00430   void sort();
00431 
00432   template <class _Predicate> void remove_if(_Predicate);
00433   template <class _BinaryPredicate> void unique(_BinaryPredicate);
00434   template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering);
00435   template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering);
00436 };
00437 
00438 template <class _Tp, class _Alloc>
00439 inline bool 
00440 operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
00441 {
00442   typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
00443   const_iterator __end1 = __x.end();
00444   const_iterator __end2 = __y.end();
00445 
00446   const_iterator __i1 = __x.begin();
00447   const_iterator __i2 = __y.begin();
00448   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00449     ++__i1;
00450     ++__i2;
00451   }
00452   return __i1 == __end1 && __i2 == __end2;
00453 }
00454 
00455 template <class _Tp, class _Alloc>
00456 inline bool operator<(const list<_Tp,_Alloc>& __x,
00457                       const list<_Tp,_Alloc>& __y)
00458 {
00459   return lexicographical_compare(__x.begin(), __x.end(),
00460                                  __y.begin(), __y.end());
00461 }
00462 
00463 template <class _Tp, class _Alloc>
00464 inline bool operator!=(const list<_Tp,_Alloc>& __x,
00465                        const list<_Tp,_Alloc>& __y) {
00466   return !(__x == __y);
00467 }
00468 
00469 template <class _Tp, class _Alloc>
00470 inline bool operator>(const list<_Tp,_Alloc>& __x,
00471                       const list<_Tp,_Alloc>& __y) {
00472   return __y < __x;
00473 }
00474 
00475 template <class _Tp, class _Alloc>
00476 inline bool operator<=(const list<_Tp,_Alloc>& __x,
00477                        const list<_Tp,_Alloc>& __y) {
00478   return !(__y < __x);
00479 }
00480 
00481 template <class _Tp, class _Alloc>
00482 inline bool operator>=(const list<_Tp,_Alloc>& __x,
00483                        const list<_Tp,_Alloc>& __y) {
00484   return !(__x < __y);
00485 }
00486 
00487 template <class _Tp, class _Alloc>
00488 inline void 
00489 swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
00490 {
00491   __x.swap(__y);
00492 }
00493 
00494 template <class _Tp, class _Alloc> template <class _InputIter>
00495 void 
00496 list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position,
00497                                       _InputIter __first, _InputIter __last,
00498                                       __false_type)
00499 {
00500   for ( ; __first != __last; ++__first)
00501     insert(__position, *__first);
00502 }
00503 
00504 template <class _Tp, class _Alloc>
00505 void 
00506 list<_Tp, _Alloc>::_M_fill_insert(iterator __position,
00507                                   size_type __n, const _Tp& __x)
00508 {
00509   for ( ; __n > 0; --__n)
00510     insert(__position, __x);
00511 }
00512 
00513 template <class _Tp, class _Alloc>
00514 typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, 
00515                                                              iterator __last)
00516 {
00517   while (__first != __last)
00518     erase(__first++);
00519   return __last;
00520 }
00521 
00522 template <class _Tp, class _Alloc>
00523 void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
00524 {
00525   iterator __i = begin();
00526   size_type __len = 0;
00527   for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
00528     ;
00529   if (__len == __new_size)
00530     erase(__i, end());
00531   else                          // __i == end()
00532     insert(end(), __new_size - __len, __x);
00533 }
00534 
00535 template <class _Tp, class _Alloc>
00536 list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x)
00537 {
00538   if (this != &__x) {
00539     iterator __first1 = begin();
00540     iterator __last1 = end();
00541     const_iterator __first2 = __x.begin();
00542     const_iterator __last2 = __x.end();
00543     while (__first1 != __last1 && __first2 != __last2) 
00544       *__first1++ = *__first2++;
00545     if (__first2 == __last2)
00546       erase(__first1, __last1);
00547     else
00548       insert(__last1, __first2, __last2);
00549   }
00550   return *this;
00551 }
00552 
00553 template <class _Tp, class _Alloc>
00554 void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
00555   iterator __i = begin();
00556   for ( ; __i != end() && __n > 0; ++__i, --__n)
00557     *__i = __val;
00558   if (__n > 0)
00559     insert(end(), __n, __val);
00560   else
00561     erase(__i, end());
00562 }
00563 
00564 template <class _Tp, class _Alloc> template <class _InputIter>
00565 void
00566 list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2,
00567                                       __false_type)
00568 {
00569   iterator __first1 = begin();
00570   iterator __last1 = end();
00571   for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
00572     *__first1 = *__first2;
00573   if (__first2 == __last2)
00574     erase(__first1, __last1);
00575   else
00576     insert(__last1, __first2, __last2);
00577 }
00578 
00579 template <class _Tp, class _Alloc>
00580 void list<_Tp, _Alloc>::remove(const _Tp& __value)
00581 {
00582   iterator __first = begin();
00583   iterator __last = end();
00584   while (__first != __last) {
00585     iterator __next = __first;
00586     ++__next;
00587     if (*__first == __value) erase(__first);
00588     __first = __next;
00589   }
00590 }
00591 
00592 template <class _Tp, class _Alloc>
00593 void list<_Tp, _Alloc>::unique()
00594 {
00595   iterator __first = begin();
00596   iterator __last = end();
00597   if (__first == __last) return;
00598   iterator __next = __first;
00599   while (++__next != __last) {
00600     if (*__first == *__next)
00601       erase(__next);
00602     else
00603       __first = __next;
00604     __next = __first;
00605   }
00606 }
00607 
00608 template <class _Tp, class _Alloc>
00609 void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)
00610 {
00611   iterator __first1 = begin();
00612   iterator __last1 = end();
00613   iterator __first2 = __x.begin();
00614   iterator __last2 = __x.end();
00615   while (__first1 != __last1 && __first2 != __last2)
00616     if (*__first2 < *__first1) {
00617       iterator __next = __first2;
00618       transfer(__first1, __first2, ++__next);
00619       __first2 = __next;
00620     }
00621     else
00622       ++__first1;
00623   if (__first2 != __last2) transfer(__last1, __first2, __last2);
00624 }
00625 
00626 inline void __List_base_reverse(_List_node_base* __p)
00627 {
00628   _List_node_base* __tmp = __p;
00629   do {
00630     std::swap(__tmp->_M_next, __tmp->_M_prev);
00631     __tmp = __tmp->_M_prev;     // Old next node is now prev.
00632   } while (__tmp != __p);
00633 }
00634 
00635 template <class _Tp, class _Alloc>
00636 inline void list<_Tp, _Alloc>::reverse() 
00637 {
00638   __List_base_reverse(this->_M_node);
00639 }    
00640 
00641 template <class _Tp, class _Alloc>
00642 void list<_Tp, _Alloc>::sort()
00643 {
00644   // Do nothing if the list has length 0 or 1.
00645   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
00646     list<_Tp, _Alloc> __carry;
00647     list<_Tp, _Alloc> __counter[64];
00648     int __fill = 0;
00649     while (!empty()) {
00650       __carry.splice(__carry.begin(), *this, begin());
00651       int __i = 0;
00652       while(__i < __fill && !__counter[__i].empty()) {
00653         __counter[__i].merge(__carry);
00654         __carry.swap(__counter[__i++]);
00655       }
00656       __carry.swap(__counter[__i]);         
00657       if (__i == __fill) ++__fill;
00658     } 
00659 
00660     for (int __i = 1; __i < __fill; ++__i)
00661       __counter[__i].merge(__counter[__i-1]);
00662     swap(__counter[__fill-1]);
00663   }
00664 }
00665 
00666 template <class _Tp, class _Alloc> template <class _Predicate>
00667 void list<_Tp, _Alloc>::remove_if(_Predicate __pred)
00668 {
00669   iterator __first = begin();
00670   iterator __last = end();
00671   while (__first != __last) {
00672     iterator __next = __first;
00673     ++__next;
00674     if (__pred(*__first)) erase(__first);
00675     __first = __next;
00676   }
00677 }
00678 
00679 template <class _Tp, class _Alloc> template <class _BinaryPredicate>
00680 void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
00681 {
00682   iterator __first = begin();
00683   iterator __last = end();
00684   if (__first == __last) return;
00685   iterator __next = __first;
00686   while (++__next != __last) {
00687     if (__binary_pred(*__first, *__next))
00688       erase(__next);
00689     else
00690       __first = __next;
00691     __next = __first;
00692   }
00693 }
00694 
00695 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00696 void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x,
00697                               _StrictWeakOrdering __comp)
00698 {
00699   iterator __first1 = begin();
00700   iterator __last1 = end();
00701   iterator __first2 = __x.begin();
00702   iterator __last2 = __x.end();
00703   while (__first1 != __last1 && __first2 != __last2)
00704     if (__comp(*__first2, *__first1)) {
00705       iterator __next = __first2;
00706       transfer(__first1, __first2, ++__next);
00707       __first2 = __next;
00708     }
00709     else
00710       ++__first1;
00711   if (__first2 != __last2) transfer(__last1, __first2, __last2);
00712 }
00713 
00714 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00715 void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
00716 {
00717   // Do nothing if the list has length 0 or 1.
00718   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
00719     list<_Tp, _Alloc> __carry;
00720     list<_Tp, _Alloc> __counter[64];
00721     int __fill = 0;
00722     while (!empty()) {
00723       __carry.splice(__carry.begin(), *this, begin());
00724       int __i = 0;
00725       while(__i < __fill && !__counter[__i].empty()) {
00726         __counter[__i].merge(__carry, __comp);
00727         __carry.swap(__counter[__i++]);
00728       }
00729       __carry.swap(__counter[__i]);         
00730       if (__i == __fill) ++__fill;
00731     } 
00732 
00733     for (int __i = 1; __i < __fill; ++__i) 
00734       __counter[__i].merge(__counter[__i-1], __comp);
00735     swap(__counter[__fill-1]);
00736   }
00737 }
00738 
00739 } // namespace std 
00740 
00741 #endif /* __SGI_STL_INTERNAL_LIST_H */
00742 
00743 // Local Variables:
00744 // mode:C++
00745 // End:

Generated at Tue May 1 16:28:39 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001