Correct feature names
[ACE_TAO.git] / ACE / ace / RB_Tree.cpp
blob0c8c2a713b6bfb188317b6d27655f84b2e7a024c
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)
9 # 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)
25 // Constructor.
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)
29 : k_ (k),
30 t_ (t),
31 color_ (RED),
32 parent_ (0),
33 left_ (0),
34 right_ (0)
36 ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)");
40 // Destructor.
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");
48 // Constructor.
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)
52 : root_ (0),
53 current_size_ (0)
55 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (ACE_Allocator *alloc)");
56 allocator_ = alloc;
57 if (this->open (alloc) == -1)
58 ACELIB_ERROR ((LM_ERROR,
59 ACE_TEXT ("ACE_RB_Tree::ACE_RB_Tree\n")));
62 // Copy constructor.
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)
66 : root_ (0),
67 current_size_ (0)
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);
76 for (iter.first ();
78 iter.is_done () == 0; iter.next ())
79 insert_i (*(iter.key ()),
80 *(iter.item ()));
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 (
85 void *location,
86 ACE_Allocator *alloc
89 ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (void *, ACE_Allocator *)");
91 if (location != this)
93 this->root_ = 0;
94 this->current_size_ = 0;
97 this->allocator_ = alloc;
99 // Destructor.
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.
108 this->close ();
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_);
119 if (this != &rbt)
121 // Clear out the existing tree.
122 close_i ();
124 // Make a deep copy of the passed tree.
125 ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iter(rbt);
127 for (iter.first ();
128 iter.is_done () == 0;
129 iter.next ())
130 insert_i (*(iter.key ()),
131 *(iter.item ()));
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");
154 if (!x)
155 ACELIB_ERROR ((LM_ERROR,
156 ACE_TEXT ("%p\n"),
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,
161 ACE_TEXT ("%p\n"),
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")));
164 else
166 ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
167 y = x->left ();
168 x->left (y->right ());
169 if (y->right ())
170 y->right ()->parent (x);
171 y->parent (x->parent ());
172 if (x->parent ())
174 if (x == x->parent ()->right ())
175 x->parent ()->right (y);
176 else
177 x->parent ()->left (y);
179 else
180 root_ = y;
181 y->right (x);
182 x->parent (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");
193 if (! x)
194 ACELIB_ERROR ((LM_ERROR,
195 ACE_TEXT ("%p\n"),
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,
200 ACE_TEXT ("%p\n"),
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")));
203 else
205 ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
206 y = x->right ();
207 x->right (y->left ());
208 if (y->left ())
209 y->left ()->parent (x);
210 y->parent (x->parent ());
211 if (x->parent ())
213 if (x == x->parent ()->left ())
214 x->parent ()->left (y);
215 else
216 x->parent ()->right (y);
218 else
219 root_ = y;
220 y->left (x);
221 x->parent (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_
235 && (!x
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
249 if (w
250 && (!w->left ()
251 || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
252 && (!w->right ()
253 || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
255 w->color (ACE_RB_Tree_Node_Base::RED);
256 x = parent;
257 parent = x->parent ();
259 else
261 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
262 if (w
263 && (!w->right ()
264 || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
266 if (w->left ())
267 w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
268 w->color (ACE_RB_Tree_Node_Base::RED);
269 RB_rotate_right (w);
270 w = parent->right ();
272 if (w)
274 w->color (parent->color ());
275 if (w->right ())
276 w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
278 parent->color (ACE_RB_Tree_Node_Base::BLACK);
279 RB_rotate_left (parent);
280 x = root_;
283 else
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);
291 w = parent->left ();
293 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
294 if (w
295 && (!w->left ()
296 || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
297 && (!w->right ()
298 || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
300 w->color (ACE_RB_Tree_Node_Base::RED);
301 x = parent;
302 parent = x->parent ();
304 else
306 // CLR pp. 263 says that nil nodes are implicitly colored BLACK
307 if (w
308 && (!w->left ()
309 || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK))
311 w->color (ACE_RB_Tree_Node_Base::RED);
312 if (w->right ())
313 w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
314 RB_rotate_left (w);
315 w = parent->left ();
317 if (w)
319 w->color (parent->color ());
320 if (w->left ())
321 w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
323 parent->color (ACE_RB_Tree_Node_Base::BLACK);
324 RB_rotate_right (parent);
325 x = root_;
330 if (x)
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_;
346 while (current)
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 ();
355 else
357 // If the right subtree is empty, we're done searching,
358 // and are positioned to the left of the insertion point.
359 result = LEFT;
360 break;
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 ();
369 else
371 // If the left subtree is empty, we're done searching,
372 // and are positioned to the right of the insertion point.
373 result = RIGHT;
374 break;
377 else
379 // If the keys match exactly, we're done as well.
380 result = EXACT;
381 break;
385 return current;
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;
397 while (x &&
398 x->parent ()
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,
405 ACE_TEXT ("%p\n"),
406 ACE_TEXT ("\nerror: parent's parent is null in ")
407 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rebalance\n")));
408 return;
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 ();
422 else
424 if (x == x->parent ()->right ())
426 // Transform case 2 into case 3 (see CLR book, pp. 269).
427 x = x->parent ();
428 RB_rotate_left (x);
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 ());
437 else
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 ();
448 else
450 if (x == x->parent ()->left ())
452 // Transform case 2 into case 3 (see CLR book, pp. 269).
453 x = x->parent ();
454 RB_rotate_right (x);
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");
473 if (x == 0)
474 return 0;
476 if (x->right ())
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 ()))
482 x = y;
483 y = y->parent ();
486 return y;
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");
495 if (x == 0)
496 return 0;
498 if (x->left ())
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 ()))
505 x = y;
506 y = y->parent ();
509 return y;
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 ()))
520 x = x->left ();
522 return x;
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 ()))
533 x = x->right ();
535 return x;
538 // Delete children (left and right) of the node. Must be called with
539 // lock held.
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)
544 if (parent)
546 this->delete_children_i (parent->left ());
547 this->delete_children_i (parent->right ());
548 ACE_DES_FREE_TEMPLATE2
549 (parent->left (),
550 this->allocator_->free,
551 ACE_RB_Tree_Node,
552 EXT_ID, INT_ID);
553 ACE_DES_FREE_TEMPLATE2
554 (parent->right (),
555 this->allocator_->free,
556 ACE_RB_Tree_Node,
557 EXT_ID, INT_ID);
558 parent->left (0);
559 parent->right (0);
561 return;
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,
575 ACE_RB_Tree_Node,
576 EXT_ID, INT_ID);
577 this->current_size_ = 0;
578 this->root_ = 0;
579 return 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);
596 if (current)
598 // Found a match
599 if (!find_exact || result == EXACT)
600 entry = current; // Assign the entry for any match.
601 return (result == EXACT ? 0 : -1);
603 else
604 // The node is not there.
605 return -1;
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);
625 if (current)
627 // If the keys match, just return a pointer to the node's item.
628 if (result == EXACT)
629 return &current->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,
639 ACE_TEXT ("%p\n"),
640 ACE_TEXT ("\nright subtree already present in ")
641 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
644 else
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
650 (tmp,
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);
664 ++current_size_;
665 return item;
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,
675 ACE_TEXT ("%p\n"),
676 ACE_TEXT ("\nleft subtree already present in ")
677 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
679 else
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
684 (tmp,
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),
689 current->left (tmp);
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 = &current->left ()->item ();
695 current->left ()->parent (current);
696 RB_rebalance (current->left ());
697 root_->color (ACE_RB_Tree_Node_Base::BLACK);
698 ++current_size_;
699 return item;
703 else
705 // The tree is empty: insert at the root and color the root
706 // black.
707 ACE_NEW_MALLOC_RETURN
708 (this->root_,
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);
714 ++current_size_;
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,
731 const INT_ID &t,
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);
739 if (current)
741 // If the keys match, just return a pointer to the node's item.
742 if (result == EXACT)
744 entry = current;
745 return 1;
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,
755 ACE_TEXT ("%p\n"),
756 ACE_TEXT ("\nright subtree already present in ")
757 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
758 -1);
760 else
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
765 (tmp,
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),
769 -1);
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
774 // inserted item.
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_;
780 return 0;
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,
790 ACE_TEXT ("%p\n"),
791 ACE_TEXT ("\nleft subtree already present in ")
792 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
793 -1);
794 else
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
799 (tmp,
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),
803 -1);
804 current->left (tmp);
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_;
813 return 0;
817 else
819 // The tree is empty: insert at the root and color the root black.
820 ACE_NEW_MALLOC_RETURN
821 (this->root_,
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),
825 -1);
826 this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
827 ++this->current_size_;
828 entry = this->root_;
829 return 0;
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
837 // held.
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.
853 i = z->item ();
854 return -1 == this->remove_i (z) ? -1 : 1;
857 // No matching node was found: return 0.
858 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)
867 if (node)
869 dump_node_i (*node);
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")));
879 else
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)
898 ? "RED" : "BLACK";
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
918 // consistency).
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")));
923 return 0;
926 return -1;
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");
938 if (!x)
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),
954 -1);
957 return 0;
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,
966 ACE_TEXT ("%p\n"),
967 ACE_TEXT ("\nRED parent has RED left child in ")
968 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
969 -1);
972 if (x->right () && x->right ()->color () == ACE_RB_Tree_Node_Base::RED)
974 ACELIB_ERROR_RETURN ((LM_ERROR,
975 ACE_TEXT ("%p\n"),
976 ACE_TEXT ("\nRED parent has RED right child in ")
977 ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
978 -1);
981 else
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)
989 : -1;
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
998 // properties.
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);
1006 else
1007 y = z;
1009 if (!y)
1010 return -1;
1012 if (y->left ())
1013 x = y->left ();
1014 else
1015 x = y->right ();
1017 parent = y->parent ();
1018 if (x)
1020 x->parent (parent);
1023 if (parent)
1025 if (y == parent->left ())
1026 parent->left (x);
1027 else
1028 parent->right (x);
1030 else
1031 this->root_ = x;
1033 if (y != z)
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 ();
1043 if (zParent)
1045 if (z == zParent->left ())
1047 zParent->left (y);
1049 else
1051 zParent->right (y);
1054 else
1056 this->root_ = y;
1058 y->parent (zParent);
1060 if (zLeftChild)
1062 zLeftChild->parent (y);
1064 y->left (zLeftChild);
1066 if (zRightChild)
1068 zRightChild->parent (y);
1070 y->right (zRightChild);
1072 if (parent == z)
1074 parent = y;
1077 ACE_RB_Tree_Node_Base::RB_Tree_Node_Color yColor = y->color ();
1078 y->color (z->color ());
1079 z->color (yColor);
1081 //Reassign the y pointer to z because the node that y points to will be
1082 //deleted
1083 y = z;
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);
1090 y->parent (0);
1091 y->right (0);
1092 y->left (0);
1093 ACE_DES_FREE_TEMPLATE2 (y,
1094 this->allocator_->free,
1095 ACE_RB_Tree_Node,
1096 EXT_ID, INT_ID);
1097 --this->current_size_;
1099 return 0;
1102 // Constructor.
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.
1111 if (set_first)
1112 node_ = tree_->RB_tree_minimum (tree_->root_);
1113 else
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)");
1122 node_ = 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);
1132 node_ = 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_),
1140 node_ (iter.node_)
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=");
1151 if (this != &iter)
1153 tree_ = iter.tree_;
1154 node_ = iter.node_;
1158 // Destructor.
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>
1169 void
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));
1180 // Constructor.
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,
1184 int set_first)
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");
1205 // Destructor.
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");
1214 // Constructor.
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");
1237 // Destructor.
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 */