//
// List.h
//
// List: A List class which holds objects of type Object.
//
// Part of the ht://Dig package
// Copyright (c) 1999-2004 The ht://Dig Group
// For copyright details, see the file COPYING in your distribution
// or the GNU Library General Public License (LGPL) version 2 or later
//
//
// $Id: List.h,v 1.9 2004/05/28 13:15:21 lha Exp $
//
#ifndef _List_h_
#define _List_h_
#include "Object.h"
//
// Behaviour of the Remove method. See comment before method
// declaration for more information.
//
#define LIST_REMOVE_DESTROY 1
#define LIST_REMOVE_RELEASE 2
class List;
class listnode;
class ListCursor {
public:
ListCursor() { current = 0; prev = 0; current_index = -1; }
void Clear() { current = 0; prev = 0; current_index = -1; }
//
// Support for the Start_Get and Get_Next routines
//
listnode *current;
listnode *prev;
int current_index;
};
class List : public Object
{
public:
//
// Constructor/Destructor
//
List();
virtual ~List();
//
// Insert at beginning of list.
//
virtual void Unshift(Object *o) { Insert(o, 0); }
//
// Remove from the beginning of the list and return the
// object.
//
virtual Object* Shift(int action = LIST_REMOVE_DESTROY) {
Object* o = Nth(0);
if(Remove(0, action) == NOTOK) return 0;
return o;
}
//
// Append an Object to the end of the list
//
virtual void Push(Object *o) { Add(o); }
//
// Remove the last object from the list and return it.
//
virtual Object *Pop(int action = LIST_REMOVE_DESTROY);
//
// Add() will append an Object to the end of the list
//
virtual void Add(Object *);
//
// Insert() will insert an object at the given position. If the
// position is larger than the number of objects in the list, the
// object is appended; no new objects are created between the end
// of the list and the given position.
//
virtual void Insert(Object *, int position);
//
// Assign() will replace the object already at the given position
// with the new object. If there is no object at the position,the
// list is extended with nil objects until the position is reached
// and then the given object is put there. (This really makes the
// List analogous to a dynamic array...)
//
virtual void Assign(Object *, int position);
//
// Find the given object in the list and remove it from the list.
// The object will NOT be deleted. If the object is not found,
// NOTOK will be returned, else OK.
//
virtual int Remove(Object *);
//
// Remove object at position from the list. If action is
// LIST_REMOVE_DESTROY delete the object stored at position.
// If action is LIST_REMOVE_RELEASE the object is not deleted.
// If the object is not found,
// NOTOK will be returned, else OK.
//
virtual int Remove(int position, int action = LIST_REMOVE_DESTROY);
//
// Release() will set the list to empty. This call will NOT
// delete objects that were in the list before this call.
//
virtual void Release();
//
// Destroy() will delete all the objects in the list. This is
// equivalent to calling the destructor
//
virtual void Destroy();
//
// List traversel
//
void Start_Get() { Start_Get(cursor); }
void Start_Get(ListCursor& cursor0) const { cursor0.current = head; cursor0.prev = 0; cursor0.current_index = -1;}
Object *Get_Next() { return Get_Next(cursor); }
Object *Get_Next(ListCursor& cursor) const;
Object *Get_First();
Object *Next(Object *current);
Object *Previous(Object *current);
Object *Last();
//
// Direct access to list items. This can only be used to retrieve
// objects from the list. To assign new objects, use Insert(),
// Add(), or Assign().
//
Object *operator[] (int n) { return Nth(n); }
const Object *operator[] (int n) const { return Nth(((List*)this)->cursor, n); }
const Object *Nth(ListCursor& cursor, int n) const;
const Object *Nth(int n) const { return Nth(((List*)this)->cursor, n); }
Object *Nth(int n) { return (Object*)((List*)this)->Nth(((List*)this)->cursor, n); }
//
// Access to the number of elements
//
int Count() const { return number; }
//
// Get the index number of an object. If the object is not found,
// returnes -1
//
int Index(Object *);
//
// Deep copy member function
//
Object *Copy() const;
//
// Assignment
//
List &operator= (List *list) {return *this = *list;}
List &operator= (List &list);
// Move one list to the end of another, emptying the other list.
void AppendList (List &list);
protected:
//
// Pointers into the list
//
listnode *head;
listnode *tail;
//
// For list traversal it is nice to know where we are...
//
ListCursor cursor;
//
// Its nice to keep track of how many things we contain...
//
int number;
};
#endif