/home/ntakagi/work/STLport-5.1.5/stlport/stl/_slist.h

Go to the documentation of this file.
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 #ifndef _STLP_INTERNAL_ALGOBASE_H
00031 #  include <stl/_algobase.h>
00032 #endif
00033 
00034 #ifndef _STLP_INTERNAL_ALLOC_H
00035 #  include <stl/_alloc.h>
00036 #endif
00037 
00038 #ifndef _STLP_INTERNAL_ITERATOR_H
00039 #  include <stl/_iterator.h>
00040 #endif
00041 
00042 #ifndef _STLP_INTERNAL_CONSTRUCT_H
00043 #  include <stl/_construct.h>
00044 #endif
00045 
00046 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
00047 #  include <stl/_function_base.h>
00048 #endif
00049 
00050 #ifndef _STLP_INTERNAL_SLIST_BASE_H
00051 #  include <stl/_slist_base.h>
00052 #endif
00053 
00054 _STLP_BEGIN_NAMESPACE
00055 
00056 _STLP_MOVE_TO_PRIV_NAMESPACE
00057 
00058 template <class _Tp>
00059 class _Slist_node : public _Slist_node_base {
00060 public:
00061   _Tp _M_data;
00062   __TRIVIAL_STUFF(_Slist_node)
00063 };
00064 
00065 struct _Slist_iterator_base {
00066   typedef size_t               size_type;
00067   typedef ptrdiff_t            difference_type;
00068   typedef forward_iterator_tag iterator_category;
00069 
00070   _Slist_node_base *_M_node;
00071 
00072   _Slist_iterator_base(_Slist_node_base *__x) : _M_node(__x) {}
00073 
00074   void _M_incr() {
00075     _M_node = _M_node->_M_next;
00076   }
00077 };
00078 
00079 template <class _Tp, class _Traits>
00080 class _Slist_iterator : public _Slist_iterator_base {
00081 public:
00082   typedef typename _Traits::value_type value_type;
00083   typedef typename _Traits::pointer    pointer;
00084   typedef typename _Traits::reference  reference;
00085   typedef forward_iterator_tag iterator_category;
00086   typedef size_t size_type;
00087   typedef ptrdiff_t difference_type;
00088 
00089   typedef _Slist_iterator<_Tp, _Traits>         _Self;
00090   typedef typename _Traits::_NonConstTraits     _NonConstTraits;
00091   typedef _Slist_iterator<_Tp, _NonConstTraits> iterator;
00092   typedef typename _Traits::_ConstTraits        _ConstTraits;
00093   typedef _Slist_iterator<_Tp, _ConstTraits>    const_iterator;
00094 
00095   typedef _Slist_node<value_type> _Node;
00096 
00097   explicit _Slist_iterator(_Slist_node_base *__x) : _Slist_iterator_base(__x) {}
00098   _Slist_iterator() : _Slist_iterator_base(0) {}
00099   //copy constructor for iterator and constructor from iterator for const_iterator
00100   _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {}
00101 
00102   reference operator*() const { return __STATIC_CAST(_Node*, this->_M_node)->_M_data; }
00103 
00104   _STLP_DEFINE_ARROW_OPERATOR
00105 
00106   _Self& operator++() {
00107     _M_incr();
00108     return *this;
00109   }
00110   _Self operator++(int) {
00111     _Self __tmp = *this;
00112     _M_incr();
00113     return __tmp;
00114   }
00115 
00116   bool operator==(const_iterator __y ) const {
00117     return this->_M_node == __y._M_node;
00118   }
00119   bool operator!=(const_iterator __y ) const {
00120     return this->_M_node != __y._M_node;
00121   }
00122 };
00123 
00124 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00125 _STLP_MOVE_TO_STD_NAMESPACE
00126 template <class _Tp, class _Traits>
00127 struct __type_traits<_STLP_PRIV _Slist_iterator<_Tp, _Traits> > {
00128   typedef __false_type   has_trivial_default_constructor;
00129   typedef __true_type    has_trivial_copy_constructor;
00130   typedef __true_type    has_trivial_assignment_operator;
00131   typedef __true_type    has_trivial_destructor;
00132   typedef __false_type   is_POD_type;
00133 };
00134 _STLP_MOVE_TO_PRIV_NAMESPACE
00135 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00136 
00137 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
00138 _STLP_MOVE_TO_STD_NAMESPACE
00139 template <class _Tp, class _Traits>
00140 inline _Tp* _STLP_CALL value_type(const _STLP_PRIV _Slist_iterator<_Tp, _Traits>&) { return __STATIC_CAST(_Tp*, 0); }
00141 inline ptrdiff_t* _STLP_CALL distance_type(const _STLP_PRIV _Slist_iterator_base&) { return 0; }
00142 inline forward_iterator_tag _STLP_CALL iterator_category(const _STLP_PRIV _Slist_iterator_base&) { return forward_iterator_tag(); }
00143 _STLP_MOVE_TO_PRIV_NAMESPACE
00144 #endif /* OLD_QUERIES */
00145 
00146 // Base class that encapsulates details of allocators and simplifies EH
00147 template <class _Tp, class _Alloc>
00148 class _Slist_base {
00149 protected:
00150   typedef _Slist_node<_Tp> _Node;
00151   typedef typename _Alloc_traits<_Node,_Alloc>::allocator_type _M_node_allocator_type;
00152   typedef _Slist_base<_Tp, _Alloc> _Self;
00153 
00154 public:
00155   typedef _STLP_alloc_proxy<_Slist_node_base, _Node, _M_node_allocator_type> _AllocProxy;
00156 
00157   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00158   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00159 
00160   _Slist_base(const allocator_type& __a) :
00161     _M_head(_STLP_CONVERT_ALLOCATOR(__a, _Node), _Slist_node_base() ) {
00162     _M_head._M_data._M_next = 0;
00163   }
00164   _Slist_base(__move_source<_Self> src) :
00165     _M_head(__move_source<_AllocProxy>(src.get()._M_head)) {
00166       src.get()._M_head._M_data._M_next = 0;
00167   }
00168   ~_Slist_base() { _M_erase_after(&_M_head._M_data, 0); }
00169 
00170 protected:
00171   _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) {
00172     _Node* __next = __STATIC_CAST(_Node*, __pos->_M_next);
00173     _Slist_node_base* __next_next = __next->_M_next;
00174     __pos->_M_next = __next_next;
00175     _STLP_STD::_Destroy(&__next->_M_data);
00176     _M_head.deallocate(__next,1);
00177     return __next_next;
00178   }
00179   _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
00180 
00181 public:
00182   allocator_type get_allocator() const
00183   { return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_head, _Tp); }
00184   _AllocProxy _M_head;
00185 };
00186 
00187 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00188 #  define slist _STLP_PTR_IMPL_NAME(slist)
00189 #elif defined (_STLP_DEBUG)
00190 #  define slist _STLP_NON_DBG_NAME(slist)
00191 #else
00192 _STLP_MOVE_TO_STD_NAMESPACE
00193 #endif
00194 
00195 template <class _Tp, _STLP_DEFAULT_ALLOCATOR_SELECT(_Tp) >
00196 class slist;
00197 
00198 #if !defined (slist)
00199 _STLP_MOVE_TO_PRIV_NAMESPACE
00200 #endif
00201 
00202 // helper functions to reduce code duplication
00203 template <class _Tp, class _Alloc, class _BinaryPredicate>
00204 void _Slist_unique(slist<_Tp, _Alloc>& __that, _BinaryPredicate __binary_pred);
00205 
00206 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00207 void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x,
00208                   _StrictWeakOrdering __comp);
00209 
00210 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00211 void _Slist_sort(slist<_Tp, _Alloc>& __that, _StrictWeakOrdering __comp);
00212 
00213 #if !defined (slist)
00214 _STLP_MOVE_TO_STD_NAMESPACE
00215 #endif
00216 
00217 template <class _Tp, class _Alloc>
00218 class slist : protected _STLP_PRIV _Slist_base<_Tp,_Alloc>
00219 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (slist)
00220             , public __stlport_class<slist<_Tp, _Alloc> >
00221 #endif
00222 {
00223 private:
00224   typedef _STLP_PRIV _Slist_base<_Tp,_Alloc> _Base;
00225   typedef slist<_Tp,_Alloc> _Self;
00226 public:
00227   typedef _Tp                value_type;
00228 
00229   typedef value_type*       pointer;
00230   typedef const value_type* const_pointer;
00231   typedef value_type&       reference;
00232   typedef const value_type& const_reference;
00233   typedef size_t            size_type;
00234   typedef ptrdiff_t         difference_type;
00235   typedef forward_iterator_tag _Iterator_category;
00236 
00237   typedef _STLP_PRIV _Slist_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
00238   typedef _STLP_PRIV _Slist_iterator<_Tp, _Const_traits<_Tp> >    const_iterator;
00239 
00240   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00241   typedef typename _Base::allocator_type allocator_type;
00242 
00243 private:
00244   typedef _STLP_PRIV _Slist_node<_Tp> _Node;
00245   typedef _STLP_PRIV _Slist_node_base _Node_base;
00246 
00247 #if !defined(_STLP_DONT_SUP_DFLT_PARAM)
00248   _Node* _M_create_node(const value_type& __x = _Tp()) {
00249 #else
00250   _Node* _M_create_node(const value_type& __x) {
00251 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00252     _Node* __node = this->_M_head.allocate(1);
00253     _STLP_TRY {
00254       _Copy_Construct(&__node->_M_data, __x);
00255       __node->_M_next = 0;
00256     }
00257     _STLP_UNWIND(this->_M_head.deallocate(__node, 1))
00258     return __node;
00259   }
00260 
00261 #if defined(_STLP_DONT_SUP_DFLT_PARAM)
00262   _Node* _M_create_node() {
00263     _Node* __node = this->_M_head.allocate(1);
00264     _STLP_TRY {
00265       _STLP_STD::_Construct(&__node->_M_data);
00266       __node->_M_next = 0;
00267     }
00268     _STLP_UNWIND(this->_M_head.deallocate(__node, 1))
00269     return __node;
00270   }
00271 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00272 
00273 public:
00274 
00275   allocator_type get_allocator() const { return _Base::get_allocator(); }
00276 
00277 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00278   explicit slist(const allocator_type& __a = allocator_type())
00279 #else
00280   slist()
00281     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type()) {}
00282   slist(const allocator_type& __a)
00283 #endif
00284     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) {}
00285 
00286 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00287   explicit slist(size_type __n, const value_type& __x = _STLP_DEFAULT_CONSTRUCTED(_Tp),
00288                  const allocator_type& __a =  allocator_type())
00289 #else
00290   explicit slist(size_type __n)
00291     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type())
00292     { _M_insert_after_fill(&this->_M_head._M_data, __n, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
00293   slist(size_type __n, const value_type& __x)
00294     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type())
00295     { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); }
00296   slist(size_type __n, const value_type& __x, const allocator_type& __a)
00297 #endif
00298     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a)
00299     { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); }
00300 
00301 #if defined (_STLP_MEMBER_TEMPLATES)
00302   // We don't need any dispatching tricks here, because _M_insert_after_range
00303   // already does them.
00304   template <class _InputIterator>
00305   slist(_InputIterator __first, _InputIterator __last,
00306         const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
00307     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a)
00308     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00309 #  if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS)
00310   // VC++ needs this crazyness
00311   template <class _InputIterator>
00312   slist(_InputIterator __first, _InputIterator __last)
00313     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type())
00314     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00315 # endif
00316 #else /* _STLP_MEMBER_TEMPLATES */
00317   slist(const_iterator __first, const_iterator __last,
00318         const allocator_type& __a =  allocator_type() )
00319     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a)
00320     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00321   slist(const value_type* __first, const value_type* __last,
00322         const allocator_type& __a =  allocator_type())
00323     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a)
00324     { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
00325 #endif /* _STLP_MEMBER_TEMPLATES */
00326 
00327   slist(const _Self& __x)
00328     : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__x.get_allocator())
00329     { _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); }
00330 
00331   slist(__move_source<_Self> src)
00332     : _STLP_PRIV _Slist_base<_Tp, _Alloc>(__move_source<_Base>(src.get())) {}
00333 
00334   _Self& operator= (const _Self& __x);
00335 
00336   ~slist() {}
00337 
00338 public:
00339   // assign(), a generalized assignment member function.  Two
00340   // versions: one that takes a count, and one that takes a range.
00341   // The range version is a member template, so we dispatch on whether
00342   // or not the type is an integer.
00343 
00344   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00345 
00346 private:
00347   void _M_fill_assign(size_type __n, const _Tp& __val);
00348 
00349 #if defined (_STLP_MEMBER_TEMPLATES)
00350 public:
00351   template <class _InputIterator>
00352   void assign(_InputIterator __first, _InputIterator __last) {
00353     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
00354     _M_assign_dispatch(__first, __last, _Integral());
00355   }
00356 
00357 private:
00358   template <class _Integer>
00359   void _M_assign_dispatch(_Integer __n, _Integer __val,
00360                           const __true_type& /*_IsIntegral*/) {
00361     _M_fill_assign((size_type) __n, (_Tp) __val);
00362   }
00363 
00364   template <class _InputIter>
00365   void _M_assign_dispatch(_InputIter __first, _InputIter __last,
00366                           const __false_type& /*_IsIntegral*/) {
00367 #else
00368 public:
00369   void assign(const_pointer __first, const_pointer __last) {
00370     _Node_base* __prev = &this->_M_head._M_data;
00371     _Node_base* __node = this->_M_head._M_data._M_next;
00372     while (__node != 0 && __first != __last) {
00373       __STATIC_CAST(_Node*, __node)->_M_data = *__first;
00374       __prev = __node;
00375       __node = __node->_M_next;
00376       ++__first;
00377     }
00378     if (__first != __last)
00379       _M_insert_after_range(__prev, __first, __last);
00380     else
00381       this->_M_erase_after(__prev, 0);
00382   }
00383   void assign(const_iterator __first, const_iterator __last) {
00384 #endif /* _STLP_MEMBER_TEMPLATES */
00385     _Node_base* __prev = &this->_M_head._M_data;
00386     _Node_base* __node = this->_M_head._M_data._M_next;
00387     while (__node != 0 && __first != __last) {
00388       __STATIC_CAST(_Node*, __node)->_M_data = *__first;
00389       __prev = __node;
00390       __node = __node->_M_next;
00391       ++__first;
00392     }
00393     if (__first != __last)
00394       _M_insert_after_range(__prev, __first, __last);
00395     else
00396       this->_M_erase_after(__prev, 0);
00397   }
00398 
00399 public:
00400 
00401   // Experimental new feature: before_begin() returns a
00402   // non-dereferenceable iterator that, when incremented, yields
00403   // begin().  This iterator may be used as the argument to
00404   // insert_after, erase_after, etc.  Note that even for an empty
00405   // slist, before_begin() is not the same iterator as end().  It
00406   // is always necessary to increment before_begin() at least once to
00407   // obtain end().
00408   iterator before_begin() { return iterator(&this->_M_head._M_data); }
00409   const_iterator before_begin() const
00410     { return const_iterator(__CONST_CAST(_Node_base*, &this->_M_head._M_data)); }
00411 
00412   iterator begin() { return iterator(this->_M_head._M_data._M_next); }
00413   const_iterator begin() const
00414     { return const_iterator(this->_M_head._M_data._M_next);}
00415 
00416   iterator end() { return iterator(); }
00417   const_iterator end() const { return const_iterator(); }
00418 
00419   size_type size() const
00420   { return _STLP_PRIV _Sl_global_inst::size(this->_M_head._M_data._M_next); }
00421 
00422   size_type max_size() const { return size_type(-1); }
00423 
00424   bool empty() const { return this->_M_head._M_data._M_next == 0; }
00425 
00426   void swap(_Self& __x) {
00427     this->_M_head.swap(__x._M_head);
00428   }
00429 
00430 public:
00431   reference front()             { return *begin(); }
00432   const_reference front() const { return *begin(); }
00433 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS)
00434   void push_front(const value_type& __x = _Tp())   {
00435 #else
00436   void push_front(const value_type& __x)   {
00437 #endif 
00438     _STLP_PRIV __slist_make_link(&this->_M_head._M_data, _M_create_node(__x));
00439   }
00440 
00441 #if defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS)
00442   void push_front() { _STLP_PRIV __slist_make_link(&this->_M_head._M_data, _M_create_node());}
00443 #endif /*_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/
00444 
00445   void pop_front() {
00446     _Node* __node = __STATIC_CAST(_Node*, this->_M_head._M_data._M_next);
00447     this->_M_head._M_data._M_next = __node->_M_next;
00448     _STLP_STD::_Destroy(&__node->_M_data);
00449     this->_M_head.deallocate(__node, 1);
00450   }
00451 
00452   iterator previous(const_iterator __pos) {
00453     return iterator(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));
00454   }
00455   const_iterator previous(const_iterator __pos) const {
00456     return const_iterator(__CONST_CAST(_Node_base*,
00457                                        _STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data,
00458                                                                                __pos._M_node)));
00459   }
00460 
00461 private:
00462 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00463   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x = _Tp()) {
00464 #else
00465   _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
00466 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00467     return __STATIC_CAST(_Node*, _STLP_PRIV __slist_make_link(__pos, _M_create_node(__x)));
00468   }
00469 
00470 #if defined (_STLP_DONT_SUP_DFLT_PARAM)
00471   _Node* _M_insert_after(_Node_base* __pos) {
00472     return __STATIC_CAST(_Node*, _STLP_PRIV __slist_make_link(__pos, _M_create_node()));
00473   }
00474 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00475 
00476   void _M_insert_after_fill(_Node_base* __pos,
00477                             size_type __n, const value_type& __x) {
00478     for (size_type __i = 0; __i < __n; ++__i)
00479       __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(__x));
00480   }
00481 
00482 #if defined (_STLP_MEMBER_TEMPLATES)
00483   // Check whether it's an integral type.  If so, it's not an iterator.
00484   template <class _InIter>
00485   void _M_insert_after_range(_Node_base* __pos,
00486                              _InIter __first, _InIter __last) {
00487     typedef typename _IsIntegral<_InIter>::_Ret _Integral;
00488     _M_insert_after_range(__pos, __first, __last, _Integral());
00489   }
00490 
00491   template <class _Integer>
00492   void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
00493                              const __true_type&) {
00494     _M_insert_after_fill(__pos, __n, __x);
00495   }
00496 
00497   template <class _InIter>
00498   void _M_insert_after_range(_Node_base* __pos,
00499                              _InIter __first, _InIter __last,
00500                              const __false_type&) {
00501 #else /* _STLP_MEMBER_TEMPLATES */
00502   void _M_insert_after_range(_Node_base* __pos,
00503                              const value_type* __first,
00504                              const value_type* __last) {
00505     while (__first != __last) {
00506       __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first));
00507       ++__first;
00508     }
00509   }
00510   void _M_insert_after_range(_Node_base* __pos,
00511                              const_iterator __first, const_iterator __last) {
00512 #endif /* _STLP_MEMBER_TEMPLATES */
00513     while (__first != __last) {
00514       __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first));
00515       ++__first;
00516     }
00517   }
00518 
00519 #if defined (_STLP_MEMBER_TEMPLATES)
00520   // Check whether it's an integral type.  If so, it's not an iterator.
00521   template <class _InIter>
00522   void _M_splice_after_range(_Node_base* __pos,
00523                              _InIter __first, _InIter __last) {
00524     typedef typename _IsIntegral<_InIter>::_Ret _Integral;
00525     _M_splice_after_range(__pos, __first, __last, _Integral());
00526   }
00527 
00528   template <class _Integer>
00529   void _M_splice_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
00530                              const __true_type&) {
00531     _M_insert_after_fill(__pos, __n, __x);
00532   }
00533 
00534   template <class _InIter>
00535   void _M_splice_after_range(_Node_base* __pos,
00536                              _InIter __first, _InIter __last,
00537                              const __false_type&) {
00538 #else /* _STLP_MEMBER_TEMPLATES */
00539   void _M_splice_after_range(_Node_base* __pos,
00540                              const value_type* __first,
00541                              const value_type* __last) {
00542     while (__first != __last) {
00543       __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first));
00544       ++__first;
00545     }
00546   }
00547   void _M_splice_after_range(_Node_base* __pos,
00548                              const_iterator __first, const_iterator __last) {
00549 #endif /* _STLP_MEMBER_TEMPLATES */
00550     //We use a temporary slist to avoid the auto reference troubles (infinite loop)
00551     _Self __tmp(__first, __last, this->get_allocator());
00552     splice_after(iterator(__pos), __tmp);
00553   }
00554 
00555 #if defined (_STLP_MEMBER_TEMPLATES)
00556   // Check whether it's an integral type.  If so, it's not an iterator.
00557   template <class _InIter>
00558   void _M_splice_range(_Node_base* __pos,
00559                        _InIter __first, _InIter __last) {
00560     typedef typename _IsIntegral<_InIter>::_Ret _Integral;
00561     _M_splice_range(__pos, __first, __last, _Integral());
00562   }
00563 
00564   template <class _Integer>
00565   void _M_splice_range(_Node_base* __pos, _Integer __n, _Integer __x,
00566                        const __true_type&) {
00567     _M_insert_after_fill(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos),
00568                          __n, __x);
00569   }
00570 
00571   template <class _InIter>
00572   void _M_splice_range(_Node_base* __pos,
00573                        _InIter __first, _InIter __last,
00574                        const __false_type&) {
00575 #else /* _STLP_MEMBER_TEMPLATES */
00576   void _M_splice_range(_Node_base* __pos,
00577                        const value_type* __first,
00578                        const value_type* __last) {
00579     while (__first != __last) {
00580       __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first));
00581       ++__first;
00582     }
00583   }
00584   void _M_splice_range(_Node_base* __pos,
00585                        const_iterator __first, const_iterator __last) {
00586 #endif /* _STLP_MEMBER_TEMPLATES */
00587     //We use a temporary slist to avoid the auto reference troubles (infinite loop)
00588     _Self __tmp(__first, __last, this->get_allocator());
00589     splice(iterator(__pos), __tmp);
00590   }
00591 
00592 public:
00593 
00594 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00595   iterator insert_after(iterator __pos, const value_type& __x = _Tp()) {
00596 #else
00597   iterator insert_after(iterator __pos, const value_type& __x) {
00598 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00599     return iterator(_M_insert_after(__pos._M_node, __x));
00600   }
00601 
00602 #if defined (_STLP_DONT_SUP_DFLT_PARAM)
00603   iterator insert_after(iterator __pos) {
00604     return insert_after(__pos, _STLP_DEFAULT_CONSTRUCTED(_Tp));
00605   }
00606 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00607 
00608   void insert_after(iterator __pos, size_type __n, const value_type& __x) {
00609     _M_insert_after_fill(__pos._M_node, __n, __x);
00610   }
00611 
00612 #if defined (_STLP_MEMBER_TEMPLATES)
00613   // We don't need any dispatching tricks here, because _M_insert_after_range
00614   // already does them.
00615   template <class _InIter>
00616   void insert_after(iterator __pos, _InIter __first, _InIter __last) {
00617 #else /* _STLP_MEMBER_TEMPLATES */
00618   void insert_after(iterator __pos,
00619                     const value_type* __first, const value_type* __last) {
00620     _M_insert_after_range(__pos._M_node, __first, __last);
00621   }
00622   void insert_after(iterator __pos,
00623                     const_iterator __first, const_iterator __last) {
00624 #endif /* _STLP_MEMBER_TEMPLATES */
00625     _M_splice_after_range(__pos._M_node, __first, __last);
00626   }
00627 
00628 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00629   iterator insert(iterator __pos, const value_type& __x = _Tp()) {
00630 #else
00631   iterator insert(iterator __pos, const value_type& __x) {
00632 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00633     return iterator(_M_insert_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00634                     __x));
00635   }
00636 
00637 #if defined (_STLP_DONT_SUP_DFLT_PARAM)
00638   iterator insert(iterator __pos) {
00639     return iterator(_M_insert_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00640                                     _STLP_DEFAULT_CONSTRUCTED(_Tp)));
00641   }
00642 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00643 
00644   void insert(iterator __pos, size_type __n, const value_type& __x) {
00645     _M_insert_after_fill(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), __n, __x);
00646   }
00647 
00648 #if defined (_STLP_MEMBER_TEMPLATES)
00649   // We don't need any dispatching tricks here, because _M_insert_after_range
00650   // already does them.
00651   template <class _InIter>
00652   void insert(iterator __pos, _InIter __first, _InIter __last) {
00653 #else /* _STLP_MEMBER_TEMPLATES */
00654   void insert(iterator __pos, const value_type* __first,
00655                               const value_type* __last) {
00656     _M_insert_after_range(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00657                           __first, __last);
00658   }
00659   void insert(iterator __pos, const_iterator __first, const_iterator __last) {
00660 #endif /* _STLP_MEMBER_TEMPLATES */
00661     _M_splice_range(__pos._M_node, __first, __last);
00662   }
00663 
00664 public:
00665   iterator erase_after(iterator __pos)
00666   { return iterator(this->_M_erase_after(__pos._M_node)); }
00667   iterator erase_after(iterator __before_first, iterator __last)
00668   { return iterator(this->_M_erase_after(__before_first._M_node, __last._M_node)); }
00669 
00670   iterator erase(iterator __pos)
00671   { return iterator(this->_M_erase_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node))); }
00672   iterator erase(iterator __first, iterator __last)
00673   { return iterator(this->_M_erase_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __first._M_node), __last._M_node)); }
00674 
00675 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00676   void resize(size_type new_size, const value_type& __x = _Tp());
00677 #else
00678   void resize(size_type new_size, const value_type& __x);
00679 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00680 
00681 #if defined (_STLP_DONT_SUP_DFLT_PARAM)
00682   void resize(size_type new_size) { resize(new_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
00683 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
00684 
00685   void clear()
00686   { this->_M_erase_after(&this->_M_head._M_data, 0); }
00687 
00688 public:
00689   // Moves the range [__before_first + 1, __before_last + 1) to *this,
00690   //  inserting it immediately after __pos.  This is constant time.
00691   void splice_after(iterator __pos, _Self& __x,
00692                     iterator __before_first, iterator __before_last) {
00693     if (__before_first != __before_last) {
00694       if (this->get_allocator() == __x.get_allocator()) {
00695         _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node,
00696                                                    __before_first._M_node, __before_last._M_node);
00697       }
00698       else {
00699         this->insert_after(__pos, iterator(__before_first._M_node->_M_next), iterator(__before_last._M_node->_M_next));
00700         __x.erase_after(__before_first, ++__before_last);
00701       }
00702     }
00703   }
00704 
00705   // Moves the element that follows __prev to *this, inserting it immediately
00706   //  after __pos.  This is constant time.
00707   void splice_after(iterator __pos, _Self& __x, iterator __prev) {
00708     if (this->get_allocator() == __x.get_allocator()) {
00709       _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node,
00710                                                  __prev._M_node, __prev._M_node->_M_next);
00711     }
00712     else {
00713       this->insert_after(__pos, __STATIC_CAST(_Node*, __prev._M_node->_M_next)->_M_data);
00714       __x.erase_after(__prev);
00715     }
00716   }
00717 
00718   // Removes all of the elements from the list __x to *this, inserting
00719   // them immediately after __pos.  __x must not be *this.  Complexity:
00720   // linear in __x.size().
00721   void splice_after(iterator __pos, _Self& __x) {
00722     if (this->get_allocator() == __x.get_allocator())
00723       _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node, &__x._M_head._M_data);
00724     else {
00725       this->insert_after(__pos, __x.begin(), __x.end());
00726       __x.clear();
00727     }
00728   }
00729 
00730   // Linear in distance(begin(), __pos), and linear in __x.size().
00731   void splice(iterator __pos, _Self& __x) {
00732     if (__x._M_head._M_data._M_next) {
00733       if (this->get_allocator() == __x.get_allocator()) {
00734         _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00735                                                    &__x._M_head._M_data,
00736                                                    _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, 0));
00737       }
00738       else {
00739         insert(__pos, __x.begin(), __x.end());
00740         __x.clear();
00741       }
00742     }
00743   }
00744 
00745   // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
00746   void splice(iterator __pos, _Self& __x, iterator __i) {
00747     if (this->get_allocator() == __x.get_allocator()) {
00748       _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00749                                                  _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, __i._M_node),
00750                                                  __i._M_node);
00751     }
00752     else {
00753       insert(__pos, *__i);
00754       __x.erase(__i);
00755     }
00756   }
00757 
00758   // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
00759   // and in distance(__first, __last).
00760   void splice(iterator __pos, _Self& __x, iterator __first, iterator __last) {
00761     if (__first != __last) {
00762       if (this->get_allocator() == __x.get_allocator()) {
00763         _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
00764                                                    _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, __first._M_node),
00765                                                    _STLP_PRIV _Sl_global_inst::__previous(__first._M_node, __last._M_node));
00766       }
00767       else {
00768         insert(__pos, __first, __last);
00769         __x.erase(__first, __last);
00770       }
00771     }
00772   }
00773 
00774 public:
00775   void reverse() {
00776     if (this->_M_head._M_data._M_next)
00777       this->_M_head._M_data._M_next = _STLP_PRIV _Sl_global_inst::__reverse(this->_M_head._M_data._M_next);
00778   }
00779 
00780   void remove(const _Tp& __val);
00781 
00782   void unique() { _STLP_PRIV _Slist_unique(*this, equal_to<value_type>()); }
00783   void merge(_Self& __x) { _STLP_PRIV _Slist_merge(*this, __x, less<value_type>()); }
00784   void sort() { _STLP_PRIV _Slist_sort(*this, less<value_type>()); }
00785 
00786 #if defined (_STLP_MEMBER_TEMPLATES)
00787   template <class _Predicate>
00788   void remove_if(_Predicate __pred) {
00789     _Node_base* __cur = &this->_M_head._M_data;
00790     while (__cur->_M_next) {
00791       if (__pred(__STATIC_CAST(_Node*, __cur->_M_next)->_M_data))
00792         this->_M_erase_after(__cur);
00793       else
00794         __cur = __cur->_M_next;
00795     }
00796   }
00797 
00798   template <class _BinaryPredicate>
00799   void unique(_BinaryPredicate __pred)
00800   { _STLP_PRIV _Slist_unique(*this, __pred); }
00801 
00802   template <class _StrictWeakOrdering>
00803   void merge(_Self& __x, _StrictWeakOrdering __comp)
00804   { _STLP_PRIV _Slist_merge(*this, __x, __comp); }
00805 
00806   template <class _StrictWeakOrdering>
00807   void sort(_StrictWeakOrdering __comp)
00808   { _STLP_PRIV _Slist_sort(*this, __comp); }
00809 #endif /* _STLP_MEMBER_TEMPLATES */
00810 };
00811 
00812 #if defined (slist)
00813 #  undef slist
00814 _STLP_MOVE_TO_STD_NAMESPACE
00815 #endif
00816 
00817 _STLP_END_NAMESPACE
00818 
00819 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
00820 #  include <stl/_slist.c>
00821 #endif
00822 
00823 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00824 #  include <stl/pointers/_slist.h>
00825 #endif
00826 
00827 #if defined (_STLP_DEBUG)
00828 #  include <stl/debug/_slist.h>
00829 #endif
00830 
00831 _STLP_BEGIN_NAMESPACE
00832 
00833 template <class _Tp, class _Alloc>
00834 inline bool  _STLP_CALL
00835 operator == (const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) {
00836   typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
00837   const_iterator __end1 = _SL1.end();
00838   const_iterator __end2 = _SL2.end();
00839 
00840   const_iterator __i1 = _SL1.begin();
00841   const_iterator __i2 = _SL2.begin();
00842   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00843     ++__i1;
00844     ++__i2;
00845   }
00846   return __i1 == __end1 && __i2 == __end2;
00847 }
00848 
00849 #define _STLP_EQUAL_OPERATOR_SPECIALIZED
00850 #define _STLP_TEMPLATE_HEADER    template <class _Tp, class _Alloc>
00851 #define _STLP_TEMPLATE_CONTAINER slist<_Tp, _Alloc>
00852 #include <stl/_relops_cont.h>
00853 #undef _STLP_TEMPLATE_CONTAINER
00854 #undef _STLP_TEMPLATE_HEADER
00855 #undef _STLP_EQUAL_OPERATOR_SPECIALIZED
00856 
00857 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00858 template <class _Tp, class _Alloc>
00859 struct __move_traits<slist<_Tp, _Alloc> > {
00860   typedef __stlp_movable implemented;
00861   typedef typename __move_traits<_Alloc>::complete complete;
00862 };
00863 
00864 // Specialization of insert_iterator so that insertions will be constant
00865 // time rather than linear time.
00866 template <class _Tp, class _Alloc>
00867 class insert_iterator<slist<_Tp, _Alloc> > {
00868 protected:
00869   typedef slist<_Tp, _Alloc> _Container;
00870   _Container* _M_container;
00871   typename _Container::iterator _M_iter;
00872 public:
00873   typedef _Container          container_type;
00874   typedef output_iterator_tag iterator_category;
00875   typedef void                value_type;
00876   typedef void                difference_type;
00877   typedef void                pointer;
00878   typedef void                reference;
00879 
00880   insert_iterator(_Container& __x, typename _Container::iterator __i)
00881     : _M_container(&__x) {
00882     if (__i == __x.begin())
00883       _M_iter = __x.before_begin();
00884     else
00885       _M_iter = __x.previous(__i);
00886   }
00887 
00888   insert_iterator<_Container>&
00889   operator = (const typename _Container::value_type& __val) {
00890     _M_iter = _M_container->insert_after(_M_iter, __val);
00891     return *this;
00892   }
00893 
00894   insert_iterator<_Container>& operator*() { return *this; }
00895   insert_iterator<_Container>& operator++() { return *this; }
00896   insert_iterator<_Container>& operator++(int) { return *this; }
00897 };
00898 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00899 
00900 _STLP_END_NAMESPACE
00901 
00902 #endif /* _STLP_INTERNAL_SLIST_H */
00903 
00904 // Local Variables:
00905 // mode:C++
00906 // End:



Generated on Mon Mar 10 15:32:35 2008 by  doxygen 1.5.1