/* * CENA C++ Utilities * * by Stephane Chatty * * Copyright 1992-1995 * Centre d'Etudes de la Navigation Aerienne (CENA) * * plain and generic lists (original ideas by Yves Berteaud) * * $Id$ * $CurLog$ */ #ifndef List_H_ #define List_H_ #include "cplus_bugs.h" #include class IvlAllocator; typedef void IvlListItem; typedef void* IvlListIndex; #ifdef CPLUS_BUG20 class IvlListLink; #endif class IvlList { friend class IvlListIter; #ifndef CPLUS_BUG20 class IvlListLink { static IvlAllocator* ListLinkMem; public: IvlListItem* Entry; IvlListLink* Next; inline IvlListLink (IvlListItem* e, IvlListLink* n = 0) { Entry = e; Next = n ? n : this; } IvlListLink* Previous (); void* operator new (size_t); void operator delete (void*); }; #endif public: enum list_status { NoError, WasEmpty, TooEarly, TooFar, BadIterator }; enum list_remove { All = -1 }; private: IvlListLink* LastLink; list_status StatusFlag; IvlListIndex InsertAfterLink (IvlListLink*, IvlListItem*); IvlListIndex InsertBeforeLink (IvlListLink*, IvlListItem*); IvlListItem* RemoveAfterLink (IvlListLink*); public: inline IvlList () : LastLink (0), StatusFlag (NoError) { } IvlList (IvlListItem*); IvlList (const IvlList&); ~IvlList (); IvlList& operator = (const IvlList&); inline list_status GetStatus () const { return StatusFlag; } inline int IsEmpty () const { return !LastLink; } IvlListItem* First (); IvlListItem* Last (); IvlListItem* Nth (int n); int Length () const; int Find (IvlListItem*, int* = 0) const; IvlListIndex Append (IvlListItem*); IvlListIndex Prepend (IvlListItem*); inline IvlList& operator << (IvlListItem* it) { Append (it); return *this; } IvlListItem* RemoveFirst (); IvlListItem* RemoveLast (); int Remove (IvlListItem*, int = 1); int Remove (int (*) (IvlListItem*), int = 1); void Clear (); IvlListIndex InsertAfter (const IvlListIter&, IvlListItem*); IvlListIndex InsertBefore (const IvlListIter&, IvlListItem*); IvlListItem* RemoveAfter (const IvlListIter&); }; class IvlListIter { friend class IvlList; public: enum listiter_status { Normal, StartOfList, EndOfList }; private: const IvlList* TheList; #ifdef CPLUS_BUG20 IvlListLink* CurLink; #else IvlList::IvlListLink* CurLink; #endif listiter_status StatusFlag; public: inline IvlListIter (const IvlList& l) : TheList (&l), CurLink (0), StatusFlag (StartOfList) { } IvlListIter (const IvlList&, IvlListIndex); inline void Reset () { CurLink = 0; StatusFlag = StartOfList; } inline IvlListIter& operator = (const IvlList& l) { TheList = &l; CurLink = 0; StatusFlag = StartOfList; return *this; } inline IvlListIter& operator = (const IvlListIter& li) { TheList = li.TheList; CurLink = li.CurLink; StatusFlag = li.StatusFlag; return *this; } IvlListIter& operator ++ (); #ifndef CPLUS_BUG16 IvlListIter& operator ++ (int); #endif IvlListItem* operator * () const; int Find (IvlListItem*); inline listiter_status GetStatus () const { return StatusFlag; } inline operator int () const { return StatusFlag == Normal; } }; #ifndef CPLUS_BUG19 template class IvlListIterOf; template class IvlListOf : public IvlList { public: inline IvlListOf () : IvlList () {} inline IvlListOf (ITEM* it) : IvlList (it) {} inline ITEM* First () { return (ITEM*) (IvlList::First ()); } inline ITEM* Last () { return (ITEM*) (IvlList::Last ()); } inline ITEM* Nth (int n) { return (ITEM*) (IvlList::Nth (n)); } inline int Find (ITEM* it, int* r = 0) const { return IvlList::Find (it, r); } inline IvlListIndex Append (ITEM* it) { return IvlList::Append (it); } inline IvlListIndex Prepend (ITEM* it) { return IvlList::Prepend (it); } inline IvlListOf& operator << (ITEM* it) { IvlList::Append (it); return *this; } inline ITEM* RemoveFirst () { return (ITEM*) (IvlList::RemoveFirst ()); } inline ITEM* RemoveLast () { return (ITEM*) (IvlList::RemoveLast ()); } inline int Remove (ITEM* it, int nb = 1) { return IvlList::Remove (it, nb); } inline int Remove (int (*p) (ITEM*), int nb = 1) { return IvlList::Remove ((int (*) (void*)) p, nb); } inline IvlListIndex InsertAfter (const IvlListIterOf & li, ITEM*it) { return IvlList::InsertAfter (li, it); } inline IvlListIndex InsertBefore (const IvlListIterOf & li, ITEM* it) { return IvlList::InsertBefore (li, it); } inline ITEM* RemoveAfter (const IvlListIterOf & li) { return (ITEM*) IvlList::RemoveAfter (li); } }; template class IvlListIterOf : public IvlListIter { public: inline IvlListIterOf (const IvlListOf & l) : IvlListIter (l) { } inline IvlListIterOf& operator = (const IvlListOf & l) { return (IvlListIterOf &) IvlListIter::operator = (l); } inline IvlListIterOf& operator = (const IvlListIterOf & li) { return (IvlListIterOf &) IvlListIter::operator = (li); } inline IvlListIterOf& operator ++ () { return (IvlListIterOf &) IvlListIter::operator ++ (); } inline ITEM* operator * () const { return (ITEM*) IvlListIter::operator * (); } inline int Find (ITEM* it) { return IvlListIter::Find (it); } }; #endif /* CPLUS_BUG19 */ typedef IvlListItem IvlStackItem; /* CPLUS_BUG10 */ class IvlStack : _private IvlList { public: IvlList :: Clear; IvlList :: IsEmpty; IvlList :: GetStatus; inline void Push (IvlStackItem* p) { Prepend (p); } inline IvlStackItem* Pop () { return RemoveFirst (); } inline IvlStackItem* Top () { return First (); } }; #ifndef CPLUS_BUG19 template class IvlStackOf : public IvlStack { public: inline void Push (ITEM* p) { IvlStack::Push (p); } inline ITEM* Pop () { return (ITEM*) IvlStack::Pop (); } inline ITEM* Top () { return (ITEM*) IvlStack::Top (); } inline operator const IvlListOf & () { return *(IvlListOf *) this; } }; #endif /* CPLUS_BUG19 */ typedef IvlListItem IvlQueueItem; #if 0 /* CPLUS_BUG10 */ class IvlQueue : _private IvlList { public: IvlList :: Clear; IvlList :: IsEmpty; IvlList :: GetStatus; inline void Put (IvlQueueItem* p) { Append (p); } inline IvlQueueItem* Get () { return RemoveFirst (); } inline operator const IvlList& () { return *this; } }; #ifndef CPLUS_BUG19 template class IvlQueueOf : public IvlQueue { public: inline void Put (ITEM* p) { IvlQueue::Put (p); } inline ITEM* Get () { return (ITEM*) IvlQueue::Get (); } inline operator const IvlListOf & () { return *(IvlListOf *) this; } }; #endif /* CPLUS_BUG19 */ #endif /* 0 */ #endif /* List_H_ */