/home/ntakagi/work/STLport-5.1.5/stlport/stl/_slist.hGo 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 ![]() |