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