slist

Go to the documentation of this file.
00001 // Singly-linked list implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  * Copyright (c) 1997
00032  * Silicon Graphics Computer Systems, Inc.
00033  *
00034  * Permission to use, copy, modify, distribute and sell this software
00035  * and its documentation for any purpose is hereby granted without fee,
00036  * provided that the above copyright notice appear in all copies and
00037  * that both that copyright notice and this permission notice appear
00038  * in supporting documentation.  Silicon Graphics makes no
00039  * representations about the suitability of this software for any
00040  * purpose.  It is provided "as is" without express or implied warranty.
00041  *
00042  */
00043 
00050 #ifndef _SLIST
00051 #define _SLIST 1
00052 
00053 #include <bits/stl_algobase.h>
00054 #include <bits/allocator.h>
00055 #include <bits/stl_construct.h>
00056 #include <bits/stl_uninitialized.h>
00057 #include <bits/concept_check.h>
00058 
00059 namespace __gnu_cxx
00060 {
00061 using std::size_t;
00062 using std::ptrdiff_t;
00063 using std::_Construct;
00064 using std::_Destroy;
00065 using std::allocator;
00066 
00067 struct _Slist_node_base
00068 {
00069   _Slist_node_base* _M_next;
00070 };
00071 
00072 inline _Slist_node_base*
00073 __slist_make_link(_Slist_node_base* __prev_node,
00074                   _Slist_node_base* __new_node)
00075 {
00076   __new_node->_M_next = __prev_node->_M_next;
00077   __prev_node->_M_next = __new_node;
00078   return __new_node;
00079 }
00080 
00081 inline _Slist_node_base*
00082 __slist_previous(_Slist_node_base* __head,
00083                  const _Slist_node_base* __node)
00084 {
00085   while (__head && __head->_M_next != __node)
00086     __head = __head->_M_next;
00087   return __head;
00088 }
00089 
00090 inline const _Slist_node_base*
00091 __slist_previous(const _Slist_node_base* __head,
00092                  const _Slist_node_base* __node)
00093 {
00094   while (__head && __head->_M_next != __node)
00095     __head = __head->_M_next;
00096   return __head;
00097 }
00098 
00099 inline void __slist_splice_after(_Slist_node_base* __pos,
00100                                  _Slist_node_base* __before_first,
00101                                  _Slist_node_base* __before_last)
00102 {
00103   if (__pos != __before_first && __pos != __before_last) {
00104     _Slist_node_base* __first = __before_first->_M_next;
00105     _Slist_node_base* __after = __pos->_M_next;
00106     __before_first->_M_next = __before_last->_M_next;
00107     __pos->_M_next = __first;
00108     __before_last->_M_next = __after;
00109   }
00110 }
00111 
00112 inline void
00113 __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
00114 {
00115   _Slist_node_base* __before_last = __slist_previous(__head, 0);
00116   if (__before_last != __head) {
00117     _Slist_node_base* __after = __pos->_M_next;
00118     __pos->_M_next = __head->_M_next;
00119     __head->_M_next = 0;
00120     __before_last->_M_next = __after;
00121   }
00122 }
00123 
00124 inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node)
00125 {
00126   _Slist_node_base* __result = __node;
00127   __node = __node->_M_next;
00128   __result->_M_next = 0;
00129   while(__node) {
00130     _Slist_node_base* __next = __node->_M_next;
00131     __node->_M_next = __result;
00132     __result = __node;
00133     __node = __next;
00134   }
00135   return __result;
00136 }
00137 
00138 inline size_t __slist_size(_Slist_node_base* __node)
00139 {
00140   size_t __result = 0;
00141   for ( ; __node != 0; __node = __node->_M_next)
00142     ++__result;
00143   return __result;
00144 }
00145 
00146 template <class _Tp>
00147 struct _Slist_node : public _Slist_node_base
00148 {
00149   _Tp _M_data;
00150 };
00151 
00152 struct _Slist_iterator_base
00153 {
00154   typedef size_t                    size_type;
00155   typedef ptrdiff_t                 difference_type;
00156   typedef std::forward_iterator_tag iterator_category;
00157 
00158   _Slist_node_base* _M_node;
00159 
00160   _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {}
00161   void _M_incr() { _M_node = _M_node->_M_next; }
00162 
00163   bool operator==(const _Slist_iterator_base& __x) const {
00164     return _M_node == __x._M_node;
00165   }
00166   bool operator!=(const _Slist_iterator_base& __x) const {
00167     return _M_node != __x._M_node;
00168   }
00169 };
00170 
00171 template <class _Tp, class _Ref, class _Ptr>
00172 struct _Slist_iterator : public _Slist_iterator_base
00173 {
00174   typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
00175   typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00176   typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
00177 
00178   typedef _Tp              value_type;
00179   typedef _Ptr             pointer;
00180   typedef _Ref             reference;
00181   typedef _Slist_node<_Tp> _Node;
00182 
00183   _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {}
00184   _Slist_iterator() : _Slist_iterator_base(0) {}
00185   _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
00186 
00187   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
00188   pointer operator->() const { return &(operator*()); }
00189 
00190   _Self& operator++()
00191   {
00192     _M_incr();
00193     return *this;
00194   }
00195   _Self operator++(int)
00196   {
00197     _Self __tmp = *this;
00198     _M_incr();
00199     return __tmp;
00200   }
00201 };
00202 
00203 template <class _Tp, class _Alloc>
00204 struct _Slist_base
00205   : public _Alloc::template rebind<_Slist_node<_Tp> >::other
00206 {
00207   typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc;
00208   typedef _Alloc allocator_type;
00209   allocator_type get_allocator() const {
00210     return *static_cast<const _Node_alloc*>(this);
00211   }
00212 
00213   _Slist_base(const allocator_type& __a)
00214     : _Node_alloc(__a) { this->_M_head._M_next = 0; }
00215   ~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
00216 
00217 protected:
00218   _Slist_node_base _M_head;
00219 
00220   _Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); }
00221   void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); }
00222 
00223 protected:
00224   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
00225   {
00226     _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
00227     _Slist_node_base* __next_next = __next->_M_next;
00228     __pos->_M_next = __next_next;
00229     _Destroy(&__next->_M_data);
00230     _M_put_node(__next);
00231     return __next_next;
00232   }
00233   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
00234 };
00235 
00236 template <class _Tp, class _Alloc>
00237 _Slist_node_base*
00238 _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
00239                                         _Slist_node_base* __last_node) {
00240   _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
00241   while (__cur != __last_node) {
00242     _Slist_node<_Tp>* __tmp = __cur;
00243     __cur = (_Slist_node<_Tp>*) __cur->_M_next;
00244     _Destroy(&__tmp->_M_data);
00245     _M_put_node(__tmp);
00246   }
00247   __before_first->_M_next = __last_node;
00248   return __last_node;
00249 }
00250 
00256 template <class _Tp, class _Alloc = allocator<_Tp> >
00257 class slist : private _Slist_base<_Tp,_Alloc>
00258 {
00259   // concept requirements
00260   __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00261 
00262 private:
00263   typedef _Slist_base<_Tp,_Alloc> _Base;
00264 public:
00265   typedef _Tp               value_type;
00266   typedef value_type*       pointer;
00267   typedef const value_type* const_pointer;
00268   typedef value_type&       reference;
00269   typedef const value_type& const_reference;
00270   typedef size_t            size_type;
00271   typedef ptrdiff_t         difference_type;
00272 
00273   typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
00274   typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00275 
00276   typedef typename _Base::allocator_type allocator_type;
00277   allocator_type get_allocator() const { return _Base::get_allocator(); }
00278 
00279 private:
00280   typedef _Slist_node<_Tp>      _Node;
00281   typedef _Slist_node_base      _Node_base;
00282   typedef _Slist_iterator_base  _Iterator_base;
00283 
00284   _Node* _M_create_node(const value_type& __x) {
00285     _Node* __node = this->_M_get_node();
00286     try {
00287       _Construct(&__node->_M_data, __x);
00288       __node->_M_next = 0;
00289     }
00290     catch(...)
00291       {
00292     this->_M_put_node(__node);
00293     __throw_exception_again;
00294       }
00295     return __node;
00296   }
00297 
00298   _Node* _M_create_node() {
00299     _Node* __node = this->_M_get_node();
00300     try {
00301       _Construct(&__node->_M_data);
00302       __node->_M_next = 0;
00303     }
00304     catch(...)
00305       {
00306     this->_M_put_node(__node);
00307     __throw_exception_again;
00308       }
00309     return __node;
00310   }
00311 
00312 public:
00313   explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {}
00314 
00315   slist(size_type __n, const value_type& __x,
00316         const allocator_type& __a =  allocator_type()) : _Base(__a)
00317     { _M_insert_after_fill(&this->_M_head, __n, __x); }
00318 
00319   explicit slist(size_type __n) : _Base(allocator_type())
00320     { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
00321 
00322   // We don't need any dispatching tricks here, because _M_insert_after_range
00323   // already does them.
00324   template <class _InputIterator>
00325   slist(_InputIterator __first, _InputIterator __last,
00326         const allocator_type& __a =  allocator_type()) : _Base(__a)
00327     { _M_insert_after_range(&this->_M_head, __first, __last); }
00328 
00329   slist(const slist& __x) : _Base(__x.get_allocator())
00330     { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
00331 
00332   slist& operator= (const slist& __x);
00333 
00334   ~slist() {}
00335 
00336 public:
00337   // assign(), a generalized assignment member function.  Two
00338   // versions: one that takes a count, and one that takes a range.
00339   // The range version is a member template, so we dispatch on whether
00340   // or not the type is an integer.
00341 
00342   void assign(size_type __n, const _Tp& __val)
00343     { _M_fill_assign(__n, __val); }
00344 
00345   void _M_fill_assign(size_type __n, const _Tp& __val);
00346 
00347   template <class _InputIterator>
00348   void assign(_InputIterator __first, _InputIterator __last) {
00349     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00350     _M_assign_dispatch(__first, __last, _Integral());
00351   }
00352 
00353   template <class _Integer>
00354   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00355     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00356 
00357   template <class _InputIterator>
00358   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00359                           __false_type);
00360 
00361 public:
00362 
00363   iterator begin() { return iterator((_Node*)this->_M_head._M_next); }
00364   const_iterator begin() const
00365     { return const_iterator((_Node*)this->_M_head._M_next);}
00366 
00367   iterator end() { return iterator(0); }
00368   const_iterator end() const { return const_iterator(0); }
00369 
00370   // Experimental new feature: before_begin() returns a
00371   // non-dereferenceable iterator that, when incremented, yields
00372   // begin().  This iterator may be used as the argument to
00373   // insert_after, erase_after, etc.  Note that even for an empty
00374   // slist, before_begin() is not the same iterator as end().  It
00375   // is always necessary to increment before_begin() at least once to
00376   // obtain end().
00377   iterator before_begin() { return iterator((_Node*) &this->_M_head); }
00378   const_iterator before_begin() const
00379     { return const_iterator((_Node*) &this->_M_head); }
00380 
00381   size_type size() const { return __slist_size(this->_M_head._M_next); }
00382 
00383   size_type max_size() const { return size_type(-1); }
00384 
00385   bool empty() const { return this->_M_head._M_next == 0; }
00386 
00387   void swap(slist& __x)
00388     { std::swap(this->_M_head._M_next, __x._M_head._M_next); }
00389 
00390 public:
00391 
00392   reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; }
00393   const_reference front() const
00394     { return ((_Node*) this->_M_head._M_next)->_M_data; }
00395   void push_front(const value_type& __x)   {
00396     __slist_make_link(&this->_M_head, _M_create_node(__x));
00397   }
00398   void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); }
00399   void pop_front() {
00400     _Node* __node = (_Node*) this->_M_head._M_next;
00401     this->_M_head._M_next = __node->_M_next;
00402     _Destroy(&__node->_M_data);
00403     this->_M_put_node(__node);
00404   }
00405 
00406   iterator previous(const_iterator __pos) {
00407     return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node));
00408   }
00409   const_iterator previous(const_iterator __pos) const {
00410     return const_iterator((_Node*) __slist_previous(&this->_M_head,
00411                                                     __pos._M_node));
00412   }
00413 
00414 private:
00415   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
00416     return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
00417   }
00418 
00419   _Node* _M_insert_after(_Node_base* __pos) {
00420     return (_Node*) (__slist_make_link(__pos, _M_create_node()));
00421   }
00422 
00423   void _M_insert_after_fill(_Node_base* __pos,
00424                             size_type __n, const value_type& __x) {
00425     for (size_type __i = 0; __i < __n; ++__i)
00426       __pos = __slist_make_link(__pos, _M_create_node(__x));
00427   }
00428 
00429   // Check whether it's an integral type.  If so, it's not an iterator.
00430   template <class _InIterator>
00431   void _M_insert_after_range(_Node_base* __pos,
00432                              _InIterator __first, _InIterator __last) {
00433     typedef typename _Is_integer<_InIterator>::_Integral _Integral;
00434     _M_insert_after_range(__pos, __first, __last, _Integral());
00435   }
00436 
00437   template <class _Integer>
00438   void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
00439                              __true_type) {
00440     _M_insert_after_fill(__pos, __n, __x);
00441   }
00442 
00443   template <class _InIterator>
00444   void _M_insert_after_range(_Node_base* __pos,
00445                              _InIterator __first, _InIterator __last,
00446                              __false_type) {
00447     while (__first != __last) {
00448       __pos = __slist_make_link(__pos, _M_create_node(*__first));
00449       ++__first;
00450     }
00451   }
00452 
00453 public:
00454 
00455   iterator insert_after(iterator __pos, const value_type& __x) {
00456     return iterator(_M_insert_after(__pos._M_node, __x));
00457   }
00458 
00459   iterator insert_after(iterator __pos) {
00460     return insert_after(__pos, value_type());
00461   }
00462 
00463   void insert_after(iterator __pos, size_type __n, const value_type& __x) {
00464     _M_insert_after_fill(__pos._M_node, __n, __x);
00465   }
00466 
00467   // We don't need any dispatching tricks here, because _M_insert_after_range
00468   // already does them.
00469   template <class _InIterator>
00470   void insert_after(iterator __pos, _InIterator __first, _InIterator __last) {
00471     _M_insert_after_range(__pos._M_node, __first, __last);
00472   }
00473 
00474   iterator insert(iterator __pos, const value_type& __x) {
00475     return iterator(_M_insert_after(__slist_previous(&this->_M_head,
00476                                                      __pos._M_node),
00477                     __x));
00478   }
00479 
00480   iterator insert(iterator __pos) {
00481     return iterator(_M_insert_after(__slist_previous(&this->_M_head,
00482                                                      __pos._M_node),
00483                                     value_type()));
00484   }
00485 
00486   void insert(iterator __pos, size_type __n, const value_type& __x) {
00487     _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
00488                          __n, __x);
00489   }
00490 
00491   // We don't need any dispatching tricks here, because _M_insert_after_range
00492   // already does them.
00493   template <class _InIterator>
00494   void insert(iterator __pos, _InIterator __first, _InIterator __last) {
00495     _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
00496                           __first, __last);
00497   }
00498 
00499 public:
00500   iterator erase_after(iterator __pos) {
00501     return iterator((_Node*) this->_M_erase_after(__pos._M_node));
00502   }
00503   iterator erase_after(iterator __before_first, iterator __last) {
00504     return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
00505                                                   __last._M_node));
00506   }
00507 
00508   iterator erase(iterator __pos) {
00509     return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head,
00510                                                           __pos._M_node));
00511   }
00512   iterator erase(iterator __first, iterator __last) {
00513     return (_Node*) this->_M_erase_after(
00514       __slist_previous(&this->_M_head, __first._M_node), __last._M_node);
00515   }
00516 
00517   void resize(size_type new_size, const _Tp& __x);
00518   void resize(size_type new_size) { resize(new_size, _Tp()); }
00519   void clear() { this->_M_erase_after(&this->_M_head, 0); }
00520 
00521 public:
00522   // Moves the range [__before_first + 1, __before_last + 1) to *this,
00523   //  inserting it immediately after __pos.  This is constant time.
00524   void splice_after(iterator __pos,
00525                     iterator __before_first, iterator __before_last)
00526   {
00527     if (__before_first != __before_last)
00528       __slist_splice_after(__pos._M_node, __before_first._M_node,
00529                            __before_last._M_node);
00530   }
00531 
00532   // Moves the element that follows __prev to *this, inserting it immediately
00533   //  after __pos.  This is constant time.
00534   void splice_after(iterator __pos, iterator __prev)
00535   {
00536     __slist_splice_after(__pos._M_node,
00537                          __prev._M_node, __prev._M_node->_M_next);
00538   }
00539 
00540 
00541   // Removes all of the elements from the list __x to *this, inserting
00542   // them immediately after __pos.  __x must not be *this.  Complexity:
00543   // linear in __x.size().
00544   void splice_after(iterator __pos, slist& __x)
00545   {
00546     __slist_splice_after(__pos._M_node, &__x._M_head);
00547   }
00548 
00549   // Linear in distance(begin(), __pos), and linear in __x.size().
00550   void splice(iterator __pos, slist& __x) {
00551     if (__x._M_head._M_next)
00552       __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
00553                            &__x._M_head, __slist_previous(&__x._M_head, 0));
00554   }
00555 
00556   // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
00557   void splice(iterator __pos, slist& __x, iterator __i) {
00558     __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
00559                          __slist_previous(&__x._M_head, __i._M_node),
00560                          __i._M_node);
00561   }
00562 
00563   // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
00564   // and in distance(__first, __last).
00565   void splice(iterator __pos, slist& __x, iterator __first, iterator __last)
00566   {
00567     if (__first != __last)
00568       __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
00569                            __slist_previous(&__x._M_head, __first._M_node),
00570                            __slist_previous(__first._M_node, __last._M_node));
00571   }
00572 
00573 public:
00574   void reverse() {
00575     if (this->_M_head._M_next)
00576       this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
00577   }
00578 
00579   void remove(const _Tp& __val);
00580   void unique();
00581   void merge(slist& __x);
00582   void sort();
00583 
00584   template <class _Predicate>
00585   void remove_if(_Predicate __pred);
00586 
00587   template <class _BinaryPredicate>
00588   void unique(_BinaryPredicate __pred);
00589 
00590   template <class _StrictWeakOrdering>
00591   void merge(slist&, _StrictWeakOrdering);
00592 
00593   template <class _StrictWeakOrdering>
00594   void sort(_StrictWeakOrdering __comp);
00595 };
00596 
00597 template <class _Tp, class _Alloc>
00598 slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x)
00599 {
00600   if (&__x != this) {
00601     _Node_base* __p1 = &this->_M_head;
00602     _Node* __n1 = (_Node*) this->_M_head._M_next;
00603     const _Node* __n2 = (const _Node*) __x._M_head._M_next;
00604     while (__n1 && __n2) {
00605       __n1->_M_data = __n2->_M_data;
00606       __p1 = __n1;
00607       __n1 = (_Node*) __n1->_M_next;
00608       __n2 = (const _Node*) __n2->_M_next;
00609     }
00610     if (__n2 == 0)
00611       this->_M_erase_after(__p1, 0);
00612     else
00613       _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
00614                                   const_iterator(0));
00615   }
00616   return *this;
00617 }
00618 
00619 template <class _Tp, class _Alloc>
00620 void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
00621   _Node_base* __prev = &this->_M_head;
00622   _Node* __node = (_Node*) this->_M_head._M_next;
00623   for ( ; __node != 0 && __n > 0 ; --__n) {
00624     __node->_M_data = __val;
00625     __prev = __node;
00626     __node = (_Node*) __node->_M_next;
00627   }
00628   if (__n > 0)
00629     _M_insert_after_fill(__prev, __n, __val);
00630   else
00631     this->_M_erase_after(__prev, 0);
00632 }
00633 
00634 template <class _Tp, class _Alloc> template <class _InputIterator>
00635 void
00636 slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00637                                        __false_type)
00638 {
00639   _Node_base* __prev = &this->_M_head;
00640   _Node* __node = (_Node*) this->_M_head._M_next;
00641   while (__node != 0 && __first != __last) {
00642     __node->_M_data = *__first;
00643     __prev = __node;
00644     __node = (_Node*) __node->_M_next;
00645     ++__first;
00646   }
00647   if (__first != __last)
00648     _M_insert_after_range(__prev, __first, __last);
00649   else
00650     this->_M_erase_after(__prev, 0);
00651 }
00652 
00653 template <class _Tp, class _Alloc>
00654 inline bool
00655 operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
00656 {
00657   typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
00658   const_iterator __end1 = _SL1.end();
00659   const_iterator __end2 = _SL2.end();
00660 
00661   const_iterator __i1 = _SL1.begin();
00662   const_iterator __i2 = _SL2.begin();
00663   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00664     ++__i1;
00665     ++__i2;
00666   }
00667   return __i1 == __end1 && __i2 == __end2;
00668 }
00669 
00670 
00671 template <class _Tp, class _Alloc>
00672 inline bool
00673 operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
00674 {
00675   return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
00676                       _SL2.begin(), _SL2.end());
00677 }
00678 
00679 template <class _Tp, class _Alloc>
00680 inline bool
00681 operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00682   return !(_SL1 == _SL2);
00683 }
00684 
00685 template <class _Tp, class _Alloc>
00686 inline bool
00687 operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00688   return _SL2 < _SL1;
00689 }
00690 
00691 template <class _Tp, class _Alloc>
00692 inline bool
00693 operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00694   return !(_SL2 < _SL1);
00695 }
00696 
00697 template <class _Tp, class _Alloc>
00698 inline bool
00699 operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00700   return !(_SL1 < _SL2);
00701 }
00702 
00703 template <class _Tp, class _Alloc>
00704 inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) {
00705   __x.swap(__y);
00706 }
00707 
00708 
00709 template <class _Tp, class _Alloc>
00710 void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x)
00711 {
00712   _Node_base* __cur = &this->_M_head;
00713   while (__cur->_M_next != 0 && __len > 0) {
00714     --__len;
00715     __cur = __cur->_M_next;
00716   }
00717   if (__cur->_M_next)
00718     this->_M_erase_after(__cur, 0);
00719   else
00720     _M_insert_after_fill(__cur, __len, __x);
00721 }
00722 
00723 template <class _Tp, class _Alloc>
00724 void slist<_Tp,_Alloc>::remove(const _Tp& __val)
00725 {
00726   _Node_base* __cur = &this->_M_head;
00727   while (__cur && __cur->_M_next) {
00728     if (((_Node*) __cur->_M_next)->_M_data == __val)
00729       this->_M_erase_after(__cur);
00730     else
00731       __cur = __cur->_M_next;
00732   }
00733 }
00734 
00735 template <class _Tp, class _Alloc>
00736 void slist<_Tp,_Alloc>::unique()
00737 {
00738   _Node_base* __cur = this->_M_head._M_next;
00739   if (__cur) {
00740     while (__cur->_M_next) {
00741       if (((_Node*)__cur)->_M_data ==
00742           ((_Node*)(__cur->_M_next))->_M_data)
00743         this->_M_erase_after(__cur);
00744       else
00745         __cur = __cur->_M_next;
00746     }
00747   }
00748 }
00749 
00750 template <class _Tp, class _Alloc>
00751 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x)
00752 {
00753   _Node_base* __n1 = &this->_M_head;
00754   while (__n1->_M_next && __x._M_head._M_next) {
00755     if (((_Node*) __x._M_head._M_next)->_M_data <
00756         ((_Node*)       __n1->_M_next)->_M_data)
00757       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
00758     __n1 = __n1->_M_next;
00759   }
00760   if (__x._M_head._M_next) {
00761     __n1->_M_next = __x._M_head._M_next;
00762     __x._M_head._M_next = 0;
00763   }
00764 }
00765 
00766 template <class _Tp, class _Alloc>
00767 void slist<_Tp,_Alloc>::sort()
00768 {
00769   if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
00770     slist __carry;
00771     slist __counter[64];
00772     int __fill = 0;
00773     while (!empty()) {
00774       __slist_splice_after(&__carry._M_head,
00775                            &this->_M_head, this->_M_head._M_next);
00776       int __i = 0;
00777       while (__i < __fill && !__counter[__i].empty()) {
00778         __counter[__i].merge(__carry);
00779         __carry.swap(__counter[__i]);
00780         ++__i;
00781       }
00782       __carry.swap(__counter[__i]);
00783       if (__i == __fill)
00784         ++__fill;
00785     }
00786 
00787     for (int __i = 1; __i < __fill; ++__i)
00788       __counter[__i].merge(__counter[__i-1]);
00789     this->swap(__counter[__fill-1]);
00790   }
00791 }
00792 
00793 template <class _Tp, class _Alloc>
00794 template <class _Predicate>
00795 void slist<_Tp,_Alloc>::remove_if(_Predicate __pred)
00796 {
00797   _Node_base* __cur = &this->_M_head;
00798   while (__cur->_M_next) {
00799     if (__pred(((_Node*) __cur->_M_next)->_M_data))
00800       this->_M_erase_after(__cur);
00801     else
00802       __cur = __cur->_M_next;
00803   }
00804 }
00805 
00806 template <class _Tp, class _Alloc> template <class _BinaryPredicate>
00807 void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred)
00808 {
00809   _Node* __cur = (_Node*) this->_M_head._M_next;
00810   if (__cur) {
00811     while (__cur->_M_next) {
00812       if (__pred(((_Node*)__cur)->_M_data,
00813                  ((_Node*)(__cur->_M_next))->_M_data))
00814         this->_M_erase_after(__cur);
00815       else
00816         __cur = (_Node*) __cur->_M_next;
00817     }
00818   }
00819 }
00820 
00821 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00822 void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x,
00823                               _StrictWeakOrdering __comp)
00824 {
00825   _Node_base* __n1 = &this->_M_head;
00826   while (__n1->_M_next && __x._M_head._M_next) {
00827     if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
00828                ((_Node*)       __n1->_M_next)->_M_data))
00829       __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
00830     __n1 = __n1->_M_next;
00831   }
00832   if (__x._M_head._M_next) {
00833     __n1->_M_next = __x._M_head._M_next;
00834     __x._M_head._M_next = 0;
00835   }
00836 }
00837 
00838 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00839 void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp)
00840 {
00841   if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
00842     slist __carry;
00843     slist __counter[64];
00844     int __fill = 0;
00845     while (!empty()) {
00846       __slist_splice_after(&__carry._M_head,
00847                            &this->_M_head, this->_M_head._M_next);
00848       int __i = 0;
00849       while (__i < __fill && !__counter[__i].empty()) {
00850         __counter[__i].merge(__carry, __comp);
00851         __carry.swap(__counter[__i]);
00852         ++__i;
00853       }
00854       __carry.swap(__counter[__i]);
00855       if (__i == __fill)
00856         ++__fill;
00857     }
00858 
00859     for (int __i = 1; __i < __fill; ++__i)
00860       __counter[__i].merge(__counter[__i-1], __comp);
00861     this->swap(__counter[__fill-1]);
00862   }
00863 }
00864 
00865 } // namespace __gnu_cxx
00866 
00867 namespace std
00868 {
00869 // Specialization of insert_iterator so that insertions will be constant
00870 // time rather than linear time.
00871 
00872 template <class _Tp, class _Alloc>
00873 class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > {
00874 protected:
00875   typedef __gnu_cxx::slist<_Tp, _Alloc> _Container;
00876   _Container* container;
00877   typename _Container::iterator iter;
00878 public:
00879   typedef _Container          container_type;
00880   typedef output_iterator_tag iterator_category;
00881   typedef void                value_type;
00882   typedef void                difference_type;
00883   typedef void                pointer;
00884   typedef void                reference;
00885 
00886   insert_iterator(_Container& __x, typename _Container::iterator __i)
00887     : container(&__x) {
00888     if (__i == __x.begin())
00889       iter = __x.before_begin();
00890     else
00891       iter = __x.previous(__i);
00892   }
00893 
00894   insert_iterator<_Container>&
00895   operator=(const typename _Container::value_type& __value) {
00896     iter = container->insert_after(iter, __value);
00897     return *this;
00898   }
00899   insert_iterator<_Container>& operator*() { return *this; }
00900   insert_iterator<_Container>& operator++() { return *this; }
00901   insert_iterator<_Container>& operator++(int) { return *this; }
00902 };
00903 
00904 } // namespace std
00905 
00906 #endif

Generated on Tue Jan 30 17:31:53 2007 for GNU C++ STL by doxygen 1.3.6