Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_tree.h
Go to the documentation of this file.
1
45
64#ifndef _RWSTD_RW_TREE_H_INCLUDED
65#define _RWSTD_RW_TREE_H_INCLUDED
66
67#ifndef _RWSTD_RW_ALGOBASE_H_INCLUDED
68# include <rw/_algobase.h>
69#endif // _RWSTD_RW_ALGOBASE_H_INCLUDED
70
71#ifndef _RWSTD_RW_ITERATOR_H_INCLUDED
72# include <rw/_iterator.h>
73#endif // _RWSTD_RW_ITERATOR_H_INCLUDED
74
75
77
78
79template <class _Alloc, class _Val, class _Key, class _KeyOf>
80struct __rw_rb_tree_node
81{
82 enum _C_color_t { _C_red, _C_black };
83
84 typedef _Val& reference;
85 typedef _Alloc allocator_type;
86
87 typedef _RWSTD_REBIND (allocator_type, __rw_rb_tree_node) _C_node_alloc_t;
88 typedef _RWSTD_REBIND (allocator_type, _Key) _C_key_alloc_t;
89
90 typedef typename _C_node_alloc_t::pointer _C_link_t;
91 typedef typename _C_key_alloc_t::const_reference _C_const_key_ref;
92
93 _C_color_t _C_color;
94 _C_link_t _C_parent;
95 _C_link_t _C_child [2]; // left (0) and right (1) children
96 _Val _C_value;
97
98 static _C_link_t _C_minmax (_C_link_t __lnk, bool __do_max) {
99 _RWSTD_ASSERT (_C_link_t () != __lnk);
100 while (_C_link_t () != __lnk->_C_child [__do_max])
101 __lnk = __lnk->_C_child [__do_max];
102 return __lnk;
103 }
104
105 static _C_link_t _C_min (_C_link_t __lnk) {
106 return _C_minmax (__lnk, false);
107 }
108
109 static _C_link_t _C_max (_C_link_t __lnk) {
110 return _C_minmax (__lnk, true);
111 }
112
113 _C_const_key_ref _C_key () const {
114 return _KeyOf ()(_C_value);
115 }
116};
117
118
119// iterator implements inorder traversal; i.e., nodes are visited
120// recursively in this order: left subtree, root, right subtree
121template <class _TypeT, class _DiffT,
122 class _Pointer, class _Reference, class _Node>
123class __rw_tree_iter
124 : public _STD::iterator <_STD::bidirectional_iterator_tag,
125 _TypeT, _DiffT, _Pointer, _Reference>
126{
127 typedef _STD::iterator <_STD::bidirectional_iterator_tag,
128 _TypeT, _DiffT, _Pointer, _Reference> _C_iter_base;
129public:
130
131 typedef typename _C_iter_base::value_type value_type;
132 typedef typename _C_iter_base::difference_type difference_type;
133 typedef typename _C_iter_base::pointer pointer;
134 typedef typename _C_iter_base::reference reference;
135 typedef typename _C_iter_base::iterator_category iterator_category;
136 typedef _Node _C_node_t;
137 typedef typename _C_node_t::allocator_type allocator_type;
138 typedef typename _C_node_t::_C_link_t _C_link_t;
139
140 typedef const value_type* const_pointer;
141 typedef const value_type& const_reference;
142
143 typedef __rw_tree_iter<_TypeT, _DiffT, value_type*, value_type&, _C_node_t>
144 _C_iterator;
145
146 _C_link_t _C_node;
147
148 __rw_tree_iter () { /* empty */ }
149
150 // no copy ctor other than the one below is defined
151 // will use a compiler generated one if __rw_tree_iter != _C_iterator
152 __rw_tree_iter (const _C_iterator &__rhs)
153 : _C_node (__rhs._C_node) { }
154
155 template <class _Ptr, class _Ref>
156 __rw_tree_iter (const __rw_tree_iter<_TypeT, _DiffT, _Ptr, _Ref, _Node>&
157 __rhs)
158 : _C_node (__rhs._C_node) { }
159
160 __rw_tree_iter (_C_link_t __lnk)
161 : _C_node (__lnk) {}
162
163#ifdef SNI
164 difference_type operator- (const __rw_tree_iter&) const {
165 return 0;
166 }
167#endif
168
169 __rw_tree_iter& operator++ () {
170 if (_C_link_t () != _C_node->_C_child [1]) {
171 _C_node = _C_node_t::_C_min (_C_node->_C_child [1]);
172 }
173 else {
174 _C_link_t __tmp = _C_node->_C_parent;
175
176 while (_C_node == __tmp->_C_child [1]) {
177 _C_node = __tmp;
178 __tmp = __tmp->_C_parent;
179 }
180
181 if (_C_node->_C_child [1] != __tmp)
182 _C_node = __tmp;
183 }
184 return *this;
185 }
186
187 __rw_tree_iter& operator-- () {
188 if ( _C_node->_C_color == _C_node_t::_C_red
189 && _C_node->_C_parent->_C_parent == _C_node)
190 //
191 // Check for header.
192 //
193 _C_node = _C_node->_C_child [1]; // Return rightmost.
194 else if (_C_link_t () != _C_node->_C_child [0]) {
195 _C_node = _C_node_t::_C_max (_C_node->_C_child [0]);
196 }
197 else {
198 _C_link_t __tmp = _C_node->_C_parent;
199
200 while (_C_node == __tmp->_C_child [0]) {
201 _C_node = __tmp;
202 __tmp = __tmp->_C_parent;
203 }
204 _C_node = __tmp;
205 }
206 return *this;
207 }
208
209 __rw_tree_iter operator++ (int) {
210 __rw_tree_iter __tmp (*this);
211 return ++*this, __tmp;
212 }
213
214 __rw_tree_iter operator-- (int) {
215 __rw_tree_iter __tmp (*this);
216 return --*this, __tmp;
217 }
218
219 reference operator* () const {
220 return _C_node->_C_value;
221 }
222
223 _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
224};
225
226
227#define _RWSTD_TREE_ITER(n) \
228 __rw_tree_iter <_TypeT, _DiffT, _Ptr##n, _Ref##n, _Node>
229
230template <class _TypeT, class _DiffT,
231 class _Ptr1, class _Ref1, class _Ptr2, class _Ref2, class _Node>
232inline bool
233operator== (const _RWSTD_TREE_ITER (1) &__lhs,
234 const _RWSTD_TREE_ITER (2) &__rhs)
235{
236 return __lhs._C_node == __rhs._C_node;
237}
238
239template <class _TypeT, class _DiffT,
240 class _Ptr1, class _Ref1, class _Ptr2, class _Ref2, class _Node>
241inline bool
242operator!= (const _RWSTD_TREE_ITER (1) &__lhs,
243 const _RWSTD_TREE_ITER (2) &__rhs)
244{
245 return !(__lhs == __rhs);
246}
247
248
249#undef _RWSTD_TREE_ITER
250
251// for convenience
252#undef _ITER_NODE
253#define _ITER_NODE(it) (_ITER_BASE (it)._C_node)
254
255
257template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
258class __rb_tree : private _Alloc
259{
260private:
261
262 typedef __rw_rb_tree_node<_Alloc,_Val,_Key,_KeyOf> _C_node_t;
263 typedef _RWSTD_ALLOC_TYPE (_Alloc,_Val) _C_val_alloc_t;
264 typedef _RWSTD_REBIND (_Alloc, _Key) _C_key_alloc_t;
265 typedef _RWSTD_REBIND (_Alloc, _C_node_t) _C_node_alloc_t;
266 typedef typename _C_node_alloc_t::pointer _C_link_t;
267
268public:
269
270 typedef _Key key_type;
271 typedef _Val value_type;
272 typedef _Comp key_compare;
273 typedef _Alloc allocator_type;
274
275 typedef typename _C_val_alloc_t::pointer pointer;
276 typedef typename _C_val_alloc_t::const_pointer const_pointer;
277 typedef typename allocator_type::size_type size_type;
278 typedef typename allocator_type::difference_type difference_type;
279 typedef typename _C_val_alloc_t::reference reference;
280 typedef typename _C_val_alloc_t::const_reference const_reference;
281
282private:
283
284 typedef __rw_tree_iter<value_type, difference_type, pointer,
285 reference, _C_node_t> _C_tree_iter;
286
287 typedef __rw_tree_iter<value_type, difference_type, const_pointer,
288 const_reference, _C_node_t> _C_tree_citer;
289
290public:
291
292#ifndef _RWSTD_NO_DEBUG_ITER
293
294 typedef __rw_debug_iter <__rb_tree, _C_tree_iter, _C_tree_iter>
295 iterator;
296
297 typedef __rw_debug_iter <__rb_tree, _C_tree_citer, _C_tree_iter>
298 const_iterator;
299
300 iterator _C_make_iter (_C_link_t __node) {
301 return iterator (*this, _C_tree_iter (__node));
302 }
303
304 const_iterator _C_make_iter (_C_link_t __node) const {
305 return const_iterator (*this, _C_tree_citer (__node));
306 }
307
308#else // if defined (_RWSTD_NO_DEBUG_ITER)
309
310 typedef _C_tree_iter iterator;
311 typedef _C_tree_citer const_iterator;
312
313 iterator _C_make_iter (_C_link_t __node) {
314 return iterator (__node);
315 }
316
317 const_iterator _C_make_iter (_C_link_t __node) const {
318 return const_iterator (__node);
319 }
320
321#endif // _RWSTD_NO_DEBUG_ITER
322
323private:
324
325#ifdef _RWSTD_NO_NESTED_CLASS_ACCESS
326
327 // allow _C_node_buf access to __rb_tree's private type(s)
328 // if the resolution of cwg issue 45 is not yet implemented
329 struct _C_node_buf;
330 friend struct _C_node_buf;
331
332#endif // _RWSTD_NO_NESTED_CLASS_ACCESS
333
334 struct _C_node_buf {
335 typedef _RWSTD_REBIND (allocator_type, _C_node_buf) _C_buf_alloc_t;
336 typedef typename _C_buf_alloc_t::pointer _C_buf_ptr_t;
337
338 _C_buf_ptr_t _C_next_buffer;
339 size_type size;
340 _C_link_t _C_buffer;
341 };
342
343 typedef typename _C_node_buf::_C_buf_alloc_t _C_buf_alloc_t;
344 typedef typename _C_node_buf::_C_buf_ptr_t _C_buf_ptr_t;
345
346 _C_buf_ptr_t _C_buf_list;
347 _C_link_t _C_free_list;
348 _C_link_t _C_next_avail;
349 _C_link_t _C_last;
350
351 void _C_add_new_buffer ();
352
353 void _C_deallocate_buffers ();
354
355 //
356 // Return a node from the free list or new storage
357 //
358 _C_link_t _C_get_link () {
359 _C_link_t __tmp = _C_free_list;
360 _C_link_t __tmp2 = (void*)_C_free_list ?
361 (_C_free_list = _RWSTD_STATIC_CAST (_C_link_t,(_C_free_list->_C_child [1])), __tmp)
362 : (_C_next_avail == _C_last ? (_C_add_new_buffer (), _C_next_avail++)
363 : _C_next_avail++);
364 __tmp2->_C_parent = 0;
365 __tmp2->_C_child [0] = 0;
366 __tmp2->_C_child [1] = 0;
367 __tmp2->_C_color = _C_node_t::_C_red;
368 return __tmp2;
369 }
370
371 //
372 // Return a node from the free list or new storage with
373 // the _Val __v constructed on it. Every call to _C_get_node
374 // must eventually be followed by a call to _C_put_node.
375 //
376 _C_link_t _C_get_node (const_reference __v) {
377 _C_link_t __tmp2 = _C_get_link ();
378
379 _TRY {
380 _RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this,
381 construct (_RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this,
382 address (__tmp2->_C_value)),
383 __v));
384 }
385 _CATCH (...) {
386 _C_put_node (__tmp2, false);
387 _RETHROW;
388 }
389 return __tmp2;
390 }
391
392 _C_link_t _C_get_node () {
393 return _C_get_link ();
394 }
395
396 //
397 // Return a node to the free list and destroy the value in it.
398 //
399 void _C_put_node (_C_link_t __p, bool __destroy = true) {
400 __p->_C_child [1] = _C_free_list;
401 if (__destroy) {
402 _RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this,
403 destroy (_RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this,
404 address (__p->_C_value))));
405 }
406 _C_free_list = __p;
407 }
408
409private:
410
411 // _C_end is end()
412 // tree root is _C_end->_C_parent
413 // the leftmost node, i.e., begin(), is _C_end->_C_child [0]
414 // the rightmost node, i.e., end() - 1, is _C_end->_C_child [1]
415 // all three pointers are null (0) when the tree is empty
416 // both child pointers of each leaf node are null (0)
417 // the parent pointer of the root node points to *_C_end
418 _C_link_t _C_end;
419
420 size_type _C_size; // number of nodes
421 key_compare _C_cmp; // comparison object
422
423public:
424
425
426#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
427
428 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
429 typedef _STD::reverse_iterator<iterator> reverse_iterator;
430
431#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
432
433 typedef std::reverse_iterator<const_iterator,
434 _STD::bidirectional_iterator_tag, value_type,
435 const_reference, const_pointer, difference_type>
436 const_reverse_iterator;
437
438 typedef std::reverse_iterator<iterator,
439 _STD::bidirectional_iterator_tag, value_type,
440 reference, pointer, difference_type>
441 reverse_iterator;
442
443#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
444
445private:
446
447 iterator _C_insert (_C_link_t, _C_link_t, const value_type&);
448
449 _C_link_t _C_copy (_C_link_t, _C_link_t);
450
451 void _C_erase (_C_link_t);
452
453 void _C_erase_leaf (_C_link_t);
454
455 void _C_init () {
456 _C_buf_list = 0;
457 _C_free_list =
458 _C_next_avail =
459 _C_last = 0;
460 _C_end = _C_get_node ();
461 _C_end->_C_parent = 0;
462 _C_end->_C_child [0] =
463 _C_end->_C_child [1] = _C_end;
464 }
465
466public:
467
468 __rb_tree (const key_compare& = key_compare (),
469 const allocator_type& = allocator_type ());
470
471 template<class _InputIter>
472 __rb_tree (_InputIter __first, _InputIter __last,
473 const key_compare &__cmp,
474 const allocator_type &__alloc, bool __dup)
475 : allocator_type (__alloc), _C_buf_list (0),
476 _C_end (0), _C_size (0),
477 _C_cmp (__cmp) {
478
479 _C_init ();
480
481 _TRY {
482 insert (__first, __last, __dup);
483 }
484 _CATCH (...) {
485 _C_deallocate_buffers ();
486 _RETHROW;
487 }
488 }
489
490 __rb_tree (const __rb_tree&);
491
492 ~__rb_tree ();
493
494 __rb_tree& operator= (const __rb_tree&);
495
496 key_compare key_comp () const {
497 return _C_cmp;
498 }
499
500 _C_val_alloc_t get_allocator () const {
501 return _C_val_alloc_t (*this);
502 }
503
504 iterator begin () {
505 return _C_make_iter (_C_end->_C_child [0]);
506 }
507
508 const_iterator begin () const {
509 return _C_make_iter (_C_end->_C_child [0]);
510 }
511
512 iterator end () {
513 return _C_make_iter (_C_end);
514 }
515
516 const_iterator end () const {
517 return _C_make_iter (_C_end);
518 }
519
520 reverse_iterator rbegin () {
521 return reverse_iterator (end ());
522 }
523
524 reverse_iterator rend () {
525 return reverse_iterator (begin ());
526 }
527
528 const_reverse_iterator rbegin () const {
529 return const_reverse_iterator (end ());
530 }
531
532 const_reverse_iterator rend () const {
533 return const_reverse_iterator (begin ());
534 }
535
536 bool empty () const {
537 return 0 == _C_size;
538 }
539
540 size_type size () const {
541 return _C_size;
542 }
543
544 size_type max_size () const {
545 return _C_node_alloc_t (*this).max_size ();
546 }
547
548 void swap (__rb_tree &__rhs) {
549 if (get_allocator () == __rhs.get_allocator ()) {
550 _STD::swap (_C_buf_list, __rhs._C_buf_list);
551 _STD::swap (_C_free_list, __rhs._C_free_list);
552 _STD::swap (_C_next_avail, __rhs._C_next_avail);
553 _STD::swap (_C_last, __rhs._C_last);
554 _STD::swap (_C_end, __rhs._C_end);
555 _STD::swap (_C_size, __rhs._C_size);
556 _STD::swap (_C_cmp, __rhs._C_cmp);
557 }
558 else {
559 __rb_tree __tmp = *this;
560 *this = __rhs;
561 __rhs = __tmp;
562 }
563 }
564
565 void _C_insert (const value_type&, _STD::pair<iterator, bool>&, bool);
566
567 _STD::pair<iterator, bool>
568 insert (const value_type &__val, bool __dup) {
569 _STD::pair<iterator, bool> __ret;
570 return _C_insert (__val, __ret, __dup), __ret;
571 }
572
573 iterator insert (iterator, const value_type&, bool);
574
575 template<class _Iterator>
576 void insert (_Iterator __first, _Iterator __last, bool __dup) {
577 for (; __first != __last; ++__first)
578 insert (*__first, __dup);
579 }
580
581 iterator erase (iterator);
582
583 size_type erase (const key_type&);
584
585 iterator erase (iterator, iterator);
586
587// MSVC 6.0 thinks S<const T*> is the same as S<T*>...
588#if !defined (_MSC_VER) || _MSC_VER > 1300
589
590 // map and set's iterator may be defined to be tree::const_iterator
591 iterator insert (const_iterator __it, const value_type &__x, bool __dup) {
592 return insert (_C_make_iter (_ITER_NODE (__it)), __x, __dup);
593 }
594
595 // map and set's iterator may be defined to be tree::const_iterator
596 iterator erase (const_iterator __it) {
597 return erase (_C_make_iter (_ITER_NODE (__it)));
598 }
599
600 // map and set's iterator may be defined to be tree::const_iterator
601 iterator erase (const_iterator __first, const_iterator __last) {
602 return erase (_C_make_iter (_ITER_NODE (__first)),
603 _C_make_iter (_ITER_NODE (__last)));
604 }
605
606#endif // _MSC_VER <= 1300
607
608 void erase (const key_type*, const key_type*);
609
610 void clear () {
611 erase (begin (), end ());
612 }
613
614 iterator find (const key_type&);
615
616 const_iterator find (const key_type& __key) const {
617 return _RWSTD_CONST_CAST (__rb_tree*, this)->find (__key);
618 }
619
620 size_type count (const key_type&) const;
621
622 iterator lower_bound (const key_type&);
623
624 const_iterator lower_bound (const key_type& __key) const {
625 return _RWSTD_CONST_CAST (__rb_tree*, this)->lower_bound (__key);
626 }
627
628 iterator upper_bound (const key_type&);
629
630 const_iterator upper_bound (const key_type& __key) const {
631 return _RWSTD_CONST_CAST (__rb_tree*, this)->upper_bound (__key);
632 }
633
634 _STD::pair<iterator, iterator> equal_range (const key_type&);
635
636 _STD::pair<const_iterator, const_iterator>
637 equal_range (const key_type& __key) const {
638 _STD::pair<iterator, iterator> __tmp =
639 _RWSTD_CONST_CAST (__rb_tree*, this)->equal_range (__key);
640 return _STD::pair<const_iterator, const_iterator>
641 (__tmp.first, __tmp.second);
642 }
643
644#ifndef _RWSTD_NO_OPTIMIZE_SPEED
645
646 void _C_rol (_C_link_t);
647 void _C_ror (_C_link_t);
648
649#else // if defined (_RWSTD_NO_OPTIMIZE_SPEED)
650
651 void _C_rotate (_C_link_t, bool);
652
653#endif // _RWSTD_NO_OPTIMIZE_SPEED
654
655 size_type _C_level (const_iterator) const;
656
657 // depth guaranteed to be <= 2 * log2(size() + 1)
658 size_type _C_depth (const_iterator, size_type* = 0) const;
659
660 size_type _C_depth () const {
661 return _C_depth (_C_make_iter (_C_end->_C_parent));
662 }
663};
664
665
666template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
667inline bool
668operator== (const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __lhs,
669 const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __rhs)
670{
671 return __lhs.size () == __rhs.size ()
672 && _STD::equal (__lhs.begin (), __lhs.end (), __rhs.begin ());
673}
674
675
676template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
677inline bool
678operator< (const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __lhs,
679 const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __rhs)
680{
681 return _STD::lexicographical_compare (__lhs.begin (), __lhs.end (),
682 __rhs.begin (), __rhs.end ());
683}
684
685
686template <class _Key,class _Val,class _KeyOf,class _Comp,class _Alloc>
687inline void
688__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
689_C_erase_leaf (_C_link_t __lnk)
690{
691 // remove a leaf node from the tree
692 const _C_link_t __parent = __lnk->_C_parent;
693
694 if (__parent == _C_end) {
695 _C_end->_C_parent = 0;
696 _C_end->_C_child [0] =
697 _C_end->_C_child [1] = __parent;
698 }
699
700#ifndef _RWSTD_NO_OPTIMIZE_SPEED
701
702 else if (__parent->_C_child [0] == __lnk) {
703 __parent->_C_child [0] = 0;
704 if (_C_end->_C_child [0] == __lnk)
705 _C_end->_C_child [0] = __parent;
706 }
707 else {
708 __parent->_C_child [1] = 0;
709 if (_C_end->_C_child [1] == __lnk)
710 _C_end->_C_child [1] = __parent;
711 }
712
713#else // if !defined (_RWSTD_NO_OPTIMIZE_SPEED)
714
715 else {
716 const bool __right = __parent->_C_child [0] != __lnk;
717 __parent->_C_child [__right] = 0;
718 if (_C_end->_C_child [__right] == __lnk)
719 _C_end->_C_child [__right] = __parent;
720 }
721
722#endif // _RWSTD_NO_OPTIMIZE_SPEED
723}
724
725
726#ifndef _RWSTD_NO_OPTIMIZE_SPEED
727
728template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
729inline void
730__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
731_C_rol (_C_link_t __lnk)
732{
733 _RWSTD_ASSERT (_C_link_t () != __lnk);
734
735 _C_link_t __tmp = __lnk->_C_child [1];
736 __lnk->_C_child [1] = __tmp->_C_child [0];
737
738 if (_C_link_t () != __tmp->_C_child [0])
739 __tmp->_C_child [0]->_C_parent = __lnk;
740
741 __tmp->_C_parent = __lnk->_C_parent;
742
743 if (__lnk == _C_end->_C_parent)
744 _C_end->_C_parent = __tmp;
745 else if (__lnk == __lnk->_C_parent->_C_child [0])
746 __lnk->_C_parent->_C_child [0] = __tmp;
747 else
748 __lnk->_C_parent->_C_child [1] = __tmp;
749
750 __tmp->_C_child [0] = __lnk;
751 __lnk->_C_parent = __tmp;
752}
753
754
755template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
756inline void
757__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
758_C_ror (_C_link_t __lnk)
759{
760 _RWSTD_ASSERT (_C_link_t () != __lnk);
761
762 _C_link_t __tmp = __lnk->_C_child [0];
763 __lnk->_C_child [0] = __tmp->_C_child [1];
764
765 if (_C_link_t () != __tmp->_C_child [1])
766 __tmp->_C_child [1]->_C_parent = __lnk;
767
768 __tmp->_C_parent = __lnk->_C_parent;
769
770 if (__lnk == _C_end->_C_parent)
771 _C_end->_C_parent = __tmp;
772 else if (__lnk == __lnk->_C_parent->_C_child [1])
773 __lnk->_C_parent->_C_child [1] = __tmp;
774 else
775 __lnk->_C_parent->_C_child [0] = __tmp;
776
777 __tmp->_C_child [1] = __lnk;
778 __lnk->_C_parent = __tmp;
779}
780
781#else // if defined (_RWSTD_NO_OPTIMIZE_SPEED)
782
783template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
784inline void
785__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
786_C_rotate (_C_link_t __lnk, bool __right)
787{
788 _RWSTD_ASSERT (_C_link_t () != __lnk);
789
790 _C_link_t __tmp = __lnk->_C_child [!__right];
791 __lnk->_C_child [!__right] = __tmp->_C_child [__right];
792
793 if (_C_link_t () != __tmp->_C_child [__right])
794 __tmp->_C_child [__right]->_C_parent = __lnk;
795
796 __tmp->_C_parent = __lnk->_C_parent;
797
798 if (__lnk == _C_end->_C_parent)
799 _C_end->_C_parent = __tmp;
800 else {
801 const bool __rt = __lnk == __lnk->_C_parent->_C_child [1];
802 __lnk->_C_parent->_C_child [__rt] = __tmp;
803 }
804
805 __tmp->_C_child [__right] = __lnk;
806 __lnk->_C_parent = __tmp;
807}
808
809#endif // _RWSTD_NO_OPTIMIZE_SPEED
810
811
812template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
813inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
814erase (const _Key* __first, const _Key* __last)
815{
816 for (; __first != __last; ++__first)
817 erase (*__first);
818}
819
820
821template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
822inline typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::size_type
823__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
824count (const _Key& __k) const
825{
826 _STD::pair<const_iterator, const_iterator> __p = equal_range (__k);
827 size_type __n = _DISTANCE (__p.first, __p.second, size_type);
828 return __n;
829}
830
831
832#define _RWSTD_RB_TREE_ITER \
833 typename __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator
834
835template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
836inline _STD::pair<_RWSTD_RB_TREE_ITER , _RWSTD_RB_TREE_ITER >
837__rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::
838equal_range (const _Key& __k)
839{
840 return _STD::pair<iterator, iterator>(lower_bound (__k), upper_bound(__k));
841}
842
843
844#undef _RWSTD_RB_TREE_ITER
845
846
847} // namespace __rw
848
849
850#ifdef _RWSTD_NO_IMPLICIT_INCLUSION
851# include <rw/_tree.cc>
852#endif
853
854#endif // _RWSTD_RW_TREE_H_INCLUDED
void count(T, T, const U &,...)
const minus< T > & operator-(const minus< T > &lhs, const minus< T > &rhs)
const plus_asgn< T > & operator*(const plus_asgn< T > &lhs, const plus_asgn< T > &rhs)
const int end
#define _RWSTD_VALUE_ALLOC(ignore, object, call)
Definition _defs.h:893
#define _RETHROW
Definition _defs.h:853
#define _RWSTD_ALLOC_TYPE(Allocator, ignore)
Definition _defs.h:891
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _EXPORT
Definition _defs.h:498
#define _RWSTD_REBIND(from, to)
Definition _defs.h:884
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _DISTANCE(first, last, ignore)
Definition _defs.h:1225
#define _CATCH(ex)
Definition _defs.h:851
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
#define _RWSTD_OPERATOR_ARROW(signature)
Definition _defs.h:965
#define _ITER_NODE(it)
#define _RWSTD_TREE_ITER(n)
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14737
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14762
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14787