[CODE][STL] LexiSTL: LList<> (part 2)

From: Chris Jacobson (fear@ATHENET.NET)
Date: 04/28/98


This is part 2... the actual file.

**********  BEGIN FILE  **********

/***********************************************************************\
[*]    __     __  ___ __  _____  __   [*]       Part of LexiMUD       [*]
[*]   / /  ___\ \/ (_) _\/__   \/ /   [*]                             [*]
[*]  / /  / _ \\  /| \ \   / /\/ /    [*] All rights reserved         [*]
[*] / /__|  __//  \| |\ \ / / / /___  [*] Copyright(C) 1997-1998      [*]
[*] \____/\___/_/\_\_\__/ \/  \____/  [*] Chris Jacobson (FearItself) [*]
[*] LexiMUD Standard Template Library [*] fear@technologist.com       [*]
[-]-----------------------------------+-+-----------------------------[-]
[*] File : stl.llist.h                                                [*]
[*] Usage: Linked List template                                       [*]
\***********************************************************************/

#ifndef __STL_LLIST_H__
#define __STL_LLIST_H__

template <class T> class LListNode;
template <class T> class LList;
template <class T> class LListIterator;

template <class T>
class LListNode {
public:
        friend class LList<T>;
        friend class LListIterator<T>;

                                                LListNode(T item) : data(item), next(NULL) { };
                                                ~LListNode(void) { };
private:
        T                                       data;
        LListNode<T> *          next;
};


template <class T>
class LList {
public:
        friend class LListIterator<T>;

                                                LList(void) : head(NULL), iters(NULL), count(0) { };
                                                LList(T item) : head(NULL), iters(NULL), count(0) {
                                                        this->Add(item);
                                                }
                                                ~LList(void) {
                                                        LListNode<T> *  element;
                                                        while(this->head) {
                                                                element = this->head;
                                                                this->head = this->head->next;
                                                                delete element;
                                                        }
                                                        while(this->iters)      delete  this->iters;
                                                }

        void                            Append(T item) {                //      Add to end of list
                                                        if (!item)      return;
                                                        LListNode<T> *  node = new LListNode<T>(item);
                                                        LListNode<T> *  temp = this->head;

                                                        if (!temp) this->head = node;
                                                        else {
                                                                while (temp->next)
                                                                        temp = temp->next;
                                                                temp->next = node;
                                                        }
                                                        count++;
                                                }
        void                            Prepend(T item) {               //      Add to beginning of list
                                                        if (!item)      return;
                                                        LListNode<T> *  node = new LListNode<T>(item);

                                                        node->next = this->head;
                                                        this->head = node;
                                                        count++;
                                                }
        void                            Add(T item) {   this->Prepend(item); }                  //      Add (to beginning)
        void                            Remove(T item) {
                                                        LListIterator<T> *      iter;
                                                        LListNode<T> *          element = NULL;

                                                        if (!item || !this->head) return;

                                                        if (this->head->data == item) {
                                                                element = this->head;
                                                                this->head = element->next;
                                                        } else {
                                                                LListNode<T> *  temp = this->head;
                                                                for (temp = this->head; temp; temp = temp->next) {
                                                                        if (temp->next && temp->next->data == item)
                                                                                        break;
                                                                }
                                                                if (temp) {
                                                                        element = temp->next;
                                                                        temp->next = temp->next->next;
                                                                }
                                                        }

                                                        if (!element)                           return;

                                                        for (iter = this->iters; iter; iter = iter->next)
                                                                iter->Update(element);

                                                        delete element;
                                                        count--;
                                                }
        void                            UpdateIters(void) {
                                                        LListIterator<T> *iter;
                                                        for (iter = this->iters; iter; iter = iter->next)
                                                                iter->list = this;
                                                }
        T                                       Top(void) { return this->head ? this->head->data : NULL; }
        SInt32                          Count(void) { return count; }
        bool                            InList(T item) {
                                                        LListNode<T> *  element;
                                                        if (!item || !this->head) return false;

                                                        for (element = this->head; element; element = element->next)
                                                                if (element->data == item) return true;
                                                        return false;
                                                }
private:
        LListNode<T> *          head;
        LListIterator<T> *      iters;
        SInt32                          count;
};


template <class T>
class LListIterator {
public:
        friend class LList<T>;
                                                LListIterator(LList<T> &theList) :
                                                                list(&theList), current(NULL), next(NULL) {
                                                        if (!this->list)        return;
                                                        this->Reset();
                                                        this->next = this->list->iters;
                                                        this->list->iters = this;
                                                }
                                                ~LListIterator(void) {
                                                        if (!this->list)        return;
                                                        this->list->iters = this->next;
                                                }
        inline void                     Update(LListNode<T> *element) {
                                                        if (element == this->current)   this->current = this->current->next;
                                                }

        inline T                        Peek(void)      { return (this->current ? this->current->data :
NULL); }
        inline T                        Next(void)      {
                                                        if (!current)   return (T)NULL;
                                                        T data = this->current->data;
                                                        this->current = this->current->next;
                                                        return data;
                                                }
        inline void                     Reset(void)     { this->current = this->list->head; }

private:
        LList<T> *                      list;
        LListNode<T> *          current;
        LListIterator<T> *      next;
};


#define START_ITER(iter, var, type, list)                                               \
        LListIterator<type>* iter = new LListIterator<type>(list);      \
        while ((var = iter->Next()))

#define END_ITER(iter)  \
        delete iter;

#endif


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST