name: Queue<class TObject>: public DstrBase <TObject>
synopsis:

>     g++ [flags ...] file ...

>     #include <Queue.h>
>     Queue();
>     boolean assign(const Queue<TObject>& copy_queue);
>     boolean add(TObject* item);
>     TObject* remove(TObject* item = (TObject*)NULL);
>     const TObject* peek() const;
>     boolean clear();

quick start:

>     // declare a character queue and add two characters into it
>     //
>     Queue<Char> queue;
>     Char item0(L'a');
>     Char item1(L'b');
>     queue.add(&item0);
>     queue.add(&item1);

>     // remove the top item from the queue
>     //
>     Char* item2 = new Char();
>     queue.remove(item2);

>     if(!item2->eq(item0)) {
>       // error
>     }

description:
The Queue class is a container class that implements a standard queue (first-in, first-out) using a double linked list. For a good reference on queues, see:

T. Cormen, C. Leiserson, R. Rivest, Introduction to Algorithms, MIT Press, Boston, Massachusetts, USA, pp. 200-203, 1998.

This class uses the double linked list in USER mode, since this list is used to store either the actual data or a pointer to it.
dependencies:

- DstrBase
- DoubleLinkedList
- String
- Char
- Console

public constants:

- define the class name:

      static const String CLASS_NAME = L"Queue";

- i/o related constants:

      static const String DEF_PARAM = L"values";

- default values and arguments:

      static const long REMOVE_ALL = -1;

      static const long REMOVE_TO_MARK = -2;

error codes:

- general Queue class error:

      static const long ERR = 40600;

- error code indicating the queue is empty:

      static const long ERR_EMPTY = 40601;

protected data:

- the internal structure of the queue is a DoubleLinkedList:

      DoubleLinkedList<TObject> queue_d;

- the allocation mode:

      ALLOCATION alloc_d;

- debugging parameters:

      static Integral::DEBUG debug_level_d;

- static memory manager:

      static MemoryManager mgr_d;

required public methods:

- static methods: the diagnose method is moved outside the class header file and defined in the QueueDiagnose.h in order to avoid issues with preprocessing of the diagnose code.

      static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods:

      boolean debug(const unichar* message) const;

      static boolean setDebug(Integral::DEBUG debug_level);

- destructor/constructor(s):

      ~Queue();

      Queue(ALLOCATION alloc = DEF_ALLOCATION);

      Queue(const Queue<TObject>& copy_queue);

- assign methods:

      boolean assign(const Queue<TObject>& copy_queue);

- operator= methods:

      Queue<TObject>& operator=(const Queue<TObject>& arg);

- equality methods:

      boolean eq(const Queue<TObject>& compare_queue) const;

- i/o methods: refer to the notes section for an explanation of why there are two read and write methods in this class

      long sofSize() const;

      boolean read(Sof& sof_a, long tag_a);

      boolean write(Sof& sof_a, long tag_a) const;

      boolean read(Sof& sof_a, long tag_a, const String& name_a);

      boolean write(Sof& sof_a, long tag_a, const String& name_a) const;

      boolean readData(Sof& sof, const String& pname = DEF_PARAM, long size = SofParser::FULL_OBJECT, boolean param_a = true, boolean nested_a = false);

      boolean writeData(Sof& sof, const String& pname = DEF_PARAM) const;

- memory management methods:

      static void* operator new(size_t size);

      static void* operator new[](size_t size);

      static void operator delete(void* ptr);

      static void operator delete[](void* ptr);

      static boolean setGrowSize(long grow_size);

      boolean clear(Integral::CMODE cmode = Integral::DEF_CMODE);

class-specific public methods:

- extensions to required methods:

      boolean ne(const Queue<TObject>& compare_queue) const;

- queue add methods:

      boolean add(TObject* item);

      boolean add(Queue<TObject>& item_queue);

      boolean add(TObject** item_list, long num_items);

- other queue manipulation methods:

      const TObject* peek() const;

      TObject* peek();

      TObject* remove(TObject* item = (TObject*)NULL);

      long remove(Queue& items, long num_items);

      boolean removeAll(Queue<TObject>& item_queue);

      boolean removeToMark(Queue<TObject>& item_queue);

- queue marker positioning methods:

      boolean setMark();

      boolean clearMark();

      boolean markIsSet() const;

      const TObject* getMark() const;

      TObject* getMark();

      boolean isMarkedElement() const;

- queue property methods:

      boolean isEmpty() const;

      long length() const;

      boolean find(TObject* value);

      boolean contains(TObject* value) const;

- queue computation methods:

      boolean apply(boolean (TObject::*method)());

      boolean apply(boolean (TObject::*method)(), Queue<TObject>& arg);

- queue element ordering methods:

      boolean sort(Integral::ORDER sort_order = Integral::ASCENDING, SORT_ALGO sort_algo = DEF_SORT_ALGO);

      boolean reverse();

      ALLOCATION getAllocationMode() const;

      boolean setAllocationMode(ALLOCATION alloc);

private methods:

- none.

examples:

- This example demonstrates the basic operation of a queue:

      #include <Char.h>
      #include <Queue.h>

      int main () {

        // local variables
        //
        Queue<Long> q;
        Long j;

        // add 10 items to the queue
        //
        for (long i = 0; i < 10; i++) {
          j = i * 3;
          q.add(&j);
        }

        // see what is on the queue
        //
        q.debug(L"after add");

        // pull things off the queue and print them in order
        //
        while (q.remove(&j) != (Long*)NULL) {
          j.debug(L"pulled off queue");
        }

        // exit gracefully
        //
        Integral::exit();
      }

- This example demonstrates the basic operation of a queue in USER mode. Note that memory is manually allocated before adding it to the queue and deleted upon removal.

      #include <Char.h>
      #include <Queue.h>

      int main () {

        // local variables (note that the queue is set to reference mode)
        //
        Queue<Long> q(USER);
        Long* j;

        // add 10 items to the queue
        //
        for (long i = 0; i < 10; i++) {
          j = new Long(i * 3);
          q.add(j);
        }

        // see what is on the queue
        //
        q.debug(L"after add");

        // pull things off the queue and print them in order
        //
        while ((j = q.remove()) != (Long*)NULL) {
          j->debug(L"pulled off queue");
          delete j;
        }

        // exit gracefully
        //
        Integral::exit();
      }

- This example demonstrates how to check if two Queues are equal:

      #include <Char.h>
      #include <Queue.h>

      int main () {

        // prepare items for the queue
        //
        Char** items = new Char*[5];
        for (long i = 0; i < 5; i++) {
           items[i] = new Char((unichar)((long)(L'a') + i));
        }

        // declare a queue and add items into it
        //
        Queue<Char> char_queue;
        char_queue.add(items, 5);

        // copy the queue
        //
        Queue<Char> copy_char_queue(char_queue);

        // see if these Queues are equivalent
        //
        if(!char_queue.eq(copy_char_queue)) {
          // exit with error
          //
          Integral::exit();

        }

        // clean up the memory used
        //
        for (long i = 0; i < 5; i++) {
          delete items[i];
        }
        delete [] items;

        // exit gracefully
        //
        Integral::exit();
      }

notes:

- Unlike other classes, we have two read and write methods in dstr classes. The interface is still the same as that in other classes. The reason behind this is that we can not use "CLASS_NAME" as default argument in the read and write methods here because the data structures build the class name on the fly.