//====================================================================
// Filename:  llist.hpp
// By:        Roger Z. Rios Mercado
// Date:      Fall 1993
// Modified:  SP/94
// Comment:   For the FUTMEX project, this file should NOT be
//            further modified
//====================================================================
//
//   This class is a general linked list container class. It expects
// the application to generate and destroy the enlisted elements,
// which are passed to llist via void pointers.
//
// Specifications:
//
// Fns. first(), last(), next(), and prev() can be used to browse the 
// structure.  These routines use an internal pointer (<current>) which
// maintains a position in the structure.  You can examine the whole 
// structure, one element at a time by calling first(), which returns
// the first data element, and then calling next() to retrieve successive 
// data elements until next() returns 0.  Likewise with last() and prev(),
// prev() returns the element prior to the previously returned element.
// All the insert* fns. set the internal notion of the <current> element
// to the just inserted element.  So calling next() or prev() after an 
// insert*() will return the next or previous data element with respect
// to the just inserted element, respectively.  For deletion, the notion 
// of the <current> element is not as well defined.  The new <current>
// element is the element just prior to the deleted element, or the head 
// of the list if the first element was deleted.  Traversing the list 
// with print() or traverse_op() resets the <current> element to the 
// first element in the structure. 
//
//====================================================================

#ifndef LLIST_HPP
#define LLIST_HPP 

#include "containr.hpp"


class llist_node; // forward declaration

class llist : public container {
public:
     llist(int (*cmp)(void*, void*), char* s) : container(cmp, s) 
          { head = tail = current = 0; }
     ~llist();
     int insert(void*);       // Put data entity in the struct, copy only
                              //    the data ptr.
     int insertfirst(void*);  // Insert data entity at beginning of struct.
     int insertlast(void*);   // Insert data entity at end of structure.
     void  print();           // Print out the data in the structure.
     void  flush();           // Empty, but don't delete the structure.
     void flush_nodes();      // Empty, but don't delete data entities.
                              // Use it when data entities also belong
                              // to some other structure.
     void* remove(void*);     // Remove data entity from structure, 
                              //    return data pointer.
     void* find(void*);       // Find data entity in structure, do not 
                              //    remove, return data pointer.
     void* first();           // Return pointer to the first data entity 
                              //    in the structure.
     void* last();            // Return pointer to the last data entity 
                              //    in the structure.
     void* next();            // Return pointer to the next data entity, 
                              //    affected by access.
     void* prev();            // Return pointer to the previois data 
                              //    entity, affected by access
private:
     llist_node* head;     // Ptr to first node in the list.
     llist_node* tail;     // Ptr to last node in the list.
     llist_node* current;  // Ptr to current node.
};

class llist_node {
friend class llist;
private:
     llist_node() : next(0), data(0) {};
     llist_node(void* d) : next(0), data(d) {};
     llist_node(void* d, llist_node* n) : next(n), data(d) {};
     ~llist_node() {next = 0; data = 0;}
     llist_node* next;  // Ptr to next node in the list.
     void *data;        // Ptr to data entity.
};

#endif

 
