_slist.h

00001 /*
00002  *
00003  * Copyright (c) 1996,1997
00004  * Silicon Graphics Computer Systems, Inc.
00005  *
00006  * Copyright (c) 1997
00007  * Moscow Center for SPARC Technology
00008  *
00009  * Copyright (c) 1999 
00010  * Boris Fomitchev
00011  *
00012  * This material is provided "as is", with absolutely no warranty expressed
00013  * or implied. Any use is at your own risk.
00014  *
00015  * Permission to use or copy this software for any purpose is hereby granted 
00016  * without fee, provided the above notices are retained on all copies.
00017  * Permission to modify the code and to distribute modified code is granted,
00018  * provided the above notices are retained, and a notice that the code was
00019  * modified is included with the above copyright notice.
00020  *
00021  */
00022 
00023 /* NOTE: This is an internal header file, included by other STL headers.
00024  *   You should not attempt to use it directly.
00025  */
00026 
00027 #ifndef _STLP_INTERNAL_SLIST_H
00028 #define _STLP_INTERNAL_SLIST_H
00029 
00030 
00031 # ifndef _STLP_INTERNAL_ALGOBASE_H
00032 #  include <stl/_algobase.h>
00033 # endif
00034 
00035 # ifndef _STLP_INTERNAL_ALLOC_H
00036 #  include <stl/_alloc.h>
00037 # endif
00038 
00039 # ifndef _STLP_INTERNAL_ITERATOR_H
00040 #  include <stl/_iterator.h>
00041 # endif
00042 
00043 # ifndef _STLP_INTERNAL_CONSTRUCT_H
00044 #  include <stl/_construct.h>
00045 # endif
00046 
00047 # ifndef _STLP_INTERNAL_SLIST_BASE_H
00048 #  include <stl/_slist_base.h>
00049 # endif
00050 
00051 # undef slist
00052 # define  slist  __WORKAROUND_DBG_RENAME(slist)
00053 
00054 _STLP_BEGIN_NAMESPACE 
00055 
00056 template <class _Tp>
00057 struct _Slist_node : public _Slist_node_base
00058 {
00059   _Tp _M_data;
00060   __TRIVIAL_STUFF(_Slist_node)
00061 };
00062 
00063 struct _Slist_iterator_base {
00064 
00065   typedef size_t               size_type;
00066   typedef ptrdiff_t            difference_type;
00067   typedef forward_iterator_tag iterator_category;
00068 
00069   _Slist_node_base* _M_node;
00070 
00071   _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {}
00072 
00073   void _M_incr() { 
00074 //    _STLP_VERBOSE_ASSERT(_M_node != 0, _StlMsg_INVALID_ADVANCE)
00075     _M_node = _M_node->_M_next; 
00076   }
00077   bool operator==(const _Slist_iterator_base& __y ) const { 
00078     return _M_node == __y._M_node; 
00079   }
00080   bool operator!=(const _Slist_iterator_base& __y ) const { 
00081     return _M_node != __y._M_node; 
00082   }
00083 };
00084 
00085 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00086 inline ptrdiff_t* _STLP_CALL distance_type(const _Slist_iterator_base&) { return 0; }
00087 inline forward_iterator_tag _STLP_CALL iterator_category(const _Slist_iterator_base&) { return forward_iterator_tag(); }
00088 #endif
00089 
00090 template <class _Tp, class _Traits>
00091 struct _Slist_iterator : public _Slist_iterator_base
00092 {
00093   typedef _Tp value_type;
00094   typedef typename _Traits::pointer    pointer;
00095   typedef typename _Traits::reference  reference;
00096   typedef forward_iterator_tag iterator_category;
00097   typedef size_t size_type;
00098   typedef ptrdiff_t difference_type;
00099   
00100   typedef _Slist_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
00101   typedef _Slist_iterator<_Tp, _Const_traits<_Tp> >    const_iterator;
00102   typedef _Slist_iterator<_Tp, _Traits>                       _Self;
00103 
00104   typedef _Slist_node<value_type> _Node;
00105 
00106   _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {}
00107   _Slist_iterator() : _Slist_iterator_base(0) {}
00108   _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
00109 
00110   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
00111 
00112   _STLP_DEFINE_ARROW_OPERATOR
00113 
00114   _Self& operator++()
00115   {
00116     _M_incr();
00117     return *this;
00118   }
00119   _Self operator++(int)
00120   {
00121     _Self __tmp = *this;
00122     _M_incr();
00123     return __tmp;
00124   }
00125 };
00126 
00127 #ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00128 template <class _Tp, class _Traits>
00129 inline _Tp* _STLP_CALL value_type(const _Slist_iterator<_Tp, _Traits>&) { return (_Tp*)0; }
00130 #endif /* OLD_QUERIES */
00131 
00132 // Base class that encapsulates details of allocators and simplifies EH
00133 
00134 template <class _Tp, class _Alloc> 
00135 struct _Slist_base {
00136   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00137   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00138   typedef _Slist_node<_Tp> _Node;
00139 
00140   _Slist_base(const allocator_type& __a) : 
00141     _M_head(_STLP_CONVERT_ALLOCATOR(__a, _Node), _Slist_node_base() ) { 
00142     _M_head._M_data._M_next = 0; 
00143   }
00144   ~_Slist_base() { _M_erase_after(&_M_head._M_data, 0); }
00145 
00146 protected:
00147   typedef typename _Alloc_traits<_Node,_Alloc>::allocator_type _M_node_allocator_type;
00148 
00149   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
00150   {
00151     _Node* __next = (_Node*) (__pos->_M_next);
00152     _Slist_node_base* __next_next = __next->_M_next;
00153     __pos->_M_next = __next_next;
00154     _Destroy(&__next->_M_data);
00155     _M_head.deallocate(__next,1);
00156     return __next_next;
00157   }
00158   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
00159 
00160 public:
00161   allocator_type get_allocator() const { 
00162     return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_head, _Tp); 
00163   }
00164   _STLP_alloc_proxy<_Slist_node_base, _Node, _M_node_allocator_type> _M_head;
00165 };  
00166 
00167 template <class _Tp, _STLP_DEFAULT_ALLOCATOR_SELECT(_Tp) >
00168 class slist : protected _Slist_base<_Tp,_Alloc>
00169 {
00170 private:
00171   typedef _Slist_base<_Tp,_Alloc> _Base;
00172   typedef slist<_Tp,_Alloc> _Self;
00173 public:
00174   typedef _Tp                value_type;
00175   typedef value_type*       pointer;
00176   typedef const value_type* const_pointer;
00177   typedef value_type&       reference;
00178   typedef const value_type& const_reference;
00179   typedef size_t            size_type;
00180   typedef ptrdiff_t         difference_type;
00181   typedef forward_iterator_tag _Iterator_category;
00182 
00183   typedef _Slist_iterator<_Tp, _Nonconst_traits<_Tp> >  iterator;
00184   typedef _Slist_iterator<_Tp, _Const_traits<_Tp> >     const_iterator;
00185 
00186   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00187   typedef typename _Base::allocator_type allocator_type;
00188 
00189 
00190 private:
00191   typedef _Slist_node<_Tp>      _Node;
00192   typedef _Slist_node_base      _Node_base;
00193   typedef _Slist_iterator_base  _Iterator_base;
00194 
00195   _Node* _M_create_node(const value_type& __x) {
00196     _Node* __node = this->_M_head.allocate(1);
00197     _STLP_TRY {
00198       _Construct(&__node->_M_data, __x);
00199       __node->_M_next = 0;
00200     }
00201     _STLP_UNWIND(this->_M_head.deallocate(__node, 1));
00202     return __node;
00203   }
00204   
00205   _Node* _M_create_node() {
00206     _Node* __node = this->_M_head.allocate(1);
00207     _STLP_TRY {
00208       _Construct(&__node->_M_data);
00209       __node->_M_next = 0;
00210     }
00211     _STLP_UNWIND(this->_M_head.deallocate(__node, 1));
00212     return __node;
00213   }
00214 
00215 public:
00216   allocator_type get_allocator() const { return _Base::get_allocator(); }
00217 
00218   explicit slist(const allocator_type& __a = allocator_type()) : _Slist_base<_Tp,_Alloc>(__a) {}
00219 
00220   slist(size_type __n, const value_type& __x,
00221         const allocator_type& __a =  allocator_type()) : _Slist_base<_Tp,_Alloc>(__a)
00222     { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); }
00223 
00224   explicit slist(size_type __n) : _Slist_base<_Tp,_Alloc>(allocator_type())
00225     { _M_insert_after_fill(&this->_M_head._M_data, __n, value_type()); }
00226 
00227 #ifdef _STLP_MEMBER_TEMPLATES
00228   // We don't need any dispatching tricks here, because _M_insert_after_range
00229   // already does them.
00230   template <class _InputIterator>
00231   slist(_InputIterator __first, _InputIterator __last,
00232         const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) : 
00233     _Slist_base<_Tp,_Alloc>(__a)
00234   { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00235 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
00236   // VC++ needs this crazyness
00237   template <class _InputIterator>
00238   slist(_InputIterator __first, _InputIterator __last) :
00239     _Slist_base<_Tp,_Alloc>(allocator_type())
00240   { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00241 # endif  
00242 #else /* _STLP_MEMBER_TEMPLATES */
00243   slist(const_iterator __first, const_iterator __last,
00244         const allocator_type& __a =  allocator_type() ) :
00245     _Slist_base<_Tp,_Alloc>(__a)
00246     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00247   slist(const value_type* __first, const value_type* __last,
00248         const allocator_type& __a =  allocator_type()) : 
00249     _Slist_base<_Tp,_Alloc>(__a)
00250     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00251 #endif /* _STLP_MEMBER_TEMPLATES */
00252 
00253   slist(const _Self& __x) : _Slist_base<_Tp,_Alloc>(__x.get_allocator())
00254     { _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); }
00255 
00256   _Self& operator= (const _Self& __x);
00257 
00258   ~slist() {}
00259 
00260 public:
00261   // assign(), a generalized assignment member function.  Two
00262   // versions: one that takes a count, and one that takes a range.
00263   // The range version is a member template, so we dispatch on whether
00264   // or not the type is an integer.
00265 
00266   void assign(size_type __n, const _Tp& __val)
00267     { _M_fill_assign(__n, __val); }
00268 
00269   void _M_fill_assign(size_type __n, const _Tp& __val);
00270 
00271 #ifdef _STLP_MEMBER_TEMPLATES
00272 
00273   template <class _InputIterator>
00274   void assign(_InputIterator __first, _InputIterator __last) {
00275     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00276     _M_assign_dispatch(__first, __last, _Integral());
00277   }
00278 
00279   template <class _Integer>
00280   void _M_assign_dispatch(_Integer __n, _Integer __val, const __true_type&)
00281     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00282 
00283   template <class _InputIter>
00284   void
00285   _M_assign_dispatch(_InputIter __first, _InputIter __last,
00286                      const __false_type&) {
00287     _Node_base* __prev = &this->_M_head._M_data;
00288     _Node* __node = (_Node*) this->_M_head._M_data._M_next;
00289     while (__node != 0 && __first != __last) {
00290       __node->_M_data = *__first;
00291       __prev = __node;
00292       __node = (_Node*) __node->_M_next;
00293       ++__first;
00294     }
00295     if (__first != __last)
00296       _M_insert_after_range(__prev, __first, __last);
00297     else
00298       this->_M_erase_after(__prev, 0);
00299   }
00300 #endif /* _STLP_MEMBER_TEMPLATES */
00301 
00302 public:
00303 
00304   // Experimental new feature: before_begin() returns a
00305   // non-dereferenceable iterator that, when incremented, yields
00306   // begin().  This iterator may be used as the argument to
00307   // insert_after, erase_after, etc.  Note that even for an empty 
00308   // slist, before_begin() is not the same iterator as end().  It 
00309   // is always necessary to increment before_begin() at least once to
00310   // obtain end().
00311   iterator before_begin() { return iterator((_Node*) &this->_M_head._M_data); }
00312   const_iterator before_begin() const
00313     { return const_iterator((_Node*) &this->_M_head._M_data); }
00314 
00315   iterator begin() { return iterator((_Node*)this->_M_head._M_data._M_next); }
00316   const_iterator begin() const 
00317     { return const_iterator((_Node*)this->_M_head._M_data._M_next);}
00318 
00319   iterator end() { return iterator(0); }
00320   const_iterator end() const { return const_iterator(0); }
00321 
00322   size_type size() const { return _Sl_global_inst::size(this->_M_head._M_data._M_next); }
00323   
00324   size_type max_size() const { return size_type(-1); }
00325 
00326   bool empty() const { return this->_M_head._M_data._M_next == 0; }
00327 
00328   void swap(_Self& __x) { 
00329     _STLP_STD::swap(this->_M_head._M_data._M_next, __x._M_head._M_data._M_next); 
00330   }
00331 
00332 public:
00333   reference front() { return ((_Node*) this->_M_head._M_data._M_next)->_M_data; }
00334   const_reference front() const 
00335     { return ((_Node*) this->_M_head._M_data._M_next)->_M_data; }
00336   void push_front(const value_type& __x)   {
00337     __slist_make_link(&this->_M_head._M_data, _M_create_node(__x));
00338   }
00339 
00340 # ifndef _STLP_NO_ANACHRONISMS
00341   void push_front() { __slist_make_link(&this->_M_head._M_data, _M_create_node());}
00342 # endif
00343 
00344   void pop_front() {
00345     _Node* __node = (_Node*) this->_M_head._M_data._M_next;
00346     this->_M_head._M_data._M_next = __node->_M_next;
00347     _Destroy(&__node->_M_data);
00348     this->_M_head.deallocate(__node, 1);
00349   }
00350 
00351   iterator previous(const_iterator __pos) {
00352     return iterator((_Node*) _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));
00353   }
00354   const_iterator previous(const_iterator __pos) const {
00355     return const_iterator((_Node*) _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));
00356   }
00357 
00358 private:
00359   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
00360     return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
00361   }
00362 
00363   _Node* _M_insert_after(_Node_base* __pos) {
00364     return (_Node*) (__slist_make_link(__pos, _M_create_node()));
00365   }
00366 
00367   void _M_insert_after_fill(_Node_base* __pos,
00368                             size_type __n, const value_type& __x) {
00369     for (size_type __i = 0; __i < __n; ++__i)
00370       __pos = __slist_make_link(__pos, _M_create_node(__x));
00371   }
00372 
00373 #ifdef _STLP_MEMBER_TEMPLATES
00374 
00375   // Check whether it's an integral type.  If so, it's not an iterator.
00376   template <class _InIter>
00377   void _M_insert_after_range(_Node_base* __pos, 
00378                              _InIter __first, _InIter __last) {
00379     typedef typename _Is_integer<_InIter>::_Integral _Integral;
00380     _M_insert_after_range(__pos, __first, __last, _Integral());
00381   }
00382 
00383   template <class _Integer>
00384   void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
00385                              const __true_type&) {
00386     _M_insert_after_fill(__pos, __n, __x);
00387   }
00388 
00389   template <class _InIter>
00390   void _M_insert_after_range(_Node_base* __pos,
00391                              _InIter __first, _InIter __last,
00392                              const __false_type&) {
00393     while (__first != __last) {
00394       __pos = __slist_make_link(__pos, _M_create_node(*__first));
00395       ++__first;
00396     }
00397   }
00398 
00399 #else /* _STLP_MEMBER_TEMPLATES */
00400 
00401   void _M_insert_after_range(_Node_base* __pos,
00402                              const_iterator __first, const_iterator __last) {
00403     while (__first != __last) {
00404       __pos = __slist_make_link(__pos, _M_create_node(*__first));
00405       ++__first;
00406     }
00407   }
00408   void _M_insert_after_range(_Node_base* __pos,
00409                              const value_type* __first,
00410                              const value_type* __last) {
00411     while (__first != __last) {
00412       __pos = __slist_make_link(__pos, _M_create_node(*__first));
00413       ++__first;
00414     }
00415   }
00416 
00417 #endif /* _STLP_MEMBER_TEMPLATES */
00418 
00419 public:
00420 
00421   iterator insert_after(iterator __pos, const value_type& __x) {
00422     return iterator(_M_insert_after(__pos._M_node, __x));
00423   }
00424 
00425   iterator insert_after(iterator __pos) {
00426     return insert_after(__pos, value_type());
00427   }
00428 
00429   void insert_after(iterator __pos, size_type __n, const value_type& __x) {
00430     _M_insert_after_fill(__pos._M_node, __n, __x);
00431   }
00432 
00433 #ifdef _STLP_MEMBER_TEMPLATES
00434 
00435   // We don't need any dispatching tricks here, because _M_insert_after_range
00436   // already does them.
00437   template <class _InIter>
00438   void insert_after(iterator __pos, _InIter __first, _InIter __last) {
00439     _M_insert_after_range(__pos._M_node, __first, __last);
00440   }
00441 
00442 #else /* _STLP_MEMBER_TEMPLATES */
00443 
00444   void insert_after(iterator __pos,
00445                     const_iterator __first, const_iterator __last) {
00446     _M_insert_after_range(__pos._M_node, __first, __last);
00447   }
00448   void insert_after(iterator __pos,
00449                     const value_type* __first, const value_type* __last) {
00450     _M_insert_after_range(__pos._M_node, __first, __last);
00451   }
00452 
00453 #endif /* _STLP_MEMBER_TEMPLATES */
00454 
00455   iterator insert(iterator __pos, const value_type& __x) {
00456     return iterator(_M_insert_after(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00457                     __x));
00458   }
00459 
00460   iterator insert(iterator __pos) {
00461     return iterator(_M_insert_after(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00462                                     value_type()));
00463   }
00464 
00465   void insert(iterator __pos, size_type __n, const value_type& __x) {
00466     _M_insert_after_fill(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), __n, __x);
00467   } 
00468     
00469 #ifdef _STLP_MEMBER_TEMPLATES
00470 
00471   // We don't need any dispatching tricks here, because _M_insert_after_range
00472   // already does them.
00473   template <class _InIter>
00474   void insert(iterator __pos, _InIter __first, _InIter __last) {
00475     _M_insert_after_range(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), 
00476                           __first, __last);
00477   }
00478 
00479 #else /* _STLP_MEMBER_TEMPLATES */
00480 
00481   void insert(iterator __pos, const_iterator __first, const_iterator __last) {
00482     _M_insert_after_range(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), 
00483                           __first, __last);
00484   }
00485   void insert(iterator __pos, const value_type* __first, 
00486                               const value_type* __last) {
00487     _M_insert_after_range(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), 
00488                           __first, __last);
00489   }
00490 
00491 #endif /* _STLP_MEMBER_TEMPLATES */
00492 
00493 
00494 public:
00495   iterator erase_after(iterator __pos) {
00496     return iterator((_Node*) this->_M_erase_after(__pos._M_node));
00497   }
00498   iterator erase_after(iterator __before_first, iterator __last) {
00499     return iterator((_Node*) this->_M_erase_after(__before_first._M_node, 
00500                                             __last._M_node));
00501   } 
00502 
00503   iterator erase(iterator __pos) {
00504     return iterator((_Node*) this->_M_erase_after(_Sl_global_inst::__previous(&this->_M_head._M_data, 
00505                                                     __pos._M_node)));
00506   }
00507   iterator erase(iterator __first, iterator __last) {
00508     return iterator((_Node*) this->_M_erase_after(
00509       _Sl_global_inst::__previous(&this->_M_head._M_data, __first._M_node), __last._M_node));
00510   }
00511 
00512   void resize(size_type new_size, const _Tp& __x);
00513   void resize(size_type new_size) { resize(new_size, _Tp()); }
00514   void clear() {
00515     this->_M_erase_after(&this->_M_head._M_data, 0); 
00516   }
00517 
00518 public:
00519   // Moves the range [__before_first + 1, __before_last + 1) to *this,
00520   //  inserting it immediately after __pos.  This is constant time.
00521   void splice_after(iterator __pos, 
00522                     iterator __before_first, iterator __before_last)
00523   {
00524     if (__before_first != __before_last) {
00525       _Sl_global_inst::__splice_after(__pos._M_node, __before_first._M_node, 
00526                            __before_last._M_node);
00527     }
00528   }
00529 
00530   // Moves the element that follows __prev to *this, inserting it immediately
00531   //  after __pos.  This is constant time.
00532   void splice_after(iterator __pos, iterator __prev)
00533   {
00534     _Sl_global_inst::__splice_after(__pos._M_node,
00535                          __prev._M_node, __prev._M_node->_M_next);
00536   }
00537 
00538   // Removes all of the elements from the list __x to *this, inserting
00539   // them immediately after __pos.  __x must not be *this.  Complexity:
00540   // linear in __x.size().
00541   void splice_after(iterator __pos, _Self& __x)
00542   {
00543     _Sl_global_inst::__splice_after(__pos._M_node, &__x._M_head._M_data);
00544   }
00545 
00546   // Linear in distance(begin(), __pos), and linear in __x.size().
00547   void splice(iterator __pos, _Self& __x) {
00548     if (__x._M_head._M_data._M_next)
00549       _Sl_global_inst::__splice_after(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00550                            &__x._M_head._M_data, _Sl_global_inst::__previous(&__x._M_head._M_data, 0));
00551   }
00552 
00553   // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
00554   void splice(iterator __pos, _Self& __x, iterator __i) {
00555     _Sl_global_inst::__splice_after(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00556                          _Sl_global_inst::__previous(&__x._M_head._M_data, __i._M_node),
00557                          __i._M_node);
00558   }
00559 
00560   // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
00561   // and in distance(__first, __last).
00562   void splice(iterator __pos, _Self& __x, iterator __first, iterator __last)
00563   {
00564     if (__first != __last)
00565       _Sl_global_inst::__splice_after(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00566                            _Sl_global_inst::__previous(&__x._M_head._M_data, __first._M_node),
00567                            _Sl_global_inst::__previous(__first._M_node, __last._M_node));
00568   }
00569 
00570 public:
00571   void reverse() { 
00572     if (this->_M_head._M_data._M_next)
00573       this->_M_head._M_data._M_next = _Sl_global_inst::__reverse(this->_M_head._M_data._M_next);
00574   }
00575 
00576   void remove(const _Tp& __val); 
00577   void unique(); 
00578   void merge(_Self& __x);
00579   void sort();     
00580 
00581 #ifdef _STLP_MEMBER_TEMPLATES
00582   template <class _Predicate>
00583   void remove_if(_Predicate __pred) {
00584     _Node_base* __cur = &this->_M_head._M_data;
00585     while (__cur->_M_next) {
00586       if (__pred(((_Node*) __cur->_M_next)->_M_data))
00587         this->_M_erase_after(__cur);
00588       else
00589         __cur = __cur->_M_next;
00590     }
00591   }
00592 
00593   template <class _BinaryPredicate> 
00594   void unique(_BinaryPredicate __pred) {
00595     _Node* __cur = (_Node*) this->_M_head._M_data._M_next;
00596     if (__cur) {
00597       while (__cur->_M_next) {
00598         if (__pred(((_Node*)__cur)->_M_data, 
00599                    ((_Node*)(__cur->_M_next))->_M_data))
00600           this->_M_erase_after(__cur);
00601         else
00602           __cur = (_Node*) __cur->_M_next;
00603       }
00604     }
00605   }
00606 
00607   template <class _StrictWeakOrdering>
00608   void merge(slist<_Tp,_Alloc>& __x,
00609              _StrictWeakOrdering __comp) {
00610     _Node_base* __n1 = &this->_M_head._M_data;
00611     while (__n1->_M_next && __x._M_head._M_data._M_next) {
00612       if (__comp(((_Node*) __x._M_head._M_data._M_next)->_M_data,
00613                  ((_Node*)       __n1->_M_next)->_M_data))
00614         _Sl_global_inst::__splice_after(__n1, &__x._M_head._M_data, __x._M_head._M_data._M_next);
00615       __n1 = __n1->_M_next;
00616     }
00617     if (__x._M_head._M_data._M_next) {
00618       __n1->_M_next = __x._M_head._M_data._M_next;
00619       __x._M_head._M_data._M_next = 0;
00620     }
00621   }
00622 
00623   template <class _StrictWeakOrdering> 
00624   void sort(_StrictWeakOrdering __comp) {
00625     if (this->_M_head._M_data._M_next && this->_M_head._M_data._M_next->_M_next) {
00626       slist __carry;
00627       slist __counter[64];
00628       int __fill = 0;
00629       while (!empty()) {
00630         _Sl_global_inst::__splice_after(&__carry._M_head._M_data, &this->_M_head._M_data, this->_M_head._M_data._M_next);
00631         int __i = 0;
00632         while (__i < __fill && !__counter[__i].empty()) {
00633           __counter[__i].merge(__carry, __comp);
00634           __carry.swap(__counter[__i]);
00635           ++__i;
00636         }
00637         __carry.swap(__counter[__i]);
00638         if (__i == __fill)
00639           ++__fill;
00640       }
00641       
00642       for (int __i = 1; __i < __fill; ++__i)
00643         __counter[__i].merge(__counter[__i-1], __comp);
00644       this->swap(__counter[__fill-1]);
00645     }
00646   }
00647 #endif /* _STLP_MEMBER_TEMPLATES */
00648 
00649 };
00650 
00651 template <class _Tp, class _Alloc>
00652 inline bool  _STLP_CALL
00653 operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
00654 {
00655   typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
00656   const_iterator __end1 = _SL1.end();
00657   const_iterator __end2 = _SL2.end();
00658 
00659   const_iterator __i1 = _SL1.begin();
00660   const_iterator __i2 = _SL2.begin();
00661   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00662     ++__i1;
00663     ++__i2;
00664    }
00665   return __i1 == __end1 && __i2 == __end2;
00666 }
00667 
00668 template <class _Tp, class _Alloc>
00669 inline bool _STLP_CALL operator<(const slist<_Tp,_Alloc>& _SL1,
00670                                  const slist<_Tp,_Alloc>& _SL2)
00671 {
00672   return lexicographical_compare(_SL1.begin(), _SL1.end(), 
00673                                  _SL2.begin(), _SL2.end());
00674 }
00675 
00676 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00677 
00678 template <class _Tp, class _Alloc>
00679 inline bool _STLP_CALL 
00680 operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00681   return !(_SL1 == _SL2);
00682 }
00683 
00684 template <class _Tp, class _Alloc>
00685 inline bool _STLP_CALL 
00686 operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00687   return _SL2 < _SL1;
00688 }
00689 
00690 template <class _Tp, class _Alloc>
00691 inline bool _STLP_CALL 
00692 operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00693   return !(_SL2 < _SL1);
00694 }
00695 
00696 template <class _Tp, class _Alloc>
00697 inline bool _STLP_CALL 
00698 operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00699   return !(_SL1 < _SL2);
00700 }
00701 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
00702 
00703 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
00704 
00705 template <class _Tp, class _Alloc>
00706 inline void _STLP_CALL swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) {
00707   __x.swap(__y);
00708 }
00709 
00710 #endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */
00711 
00712 _STLP_END_NAMESPACE
00713 
00714 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00715 #  include <stl/_slist.c>
00716 # endif
00717 
00718 #  undef  slist
00719 #  define __slist__ __FULL_NAME(slist)
00720 
00721 #if defined (_STLP_DEBUG) && !defined (_STLP_INTERNAL_DBG_SLIST_H)
00722 # include <stl/debug/_slist.h>
00723 #endif
00724 
00725 _STLP_BEGIN_NAMESPACE
00726 // Specialization of insert_iterator so that insertions will be constant
00727 // time rather than linear time.
00728 
00729 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00730 
00731 template <class _Tp, class _Alloc>
00732 class insert_iterator<slist<_Tp, _Alloc> > {
00733 protected:
00734   typedef slist<_Tp, _Alloc> _Container;
00735   _Container* container;
00736   typename _Container::iterator iter;
00737 public:
00738   typedef _Container          container_type;
00739   typedef output_iterator_tag iterator_category;
00740   typedef void                value_type;
00741   typedef void                difference_type;
00742   typedef void                pointer;
00743   typedef void                reference;
00744 
00745   insert_iterator(_Container& __x, typename _Container::iterator __i) 
00746     : container(&__x) {
00747     if (__i == __x.begin())
00748       iter = __x.before_begin();
00749     else
00750       iter = __x.previous(__i);
00751   }
00752 
00753   insert_iterator<_Container>&
00754   operator=(const typename _Container::value_type& __value) { 
00755     iter = container->insert_after(iter, __value);
00756     return *this;
00757   }
00758   insert_iterator<_Container>& operator*() { return *this; }
00759   insert_iterator<_Container>& operator++() { return *this; }
00760   insert_iterator<_Container>& operator++(int) { return *this; }
00761 };
00762 
00763 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00764 
00765 _STLP_END_NAMESPACE
00766 
00767 
00768 # if defined ( _STLP_USE_WRAPPER_FOR_ALLOC_PARAM )
00769 # include <stl/wrappers/_slist.h>
00770 # endif
00771 
00772 #endif /* _STLP_INTERNAL_SLIST_H */
00773 
00774 // Local Variables:
00775 // mode:C++
00776 // End:
00777 

Generated on Mon Jun 5 10:20:47 2006 for Intelligence.kdevelop by  doxygen 1.4.6