Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_tree.h
Go to the documentation of this file.
00001 /* 00002 * 00003 * Copyright (c) 1994 00004 * Hewlett-Packard Company 00005 * 00006 * Copyright (c) 1996,1997 00007 * Silicon Graphics Computer Systems, Inc. 00008 * 00009 * Copyright (c) 1997 00010 * Moscow Center for SPARC Technology 00011 * 00012 * Copyright (c) 1999 00013 * Boris Fomitchev 00014 * 00015 * This material is provided "as is", with absolutely no warranty expressed 00016 * or implied. Any use is at your own risk. 00017 * 00018 * Permission to use or copy this software for any purpose is hereby granted 00019 * without fee, provided the above notices are retained on all copies. 00020 * Permission to modify the code and to distribute modified code is granted, 00021 * provided the above notices are retained, and a notice that the code was 00022 * modified is included with the above copyright notice. 00023 * 00024 */ 00025 00026 /* NOTE: This is an internal header file, included by other STL headers. 00027 * You should not attempt to use it directly. 00028 */ 00029 00030 #ifndef _STLP_INTERNAL_TREE_H 00031 #define _STLP_INTERNAL_TREE_H 00032 00033 /* 00034 00035 Red-black tree class, designed for use in implementing STL 00036 associative containers (set, multiset, map, and multimap). The 00037 insertion and deletion algorithms are based on those in Cormen, 00038 Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990), 00039 except that 00040 00041 (1) the header cell is maintained with links not only to the root 00042 but also to the leftmost node of the tree, to enable constant time 00043 begin(), and to the rightmost node of the tree, to enable linear time 00044 performance when used with the generic set algorithms (set_union, 00045 etc.); 00046 00047 (2) when a node being deleted has two children its successor node is 00048 relinked into its place, rather than copied, so that the only 00049 iterators invalidated are those referring to the deleted node. 00050 00051 */ 00052 00053 #ifndef _STLP_INTERNAL_ALGOBASE_H 00054 # include <stl/_algobase.h> 00055 #endif 00056 00057 #ifndef _STLP_INTERNAL_ALLOC_H 00058 # include <stl/_alloc.h> 00059 #endif 00060 00061 #ifndef _STLP_INTERNAL_ITERATOR_H 00062 # include <stl/_iterator.h> 00063 #endif 00064 00065 #ifndef _STLP_INTERNAL_CONSTRUCT_H 00066 # include <stl/_construct.h> 00067 #endif 00068 00069 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H 00070 # include <stl/_function_base.h> 00071 #endif 00072 00073 _STLP_BEGIN_NAMESPACE 00074 00075 _STLP_MOVE_TO_PRIV_NAMESPACE 00076 00077 typedef bool _Rb_tree_Color_type; 00078 //const _Rb_tree_Color_type _S_rb_tree_red = false; 00079 //const _Rb_tree_Color_type _S_rb_tree_black = true; 00080 00081 #define _S_rb_tree_red false 00082 #define _S_rb_tree_black true 00083 00084 struct _Rb_tree_node_base { 00085 typedef _Rb_tree_Color_type _Color_type; 00086 typedef _Rb_tree_node_base* _Base_ptr; 00087 00088 _Color_type _M_color; 00089 _Base_ptr _M_parent; 00090 _Base_ptr _M_left; 00091 _Base_ptr _M_right; 00092 00093 static _Base_ptr _STLP_CALL _S_minimum(_Base_ptr __x) { 00094 while (__x->_M_left != 0) __x = __x->_M_left; 00095 return __x; 00096 } 00097 00098 static _Base_ptr _STLP_CALL _S_maximum(_Base_ptr __x) { 00099 while (__x->_M_right != 0) __x = __x->_M_right; 00100 return __x; 00101 } 00102 }; 00103 00104 template <class _Value> 00105 struct _Rb_tree_node : public _Rb_tree_node_base { 00106 _Value _M_value_field; 00107 __TRIVIAL_STUFF(_Rb_tree_node) 00108 }; 00109 00110 struct _Rb_tree_base_iterator; 00111 00112 template <class _Dummy> 00113 class _Rb_global { 00114 public: 00115 typedef _Rb_tree_node_base* _Base_ptr; 00116 // those used to be global functions 00117 static void _STLP_CALL _Rebalance(_Base_ptr __x, _Base_ptr& __root); 00118 static _Base_ptr _STLP_CALL _Rebalance_for_erase(_Base_ptr __z, 00119 _Base_ptr& __root, 00120 _Base_ptr& __leftmost, 00121 _Base_ptr& __rightmost); 00122 // those are from _Rb_tree_base_iterator - moved here to reduce code bloat 00123 // moved here to reduce code bloat without templatizing _Rb_tree_base_iterator 00124 static _Base_ptr _STLP_CALL _M_increment (_Base_ptr); 00125 static _Base_ptr _STLP_CALL _M_decrement (_Base_ptr); 00126 static void _STLP_CALL _Rotate_left (_Base_ptr __x, _Base_ptr& __root); 00127 static void _STLP_CALL _Rotate_right(_Base_ptr __x, _Base_ptr& __root); 00128 }; 00129 00130 # if defined (_STLP_USE_TEMPLATE_EXPORT) 00131 _STLP_EXPORT_TEMPLATE_CLASS _Rb_global<bool>; 00132 # endif 00133 00134 typedef _Rb_global<bool> _Rb_global_inst; 00135 00136 struct _Rb_tree_base_iterator { 00137 typedef _Rb_tree_node_base* _Base_ptr; 00138 typedef bidirectional_iterator_tag iterator_category; 00139 typedef ptrdiff_t difference_type; 00140 _Base_ptr _M_node; 00141 _Rb_tree_base_iterator() : _M_node(0) {} 00142 _Rb_tree_base_iterator(_Base_ptr __x) : _M_node(__x) {} 00143 }; 00144 00145 template <class _Value, class _Traits> 00146 struct _Rb_tree_iterator : public _Rb_tree_base_iterator { 00147 typedef _Value value_type; 00148 typedef typename _Traits::reference reference; 00149 typedef typename _Traits::pointer pointer; 00150 typedef _Rb_tree_iterator<_Value, _Traits> _Self; 00151 typedef _Rb_tree_node_base* _Base_ptr; 00152 typedef _Rb_tree_node<_Value>* _Link_type; 00153 00154 typedef typename _Traits::_NonConstTraits _NonConstTraits; 00155 typedef _Rb_tree_iterator<_Value, _NonConstTraits> iterator; 00156 typedef typename _Traits::_ConstTraits _ConstTraits; 00157 typedef _Rb_tree_iterator<_Value, _ConstTraits> const_iterator; 00158 00159 _Rb_tree_iterator() {} 00160 #if !defined (_STLP_DEBUG) 00161 /* In STL debug mode we need this constructor implicit for the pointer 00162 * specialization implementation. 00163 */ 00164 explicit 00165 #endif 00166 _Rb_tree_iterator(_Base_ptr __x) : _Rb_tree_base_iterator(__x) {} 00167 //copy constructor for iterator and constructor from iterator for const_iterator 00168 _Rb_tree_iterator(const iterator& __it) : _Rb_tree_base_iterator(__it._M_node) {} 00169 00170 reference operator*() const { 00171 return __STATIC_CAST(_Link_type, _M_node)->_M_value_field; 00172 } 00173 00174 _STLP_DEFINE_ARROW_OPERATOR 00175 00176 _Self& operator++() { 00177 _M_node = _Rb_global_inst::_M_increment(_M_node); 00178 return *this; 00179 } 00180 _Self operator++(int) { 00181 _Self __tmp = *this; 00182 ++(*this); 00183 return __tmp; 00184 } 00185 00186 _Self& operator--() { 00187 _M_node = _Rb_global_inst::_M_decrement(_M_node); 00188 return *this; 00189 } 00190 _Self operator--(int) { 00191 _Self __tmp = *this; 00192 --(*this); 00193 return __tmp; 00194 } 00195 00196 bool operator == (const_iterator __rhs) const { 00197 return _M_node == __rhs._M_node; 00198 } 00199 bool operator != (const_iterator __rhs) const { 00200 return _M_node != __rhs._M_node; 00201 } 00202 }; 00203 00204 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 00205 _STLP_MOVE_TO_STD_NAMESPACE 00206 template <class _Value, class _Traits> 00207 struct __type_traits<_STLP_PRIV _Rb_tree_iterator<_Value, _Traits> > { 00208 typedef __false_type has_trivial_default_constructor; 00209 typedef __true_type has_trivial_copy_constructor; 00210 typedef __true_type has_trivial_assignment_operator; 00211 typedef __true_type has_trivial_destructor; 00212 typedef __false_type is_POD_type; 00213 }; 00214 _STLP_MOVE_TO_PRIV_NAMESPACE 00215 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ 00216 00217 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES) 00218 _STLP_MOVE_TO_STD_NAMESPACE 00219 template <class _Value, class _Traits> 00220 inline _Value* value_type(const _STLP_PRIV _Rb_tree_iterator<_Value, _Traits>&) 00221 { return (_Value*)0; } 00222 inline bidirectional_iterator_tag iterator_category(const _STLP_PRIV _Rb_tree_base_iterator&) 00223 { return bidirectional_iterator_tag(); } 00224 inline ptrdiff_t* distance_type(const _STLP_PRIV _Rb_tree_base_iterator&) 00225 { return (ptrdiff_t*) 0; } 00226 _STLP_MOVE_TO_PRIV_NAMESPACE 00227 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ 00228 00229 // Base class to help EH 00230 00231 template <class _Tp, class _Alloc> 00232 class _Rb_tree_base { 00233 public: 00234 typedef _Rb_tree_node_base _Node_base; 00235 typedef _Rb_tree_node<_Tp> _Node; 00236 _STLP_FORCE_ALLOCATORS(_Tp, _Alloc) 00237 typedef _Alloc allocator_type; 00238 private: 00239 typedef _Rb_tree_base<_Tp, _Alloc> _Self; 00240 typedef typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator_type; 00241 typedef _STLP_alloc_proxy<_Node_base, _Node, _M_node_allocator_type> _AllocProxy; 00242 00243 public: 00244 allocator_type get_allocator() const { 00245 return _STLP_CONVERT_ALLOCATOR(_M_header, _Tp); 00246 } 00247 00248 protected: 00249 _Rb_tree_base(const allocator_type& __a) : 00250 _M_header(_STLP_CONVERT_ALLOCATOR(__a, _Node), _Node_base() ) { 00251 _M_empty_initialize(); 00252 } 00253 00254 #if !defined (_STLP_NO_MOVE_SEMANTIC) 00255 _Rb_tree_base(__move_source<_Self> src) : 00256 _M_header(__move_source<_AllocProxy>(src.get()._M_header)) { 00257 _M_rebind(&src.get()._M_header._M_data); 00258 src.get()._M_empty_initialize(); 00259 } 00260 #endif 00261 00262 void _M_empty_initialize() { 00263 _M_header._M_data._M_color = _S_rb_tree_red; // used to distinguish header from 00264 // __root, in iterator.operator++ 00265 _M_header._M_data._M_parent = 0; 00266 _M_header._M_data._M_left = &_M_header._M_data; 00267 _M_header._M_data._M_right = &_M_header._M_data; 00268 } 00269 00270 void _M_rebind(_Node_base *__static_node) { 00271 if (_M_header._M_data._M_parent != 0) { 00272 _M_header._M_data._M_parent->_M_parent = &_M_header._M_data; 00273 } 00274 if (_M_header._M_data._M_right == __static_node) { 00275 _M_header._M_data._M_right = &_M_header._M_data; 00276 } 00277 if (_M_header._M_data._M_left == __static_node) { 00278 _M_header._M_data._M_left = &_M_header._M_data; 00279 } 00280 } 00281 00282 _AllocProxy _M_header; 00283 }; 00284 00285 #if defined (_STLP_DEBUG) 00286 # define _Rb_tree _STLP_NON_DBG_NAME(Rb_tree) 00287 #endif 00288 00289 template <class _Key, class _Compare, 00290 class _Value, class _KeyOfValue, class _Traits, 00291 _STLP_DFL_TMPL_PARAM(_Alloc, allocator<_Value>) > 00292 class _Rb_tree : public _Rb_tree_base<_Value, _Alloc> { 00293 typedef _Rb_tree_base<_Value, _Alloc> _Base; 00294 typedef _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc> _Self; 00295 protected: 00296 typedef _Rb_tree_node_base * _Base_ptr; 00297 typedef _Rb_tree_node<_Value> _Node; 00298 typedef _Node* _Link_type; 00299 typedef _Rb_tree_Color_type _Color_type; 00300 public: 00301 typedef _Key key_type; 00302 typedef _Value value_type; 00303 typedef typename _Traits::pointer pointer; 00304 typedef const value_type* const_pointer; 00305 typedef typename _Traits::reference reference; 00306 typedef const value_type& const_reference; 00307 typedef size_t size_type; 00308 typedef ptrdiff_t difference_type; 00309 typedef bidirectional_iterator_tag _Iterator_category; 00310 typedef typename _Base::allocator_type allocator_type; 00311 00312 protected: 00313 00314 _STLP_KEY_TYPE_FOR_CONT_EXT(key_type) 00315 _Base_ptr _M_create_node(const value_type& __x) { 00316 _Link_type __tmp = this->_M_header.allocate(1); 00317 _STLP_TRY { 00318 _Copy_Construct(&__tmp->_M_value_field, __x); 00319 } 00320 _STLP_UNWIND(this->_M_header.deallocate(__tmp,1)) 00321 _S_left(__tmp) = 0; 00322 _S_right(__tmp) = 0; 00323 return __tmp; 00324 } 00325 00326 _Base_ptr _M_clone_node(_Base_ptr __x) { 00327 _Base_ptr __tmp = _M_create_node(_S_value(__x)); 00328 _S_color(__tmp) = _S_color(__x); 00329 return __tmp; 00330 } 00331 00332 size_type _M_node_count; // keeps track of size of tree 00333 _Compare _M_key_compare; 00334 00335 _Base_ptr _M_root() const 00336 { return this->_M_header._M_data._M_parent; } 00337 _Base_ptr _M_leftmost() const 00338 { return this->_M_header._M_data._M_left; } 00339 _Base_ptr _M_rightmost() const 00340 { return this->_M_header._M_data._M_right; } 00341 00342 _Base_ptr& _M_root() 00343 { return this->_M_header._M_data._M_parent; } 00344 _Base_ptr& _M_leftmost() 00345 { return this->_M_header._M_data._M_left; } 00346 _Base_ptr& _M_rightmost() 00347 { return this->_M_header._M_data._M_right; } 00348 00349 static _Base_ptr& _STLP_CALL _S_left(_Base_ptr __x) 00350 { return __x->_M_left; } 00351 static _Base_ptr& _STLP_CALL _S_right(_Base_ptr __x) 00352 { return __x->_M_right; } 00353 static _Base_ptr& _STLP_CALL _S_parent(_Base_ptr __x) 00354 { return __x->_M_parent; } 00355 static value_type& _STLP_CALL _S_value(_Base_ptr __x) 00356 { return __STATIC_CAST(_Link_type, __x)->_M_value_field; } 00357 static const _Key& _STLP_CALL _S_key(_Base_ptr __x) 00358 { return _KeyOfValue()(_S_value(__x));} 00359 static _Color_type& _STLP_CALL _S_color(_Base_ptr __x) 00360 { return (_Color_type&)(__x->_M_color); } 00361 00362 static _Base_ptr _STLP_CALL _S_minimum(_Base_ptr __x) 00363 { return _Rb_tree_node_base::_S_minimum(__x); } 00364 00365 static _Base_ptr _STLP_CALL _S_maximum(_Base_ptr __x) 00366 { return _Rb_tree_node_base::_S_maximum(__x); } 00367 00368 public: 00369 typedef typename _Traits::_NonConstTraits _NonConstTraits; 00370 typedef typename _Traits::_ConstTraits _ConstTraits; 00371 typedef _Rb_tree_iterator<value_type, _NonConstTraits> iterator; 00372 typedef _Rb_tree_iterator<value_type, _ConstTraits> const_iterator; 00373 _STLP_DECLARE_BIDIRECTIONAL_REVERSE_ITERATORS; 00374 00375 private: 00376 iterator _M_insert(_Base_ptr __parent, const value_type& __val, _Base_ptr __on_left = 0, _Base_ptr __on_right = 0); 00377 _Base_ptr _M_copy(_Base_ptr __x, _Base_ptr __p); 00378 void _M_erase(_Base_ptr __x); 00379 00380 public: 00381 // allocation/deallocation 00382 _Rb_tree() 00383 : _Rb_tree_base<_Value, _Alloc>(allocator_type()), _M_node_count(0), _M_key_compare(_Compare()) 00384 {} 00385 00386 _Rb_tree(const _Compare& __comp) 00387 : _Rb_tree_base<_Value, _Alloc>(allocator_type()), _M_node_count(0), _M_key_compare(__comp) 00388 {} 00389 00390 _Rb_tree(const _Compare& __comp, const allocator_type& __a) 00391 : _Rb_tree_base<_Value, _Alloc>(__a), _M_node_count(0), _M_key_compare(__comp) 00392 {} 00393 00394 _Rb_tree(const _Self& __x) 00395 : _Rb_tree_base<_Value, _Alloc>(__x.get_allocator()), 00396 _M_node_count(0), _M_key_compare(__x._M_key_compare) { 00397 if (__x._M_root() != 0) { 00398 _S_color(&this->_M_header._M_data) = _S_rb_tree_red; 00399 _M_root() = _M_copy(__x._M_root(), &this->_M_header._M_data); 00400 _M_leftmost() = _S_minimum(_M_root()); 00401 _M_rightmost() = _S_maximum(_M_root()); 00402 } 00403 _M_node_count = __x._M_node_count; 00404 } 00405 00406 #if !defined (_STLP_NO_MOVE_SEMANTIC) 00407 _Rb_tree(__move_source<_Self> src) 00408 : _Rb_tree_base<_Value, _Alloc>(__move_source<_Base>(src.get())), 00409 _M_node_count(src.get()._M_node_count), 00410 _M_key_compare(_AsMoveSource(src.get()._M_key_compare)) 00411 { src.get()._M_node_count = 0; } 00412 #endif 00413 00414 ~_Rb_tree() { clear(); } 00415 _Self& operator=(const _Self& __x); 00416 00417 public: 00418 // accessors: 00419 _Compare key_comp() const { return _M_key_compare; } 00420 00421 iterator begin() { return iterator(_M_leftmost()); } 00422 const_iterator begin() const { return const_iterator(_M_leftmost()); } 00423 iterator end() { return iterator(&this->_M_header._M_data); } 00424 const_iterator end() const { return const_iterator(__CONST_CAST(_Base_ptr, &this->_M_header._M_data)); } 00425 00426 reverse_iterator rbegin() { return reverse_iterator(end()); } 00427 const_reverse_iterator rbegin() const 00428 { return const_reverse_iterator(end()); } 00429 reverse_iterator rend() { return reverse_iterator(begin()); } 00430 const_reverse_iterator rend() const 00431 { return const_reverse_iterator(begin()); } 00432 bool empty() const { return _M_node_count == 0; } 00433 size_type size() const { return _M_node_count; } 00434 size_type max_size() const { return size_type(-1); } 00435 00436 void swap(_Self& __t) { 00437 if (__t.empty()) { 00438 if (this->empty()) return; 00439 __t._M_header.swap(this->_M_header); 00440 __t._M_rebind(&this->_M_header._M_data); 00441 this->_M_empty_initialize(); 00442 } 00443 else if (this->empty()) { 00444 __t.swap(*this); 00445 return; 00446 } 00447 else { 00448 this->_M_header.swap(__t._M_header); 00449 this->_M_rebind(&__t._M_header._M_data); 00450 __t._M_rebind(&this->_M_header._M_data); 00451 } 00452 _STLP_STD::swap(_M_node_count, __t._M_node_count); 00453 _STLP_STD::swap(_M_key_compare, __t._M_key_compare); 00454 } 00455 00456 public: 00457 // insert/erase 00458 pair<iterator,bool> insert_unique(const value_type& __x); 00459 iterator insert_equal(const value_type& __x); 00460 00461 iterator insert_unique(iterator __pos, const value_type& __x); 00462 iterator insert_equal(iterator __pos, const value_type& __x); 00463 00464 #if defined (_STLP_MEMBER_TEMPLATES) 00465 template<class _II> void insert_equal(_II __first, _II __last) { 00466 for ( ; __first != __last; ++__first) 00467 insert_equal(*__first); 00468 } 00469 template<class _II> void insert_unique(_II __first, _II __last) { 00470 for ( ; __first != __last; ++__first) 00471 insert_unique(*__first); 00472 } 00473 #else 00474 void insert_unique(const_iterator __first, const_iterator __last) { 00475 for ( ; __first != __last; ++__first) 00476 insert_unique(*__first); 00477 } 00478 void insert_unique(const value_type* __first, const value_type* __last) { 00479 for ( ; __first != __last; ++__first) 00480 insert_unique(*__first); 00481 } 00482 void insert_equal(const_iterator __first, const_iterator __last) { 00483 for ( ; __first != __last; ++__first) 00484 insert_equal(*__first); 00485 } 00486 void insert_equal(const value_type* __first, const value_type* __last) { 00487 for ( ; __first != __last; ++__first) 00488 insert_equal(*__first); 00489 } 00490 #endif 00491 00492 void erase(iterator __pos) { 00493 _Base_ptr __x = _Rb_global_inst::_Rebalance_for_erase(__pos._M_node, 00494 this->_M_header._M_data._M_parent, 00495 this->_M_header._M_data._M_left, 00496 this->_M_header._M_data._M_right); 00497 _STLP_STD::_Destroy(&_S_value(__x)); 00498 this->_M_header.deallocate(__STATIC_CAST(_Link_type, __x), 1); 00499 --_M_node_count; 00500 } 00501 00502 size_type erase(const key_type& __x) { 00503 pair<iterator,iterator> __p = equal_range(__x); 00504 size_type __n = _STLP_STD::distance(__p.first, __p.second); 00505 erase(__p.first, __p.second); 00506 return __n; 00507 } 00508 00509 size_type erase_unique(const key_type& __x) { 00510 iterator __i = find(__x); 00511 if (__i._M_node != &this->_M_header._M_data) { 00512 erase(__i); 00513 return 1; 00514 } 00515 return 0; 00516 } 00517 00518 void erase(iterator __first, iterator __last) { 00519 if (__first._M_node == this->_M_header._M_data._M_left && // begin() 00520 __last._M_node == &this->_M_header._M_data) // end() 00521 clear(); 00522 else 00523 while (__first != __last) erase(__first++); 00524 } 00525 00526 void erase(const key_type* __first, const key_type* __last) { 00527 while (__first != __last) erase(*__first++); 00528 } 00529 00530 void clear() { 00531 if (_M_node_count != 0) { 00532 _M_erase(_M_root()); 00533 _M_leftmost() = &this->_M_header._M_data; 00534 _M_root() = 0; 00535 _M_rightmost() = &this->_M_header._M_data; 00536 _M_node_count = 0; 00537 } 00538 } 00539 00540 public: 00541 // set operations: 00542 _STLP_TEMPLATE_FOR_CONT_EXT 00543 iterator find(const _KT& __k) { return iterator(_M_find(__k)); } 00544 _STLP_TEMPLATE_FOR_CONT_EXT 00545 const_iterator find(const _KT& __k) const { return const_iterator(_M_find(__k)); } 00546 private: 00547 _STLP_TEMPLATE_FOR_CONT_EXT 00548 _Base_ptr _M_find(const _KT& __k) const { 00549 _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); // Last node which is not less than __k. 00550 _Base_ptr __x = _M_root(); // Current node. 00551 00552 while (__x != 0) 00553 if (!_M_key_compare(_S_key(__x), __k)) 00554 __y = __x, __x = _S_left(__x); 00555 else 00556 __x = _S_right(__x); 00557 00558 if (__y != &this->_M_header._M_data) { 00559 if (_M_key_compare(__k, _S_key(__y))) { 00560 __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); 00561 } 00562 } 00563 return __y; 00564 } 00565 00566 _STLP_TEMPLATE_FOR_CONT_EXT 00567 _Base_ptr _M_lower_bound(const _KT& __k) const { 00568 _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); /* Last node which is not less than __k. */ 00569 _Base_ptr __x = _M_root(); /* Current node. */ 00570 00571 while (__x != 0) 00572 if (!_M_key_compare(_S_key(__x), __k)) 00573 __y = __x, __x = _S_left(__x); 00574 else 00575 __x = _S_right(__x); 00576 00577 return __y; 00578 } 00579 00580 _STLP_TEMPLATE_FOR_CONT_EXT 00581 _Base_ptr _M_upper_bound(const _KT& __k) const { 00582 _Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); /* Last node which is greater than __k. */ 00583 _Base_ptr __x = _M_root(); /* Current node. */ 00584 00585 while (__x != 0) 00586 if (_M_key_compare(__k, _S_key(__x))) 00587 __y = __x, __x = _S_left(__x); 00588 else 00589 __x = _S_right(__x); 00590 00591 return __y; 00592 } 00593 00594 public: 00595 _STLP_TEMPLATE_FOR_CONT_EXT 00596 size_type count(const _KT& __x) const { 00597 pair<const_iterator, const_iterator> __p = equal_range(__x); 00598 return _STLP_STD::distance(__p.first, __p.second); 00599 } 00600 _STLP_TEMPLATE_FOR_CONT_EXT 00601 iterator lower_bound(const _KT& __x) { return iterator(_M_lower_bound(__x)); } 00602 _STLP_TEMPLATE_FOR_CONT_EXT 00603 const_iterator lower_bound(const _KT& __x) const { return const_iterator(_M_lower_bound(__x)); } 00604 _STLP_TEMPLATE_FOR_CONT_EXT 00605 iterator upper_bound(const _KT& __x) { return iterator(_M_upper_bound(__x)); } 00606 _STLP_TEMPLATE_FOR_CONT_EXT 00607 const_iterator upper_bound(const _KT& __x) const { return const_iterator(_M_upper_bound(__x)); } 00608 _STLP_TEMPLATE_FOR_CONT_EXT 00609 pair<iterator,iterator> equal_range(const _KT& __x) 00610 { return pair<iterator, iterator>(lower_bound(__x), upper_bound(__x)); } 00611 _STLP_TEMPLATE_FOR_CONT_EXT 00612 pair<const_iterator, const_iterator> equal_range(const _KT& __x) const 00613 { return pair<const_iterator, const_iterator>(lower_bound(__x), upper_bound(__x)); } 00614 _STLP_TEMPLATE_FOR_CONT_EXT 00615 pair<iterator,iterator> equal_range_unique(const _KT& __x) { 00616 pair<iterator, iterator> __p; 00617 __p.second = lower_bound(__x); 00618 if (__p.second._M_node != &this->_M_header._M_data && 00619 !_M_key_compare(__x, _S_key(__p.second._M_node))) { 00620 __p.first = __p.second++; 00621 } 00622 else { 00623 __p.first = __p.second; 00624 } 00625 return __p; 00626 } 00627 _STLP_TEMPLATE_FOR_CONT_EXT 00628 pair<const_iterator, const_iterator> equal_range_unique(const _KT& __x) const { 00629 pair<const_iterator, const_iterator> __p; 00630 __p.second = lower_bound(__x); 00631 if (__p.second._M_node != &this->_M_header._M_data && 00632 !_M_key_compare(__x, _S_key(__p.second._M_node))) { 00633 __p.first = __p.second++; 00634 } 00635 else { 00636 __p.first = __p.second; 00637 } 00638 return __p; 00639 } 00640 00641 #if defined (_STLP_DEBUG) 00642 public: 00643 // Debugging. 00644 bool __rb_verify() const; 00645 #endif //_STLP_DEBUG 00646 }; 00647 00648 #if defined (_STLP_DEBUG) 00649 # undef _Rb_tree 00650 #endif 00651 00652 _STLP_MOVE_TO_STD_NAMESPACE 00653 00654 _STLP_END_NAMESPACE 00655 00656 #if !defined (_STLP_LINK_TIME_INSTANTIATION) 00657 # include <stl/_tree.c> 00658 #endif 00659 00660 #if defined (_STLP_DEBUG) 00661 # include <stl/debug/_tree.h> 00662 #endif 00663 00664 _STLP_BEGIN_NAMESPACE 00665 00666 #define _STLP_TEMPLATE_HEADER template <class _Key, class _Compare, class _Value, class _KeyOfValue, class _Traits, class _Alloc> 00667 #define _STLP_TEMPLATE_CONTAINER _STLP_PRIV _Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> 00668 #include <stl/_relops_cont.h> 00669 #undef _STLP_TEMPLATE_CONTAINER 00670 #undef _STLP_TEMPLATE_HEADER 00671 00672 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC) 00673 template <class _Key, class _Compare, class _Value, class _KeyOfValue, class _Traits, class _Alloc> 00674 struct __move_traits<_STLP_PRIV _Rb_tree<_Key, _Compare, _Value, _KeyOfValue, _Traits, _Alloc> > 00675 : _STLP_PRIV __move_traits_help2<_Compare, _Alloc> {}; 00676 #endif 00677 00678 _STLP_END_NAMESPACE 00679 00680 #endif /* _STLP_INTERNAL_TREE_H */ 00681 00682 // Local Variables: 00683 // mode:C++ 00684 // End: Generated on Thu May 24 2012 04:30:18 for ReactOS by
1.7.6.1
|