/*
 *  slist.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
/*  slist.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
// This file defines the base classes for linked lists. 
// It is largely copied from Stroustrup's C++ Book. pp. 203 
#ifndef SLIST_DOT_H
#define SLIST_DOT_H
#include "ObjProGen/errcode.h"

class SingleListIterator ;

typedef void * Entity ;

class SingleLink {
friend class SingleList ;
friend class SingleListIterator ;
	SingleLink * Next;
	Entity Entry ;
	SingleLink(Entity e, SingleLink * p) {Entry=e; Next=p;}
} ;
 
class SingleList {
friend class SingleListIterator ;
	SingleLink * Last ;
public:
	ErrCode Insert(Entity a) ;	// Add at head of list
	ErrCode Append(Entity a) ;  // Add at end of list
	ErrCode Append(SingleList * lst) ;  // Add at end of list
	Entity Get() ;		// Return and remove head of list
	Entity Pop() ;		// Return and remove tail of list
	void Clear() ;		// Remove all links
	Entity GetFirst() ;
	Entity GetLast() ;

	SingleList()         {Last = 0; }
	~SingleList()	     {Clear(); }
	SingleList(Entity a) {Last = new SingleLink(a,0); Last->Next=Last;}
	SingleList(SingleList *a) {Last=0; Append(a);}
	int Size() const ;
	ErrCode RemoveEntry(Entity a) ;
} ;

class SingleListIterator {
friend class SingleList ;
	SingleLink * CurrentEntry ;
	const SingleList * CurrentList ;
public:
	SingleListIterator(const SingleList& Slist) {CurrentList = &Slist ;
						CurrentEntry = 0;}
	Entity Next() ;
} ;

class StringList:public SingleList {
public:
	ErrCode Insert(char *nt) {return SingleList::Insert((Entity)nt);}
	ErrCode Append(char *nt) {return SingleList::Append((Entity)nt);}
	ErrCode Append(SingleList *lst)
		{return SingleList::Append((SingleList *)lst);}
	char * Get()  {return (char *) SingleList::Get();}
	char * Pop() {return (char *) SingleList::Pop();}
	StringList(){;}
	int Size() const {return SingleList::Size();}
	int IsInList(const char *);
} ;

class StringListIterator: public SingleListIterator {
public:
	StringListIterator(const StringList& df):
		SingleListIterator((SingleList&) df){}
	char * operator()()
		{return (char *) Next();}
};
class SingleListIterator ;

typedef const char * ConstEntity ;

class ConstSingleLink {
friend class ConstSingleList ;
friend class ConstSingleListIterator ;
	ConstSingleLink * Next;
	ConstEntity Entry ;
	ConstSingleLink(ConstEntity e, ConstSingleLink * p) {Entry=e; Next=p;}
} ;
 
class ConstSingleList {
friend class ConstSingleListIterator ;
	ConstSingleLink * Last ;
public:
	ErrCode Insert(ConstEntity a) ;	// Add at head of list
	ErrCode Append(ConstEntity a) ;  // Add at end of list
	ErrCode Append(ConstSingleList * lst) ;
	ConstEntity Get() ;		// Return and remove head of list
	ConstEntity Pop() ;		// Return and remove tail of list
	void Clear() ;		// Remove all links

	ConstSingleList()         {Last = 0; }
	ConstSingleList(ConstEntity a)
		{Last = new ConstSingleLink(a,0); Last->Next=Last;}
	ConstSingleList(ConstSingleList * A) {Last=0; Append(A);}
	int Size() const ;
	~ConstSingleList()	     {Clear(); }
} ;

class ConstSingleListIterator {
	ConstSingleLink * CurrentEntry ;
	const ConstSingleList * CurrentList ;
public:
	ConstSingleListIterator(const ConstSingleList& Slist)
		{CurrentList = &Slist ; CurrentEntry = 0;}
	ConstEntity Next() ;
} ;

class ConstStringList: public ConstSingleList {
public:
	ErrCode Insert(const char *nt)
		{return ConstSingleList::Insert(nt);}
	ErrCode Append(const char *nt)
		{return ConstSingleList::Append(nt);}
	ErrCode Append(ConstStringList * lst)
		{return ConstSingleList::Append(lst);}
	const char * Get() {return ConstSingleList::Get();}
	const char * Pop() {return ConstSingleList::Pop();}
	ConstStringList(){;}
	ConstStringList(const char *a):ConstSingleList((ConstEntity)a){}
	ConstStringList(ConstStringList *a):
		ConstSingleList((ConstSingleList *)a){}
	int Size() const {return ConstSingleList::Size();}
	int IsInList(const char *);
} ;

class ConstStringListIterator: public ConstSingleListIterator {
public:
	ConstStringListIterator(const ConstStringList& df):
		ConstSingleListIterator((ConstSingleList&) df){}
	const char * operator()()
		{return Next();}
};


#endif /* #ifdef SLIST_DOT_H */
