ACE/FAQ/APG/Containers
Материал из Wiki.crossplatform.ru
(Различия между версиями)
ViGOur (Обсуждение | вклад)
(Новая страница: «__TOC__ Категория:ACE FAQ == DataElement.h == <source lang="cpp"> - →-*- C++ -*-: // $Id: DataElement.h 80826 2008-03-04 14:51:23Z wotte $ #if !defi…»)
(Новая страница: «__TOC__ Категория:ACE FAQ == DataElement.h == <source lang="cpp"> - →-*- C++ -*-: // $Id: DataElement.h 80826 2008-03-04 14:51:23Z wotte $ #if !defi…»)
Текущая версия на 18:43, 6 февраля 2012
Содержание |
[править] DataElement.h
/* -*- C++ -*- */ // $Id: DataElement.h 80826 2008-03-04 14:51:23Z wotte $ #if !defined(DATAELEMENT_H) #define DATAELEMENT_H class DataElementEx; // Listing 1 code/ch05 // A simple data element class. class DataElement { friend class DataElementEx; public: DataElement () : data_ (0) { count_++; } DataElement (int data) : data_(data) { count_++; } DataElement (const DataElement& e) { data_ = e.getData (); count_++; } DataElement & operator= (const DataElement& e) { data_ = e.getData (); return *this; } bool operator== (const DataElement& e) { return this->data_ == e.data_; } ~DataElement () { count_--; } int getData (void) const { return data_; } void setData (int val) { data_ = val; } static int numOfActiveObjects (void) { return count_; } private: int data_; static int count_; }; // Listing 1 int DataElement::count_ = 0; #endif /*DATAELEMENT_H*/
[править] Hash_Map_Hash.h
/* -*- C++ -*- */ // $Id: Hash_Map_Hash.h 80826 2008-03-04 14:51:23Z wotte $ #ifndef __HASH_MAP_HASH_H_ #define __HASH_MAP_HASH_H_ // Listing 1 code/ch05 // Key type that we are going to use. class KeyType { public: KeyType () : val_(0) {} KeyType (int i) : val_(i) {} KeyType (const KeyType& kt) { this->val_ = kt.val_; } operator int (void) const { return val_; } private: int val_; }; ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Specialize the hash functor. template<> class ACE_Hash<KeyType> { public: u_long operator() (const KeyType kt) const { int val = kt; return (u_long)val; } }; // Specialize the equality functor. template<> class ACE_Equal_To<KeyType> { public: int operator() (const KeyType& kt1, const KeyType& kt2) const { int val1 = kt1; int val2 = kt2; return (val1 == val2); } }; ACE_END_VERSIONED_NAMESPACE_DECL // Listing 1 #endif /* __HASH_MAP_HASH_H_ */
[править] KeyType.h
/* -*- C++ -*- */ // $Id: KeyType.h 80826 2008-03-04 14:51:23Z wotte $ #ifndef __KEYTYPE_H_ #define __KEYTYPE_H_ // Listing 1 code/ch05 class KeyType { public: friend bool operator == (const KeyType&, const KeyType&); KeyType () : val_(0) {} KeyType (int i) : val_(i) {} KeyType (const KeyType& kt) { this->val_ = kt.val_; }; operator int() const { return val_; }; private: int val_; }; bool operator == (const KeyType& a, const KeyType& b) { return (a.val_ == b.val_); } // Listing 1 #endif /* __KEYTYPE_H_ */
[править] RB_Tree_Functors.h
/* -*- C++ -*- */ // $Id: RB_Tree_Functors.h 80826 2008-03-04 14:51:23Z wotte $ #ifndef __RB_TREE_FUNCTORS_H_ #define __RB_TREE_FUNCTORS_H_ #include "ace/Functor.h" // Listing 1 code/ch05 // Same key type. class KeyType { public: KeyType () : val_(0) {} KeyType (int i) : val_ (i) {} KeyType (const KeyType& kt) { this->val_ = kt.val_; } operator int() const { return val_; }; private: int val_; }; ACE_BEGIN_VERSIONED_NAMESPACE_DECL template<> class ACE_Less_Than<KeyType> { public: int operator() (const KeyType k1, const KeyType k2) { return k1 < k2; } }; ACE_END_VERSIONED_NAMESPACE_DECL // Listing 1 #endif /* __RB_TREE_FUNCTORS_H_ */
[править] Allocator
// $Id: Allocator.cpp 95465 2012-01-20 19:07:06Z johnnyw $ #include "ace/Containers.h" #include "ace/Malloc_T.h" #include "ace/Synch.h" // Needed for the lock. #include "DataElement.h" class StackExample { public: // Illustrate all the differnet // types of stacks provided by ACE. int run (void); private: // Illustrate the use of an unbounded stack. int runUnboundedStack (ACE_Allocator* allocator); }; // Listing 1 code/ch05 int StackExample::run (void) { ACE_TRACE ("StackExample::run"); ACE_Allocator *allocator = 0; size_t block_size = sizeof(ACE_Node<DataElement>); ACE_NEW_RETURN (allocator, ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex> (100 + 1, block_size), -1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); ACE_TEST_ASSERT (this->runUnboundedStack (allocator) != -1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); delete allocator; return 0; } // Listing 1 // Listing 2 code/ch05 int StackExample::runUnboundedStack (ACE_Allocator* allocator) { ACE_TRACE ("StackExample::runUnboundedStack"); // Pass in an allocator during construction. ACE_Unbounded_Stack<DataElement> ustack (allocator); for (int m = 0; m < 100; m++) { DataElement elem (m); int result = ustack.push (elem); if (result == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Push Next Element")), -1); } void* furtherMemory = 0; furtherMemory = allocator->malloc (sizeof(ACE_Node<DataElement>)); ACE_TEST_ASSERT (furtherMemory == 0); // No memory left.. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%p\n"), ACE_TEXT ("No memory.."))); // Free up some memory in the allocator. DataElement e; for (int n = 0; n < 10; n++) { ustack.pop (e); } furtherMemory = allocator->malloc (sizeof (ACE_Node<DataElement>)); ACE_TEST_ASSERT (furtherMemory != 0); return 0; } // Listing 2 int ACE_TMAIN (int, ACE_TCHAR *[]) { StackExample se; return se.run (); }
[править] Array
// $Id: Array.cpp 80826 2008-03-04 14:51:23Z wotte $ #include "ace/OS_Memory.h" #include "ace/Log_Msg.h" // Listing 1 code/ch05 #include "ace/Containers.h" #include "DataElement.h" int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_Array<DataElement*> arr (10); DataElement *elem = 0; // Allocate and insert elements. for (int i = 0; i < 10; i++) { ACE_NEW_RETURN (elem, DataElement (i), -1); arr[i] = elem; } // Checked access. ACE_ASSERT (arr.set (elem, 11) == -1); ACE_ASSERT (arr.get (elem, 11) == -1); // Make a copy and compare to the original. ACE_Array<DataElement*> copy = arr; ACE_ASSERT (copy == arr); ACE_Array<DataElement*>::ITERATOR iter (arr); while (!iter.done ()) { DataElement** data; iter.next (data); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d\n"), (*data)->getData ())); delete (*data); iter.advance (); } return 0; } // Listing 1
[править] List
// $Id: DLList.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/OS_Memory.h" #include "ace/Log_Msg.h" // Listing 1 code/ch05 #include "ace/Containers.h" #include "DataElement.h" // Create a new type of list that can store only DataElements. typedef ACE_DLList<DataElement> MyList; // Listing 1 // Listing 2 code/ch05 class ListTest { public: int run (void); void displayList (MyList & list); // Display all elements. void destroyList (MyList& list); // Destroy all elements. }; // Listing 2 // Listing 3 code/ch05 int ListTest::run (void) { ACE_TRACE ("ListTest::run"); // Create a list and insert 100 elements. MyList list1; for (int i = 0; i < 100; i++) { DataElement *element; ACE_NEW_RETURN (element, DataElement (i), -1); list1.insert_tail (element); } // Iterate through and display to output. this->displayList (list1); // Create a copy of list1. MyList list2; list2 = list1; // Iterate over the copy and display it to output. this->displayList(list2); // Get rid of the copy list and all its elements. // Since both lists had the *same* elements // this will cause list1 to contain pointers that // point to data elements that have already been destroyed! this->destroyList (list2); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("# of live objects: %d\n"), DataElement::numOfActiveObjects())); // The lists themselves are destroyed here. Note that the // list destructor will destroy copies of whatever data the // list contained. Since in this case the list contained // copies of pointers to the data elements these are the // only thing that gets destroyed here. return 0; } // Listing 3 // Listing 4 code/ch05 void ListTest::destroyList (MyList& list) { ACE_TRACE ("ListTest::destroyList"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Destroying data elements\n"))); // Iterate through and delete all the data elements on the list. for (ACE_DLList_Iterator<DataElement> iter (list); !iter.done (); iter++) { DataElement *de = iter.next (); delete de; } } // Listing 4 // Listing 5 code/ch05 void ListTest::displayList (MyList& list) { ACE_TRACE ("ListTest::displayList"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); ACE_DLList_Iterator<DataElement> iter (list); while (!iter.done ()) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), iter.next()->getData())); iter++; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration\n"))); ACE_DLList_Reverse_Iterator<DataElement> riter (list); while (!riter.done ()) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), riter.next()->getData())); riter++; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } // Listing 5 int ACE_TMAIN (int, ACE_TCHAR *[]) { ListTest test; return test.run (); }
[править] Hash Map
// $Id: Hash_Map.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/Hash_Map_Manager.h" #include "ace/Synch.h" // needed for the lock #include "ace/Functor.h" #include "DataElement.h" // Listing 1 code/ch05 // Little helper class. template<class EXT_ID, class INT_ID> class Hash_Map : public ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, ACE_Hash<EXT_ID>, ACE_Equal_To<EXT_ID>, ACE_Null_Mutex> {}; // Listing 1 class Hash_Map_Example { public: // Constructor Hash_Map_Example (); // Illustrate the hash map. int run (void); // Use the forward iterator. void iterate_forward (void); // Use the reverse iterator. void iterate_reverse (void); // Remove all the elements from the map. void remove_all (void); private: Hash_Map<int, DataElement> map_; }; // Listing 2 code/ch05 Hash_Map_Example::Hash_Map_Example() { ACE_TRACE ("Hash_Map_Example::Hash_Map_Example"); map_.open (100); } // Listing 2 int Hash_Map_Example::run (void) { ACE_TRACE ("Hash_Map_Example::run"); for (int i = 0; i < 100; i++) { map_.bind (i, DataElement(i)); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has\n"))); for (int j = 0; j < 100; j++) { DataElement d; map_.find (j,d); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Use the forward iterator. this->iterate_forward (); // Use the reverse iterator. this->iterate_reverse (); // Remove all the elements from the map. this->remove_all (); // Iterate through the map again. this->iterate_forward (); return 0; } void Hash_Map_Example::iterate_forward (void) { ACE_TRACE ("Hash_Map_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration\n"))); for (Hash_Map<int, DataElement>::iterator iter = map_.begin (); iter != map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Hash_Map_Example::iterate_reverse (void) { ACE_TRACE ("Hash_Map_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration\n"))); for (Hash_Map<int, DataElement>::reverse_iterator iter = map_.rbegin (); iter != map_.rend (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Hash_Map_Example::remove_all (void) { ACE_TRACE ("Hash_Map_Example::remove_all"); map_.unbind_all (); } int ACE_TMAIN (int, ACE_TCHAR *[]) { Hash_Map_Example me; return me.run (); }
[править] Hash Map Hash
// $Id: Hash_Map_Hash.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/Hash_Map_Manager.h" #include "ace/Synch.h" // Needed for the lock #include "ace/Functor.h" #include "DataElement.h" #include "Hash_Map_Hash.h" // Little helper class template<class EXT_ID, class INT_ID> class Hash_Map : public ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, ACE_Hash<EXT_ID>, ACE_Equal_To<EXT_ID>, ACE_Null_Mutex> {}; class Hash_Map_Example { public: ~Hash_Map_Example () { map_.close (); } // illustrate the hash map int run (void); // use the forward iterate void iterate_forward (void); // use the reverse iterator void iterate_reverse (void); // remove all the elements from the map void remove_all (void); private: Hash_Map<KeyType, DataElement> map_; }; int Hash_Map_Example::run (void) { ACE_TRACE ("Hash_Map_Example::run"); for (int i = 0; i < 100; i++) { map_.bind (i, DataElement (i)); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has\n"))); for (int j = 0; j < 100; j++) { DataElement d; map_.find (j, d); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Use the forward iterator. this->iterate_forward (); // Use the reverse iterator. this->iterate_reverse (); // Remove all the elements from the map. this->remove_all (); // Iterate through the map again. this->iterate_forward (); return 0; } void Hash_Map_Example::iterate_forward (void) { ACE_TRACE ("Hash_Map_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration\n"))); for (Hash_Map<KeyType, DataElement>::iterator iter = map_.begin (); iter != map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Hash_Map_Example::iterate_reverse (void) { ACE_TRACE ("Hash_Map_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration\n"))); for (Hash_Map<KeyType, DataElement>::reverse_iterator iter = map_.rbegin (); iter != map_.rend (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Hash_Map_Example::remove_all (void) { ACE_TRACE ("Hash_Map_Example::remove_all"); map_.unbind_all (); } int ACE_TMAIN (int, ACE_TCHAR *[]) { Hash_Map_Example me; return me.run (); }
[править] Map Manager
// $Id: Map_Manager.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/Log_Msg.h" #include "ace/Map_Manager.h" #include "ace/Synch.h" #include "DataElement.h" #include "KeyType.h" class Map_Example { public: // Illustrate the ACE_Map_Manager. int run (void); private: // Iterate in the forward direction. void iterate_forward (void); // Iterate in the other direction. void iterate_reverse (void); // Remove all elements from the map. void remove_all (void); private: ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex> map_; }; // Listing 2 code/ch05 int Map_Example::run (void) { ACE_TRACE ("Map_Example::run"); // Corresponding KeyType objects are created on the fly. for (int i = 0; i < 100; i++) { map_.bind (i, DataElement (i)); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has\n"))); for (int j = 0; j < 100; j++) { DataElement d; map_.find (j,d); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Iterate in the forward direction. this->iterate_forward (); // Iterate in the other direction. this->iterate_reverse (); // Remove all elements from the map. this->remove_all (); // Iterate in the forward direction. this->iterate_forward (); return 0; } // Listing 2 // Listing 3 code/ch05 void Map_Example::iterate_forward (void) { ACE_TRACE ("Map_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::iterator iter = map_.begin (); iter != map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Map_Example::iterate_reverse (void) { ACE_TRACE ("Map_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse iteration\n"))); for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::reverse_iterator iter = map_.rbegin (); iter != map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } // Listing 3 // Listing 4 code/ch05 void Map_Example::remove_all (void) { ACE_TRACE ("Map_Example::remove_all"); // Note that we can't use the iterators here as they // are invalidated after deletions or insertions. map_.unbind_all (); } // Listing 4 int ACE_TMAIN (int, ACE_TCHAR *[]) { Map_Example me; return me.run (); }
[править] Map Manager Specialization
// $Id: Map_Manager_Specialization.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/Log_Msg.h" #include "ace/Map_Manager.h" #include "ace/Synch.h" // Needed for the lock. #include "DataElement.h" #include "KeyType.h" /* ** This needs to stay in the book for 2nd printing, but is the same as ** what's in KeyType.h. */ #if 0 // Listing 1 code/ch05 class KeyType { public: KeyType () : val_(0) {} KeyType (int i) : val_(i) {} KeyType (const KeyType& kt) { this->val_ = kt.val_; }; operator int () const { return val_; }; private: int val_; }; template<> int ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::equal (const KeyType& r1, const KeyType &r2) { return (r1 == r2); } // Listing 1 #else ACE_BEGIN_VERSIONED_NAMESPACE_DECL template<> int ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::equal (const KeyType& r1, const KeyType &r2) { return (r1 == r2); } ACE_END_VERSIONED_NAMESPACE_DECL #endif /* 0 */ class Map_Example { public: // Illustrate the ACE_Map_Manager<>. int run (void); private: // Iterate in the forward direction. void iterate_forward (void); // Iterate in the other direction. void iterate_reverse (void); // Remove all elements from the map. void remove_all (void); private: ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex> map_; }; int Map_Example::run (void) { ACE_TRACE ("Map_Example::run"); // Corresponding KeyType objects are created on the fly. for (int i = 0; i < 100; i++) { map_.bind (i, DataElement (i)); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has\n"))); for (int j = 0; j < 100; j++) { DataElement d; int result = map_.find (j,d); if (result == 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ())); } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Iterate in the forward direction. this->iterate_forward (); // Iterate in the other direction. this->iterate_reverse (); // Remove all elements from the map. this->remove_all (); // Iterate in the forward direction. this->iterate_forward (); return 0; } void Map_Example::iterate_forward (void) { ACE_TRACE ("Map_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration\n"))); for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::iterator iter = map_.begin (); iter!= map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Map_Example::iterate_reverse (void) { ACE_TRACE ("Map_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse iteration\n"))); for (ACE_Map_Manager<KeyType, DataElement, ACE_Null_Mutex>::reverse_iterator iter = map_.rbegin (); iter!= map_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).int_id_.getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Map_Example::remove_all (void) { ACE_TRACE ("Map_Example::remove_all"); // Note that we can't use the iterators here // as they are invalidated after deletions // or insertions. for (int i = 0; i < 100; i++) { map_.unbind (i); } } int ACE_TMAIN (int, ACE_TCHAR *[]) { Map_Example me; return me.run (); }
[править] Queues
// $Id: Queues.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/OS_Memory.h" #include "ace/Log_Msg.h" #include "ace/Containers.h" #include "DataElement.h" class QueueExample { public: // Illustrate the various ACE Queues. int run (void); private: // Illustrate the ACE unbounded queue // that has copies of the data elements. int runStackUnboundedQueue (void); // Illustrate the ACE unbounded queue // with pointers to elements on the heap. int runHeapUnboundedQueue (void); }; int QueueExample::run (void) { ACE_TRACE ("QueueExample::run"); // Illustrate the queue with elements on the stack. if (this->runStackUnboundedQueue () != 0) { return -1; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); // Illustrate the queue with elements on the heap. if (this->runHeapUnboundedQueue () != 0) { return -1; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); return 0; } // Listing 1 code/ch05 int QueueExample::runStackUnboundedQueue (void) { ACE_TRACE ("QueueExample::runStackUnboundedQueue"); ACE_Unbounded_Queue<DataElement> queue; DataElement elem1[10]; int i; for (i = 0; i < 10; i++) { elem1[i].setData (9-i); queue.enqueue_head (elem1[i]); } DataElement elem2[10]; for (i = 0; i < 10; i++) { elem2[i].setData (i+10); queue.enqueue_tail (elem2[i]); } for (ACE_Unbounded_Queue_Iterator<DataElement> iter (queue); !iter.done (); iter.advance ()) { DataElement *elem = 0; iter.next (elem); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); } return 0; } // Listing 1 // Listing 2 code/ch05 int QueueExample::runHeapUnboundedQueue (void) { ACE_TRACE ("QueueExample::runHeapUnboundedQueue"); ACE_Unbounded_Queue<DataElement*> queue; for (int i = 0; i < 20; i++) { DataElement *elem; ACE_NEW_RETURN(elem, DataElement (i), -1); queue.enqueue_head (elem); } for (ACE_Unbounded_Queue_Iterator<DataElement*> iter = queue.begin (); !iter.done (); iter.advance ()) { DataElement **elem = 0; iter.next(elem); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*elem)->getData ())); delete (*elem); } return 0; } // Listing 2 int ACE_TMAIN (int, ACE_TCHAR *[]) { QueueExample que; return que.run (); }
[править] Red Black Tree
// $Id: RB_Tree.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/RB_Tree.h" #include "ace/Log_Msg.h" #include "ace/Synch.h" #include "DataElement.h" // Little helper class. template<class EXT_ID, class INT_ID> class Tree : public ACE_RB_Tree<EXT_ID, INT_ID, ACE_Less_Than<EXT_ID>, ACE_Null_Mutex> {}; class Tree_Example { public: // Illustrate the tree. int run (void); private: // Use the forward iterator. void iterate_forward (void); // Use the reverse iterator. void iterate_reverse (void); // Remove all elements from the tree. int remove_all (void); private: Tree<int, DataElement*> tree_; }; // Listing 1 code/ch05 int Tree_Example::run (void) { ACE_TRACE ("Tree_Example::run"); DataElement *d = 0; for (int i = 0; i < 100; i++) { ACE_NEW_RETURN (d, DataElement (i), -1); int result = tree_.bind (i, d); if (result!= 0) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Bind")), -1); } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using find:\n"))); for (int j = 0; j < 100; j++) { tree_.find (j, d); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Use the forward iterator. this->iterate_forward (); // Use the reverse iterator. this->iterate_reverse (); // Remove all elements from the tree. ACE_ASSERT (this->remove_all ()!= -1); // Iterate through once again. this->iterate_forward (); return 0; } void Tree_Example::iterate_forward (void) { ACE_TRACE ("Tree_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration:\n"))); for (Tree<int, DataElement*>::iterator iter = tree_.begin (); iter != tree_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Tree_Example::iterate_reverse (void) { ACE_TRACE ("Tree_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration:\n"))); for (Tree<int, DataElement*>::reverse_iterator iter = tree_.rbegin (); iter != tree_.rend (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } int Tree_Example::remove_all (void) { ACE_TRACE ("Tree_Example::remove_all"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Removing elements\n"))); // Note that we can't use the iterators here as they are // invalidated after deletions or insertions. for (int i = 0; i < 100; i++) { DataElement * d = 0; int result = tree_.unbind (i, d); if (result != 0) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Unbind")), -1); } ACE_ASSERT (d!= 0); delete d; } return 0; } // Listing 1 int ACE_TMAIN (int, ACE_TCHAR *[]) { Tree_Example te; return te.run (); }
[править] Red Black Tree Functors
// $Id: RB_Tree_Functors.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/Log_Msg.h" #include "DataElement.h" #include "RB_Tree_Functors.h" // Listing 0 code/ch05 #include "ace/RB_Tree.h" #include "ace/Synch.h" // Little helper class. template<class EXT_ID, class INT_ID> class Tree : public ACE_RB_Tree<EXT_ID, INT_ID, ACE_Less_Than<EXT_ID>, ACE_Null_Mutex> {}; // Listing 0 class Tree_Example { public: // Illustrate the tree. int run (void); private: // Use the forward iterator. void iterate_forward (void); // Use the reverse iterator. void iterate_reverse (void); // Remove all elements from the tree. int remove_all (void); private: Tree<KeyType, DataElement*> tree_; }; int Tree_Example::run () { ACE_TRACE ("Tree_Example::run"); DataElement *d = 0; for (int i = 0; i < 100; i++) { ACE_NEW_RETURN (d, DataElement (i), -1); int result = tree_.bind(i, d); if (result != 0) { ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Bind"), -1); } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using find:\n"))); for (int j = 0; j < 100; j++) { DataElement* d = 0; int result = tree_.find (j, d); if (result != 0) { ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Find"), -1); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); // Use the forward iterator. this->iterate_forward (); // Use the reverse iterator. this->iterate_reverse (); // Remove all elements from the tree. ACE_ASSERT (this->remove_all ()!= -1); // Iterate through once again. this->iterate_forward (); return 0; } void Tree_Example::iterate_forward (void) { ACE_TRACE ("Tree_Example::iterate_forward"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward Iteration\n"))); for (Tree<KeyType, DataElement*>::iterator iter = tree_.begin (); iter != tree_.end (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } void Tree_Example::iterate_reverse (void) { ACE_TRACE ("Tree_Example::iterate_reverse"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse Iteration\n"))); for (Tree<KeyType, DataElement*>::reverse_iterator iter = tree_.rbegin (); iter != tree_.rend (); iter++) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*iter).item ()->getData ())); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n"))); } int Tree_Example::remove_all (void) { ACE_TRACE ("Tree_Example::remove_all"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Removing elements\n"))); for (int i = 0; i < 100; i++) { DataElement * d = 0; int result = tree_.unbind (i, d); if (result != 0) { ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Unbind"), -1); } ACE_ASSERT (d != 0); delete d; } return 0; } int ACE_TMAIN (int, ACE_TCHAR *[]) { Tree_Example te; return te.run (); }
[править] Set
// $Id: Sets.cpp 94310 2011-07-09 19:10:06Z schmidt $ #include "ace/OS_Memory.h" #include "ace/Log_Msg.h" #include "ace/Containers.h" #include "DataElement.h" class SetExample { public: // Illustrate all ACE set types. int run (void); private: // Illustrate the ACE Bounded Sets. int runBoundedSet (void); // Illustrate the ACE Unbounded sets. int runUnboundedSet (void); }; int SetExample::run (void) { ACE_TRACE ("SetExample::run"); ACE_ASSERT (!this->runBoundedSet ()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); ACE_ASSERT (!this->runUnboundedSet ()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects ())); return 0; } // Listing 1 code/ch05 int SetExample::runBoundedSet () { ACE_TRACE ("SetExample::runBoundedSet"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a bounded set\n"))); ACE_Bounded_Set<DataElement> bset (100); DataElement elem[100]; for (int i = 0; i < 100; i++) { elem[i].setData (i); // Inserting two copies of the same element isn't allowed. bset.insert (elem[i]); if (bset.insert (elem[i]) == -1) { ACE_DEBUG ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("insert set"))); } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d\n"), DataElement::numOfActiveObjects ())); DataElement elem1 (10), elem2 (99); if (!bset.find (elem1) && !bset.find (elem2)) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("The elements %d and %d are ") ACE_TEXT ("in the set!\n"), elem1.getData (), elem2.getData ())); } for (int j = 0; j < 50; j++) { bset.remove (elem[j]); // Remove the element from the set. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem[j].getData ())); } if ((bset.find (elem[0]) == -1) && (bset.find (elem[49]) == -1)) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("The elements %d and %d are ") ACE_TEXT ("NOT in the set!\n"), elem[0].getData (), elem[99].getData ())); } return 0; } // Listing 1 // Listing 2 code/ch05 int SetExample::runUnboundedSet () { ACE_TRACE ("SetExample::runUnboundedSet"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded set.\n"))); ACE_Unbounded_Set<DataElement*> uset; for (int m = 0; m < 100; m++) { DataElement *elem; ACE_NEW_RETURN (elem, DataElement (m), -1); uset.insert (elem); } DataElement deBegin (0), deEnd (99); if (!uset.find (&deBegin) && !uset.find (&deEnd)) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Found the elements\n"))); } // Iterate and destroy the elements in the set. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Deleting the elements\n"))); ACE_Unbounded_Set_Iterator<DataElement*> iter (uset); for (iter = uset.begin (); iter != uset.end (); iter++) { DataElement* elem = (*iter); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); delete elem; } return 0; } // Listing 2 int ACE_TMAIN (int, ACE_TCHAR *[]) { SetExample se; se.run (); return 0; }
[править] Stack
// $Id: Stacks.cpp 94312 2011-07-11 00:39:42Z schmidt $ #include "ace/OS_Memory.h" #include "ace/Log_Msg.h" #include "ace/Containers.h" #include "DataElement.h" class StackExample { public: StackExample (): privateStack_(100) {} // Illustrate all the differnet // types of stacks provided by ACE. int run (void); private: // Illustrate the use of a bounded stack. int runBoundedStack (void); // Illustrate the use of an unbounded stack. int runUnboundedStack (void); // Illustrate the use of a compile time fixed stack. int runFixedStack (void); private: ACE_Bounded_Stack<DataElement*> privateStack_; }; int StackExample::run (void) { ACE_TRACE ("StackExample::run"); ACE_ASSERT(!this->runBoundedStack()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects())); ACE_ASSERT(!this->runFixedStack()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects())); ACE_ASSERT(!this->runUnboundedStack()); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n# of live objects %d\n"), DataElement::numOfActiveObjects())); return 0; } // Listing 1 code/ch05 int StackExample::runBoundedStack (void) { ACE_TRACE ("StackExample::runBoundedStack"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a bounded stack\n"))); ACE_Bounded_Stack<DataElement> bstack1 (100); // The element array is constrained to this scope. { DataElement elem[100]; for (int i = 0; i < 100; i++) { elem[i].setData(i); // Push the element on the stack. bstack1.push (elem[i]); } } ACE_Bounded_Stack<DataElement> bstack2 (100); // Make a copy! bstack2 = bstack1; for (int j = 0; j < 100; j++) { DataElement elem; bstack2.pop (elem); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem.getData ())); } return 0; } // Listing 1 // Listing 2 code/ch05 int StackExample::runFixedStack (void) { ACE_TRACE ("StackExample::runFixedStack"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a fixed stack\n"))); ACE_Fixed_Stack<DataElement*, 100> fstack; for (int k = 0; k < 100; k++) { DataElement* elem; ACE_NEW_RETURN(elem, DataElement (k), -1); fstack.push (elem); // Push the element on the stack. } for (int l = 0; l < 100; l++) { DataElement* elem = 0; fstack.pop (elem); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ())); delete elem; } return 0; } int StackExample::runUnboundedStack (void) { ACE_TRACE ("StackExample::runUnboundedStack"); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded stack\n"))); ACE_Unbounded_Stack<DataElement*> ustack; for (int m = 0; m < 100; m++) { DataElement *elem; ACE_NEW_RETURN(elem, DataElement (m), -1); // Push the element on both stacks. ustack.push (elem); privateStack_.push (elem); } // Oddly enough, you can actually iterate through an // unbounded stack! This is because underneath the covers // the unbounded stack is a linked list. // This will cause the elements in the private stack to // also disappear! ACE_Unbounded_Stack_Iterator<DataElement*> iter (ustack); for (iter.first (); !iter.done (); iter.advance ()) { DataElement** elem = 0; iter.next (elem); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), (*elem)->getData ())); delete (*elem); } return 0; } // Listing 2 int ACE_TMAIN (int, ACE_TCHAR *[]) { StackExample se; return se.run (); }