1 #ifndef ACE_RB_TREE_CPP
2 #define ACE_RB_TREE_CPP
4 #include "ace/Global_Macros.h"
5 #include "ace/RB_Tree.h"
6 #include "ace/SString.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 #if !defined (__ACE_INLINE__)
13 #include "ace/RB_Tree.inl"
14 #endif /* __ACE_INLINE__ */
16 #include "ace/Log_Category.h"
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE_Tc4(ACE_RB_Tree
)
21 ACE_ALLOC_HOOK_DEFINE_Tc4(ACE_RB_Tree_Iterator_Base
)
22 ACE_ALLOC_HOOK_DEFINE_Tc4(ACE_RB_Tree_Iterator
)
23 ACE_ALLOC_HOOK_DEFINE_Tc4(ACE_RB_Tree_Reverse_Iterator
)
27 template <class EXT_ID
, class INT_ID
>
28 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>::ACE_RB_Tree_Node (const EXT_ID
&k
, const INT_ID
&t
)
36 ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)");
42 template <class EXT_ID
, class INT_ID
>
43 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>::~ACE_RB_Tree_Node (void)
45 ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::~ACE_RB_Tree_Node");
50 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
51 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree (ACE_Allocator
*alloc
)
55 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (ACE_Allocator *alloc)");
57 if (this->open (alloc
) == -1)
58 ACELIB_ERROR ((LM_ERROR
,
59 ACE_TEXT ("ACE_RB_Tree::ACE_RB_Tree\n")));
64 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
65 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &rbt
)
69 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt)");
70 ACE_WRITE_GUARD (ACE_LOCK
, ace_mon
, this->lock_
);
71 allocator_
= rbt
.allocator_
;
73 // Make a deep copy of the passed tree.
74 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> iter(rbt
);
78 iter
.is_done () == 0; iter
.next ())
79 insert_i (*(iter
.key ()),
83 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
84 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree (
89 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (void *, ACE_Allocator *)");
94 this->current_size_
= 0;
97 this->allocator_
= alloc
;
101 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
102 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::~ACE_RB_Tree ()
104 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree");
106 // Use the locked public method, to be totally safe, as the class
107 // can be used with an allocator and placement new.
111 // Assignment operator.
113 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
114 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::operator = (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &rbt
)
116 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator =");
117 ACE_WRITE_GUARD (ACE_LOCK
, ace_mon
, this->lock_
);
121 // Clear out the existing tree.
124 // Make a deep copy of the passed tree.
125 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> iter(rbt
);
128 iter
.is_done () == 0;
130 insert_i (*(iter
.key ()),
133 // Use the same allocator as the rhs.
134 allocator_
= rbt
.allocator_
;
137 // Less than comparison function for keys, default functor
138 // implementation returns 1 if k1 < k2, 0 otherwise.
140 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
141 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::lessthan (const EXT_ID
&k1
, const EXT_ID
&k2
)
143 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::lessthan");
144 return this->compare_keys_ (k1
, k2
);
147 // Method for right rotation of the tree about a given node.
149 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
150 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_rotate_right (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
)
152 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_right");
155 ACELIB_ERROR ((LM_ERROR
,
157 ACE_TEXT ("\nerror: x is a null pointer in ")
158 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
159 else if (! (x
->left()))
160 ACELIB_ERROR ((LM_ERROR
,
162 ACE_TEXT ("\nerror: x->left () is a null pointer in ")
163 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
166 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> * y
;
168 x
->left (y
->right ());
170 y
->right ()->parent (x
);
171 y
->parent (x
->parent ());
174 if (x
== x
->parent ()->right ())
175 x
->parent ()->right (y
);
177 x
->parent ()->left (y
);
186 // Method for left rotation of the tree about a given node.
188 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
189 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_rotate_left (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> * x
)
191 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_left");
194 ACELIB_ERROR ((LM_ERROR
,
196 ACE_TEXT ("\nerror: x is a null pointer in ")
197 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
198 else if (! (x
->right()))
199 ACELIB_ERROR ((LM_ERROR
,
201 ACE_TEXT ("\nerror: x->right () is a null pointer ")
202 ACE_TEXT ("in ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
205 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> * y
;
207 x
->right (y
->left ());
209 y
->left ()->parent (x
);
210 y
->parent (x
->parent ());
213 if (x
== x
->parent ()->left ())
214 x
->parent ()->left (y
);
216 x
->parent ()->right (y
);
225 // Method for restoring Red-Black properties after a specific deletion case.
227 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
228 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::
229 RB_delete_fixup (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
,
230 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *parent
)
232 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_delete_fixup");
234 while (x
!= this->root_
236 || x
->color () == ACE_RB_Tree_Node_Base::BLACK
))
238 if (x
== parent
->left ())
240 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *w
= parent
->right ();
241 if (w
&& w
->color () == ACE_RB_Tree_Node_Base::RED
)
243 w
->color (ACE_RB_Tree_Node_Base::BLACK
);
244 parent
->color (ACE_RB_Tree_Node_Base::RED
);
245 RB_rotate_left (parent
);
246 w
= parent
->right ();
248 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
251 || w
->left ()->color () == ACE_RB_Tree_Node_Base::BLACK
)
253 || w
->right ()->color () == ACE_RB_Tree_Node_Base::BLACK
))
255 w
->color (ACE_RB_Tree_Node_Base::RED
);
257 parent
= x
->parent ();
261 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
264 || w
->right ()->color () == ACE_RB_Tree_Node_Base::BLACK
))
267 w
->left ()->color (ACE_RB_Tree_Node_Base::BLACK
);
268 w
->color (ACE_RB_Tree_Node_Base::RED
);
270 w
= parent
->right ();
274 w
->color (parent
->color ());
276 w
->right ()->color (ACE_RB_Tree_Node_Base::BLACK
);
278 parent
->color (ACE_RB_Tree_Node_Base::BLACK
);
279 RB_rotate_left (parent
);
285 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *w
= parent
->left ();
286 if (w
&& w
->color () == ACE_RB_Tree_Node_Base::RED
)
288 w
->color (ACE_RB_Tree_Node_Base::BLACK
);
289 parent
->color (ACE_RB_Tree_Node_Base::RED
);
290 RB_rotate_right (parent
);
293 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
296 || w
->left ()->color () == ACE_RB_Tree_Node_Base::BLACK
)
298 || w
->right ()->color () == ACE_RB_Tree_Node_Base::BLACK
))
300 w
->color (ACE_RB_Tree_Node_Base::RED
);
302 parent
= x
->parent ();
306 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
309 || w
->left ()->color () == ACE_RB_Tree_Node_Base::BLACK
))
311 w
->color (ACE_RB_Tree_Node_Base::RED
);
313 w
->right ()->color (ACE_RB_Tree_Node_Base::BLACK
);
319 w
->color (parent
->color ());
321 w
->left ()->color (ACE_RB_Tree_Node_Base::BLACK
);
323 parent
->color (ACE_RB_Tree_Node_Base::BLACK
);
324 RB_rotate_right (parent
);
331 x
->color (ACE_RB_Tree_Node_Base::BLACK
);
334 // Return a pointer to a matching node if there is one, a pointer to
335 // the node under which to insert the item if the tree is not empty
336 // and there is no such match, or 0 if the tree is empty.
338 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *
339 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::find_node (const EXT_ID
&k
, ACE_RB_Tree_Base::RB_SearchResult
&result
)
341 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node");
343 // Start at the root.
344 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *current
= root_
;
348 // While there are more nodes to examine.
349 if (this->lessthan (current
->key (), k
))
351 // If the search key is greater than the current node's key.
352 if (current
->right ())
353 // If the right subtree is not empty, search to the right.
354 current
= current
->right ();
357 // If the right subtree is empty, we're done searching,
358 // and are positioned to the left of the insertion point.
363 else if (this->lessthan (k
, current
->key ()))
365 // Else if the search key is less than the current node's key.
366 if (current
->left ())
367 // If the left subtree is not empty, search to the left.
368 current
= current
->left ();
371 // If the left subtree is empty, we're done searching,
372 // and are positioned to the right of the insertion point.
379 // If the keys match exactly, we're done as well.
388 // Rebalance the tree after insertion of a node.
390 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
391 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_rebalance (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> * x
)
393 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rebalance");
395 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *y
= 0;
399 && x
->parent ()->color () == ACE_RB_Tree_Node_Base::RED
)
401 if (! x
->parent ()->parent ())
403 // If we got here, something is drastically wrong!
404 ACELIB_ERROR ((LM_ERROR
,
406 ACE_TEXT ("\nerror: parent's parent is null in ")
407 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rebalance\n")));
411 if (x
->parent () == x
->parent ()->parent ()->left ())
413 y
= x
->parent ()->parent ()->right ();
414 if (y
&& y
->color () == ACE_RB_Tree_Node_Base::RED
)
416 // Handle case 1 (see CLR book, pp. 269).
417 x
->parent ()->color (ACE_RB_Tree_Node_Base::BLACK
);
418 y
->color (ACE_RB_Tree_Node_Base::BLACK
);
419 x
->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED
);
420 x
= x
->parent ()->parent ();
424 if (x
== x
->parent ()->right ())
426 // Transform case 2 into case 3 (see CLR book, pp. 269).
431 // Handle case 3 (see CLR book, pp. 269).
432 x
->parent ()->color (ACE_RB_Tree_Node_Base::BLACK
);
433 x
->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED
);
434 RB_rotate_right (x
->parent ()->parent ());
439 y
= x
->parent ()->parent ()->left ();
440 if (y
&& y
->color () == ACE_RB_Tree_Node_Base::RED
)
442 // Handle case 1 (see CLR book, pp. 269).
443 x
->parent ()->color (ACE_RB_Tree_Node_Base::BLACK
);
444 y
->color (ACE_RB_Tree_Node_Base::BLACK
);
445 x
->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED
);
446 x
= x
->parent ()->parent ();
450 if (x
== x
->parent ()->left ())
452 // Transform case 2 into case 3 (see CLR book, pp. 269).
457 // Handle case 3 (see CLR book, pp. 269).
458 x
->parent ()->color (ACE_RB_Tree_Node_Base::BLACK
);
459 x
->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED
);
460 RB_rotate_left (x
->parent ()->parent ());
466 // Method to find the successor node of the given node in the tree.
468 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *
469 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_tree_successor (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
) const
471 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor");
477 return RB_tree_minimum (x
->right ());
479 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *y
= x
->parent ();
480 while ((y
) && (x
== y
->right ()))
489 // Method to find the predecessor node of the given node in the tree.
491 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *
492 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_tree_predecessor (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
) const
494 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_predecessor");
499 return RB_tree_maximum (x
->left ());
501 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *y
= x
->parent ();
503 while ((y
) && (x
== y
->left ()))
512 // Method to find the minimum node of the subtree rooted at the given node.
514 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *
515 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_tree_minimum (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
) const
517 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_minimum");
519 while ((x
) && (x
->left ()))
525 // Method to find the maximum node of the subtree rooted at the given node.
527 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *
528 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::RB_tree_maximum (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
) const
530 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_maximum");
532 while ((x
) && (x
->right ()))
538 // Delete children (left and right) of the node. Must be called with
540 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
541 void ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::delete_children_i
542 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *parent
)
546 this->delete_children_i (parent
->left ());
547 this->delete_children_i (parent
->right ());
548 ACE_DES_FREE_TEMPLATE2
550 this->allocator_
->free
,
553 ACE_DES_FREE_TEMPLATE2
555 this->allocator_
->free
,
564 // Close down an RB_Tree. this method should only be called with
565 // locks already held.
567 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
568 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::close_i ()
570 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::close_i");
572 this->delete_children_i (this->root_
);
573 ACE_DES_FREE_TEMPLATE2 (this->root_
,
574 this->allocator()->free
,
577 this->current_size_
= 0;
582 // Returns a pointer to the item corresponding to the given key, or 0
583 // if it cannot find the key in the tree. This method should only be
584 // called with locks already held.
586 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
587 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::find_i (const EXT_ID
&k
,
588 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>* &entry
, int find_exact
)
590 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_i");
592 // Try to find a match.
593 RB_SearchResult result
= LEFT
;
594 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *current
= find_node (k
, result
);
599 if (!find_exact
|| result
== EXACT
)
600 entry
= current
; // Assign the entry for any match.
601 return (result
== EXACT
? 0 : -1);
604 // The node is not there.
608 // Inserts a *copy* of the key and the item into the tree: both the
609 // key type EXT_ID and the item type INT_ID must have well defined
610 // semantics for copy construction and < comparison. This method
611 // returns a pointer to the inserted item copy, or 0 if an error
612 // occurred. NOTE: if an identical key already exists in the tree, no
613 // new item is created, and the returned pointer addresses the
614 // existing item associated with the existing key. This method should
615 // only be called with locks already held.
617 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> INT_ID
*
618 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::insert_i (const EXT_ID
&k
, const INT_ID
&t
)
620 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)");
622 // Find the closest matching node, if there is one.
623 RB_SearchResult result
= LEFT
;
624 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *current
= find_node (k
, result
);
627 // If the keys match, just return a pointer to the node's item.
629 return ¤t
->item ();
631 // Otherwise if we're to the left of the insertion point, insert
632 // into the right subtree.
633 else if (result
== LEFT
)
635 if (current
->right ())
637 // If there is already a right subtree, complain.
638 ACELIB_ERROR_RETURN ((LM_ERROR
,
640 ACE_TEXT ("\nright subtree already present in ")
641 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
646 // The right subtree is empty: insert new node there.
647 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *tmp
= 0;
649 ACE_NEW_MALLOC_RETURN
651 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
652 (this->allocator_
->malloc (sizeof (*tmp
)))),
653 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
655 current
->right (tmp
);
657 // If the node was successfully inserted, set its
658 // parent, rebalance the tree, color the root black, and
659 // return a pointer to the inserted item.
660 INT_ID
*item
= &(current
->right ()->item ());
661 current
->right ()->parent (current
);
662 RB_rebalance (current
->right ());
663 root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
668 // Otherwise, we're to the right of the insertion point, so
669 // insert into the left subtree.
670 else // (result == RIGHT)
672 if (current
->left ())
673 // If there is already a left subtree, complain.
674 ACELIB_ERROR_RETURN ((LM_ERROR
,
676 ACE_TEXT ("\nleft subtree already present in ")
677 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
681 // The left subtree is empty: insert new node there.
682 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *tmp
= 0;
683 ACE_NEW_MALLOC_RETURN
685 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
686 (this->allocator_
->malloc (sizeof (*tmp
)))),
687 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
691 // If the node was successfully inserted, set its
692 // parent, rebalance the tree, color the root black, and
693 // return a pointer to the inserted item.
694 INT_ID
*item
= ¤t
->left ()->item ();
695 current
->left ()->parent (current
);
696 RB_rebalance (current
->left ());
697 root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
705 // The tree is empty: insert at the root and color the root
707 ACE_NEW_MALLOC_RETURN
709 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
710 (this->allocator_
->malloc (sizeof (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>)))),
711 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
713 this->root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
715 return &this->root_
->item ();
719 // Inserts a *copy* of the key and the item into the tree: both the
720 // key type EXT_ID and the item type INT_ID must have well defined
721 // semantics for copy construction. The default implementation also
722 // requires that the key type support well defined < semantics. This
723 // method passes back a pointer to the inserted (or existing) node,
724 // and the search status. If the node already exists, the method
725 // returns 1. If the node does not exist, and a new one is
726 // successfully created, and the method returns 0. If there was an
727 // error, the method returns -1.
729 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
730 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::insert_i (const EXT_ID
&k
,
732 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *&entry
)
734 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i");
736 // Find the closest matching node, if there is one.
737 RB_SearchResult result
= LEFT
;
738 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *current
= find_node (k
, result
);
741 // If the keys match, just return a pointer to the node's item.
747 // Otherwise if we're to the left of the insertion
748 // point, insert into the right subtree.
749 else if (result
== LEFT
)
751 if (current
->right ())
753 // If there is already a right subtree, complain.
754 ACELIB_ERROR_RETURN ((LM_ERROR
,
756 ACE_TEXT ("\nright subtree already present in ")
757 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
762 // The right subtree is empty: insert new node there.
763 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *tmp
= 0;
764 ACE_NEW_MALLOC_RETURN
766 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
767 (this->allocator_
->malloc (sizeof (*tmp
)))),
768 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
770 current
->right (tmp
);
772 // If the node was successfully inserted, set its parent, rebalance
773 // the tree, color the root black, and return a pointer to the
775 entry
= current
->right ();
776 current
->right ()->parent (current
);
777 RB_rebalance (current
->right ());
778 this->root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
779 ++this->current_size_
;
783 // Otherwise, we're to the right of the insertion point, so
784 // insert into the left subtree.
785 else // (result == RIGHT)
787 if (current
->left ())
788 // If there is already a left subtree, complain.
789 ACELIB_ERROR_RETURN ((LM_ERROR
,
791 ACE_TEXT ("\nleft subtree already present in ")
792 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
796 // The left subtree is empty: insert new node there.
797 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *tmp
= 0;
798 ACE_NEW_MALLOC_RETURN
800 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
801 (this->allocator_
->malloc (sizeof (*tmp
)))),
802 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
805 // If the node was successfully inserted, set its
806 // parent, rebalance the tree, color the root black, and
807 // return a pointer to the inserted item.
808 entry
= current
->left ();
809 current
->left ()->parent (current
);
810 RB_rebalance (current
->left ());
811 this->root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
812 ++this->current_size_
;
819 // The tree is empty: insert at the root and color the root black.
820 ACE_NEW_MALLOC_RETURN
822 (reinterpret_cast<ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>*>
823 (this->allocator_
->malloc (sizeof (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>)))),
824 (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>) (k
, t
),
826 this->root_
->color (ACE_RB_Tree_Node_Base::BLACK
);
827 ++this->current_size_
;
833 // Removes the item associated with the given key from the tree and
834 // destroys it. Returns 1 if it found the item and successfully
835 // destroyed it, 0 if it did not find the item, or -1 if an error
836 // occurred. This method should only be called with locks already
839 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
840 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::remove_i (const EXT_ID
&k
, INT_ID
&i
)
842 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)");
844 // Find a matching node, if there is one.
845 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *z
;
846 RB_SearchResult result
= LEFT
;
847 z
= find_node (k
, result
);
849 // If there is a matching node: remove and destroy it.
850 if (z
&& result
== EXACT
)
852 // Return the internal id stored in the deleted node.
854 return -1 == this->remove_i (z
) ? -1 : 1;
857 // No matching node was found: return 0.
861 /// Recursive function to dump the state of an object.
862 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
863 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::
864 dump_i (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *node
) const
866 #if defined (ACE_HAS_DUMP)
871 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ndown left\n")));
872 this->dump_i (node
->left ());
873 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nup left\n")));
875 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ndown right\n")));
876 this->dump_i (node
->right ());
877 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nup right\n")));
881 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nNULL POINTER (BLACK)\n")));
883 #else /* !ACE_HAS_DUMP */
884 ACE_UNUSED_ARG (node
);
885 #endif /* ACE_HAS_DUMP */
888 /// Function to dump node itself. Does not show parameterized node contents
889 /// in its basic form, but template specialization can be used to
890 /// provide definitions for various EXT_ID and INT_ID types.
892 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
893 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::
894 dump_node_i (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> &node
) const
896 #if defined (ACE_HAS_DUMP)
897 const char * color_str
= (node
.color () == ACE_RB_Tree_Node_Base::RED
)
900 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT (" color=[%s]\n"), color_str
));
901 #else /* !ACE_HAS_DUMP */
902 ACE_UNUSED_ARG (node
);
903 #endif /* ACE_HAS_DUMP */
906 /// Tests the red-black invariant(s) throughout the whole tree.
908 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
909 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::test_invariant (void)
911 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant");
912 ACE_READ_GUARD_RETURN (ACE_LOCK
, ace_mon
, this->lock_
, -1);
914 // Recurse from the root, starting with the measured black height at
915 // 0, and the expected black height at -1, which will cause the
916 // count from first measured path to a leaf to be used as the
917 // expected one from that point onward (the key is to check
919 int expected_black_height
= -1;
920 if (this->test_invariant_recurse (this->root_
, expected_black_height
, 0) == 0)
922 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("invariant holds\n")));
929 /// Recursive function to test the red-black invariant(s) at all nodes in a subtree.
931 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
932 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::test_invariant_recurse (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
,
933 int & expected_black_height
,
934 int measured_black_height
)
936 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant_recurse");
940 // Count each leaf (zero pointer) as a black node (per CLR algorithm description).
941 ++measured_black_height
;
943 if (expected_black_height
== -1)
945 expected_black_height
= measured_black_height
;
947 else if (expected_black_height
!= measured_black_height
)
949 ACELIB_ERROR_RETURN ((LM_ERROR
,
950 ACE_TEXT ("\nexpected_black_height = %d but ")
951 ACE_TEXT ("\nmeasured_black_height = %d in ")
952 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n"),
953 expected_black_height
, measured_black_height
),
960 // Check the invariant that a red node cannot have a red child.
961 if (x
->color () == ACE_RB_Tree_Node_Base::RED
)
963 if (x
->left () && x
->left ()->color () == ACE_RB_Tree_Node_Base::RED
)
965 ACELIB_ERROR_RETURN ((LM_ERROR
,
967 ACE_TEXT ("\nRED parent has RED left child in ")
968 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
972 if (x
->right () && x
->right ()->color () == ACE_RB_Tree_Node_Base::RED
)
974 ACELIB_ERROR_RETURN ((LM_ERROR
,
976 ACE_TEXT ("\nRED parent has RED right child in ")
977 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
983 // Count each black node traversed.
984 ++measured_black_height
;
987 return (test_invariant_recurse (x
->left (), expected_black_height
, measured_black_height
) == 0)
988 ? test_invariant_recurse (x
->right (), expected_black_height
, measured_black_height
)
992 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> int
993 ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::remove_i (ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *z
)
995 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)");
997 // Delete the node and reorganize the tree to satisfy the Red-Black
1000 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *x
;
1001 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *y
;
1002 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *parent
;
1004 if (z
->left () && z
->right ())
1005 y
= RB_tree_successor (z
);
1017 parent
= y
->parent ();
1025 if (y
== parent
->left ())
1035 // Replace node z with node y, since y's pointer may well be
1036 // held externally, and be linked with y's key and item.
1037 // We will end up deleting the old unlinked, node z.
1039 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *zParent
= z
->parent ();
1040 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *zLeftChild
= z
->left ();
1041 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
> *zRightChild
= z
->right ();
1045 if (z
== zParent
->left ())
1058 y
->parent (zParent
);
1062 zLeftChild
->parent (y
);
1064 y
->left (zLeftChild
);
1068 zRightChild
->parent (y
);
1070 y
->right (zRightChild
);
1077 ACE_RB_Tree_Node_Base::RB_Tree_Node_Color yColor
= y
->color ();
1078 y
->color (z
->color ());
1081 //Reassign the y pointer to z because the node that y points to will be
1086 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
1087 if (!y
|| y
->color () == ACE_RB_Tree_Node_Base::BLACK
)
1088 RB_delete_fixup (x
, parent
);
1093 ACE_DES_FREE_TEMPLATE2 (y
,
1094 this->allocator_
->free
,
1097 --this->current_size_
;
1104 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1105 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
, int set_first
)
1106 : tree_ (&tree
), node_ (0)
1108 ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (ACE_RB_Tree, int)");
1110 // Position the iterator at the first (or last) node in the tree.
1112 node_
= tree_
->RB_tree_minimum (tree_
->root_
);
1114 node_
= tree_
->RB_tree_maximum (tree_
->root_
);
1117 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1118 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
, ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>* entry
)
1119 : tree_ (&tree
), node_ (0)
1121 ACE_TRACE ("ACE_RB_Tree_Iterator_Base(const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)");
1125 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1126 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator_Base (const EXT_ID
& key
,ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
)
1127 : tree_ (&tree
), node_ (0)
1129 ACE_TRACE("ACE_RB_Tree_Iterator_Base (ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, const EXT_ID& key)");
1130 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>* entry
= 0;
1131 tree
.find_i(key
, entry
);
1135 // Copy constructor.
1137 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1138 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &iter
)
1139 : tree_ (iter
.tree_
),
1142 ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (ACE_RB_Tree_Iterator_Base)");
1145 // Assignment operator.
1147 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
> void
1148 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::operator= (const ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &iter
)
1150 ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator=");
1160 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1161 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::~ACE_RB_Tree_Iterator_Base ()
1163 ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator_Base");
1166 // Dump the state of an object.
1168 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1170 ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::dump_i (void) const
1172 ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::dump_i");
1174 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
1175 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nnode_ = %x\n"), this->node_
));
1176 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
1182 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1183 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
,
1185 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> (tree
, set_first
)
1187 ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
1190 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1191 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
,
1192 ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>* entry
)
1193 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> (tree
,entry
)
1195 ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
1198 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1199 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Iterator (const EXT_ID
& key
,ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
)
1200 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>(key
,tree
)
1202 ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
1207 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1208 ACE_RB_Tree_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::~ACE_RB_Tree_Iterator ()
1210 ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator");
1216 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1217 ACE_RB_Tree_Reverse_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
, int set_last
)
1218 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> (tree
, set_last
? 0 : 1)
1220 ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
1223 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1224 ACE_RB_Tree_Reverse_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
, ACE_RB_Tree_Node
<EXT_ID
, INT_ID
>* entry
)
1225 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> (tree
,entry
)
1227 ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
1230 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1231 ACE_RB_Tree_Reverse_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::ACE_RB_Tree_Reverse_Iterator (const EXT_ID
& key
,ACE_RB_Tree
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
> &tree
)
1232 : ACE_RB_Tree_Iterator_Base
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>(key
,tree
)
1234 ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
1239 template <class EXT_ID
, class INT_ID
, class COMPARE_KEYS
, class ACE_LOCK
>
1240 ACE_RB_Tree_Reverse_Iterator
<EXT_ID
, INT_ID
, COMPARE_KEYS
, ACE_LOCK
>::~ACE_RB_Tree_Reverse_Iterator ()
1242 ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Reverse_Iterator");
1245 ACE_END_VERSIONED_NAMESPACE_DECL
1247 #endif /* !ACE_RB_TREE_CPP */