// $Id$ #ifndef ACE_UNBOUNDED_SET_EX_C #define ACE_UNBOUNDED_SET_EX_C #include "ace/Unbounded_Set_Ex.h" #include "ace/Malloc_Base.h" #include "ace/Log_Msg.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #if !defined (__ACE_INLINE__) #include "ace/Unbounded_Set_Ex.inl" #endif /* __ACE_INLINE__ */ ACE_RCSID(ace, Unbounded_Set_Ex, "$Id$") ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex) template size_t ACE_Unbounded_Set_Ex::size (void) const { // ACE_TRACE ("ACE_Unbounded_Set_Ex::size"); return this->cur_size_; } template int ACE_Unbounded_Set_Ex::insert_tail (const T &item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::insert_tail"); ACE_Node *temp; // Insert into the old dummy node location. this->head_->item_ = item; // Create a new dummy node. ACE_NEW_MALLOC_RETURN (temp, ACE_static_cast(ACE_Node*, this->allocator_->malloc (sizeof (ACE_Node))), ACE_Node (this->head_->next_), -1); // Link this pointer into the list. this->head_->next_ = temp; // Point the head to the new dummy node. this->head_ = temp; this->cur_size_++; return 0; } template void ACE_Unbounded_Set_Ex::reset (void) { ACE_TRACE ("reset"); this->delete_nodes (); } template void ACE_Unbounded_Set_Ex::dump (void) const { ACE_TRACE ("ACE_Unbounded_Set_Ex::dump"); ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nhead_ = %u"), this->head_)); ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nhead_->next_ = %u"), this->head_->next_)); ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncur_size_ = %d\n"), this->cur_size_)); T *item = 0; #if !defined (ACE_NLOGGING) size_t count = 1; #endif /* ! ACE_NLOGGING */ for (ACE_Unbounded_Set_Ex_Iterator iter (*(ACE_Unbounded_Set_Ex *) this); iter.next (item) != 0; iter.advance ()) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("count = %d\n"), count++)); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } template void ACE_Unbounded_Set_Ex::copy_nodes (const ACE_Unbounded_Set_Ex &us) { for (ACE_Node *curr = us.head_->next_; curr != us.head_; curr = curr->next_) { if (!curr->deleted_) this->insert_tail (curr->item_); } } template void ACE_Unbounded_Set_Ex::delete_nodes (void) { ACE_Node *curr = this->head_->next_; ACE_ASSERT (number_of_iterators_ == 0); // Keep looking until we've hit the dummy node. while (curr != this->head_) { ACE_Node *temp = curr; curr = curr->next_; if (!temp->deleted_) this->cur_size_--; ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, ACE_Node, ); } // Reset the list to be a circular list with just a dummy node. this->head_->next_ = this->head_; } template void ACE_Unbounded_Set_Ex::cleanup () { /// curr is the address of the chaining ACE_Node **curr = &(this->head_->next_); ACE_ASSERT (number_of_iterators_ == 0); // Keep looking until we've hit the dummy node. while (*curr != this->head_) { if ((*curr)->deleted_) { ACE_Node *temp = *curr; *curr = (*curr)->next_; // skip the deleted, curr is still the same ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, ACE_Node, ); } else { curr = &((*curr)->next_); } } } template ACE_Unbounded_Set_Ex::~ACE_Unbounded_Set_Ex (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::~ACE_Unbounded_Set_Ex"); this->delete_nodes (); // Delete the dummy node. ACE_DES_FREE_TEMPLATE (head_, this->allocator_->free, ACE_Node, ); this->head_ = 0; } template ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex (ACE_Allocator *alloc) : head_ (0), cur_size_ (0), allocator_ (alloc), number_of_iterators_ (0) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex"); if (this->allocator_ == 0) this->allocator_ = ACE_Allocator::instance (); ACE_NEW_MALLOC (this->head_, (ACE_Node*) this->allocator_->malloc (sizeof (ACE_Node)), ACE_Node); // Make the list circular by pointing it back to itself. this->head_->next_ = this->head_; } template ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex (const ACE_Unbounded_Set_Ex &us) : head_ (0), cur_size_ (0), allocator_ (us.allocator_), number_of_iterators_ (0) { ACE_TRACE ("ACE_Unbounded_Set_Ex::ACE_Unbounded_Set_Ex"); if (this->allocator_ == 0) this->allocator_ = ACE_Allocator::instance (); ACE_NEW_MALLOC (this->head_, (ACE_Node*) this->allocator_->malloc (sizeof (ACE_Node)), ACE_Node); this->head_->next_ = this->head_; this->copy_nodes (us); } template void ACE_Unbounded_Set_Ex::operator= (const ACE_Unbounded_Set_Ex &us) { ACE_TRACE ("ACE_Unbounded_Set_Ex::operator="); if (this != &us) { this->delete_nodes (); this->copy_nodes (us); } } template int ACE_Unbounded_Set_Ex::find (const T &item) const { // ACE_TRACE ("ACE_Unbounded_Set_Ex::find"); // Set into the dummy node. this->head_->item_ = item; ACE_Node *temp = this->head_->next_; // Keep looping until we find the item. while (!(temp->item_ == item && !temp->deleted_)) temp = temp->next_; // If we found the dummy node then it's not really there, otherwise, // it is there. return temp == this->head_ ? -1 : 0; } template int ACE_Unbounded_Set_Ex::insert (const T &item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::insert"); if (this->find (item) == 0) return 1; else return this->insert_tail (item); } template int ACE_Unbounded_Set_Ex::remove (const T &item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::remove"); // Insert the item to be founded into the dummy node. this->head_->item_ = item; this->head_->deleted_ = false; ACE_Node *curr = this->head_; while (!(curr->next_->item_ == item) || curr->next_->deleted_) curr = curr->next_; if (curr->next_ == this->head_) return -1; // Item was not found. else { this->cur_size_--; ACE_Node *temp = curr->next_; if (number_of_iterators_>0) { temp->deleted_=true; } else { // Skip over the node that we're deleting. curr->next_ = temp->next_; ACE_DES_FREE_TEMPLATE (temp, this->allocator_->free, ACE_Node, ); } return 0; } } template ACE_Unbounded_Set_Ex_Iterator ACE_Unbounded_Set_Ex::begin (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::begin"); return ACE_Unbounded_Set_Ex_Iterator (*this); } template ACE_Unbounded_Set_Ex_Iterator ACE_Unbounded_Set_Ex::end (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex::end"); return ACE_Unbounded_Set_Ex_Iterator (*this, 1); } template void ACE_Unbounded_Set_Ex::iterator_add (void) const { number_of_iterators_++; } template void ACE_Unbounded_Set_Ex::iterator_leave (void) { ACE_ASSERT (number_of_iterators_ > 0); number_of_iterators_--; if (number_of_iterators_ == 0) cleanup (); } template void ACE_Unbounded_Set_Ex::const_iterator_leave (void) const { ACE_ASSERT (number_of_iterators_ > 0); number_of_iterators_--; } ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex_Iterator) template void ACE_Unbounded_Set_Ex_Iterator::dump (void) const { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::dump"); } template ACE_Unbounded_Set_Ex_Iterator::ACE_Unbounded_Set_Ex_Iterator (ACE_Unbounded_Set_Ex &s, int end) : current_ (end == 0 ? s.head_->next_ : s.head_ ), set_ (&s) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::ACE_Unbounded_Set_Ex_Iterator"); // the first one may be deleted while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; registered_in_set_ = (!end && this->current_ != this->set_->head_); if (registered_in_set_) set_->iterator_add (); } template ACE_Unbounded_Set_Ex_Iterator::ACE_Unbounded_Set_Ex_Iterator (const ACE_Unbounded_Set_Ex_Iterator &o) : current_ (o.current_), set_ (o.set_), registered_in_set_ (o.registered_in_set_) { if (registered_in_set_) set_->iterator_add (); } template void ACE_Unbounded_Set_Ex_Iterator::operator= (const ACE_Unbounded_Set_Ex_Iterator &o) { if (this == &o) return; if (registered_in_set_) set_->iterator_leave (); this->set_ = o.set_; this->current_ = o.current_; this->registered_in_set_ = o.registered_in_set_; if (registered_in_set_) set_->iterator_add (); } template ACE_Unbounded_Set_Ex_Iterator::~ACE_Unbounded_Set_Ex_Iterator () { if (registered_in_set_) set_->iterator_leave (); } template int ACE_Unbounded_Set_Ex_Iterator::advance (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::advance"); this->current_ = this->current_->next_; while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; int completed = (this->current_ == this->set_->head_); if (completed && registered_in_set_) { set_->iterator_leave (); registered_in_set_ = false; } return !completed; } template int ACE_Unbounded_Set_Ex_Iterator::first (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::first"); this->current_ = this->set_->head_->next_; while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; int non_empty = (this->current_ != this->set_->head_); if (non_empty && !registered_in_set_) { registered_in_set_ = true; set_->iterator_add (); } return non_empty; } template int ACE_Unbounded_Set_Ex_Iterator::done (void) const { ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::done"); return this->current_ == this->set_->head_; } template int ACE_Unbounded_Set_Ex_Iterator::next (T *&item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::next"); int completed = (this->current_ == this->set_->head_); if (completed) { if (registered_in_set_) { set_->iterator_leave (); registered_in_set_ = false; } return 0; } item = &this->current_->item_; return 1; } template ACE_Unbounded_Set_Ex_Iterator ACE_Unbounded_Set_Ex_Iterator::operator++ (int) { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator++ (int)"); ACE_Unbounded_Set_Ex_Iterator retv (*this); // postfix operator this->advance (); return retv; } template ACE_Unbounded_Set_Ex_Iterator& ACE_Unbounded_Set_Ex_Iterator::operator++ (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator++ (void)"); // prefix operator this->advance (); return *this; } template T& ACE_Unbounded_Set_Ex_Iterator::operator* (void) { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator*"); T *retv = 0; int result = this->next (retv); ACE_ASSERT (result != 0); ACE_UNUSED_ARG (result); return *retv; } template int ACE_Unbounded_Set_Ex_Iterator::operator== (const ACE_Unbounded_Set_Ex_Iterator &rhs) const { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator=="); return (this->set_ == rhs.set_ && this->current_ == rhs.current_); } template int ACE_Unbounded_Set_Ex_Iterator::operator!= (const ACE_Unbounded_Set_Ex_Iterator &rhs) const { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Iterator::operator!="); return (this->set_ != rhs.set_ || this->current_ != rhs.current_); } ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Ex_Const_Iterator) template void ACE_Unbounded_Set_Ex_Const_Iterator::dump (void) const { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::dump"); } template ACE_Unbounded_Set_Ex_Const_Iterator::ACE_Unbounded_Set_Ex_Const_Iterator (const ACE_Unbounded_Set_Ex &s, int end) : current_ (end == 0 ? s.head_->next_ : s.head_ ), set_ (&s) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::ACE_Unbounded_Set_Ex_Const_Iterator"); // the first one may be deleted while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; registered_in_set_ = (!end && this->current_ != this->set_->head_); if (registered_in_set_) set_->iterator_add (); } template ACE_Unbounded_Set_Ex_Const_Iterator::ACE_Unbounded_Set_Ex_Const_Iterator (const ACE_Unbounded_Set_Ex_Const_Iterator &o) : current_ (o.current_), set_ (o.set_), registered_in_set_ (o.registered_in_set_) { if (registered_in_set_) set_->iterator_add (); } template void ACE_Unbounded_Set_Ex_Const_Iterator::operator= (const ACE_Unbounded_Set_Ex_Const_Iterator& o) { if (this == &o) return; if (registered_in_set_) set_->const_iterator_leave (); this->set_ = o.set_; this->current_ = o.current_; this->registered_in_set_ = o.registered_in_set_; if (registered_in_set_) set_->iterator_add (); } template ACE_Unbounded_Set_Ex_Const_Iterator::~ACE_Unbounded_Set_Ex_Const_Iterator () { if (registered_in_set_) set_->const_iterator_leave (); } template int ACE_Unbounded_Set_Ex_Const_Iterator::advance (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::advance"); this->current_ = this->current_->next_; while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; int completed = (this->current_ == this->set_->head_); if (completed && registered_in_set_) { set_->const_iterator_leave (); registered_in_set_ = false; } return !completed; } template int ACE_Unbounded_Set_Ex_Const_Iterator::first (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::first"); this->current_ = this->set_->head_->next_; while (this->current_->deleted_ && this->current_ != this->set_->head_) this->current_ = this->current_->next_; int non_empty = (this->current_ != this->set_->head_); if (non_empty && !registered_in_set_) { registered_in_set_ = true; set_->iterator_add (); } return non_empty; } template int ACE_Unbounded_Set_Ex_Const_Iterator::done (void) const { ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::done"); return this->current_ == this->set_->head_; } template int ACE_Unbounded_Set_Ex_Const_Iterator::next (T *&item) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::next"); int completed = (this->current_ == this->set_->head_); if (completed) { if (registered_in_set_) { set_->const_iterator_leave (); registered_in_set_ = false; } return 0; } item = &this->current_->item_; return 1; } template ACE_Unbounded_Set_Ex_Const_Iterator ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (int) { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (int)"); ACE_Unbounded_Set_Ex_Const_Iterator retv (*this); // postfix operator this->advance (); return retv; } template ACE_Unbounded_Set_Ex_Const_Iterator& ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (void) { // ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator++ (void)"); // prefix operator this->advance (); return *this; } template T& ACE_Unbounded_Set_Ex_Const_Iterator::operator* (void) { //ACE_TRACE ("ACE_Unbounded_Set_Ex_Const_Iterator::operator*"); T *retv = 0; int result = this->next (retv); ACE_ASSERT (result != 0); ACE_UNUSED_ARG (result); return *retv; } #endif /* ACE_UNBOUNDED_SET_EX_C */