name: SingleLinkedList<class TObject>: public :DstrBase;
synopsis:

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

>     #include <SingleLinkedList.h>

>     SingleLinkedList(ALLOCATION alloc_d = DEF_ALLOCATION) ;
>     boolean insert(TObject* item, boolean insert_before);
>     boolean insertFirst(TObject* item);
>     boolean removeLast();
>     const TObject* getNext() const;
>     boolean apply(boolean (TObject::*method)());

quick start:

>     // declare a character list and add two characters into it
>     //
>     SingleLinkedList<Char> list;
>     Char item0(L'a');
>     Char item1(L'b');
>     list.insertFirst(&item0);
>     list.insert(&item1);

>     // get the last character
>     //
>     list.gotoLast();
>     Char* item2 = list.getCurr();
>     if (item2->ne(item1)) {
>        // error
>     }

description:
The SingleLinkedList class, as its name suggests, is a list template class that supports list processing using a data structure that contains a pointer to the next element in the list. (A doubly linked list, by constrast, contains a pointer to the previous node as well as the next list). For a good reference on lists, see:

T. Budd, Data Structures in C++ using the Standard Template Library, Addison Wesley, Reading, Massachusetts, USA, pp. 185-216, 1998.

The user may select the memory management mode in which this class operates: USER or SYSTEM. In SYSTEM mode, the class is responsible for managing the memory for the objects it contains. This implies that a copy is made each time an object is inserted to the list. In USER mode the user is responsible for allocation and deletion of the objects that are stored in the list. In this mode, pointers to the external objects are stored - a copy is not made. The best mode for your application depends on your need to trade-off speed versus the complexity of object management.
dependencies:

- DstrBase
- SingleLinkedNode
- VectorLong
- String
- Char
- Long
- Console
- Stack

public constants:

- define the class name:

      static const SysString CLASS_NAME = L"SingleLinkedList";

- i/o related constants:

      static const SysString DEF_PARAM = L"values";

error codes:

- general SingleLinkedList class error:

      static const long ERR = 40300;

protected data:

- define the NODE object

      typedef SingleLinkedNode NODE;

- pointers to the first node, last node and current node:

      NODE* first_d;

      NODE* last_d;

      NODE* curr_d;

- a pointer to a node the user marks:

      NODE* mark_d;

- the number of nodes in the list:

      Long length_d;

- the flag of memory allocation mode:

      ALLOCATION alloc_d;

- debugging parameters:

      static Integral::DEBUG debug_level_d;

- define the memory manager:

      static MemoryManager mgr_d;

required public methods:

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

      static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods:

      static boolean setDebug(Integral::DEBUG debug_level);

      boolean debug(const unichar* message) const;

- destructor/constructor(s):

      ~SingleLinkedList();

      SingleLinkedList(ALLOCATION alloc = DEF_ALLOCATION);

      SingleLinkedList(const SingleLinkedList<TObject>& copy_list);

- assign methods:

      boolean assign(const SingleLinkedList<TObject>& copy_list);

- operator= methods:

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

- equality methods:

      boolean eq(const SingleLinkedList<TObject>& compare_list) 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:

- overloaded operators and extensions to required methods:

      TObject& operator() (long index);

      const TObject& operator() (long index) const;

      boolean ne(const SingleLinkedList<TObject>& compare_list) const;

- positioning methods:

      boolean gotoFirst();

      boolean gotoLast();

      boolean gotoNext();

      boolean gotoPrev();

      boolean gotoMark();

      boolean gotoPosition(long number);

      long getPosition() const;

- marking methods:

      boolean markIsSet() const;

      boolean isMarkedElement() const;

      boolean clearMark();

      boolean setMark();

- access methods:

      TObject* getFirst();

      const TObject* getFirst() const;

      TObject* getLast();

      const TObject* getLast() const;

      TObject* getNext();

      const TObject* getNext() const;

      TObject* getPrev();

      const TObject* getPrev() const;

      TObject* getMark();

      const TObject* getMark() const;

      TObject* getCurr();

      const TObject* getCurr() const;

- insert and remove methods:

      boolean insert(TObject* item, boolean insert_before);

      boolean insert(SingleLinkedList& ilist);

      boolean remove(TObject*& item);

      boolean remove();

      boolean insertFirst(TObject* item);

      boolean insertFirst(SingleLinkedList& ilist);

      boolean removeFirst(TObject*& item);

      boolean removeFirst();

      boolean insertLast(TObject* item);

      boolean insertLast(SingleLinkedList& ilist);

      boolean removeLast(TObject*& item);

      boolean removeLast();

