// -*- C++ -*- // // $Id: RB_Tree.inl 96985 2013-04-11 15:50:32Z huangh $ #include "ace/Guard_T.h" #include "ace/Malloc_Base.h" #include "ace/Log_Category.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL ///////////////////////////////////////////////////// // template class ACE_RB_Tree_Node // ///////////////////////////////////////////////////// // Key accessor. template ACE_INLINE EXT_ID & ACE_RB_Tree_Node::key () { ACE_TRACE ("ACE_RB_Tree_Node::key"); return k_; } // Item accessor. template ACE_INLINE INT_ID & ACE_RB_Tree_Node::item () { ACE_TRACE ("ACE_RB_Tree_Node:item"); return t_; } // Set color of the node. template ACE_INLINE void ACE_RB_Tree_Node::color (ACE_RB_Tree_Node_Base::RB_Tree_Node_Color c) { ACE_TRACE ("ACE_RB_Tree_Node::color mutator"); color_ = c; } // Get color of the node. template ACE_INLINE ACE_RB_Tree_Node_Base::RB_Tree_Node_Color ACE_RB_Tree_Node::color () { ACE_TRACE ("ACE_RB_Tree_Node::color accessor"); return color_; } // Accessor for node's parent pointer. template ACE_INLINE ACE_RB_Tree_Node * ACE_RB_Tree_Node::parent () { ACE_TRACE ("ACE_RB_Tree_Node::parent accessor"); return parent_; } // Mutator for node's parent pointer. template ACE_INLINE void ACE_RB_Tree_Node::parent (ACE_RB_Tree_Node * p) { ACE_TRACE ("ACE_RB_Tree_Node::parent mutator"); parent_ = p; } // Accessor for node's left child pointer. template ACE_INLINE ACE_RB_Tree_Node * ACE_RB_Tree_Node::left () { ACE_TRACE ("ACE_RB_Tree_Node::left accessor"); return left_; } // Mutator for node's left child pointer. template ACE_INLINE void ACE_RB_Tree_Node::left (ACE_RB_Tree_Node * l) { ACE_TRACE ("ACE_RB_Tree_Node::left mutator"); left_ = l; } // Accessor for node's right child pointer. template ACE_INLINE ACE_RB_Tree_Node * ACE_RB_Tree_Node::right () { ACE_TRACE ("ACE_RB_Tree_Node::right accessor"); return right_; } // Mutator for node's right child pointer. template ACE_INLINE void ACE_RB_Tree_Node::right (ACE_RB_Tree_Node * r) { ACE_TRACE ("ACE_RB_Tree_Node::right mutator"); right_ = r; } //////////////////////////////////////////////////////////////////////// // template class ACE_RB_Tree // //////////////////////////////////////////////////////////////////////// // Initialize an RB Tree. template ACE_INLINE int ACE_RB_Tree::open (ACE_Allocator *alloc) { ACE_TRACE ("ACE_RB_Tree::open"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); // Calling this->close_i () ensures we release previously allocated // memory before allocating new memory. this->close_i (); // If we were passed an allocator use it, // otherwise use the default instance. if (alloc == 0) alloc = ACE_Allocator::instance (); this->allocator_ = alloc; return 0; } // Close down an RB_Tree and release dynamically allocated // resources. template ACE_INLINE int ACE_RB_Tree::close (void) { ACE_TRACE ("ACE_RB_Tree::close"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); return this->close_i (); } // Associate with . If is already in the // tree then the is not changed. Returns 0 if a // new entry is bound successfully, returns 1 if an attempt is made // to bind an existing entry, and returns -1 if failures occur. template ACE_INLINE int ACE_RB_Tree::bind (const EXT_ID &ext_id, const INT_ID &int_id) { ACE_TRACE ("ACE_RB_Tree::bind (const EXT_ID &item, const INT_ID &int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry; return this->insert_i (ext_id, int_id, entry); } // Same as a normal bind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. template ACE_INLINE int ACE_RB_Tree::bind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::bind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); return this->insert_i (ext_id, int_id, entry); } // Associate with if and only if is not // in the tree. If is already in the tree then the // parameter is assigned the existing value in the tree. Returns 0 // if a new entry is bound successfully, returns 1 if an attempt is // made to bind an existing entry, and returns -1 if failures occur. template ACE_INLINE int ACE_RB_Tree::trybind (const EXT_ID &ext_id, INT_ID &int_id) { ACE_TRACE ("ACE_RB_Tree::trybind (const EXT_ID &ext_id, INT_ID &int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry; int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { int_id = entry->item (); } return result; } // Same as a normal trybind, except the tree entry is also passed // back to the caller. The entry in this case will either be the // newly created entry, or the existing one. template ACE_INLINE int ACE_RB_Tree::trybind (const EXT_ID &ext_id, INT_ID &int_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::trybind (const EXT_ID &ext_id, INT_ID &int_id, ACE_RB_Tree_Node *&entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { int_id = entry->item (); } return result; } // Reassociate with . If is not in the // tree then behaves just like . Returns 0 if a new entry is // bound successfully, returns 1 if an existing entry was rebound, // and returns -1 if failures occur. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry; int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { entry->key () = ext_id; entry->item () = int_id; } return result; } // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { entry->key () = ext_id; entry->item () = int_id; } return result; } // Associate with . If is not in the tree // then behaves just like . Otherwise, store the old value of // into the "out" parameter and rebind the new parameters. // Returns 0 if a new entry is bound successfully, returns 1 if an // existing entry was rebound, and returns -1 if failures occur. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, INT_ID &old_int_id) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, INT_ID &old_int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry; int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { old_int_id = entry->item (); entry->key () = ext_id; entry->item () = int_id; } return result; } // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, INT_ID &old_int_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id,INT_ID &old_int_id, ACE_RB_Tree_Node *&entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { old_int_id = entry->item (); entry->key () = ext_id; entry->item () = int_id; } return result; } // Associate with . If is not in the tree // then behaves just like . Otherwise, store the old values // of and into the "out" parameters and rebind the // new parameters. This is very useful if you need to have an // atomic way of updating and you also need // full control over memory allocation. Returns 0 if a new entry is // bound successfully, returns 1 if an existing entry was rebound, // and returns -1 if failures occur. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, EXT_ID &old_ext_id, INT_ID &old_int_id) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id,EXT_ID &old_ext_id, INT_ID &old_int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry; int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { old_ext_id = entry->key (); old_int_id = entry->item (); entry->key () = ext_id; entry->item () = int_id; } return result; } // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. template ACE_INLINE int ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, EXT_ID &old_ext_id, INT_ID &old_int_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::rebind (const EXT_ID &ext_id, const INT_ID &int_id, EXT_ID &old_ext_id, INT_ID &old_int_id, ACE_RB_Tree_Node *&entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); int result = this->insert_i (ext_id, int_id, entry); if (result == 1) { old_ext_id = entry->key (); old_int_id = entry->item (); entry->key () = ext_id; entry->item () = int_id; } return result; } // Locate and pass out parameter via . If found, // return 0, returns -1 if not found. template ACE_INLINE int ACE_RB_Tree::find (const EXT_ID &ext_id, INT_ID &int_id) { ACE_TRACE ("ACE_RB_Tree::find (const EXT_ID &ext_id, INT_ID &int_id)"); ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); ACE_RB_Tree_Node *entry = 0; int result = this->find_i (ext_id, entry); if (result == 0) { int_id = entry->item (); } return result; } // Locate and pass out parameter via . If found, // return 0, returns -1 if not found. template ACE_INLINE int ACE_RB_Tree::find (const EXT_ID &ext_id, ACE_RB_Tree_Node *&entry) { ACE_TRACE ("ACE_RB_Tree::find (const EXT_ID &ext_id, ACE_RB_Tree_Node *&entry)"); ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); return this->find_i (ext_id, entry); } // Unbind (remove) the from the tree. Don't return the // to the caller (this is useful for collections where the // s are *not* dynamically allocated...). template ACE_INLINE int ACE_RB_Tree::unbind (const EXT_ID &ext_id) { ACE_TRACE ("ACE_RB_Tree::unbind (const EXT_ID &ext_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); INT_ID int_id; int result = this->remove_i (ext_id, int_id); // Remap the return codes from the internal method: this // is maintained this way in support of deprecated methods, // and will be cleaned up when these methods are removed. switch (result) { case 1: // If the node was found and deleted, return success. return 0; case 0: // If nothing was found, set errno and break. errno = ENOENT; break; case -1: // If an error happened, just break. break; } // Return an error if we didn't already return success. return -1; } // Break any association of . Returns the value of // in case the caller needs to deallocate memory. template ACE_INLINE int ACE_RB_Tree::unbind (const EXT_ID &ext_id, INT_ID &int_id) { ACE_TRACE ("ACE_RB_Tree::unbind (const EXT_ID &ext_id, INT_ID &int_id)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); int result = this->remove_i (ext_id, int_id); // Remap the return codes from the internal method: this // is maintained this way in support of deprecated methods, // and will be cleaned up when these methods are removed. switch (result) { case 1: // If the node was found and deleted, return success. return 0; case 0: // If nothing was found, set errno and break. errno = ENOENT; break; case -1: // If an error happened, just break. break; } // Return an error if we didn't already return success. return -1; } // Remove entry from the tree. This method should be used with *extreme* // caution, and only for optimization purposes. The node being passed // in had better have been allocated by the tree that is unbinding it. template ACE_INLINE int ACE_RB_Tree::unbind (ACE_RB_Tree_Node *entry) { ACE_TRACE ("ACE_RB_Tree::unbind (ACE_RB_Tree_Node *entry)"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); return this->remove_i (entry); } // Returns a reference to the underlying . This makes it // possible to acquire the lock explicitly, which can be useful in // some cases if you instantiate the with an // or , or if you need to // guard the state of an iterator. NOTE: the right name would be // , but HP/C++ will choke on that! template ACE_INLINE ACE_LOCK & ACE_RB_Tree::mutex (void) { ACE_TRACE ("ACE_RB_Tree::mutex"); return this->lock_; } // Dump the state of an object. template ACE_INLINE void ACE_RB_Tree::dump (void) const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_RB_Tree::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncurrent_size_ = %d\n"), this->current_size_)); this->allocator_->dump (); this->lock_.dump (); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nDumping nodes from root\n"))); this->dump_i (this->root_); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } // Return forward iterator positioned at first node in tree. template ACE_INLINE ACE_RB_Tree_Iterator ACE_RB_Tree::begin (void) { ACE_TRACE ("ACE_RB_Tree::begin"); return ACE_RB_Tree_Iterator (*this); } // Return forward iterator positioned at last node in tree. template ACE_INLINE ACE_RB_Tree_Iterator ACE_RB_Tree::end (void) { ACE_TRACE ("ACE_RB_Tree::end"); return ACE_RB_Tree_Iterator (); } // Return reverse iterator positioned at last node in tree. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator ACE_RB_Tree::rbegin (void) { ACE_TRACE ("ACE_RB_Tree::rbegin"); return ACE_RB_Tree_Reverse_Iterator (*this); } // Return reverse iterator positioned at first node in tree. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator ACE_RB_Tree::rend (void) { ACE_TRACE ("ACE_RB_Tree::rend"); return ACE_RB_Tree_Reverse_Iterator (); } // Returns a pointer to the item corresponding to the given key, // or 0 if it cannot find the key in the tree. DEPRECATED. template ACE_INLINE INT_ID* ACE_RB_Tree::find (const EXT_ID &k) { ACE_TRACE ("ACE_RB_Tree::find (const EXT_ID &k)"); // The reinterpret cast is to ensure that when this deprecated // method is removed, and is replaced (as planned) by a find method // that takes the same argument signature but returns an int, that // the compiler will cough if this return macro is not changed to // just return an int (whose value will be -1). Please leave this // as is. ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, reinterpret_cast (0L)); ACE_RB_Tree_Node *entry = 0; int result = this->find_i (k, entry); return (result == 0) ? &(entry->item ()) : 0; } // Inserts a *copy* of the key and the item into the tree: // both the key type EXT_ID and the item type INT_ID must have well // defined semantics for copy construction and < comparison. // This method returns a pointer to the inserted item copy, // or 0 if an error occurred. NOTE: if an identical key // already exists in the tree, no new item is created, and // the returned pointer addresses the existing item // associated with the existing key. DEPRECATED. template ACE_INLINE INT_ID* ACE_RB_Tree::insert (const EXT_ID &k, const INT_ID &t) { ACE_TRACE ("ACE_RB_Tree::insert"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, reinterpret_cast (0L)); return this->insert_i (k, t); } // Removes the item associated with the given key from the // tree and destroys it. Returns 1 if it found the item // and successfully destroyed it, 0 if it did not find the // item, or -1 if an error occurred. DEPRECATED. template ACE_INLINE int ACE_RB_Tree::remove (const EXT_ID &k) { ACE_TRACE ("ACE_RB_Tree::remove"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); INT_ID i; return this->remove_i (k, i); } // Destroys all nodes and sets the root pointer null. DEPRECATED template ACE_INLINE void ACE_RB_Tree::clear () { ACE_TRACE ("ACE_RB_Tree::clear"); ACE_WRITE_GUARD (ACE_LOCK, ace_mon, this->lock_); this->close_i (); } // Returns the current number of nodes in the tree. template ACE_INLINE size_t ACE_RB_Tree::current_size () const { ACE_TRACE ("ACE_RB_Tree::current_size"); return current_size_; } /////////////////////////////////////////////////////////////////////// // template class // // ACE_RB_Tree_Iterator_Base // /////////////////////////////////////////////////////////////////////// template ACE_INLINE ACE_RB_Tree_Iterator_Base::ACE_RB_Tree_Iterator_Base (void) : tree_ (0), node_ (0) { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::ACE_RB_Tree_Iterator_Base (void)"); } // Returns 1 when the iteration has completed, otherwise 0. template ACE_INLINE int ACE_RB_Tree_Iterator_Base::done (void) const { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::done"); return node_ ? 0 : 1; } // STL-like iterator dereference operator: returns a reference // to the node underneath the iterator. template ACE_INLINE ACE_RB_Tree_Node & ACE_RB_Tree_Iterator_Base::operator* (void) const { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::operator*"); return *(this->node_); } // STL-like iterator dereference operator: returns a reference // to the node underneath the iterator. template ACE_INLINE ACE_RB_Tree_Node * ACE_RB_Tree_Iterator_Base::operator-> (void) const { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::operator->"); return this->node_; } // Returns a reference to the tree over which we're iterating. template ACE_INLINE const ACE_RB_Tree & ACE_RB_Tree_Iterator_Base::tree (void) { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::tree"); return *tree_; } // Comparison operator: returns 1 if both iterators point to the same position, otherwise 0. template ACE_INLINE bool ACE_RB_Tree_Iterator_Base::operator== (const ACE_RB_Tree_Iterator_Base &rbt) const { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::operator=="); return (this->node_ == rbt.node_) ? true : false; } // Comparison operator: returns 1 if the iterators point to different positions, otherwise 0. template ACE_INLINE bool ACE_RB_Tree_Iterator_Base::operator!= (const ACE_RB_Tree_Iterator_Base &rbt) const { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::operator!="); return (this->node_ == rbt.node_) ? false : true; } // Move forward by one element in the tree. Returns 0 when // there are no more elements in the tree, otherwise 1. template ACE_INLINE int ACE_RB_Tree_Iterator_Base::forward_i (void) { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::forward_i"); if (node_) { node_ = tree_->RB_tree_successor (node_); } return node_ ? 1 : 0; } // Move back by one element in the tree. Returns 0 when // there are no more elements in the tree, otherwise 1. template ACE_INLINE int ACE_RB_Tree_Iterator_Base::reverse_i (void) { ACE_TRACE ("ACE_RB_Tree_Iterator_Base::reverse_i"); if (node_) { node_ = tree_->RB_tree_predecessor (node_); } return node_ ? 1 : 0; } ////////////////////////////////////////////////////////////////// // template class // // ACE_RB_Tree_Iterator // ////////////////////////////////////////////////////////////////// template ACE_INLINE ACE_RB_Tree_Iterator::ACE_RB_Tree_Iterator (void) : ACE_RB_Tree_Iterator_Base () { ACE_TRACE ("ACE_RB_Tree_Iterator::ACE_RB_Tree_Iterator (void)"); } // Move forward by one element in the tree. Returns // 0 when all elements have been seen, else 1. template ACE_INLINE int ACE_RB_Tree_Iterator::advance (void) { ACE_TRACE ("ACE_RB_Tree_Iterator::advance"); return this->forward_i (); } // Dump the state of an object. template ACE_INLINE void ACE_RB_Tree_Iterator::dump (void) const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_RB_Tree_Iterator::dump"); this->dump_i (); #endif /* ACE_HAS_DUMP */ } // Prefix advance. template ACE_INLINE ACE_RB_Tree_Iterator & ACE_RB_Tree_Iterator::operator++ (void) { ACE_TRACE ("ACE_RB_Tree_Iterator operator++ (void)"); this->forward_i (); return *this; } // Postfix advance. template ACE_INLINE ACE_RB_Tree_Iterator ACE_RB_Tree_Iterator::operator++ (int) { ACE_TRACE ("ACE_RB_Tree_Iterator operator++ (int)"); ACE_RB_Tree_Iterator retv (*this); ++*this; return retv; } // Prefix reverse. template ACE_INLINE ACE_RB_Tree_Iterator & ACE_RB_Tree_Iterator::operator-- (void) { ACE_TRACE ("ACE_RB_Tree_Iterator operator-- (void)"); this->reverse_i (); return *this; } // Postfix reverse. template ACE_INLINE ACE_RB_Tree_Iterator ACE_RB_Tree_Iterator::operator-- (int) { ACE_TRACE ("ACE_RB_Tree_Iterator operator-- (int)"); ACE_RB_Tree_Iterator retv (*this); --*this; return retv; } // Passes back the under the iterator. Returns 0 if // the iteration has completed, otherwise 1. This method must // be declared and defined in both the derived forward and // reverse iterator classes rather than in the base iterator // class because of a method signature resolution problem // caused by the existence of the deprecated next (void) // method in the derived forward iterator class. When that // deprecated method is removed, this method should be removed // from the derived classes and placed in the base class. template ACE_INLINE int ACE_RB_Tree_Iterator::next (ACE_RB_Tree_Node *&next_entry) const { ACE_TRACE ("ACE_RB_Tree_Iterator::next"); if (this->node_) { next_entry = this->node_; return 1; } return 0; } // Accessor for key of node under iterator (if any). DEPRECATED. template ACE_INLINE EXT_ID * ACE_RB_Tree_Iterator::key () { ACE_TRACE ("ACE_RB_Tree_Iterator::key"); return this->node_ ? (&(this->node_->key ())) : 0; } // Accessor for item of node under iterator (if any). DEPRECATED. template ACE_INLINE INT_ID * ACE_RB_Tree_Iterator::item () { ACE_TRACE ("ACE_RB_Tree_Iterator::item"); return this->node_ ? (&(this->node_->item ())) : 0; } // Move to the first item in the tree. DEPRECATED. template ACE_INLINE int ACE_RB_Tree_Iterator::first () { ACE_TRACE ("ACE_RB_Tree_Iterator::first"); this->node_ = this->tree_->RB_tree_minimum (this->tree_->root_); return this->node_ ? 1 : 0; } // Move to the last item in the tree. DEPRECATED. template ACE_INLINE int ACE_RB_Tree_Iterator::last () { ACE_TRACE ("ACE_RB_Tree_Iterator::last"); this->node_ = this->tree_->RB_tree_maximum (this->tree_->root_); return this->node_ ? 1 : 0; } // Moves to the next item in the tree, // returns 1 if there is a next item, 0 otherwise. DEPRECATED. template ACE_INLINE int ACE_RB_Tree_Iterator::next () { ACE_TRACE ("ACE_RB_Tree_Iterator::next"); this->node_ = this->tree_->RB_tree_successor (this->node_); return this->node_ ? 1 : 0; } // Moves to the previous item in the tree, // returns 1 if there is a previous item, 0 otherwise. DEPRECATED. template ACE_INLINE int ACE_RB_Tree_Iterator::previous () { ACE_TRACE ("ACE_RB_Tree_Iterator::previous"); this->node_ = this->tree_->RB_tree_predecessor (this->node_); return this->node_ ? 1 : 0; } // Returns 0 if the iterator is positioned over a valid ACE_RB_Tree // node, returns 1 if not. DEPRECATED. template ACE_INLINE int ACE_RB_Tree_Iterator::is_done () { ACE_TRACE ("ACE_RB_Tree_Iterator::is_done"); return this->node_ ? 0 : 1; } ////////////////////////////////////////////////////////////////////////// // template class // // ACE_RB_Tree_Reverse_Iterator // ////////////////////////////////////////////////////////////////////////// template ACE_INLINE ACE_RB_Tree_Reverse_Iterator::ACE_RB_Tree_Reverse_Iterator (void) : ACE_RB_Tree_Iterator_Base () { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::ACE_RB_Tree_Reverse_Iterator (void)"); } // Move forward by one element in the tree. Returns // 0 when all elements have been seen, else 1. template ACE_INLINE int ACE_RB_Tree_Reverse_Iterator::advance (void) { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::advance"); return this->reverse_i (); } // Dump the state of an object. template ACE_INLINE void ACE_RB_Tree_Reverse_Iterator::dump (void) const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::dump"); this->dump_i (); #endif /* ACE_HAS_DUMP */ } // Prefix advance. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator & ACE_RB_Tree_Reverse_Iterator::operator++ (void) { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::operator++ (void)"); this->reverse_i (); return *this; } // Postfix advance. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator ACE_RB_Tree_Reverse_Iterator::operator++ (int) { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::operator++ (int)"); ACE_RB_Tree_Reverse_Iterator retv (*this); ++*this; return retv; } // Prefix reverse. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator & ACE_RB_Tree_Reverse_Iterator::operator-- (void) { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::operator-- (void)"); this->forward_i (); return *this; } // Postfix reverse. template ACE_INLINE ACE_RB_Tree_Reverse_Iterator ACE_RB_Tree_Reverse_Iterator::operator-- (int) { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::operator-- (int)"); ACE_RB_Tree_Reverse_Iterator retv (*this); --*this; return retv; } // Passes back the under the iterator. Returns 0 if // the iteration has completed, otherwise 1. This method must // be declared and defined in both the derived forward and // reverse iterator classes rather than in the base iterator // class because of a method signature resolution problem // caused by the existence of the deprecated next (void) // method in the derived forward iterator class. When that // deprecated method is removed, this method should be removed // from the derived classes and placed in the base class. template ACE_INLINE int ACE_RB_Tree_Reverse_Iterator::next (ACE_RB_Tree_Node *&next_entry) const { ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator::next"); if (this->node_) { next_entry = this->node_; return 1; } return 0; } ACE_END_VERSIONED_NAMESPACE_DECL