ACE/FAQ/APG/Containers

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск

Содержание


[править] 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 ();
}