- property methods:

      boolean isEmpty() const;

      boolean isFirst() const;

      boolean isLast() const;

      long length() const;

      boolean find(const TObject* item);

      boolean contains(TObject* value);

- ordering methods:

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

      boolean reverse();

      boolean swap(long i, long j);

- apply methods: methods to apply an external function to each element in the SingleLinkedList

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

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

- allocation mode methods:

      ALLOCATION getAllocationMode() const;

      boolean setAllocationMode(ALLOCATION alloc);

private methods:

- sort methods:

      boolean randQuickSort(Integral::ORDER sort_order);

      boolean insertionSort(Integral::ORDER sort_order);

- swap methods: exchange two nodes in the list. this method assumes the nodes are in the list and in the proper order. this avoids the overhead of checking the order. this method is used inside the sort algorithm.

      boolean swap(NODE*& i, NODE*& j);

- node addressing methods:

      NODE* getNode(long index) const;

- previous node access methods: this method finds the previous node of the given node since SingleLinkedNode has no pointer to its previous node

      NODE* getPrevNode(NODE* node) const;

friend classes:

    friend class SingleLinkedListDiagnose;

examples:

- This example shows the basic operation of a SingleLinkedList

      #include <SingleLinkedList.h>
      #include <Char.h>

      int main() {

        // local variables
        //
        SingleLinkedList<Long> s;
        Long j;

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

        // see what is on the SingleLinkedList
        //
        s.debug(L"after insertion");

        // get the elements and print them
        //
        s.gotoFirst();
        Long* l = s.getFirst();
        l->debug(L"item from the List");

        while((l= s.getNext())!=NULL) {
          s.gotoNext();
          l->debug(L"item from the List");
        }

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

- This example shows the basic operation of a SingleLinkedList in USER mode. Note that memory is manually allocated before inserting it to the List and deleted later.

      #include <SingleLinkedList.h>
      #include <Char.h>

      int main() {

        // local variables
        //
        SingleLinkedList<Long> s(USER);
        Long* j;

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

        // see what is on the SingleLinkedList
        //
        s.debug(L"after insertion");

        // get the elements and print them
        //
        s.gotoFirst();
        Long* l = s.getFirst();
        l->debug(L"item from the List");
        delete l;

        while((l=s.getNext())!=NULL) {
          s.gotoNext();
          l->debug(L"item from the List");
          delete l;
        }

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

- This example shows how to check if SingleLinkedLists are equal

      #include <SingleLinkedList.h>
      #include <Char.h>

      int main() {

        // prepare items for the list
        //
        Char** items = new Char*[10];

        // declare a SYSTEM-allocating SingleLinkedList and add items into it
        //
        SingleLinkedList<Char> char_list;

        for (long i = 0; i < 10; i++) {
          items[i] = new Char((unichar)((long)'a' + i));

          // insert the items to the list
          //
          char_list.insert(items[i]);

        }

        // copy the SingleLinkedList
        //
        SingleLinkedList<Char> char_copy_list(char_list);

        // declare a third list that is SYSTEM-allocating, and has the same items
        //
        SingleLinkedList<Char>* system_char_list = new SingleLinkedList<Char>();
        system_char_list->assign(char_list);

        // see if these SingleLinkedLists are equivalent
        //
        if(!char_list.eq(char_copy_list) || !system_char_list->eq(char_list)) {

          // exit with error
          //
          Integral::exit();
        }

        // clean up the memory used
        //
        delete system_char_list;
        delete [] items;

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

notes:

- There are two memory allocation modes for SingleLinkedList as indicated by the protected member data, alloc_d. The default allocation mode is SYSTEM. If alloc_d is set to SYSTEM, the list handles allocation and deletion of the objects. When the user puts an object into the list, a copy of the object is made and inserted into the list via local memory allocation - note that this requires a call to the copy constructor so the user will experience an efficiency decrease. When the object is removed from the list, the object is automatically deleted.
- If alloc_d is set to USER, the user is required to handle all memory allocation and deletion. When the user adds an object to the list, the object passed in is stored in the list by pointer reference. when an object is removed, the user is required to accept a pointer to the object.
- 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.