/* * CENA C++ Utilities * * by Stephane Chatty * * Copyright 1992-1995 * Centre d'Etudes de la Navigation Aerienne (CENA) * * plain and generic double-linked lists (original ideas by Yves Berteaud) * * $Id$ * $CurLog$ */ #ifndef DList_H_ #define DList_H_ #include "cplus_bugs.h" #include class CcuAllocator; typedef void CcuDListItem; #ifdef CPLUS_BUG20 class CcuDListLink; #endif class CcuDList { friend class CcuDListIter; #ifndef CPLUS_BUG20 class CcuDListLink { static CcuAllocator* DListLinkMem; public: CcuDListItem* Entry; CcuDListLink* Previous; CcuDListLink* Next; inline CcuDListLink (CcuDListItem* e, CcuDListLink* p) : Entry (e), Previous (p), Next (p->Next) { Previous->Next = Next->Previous = this; } inline CcuDListLink (CcuDListItem* e) : Entry (e), Previous (this), Next (this) {} void* operator new (size_t); void operator delete (void*); }; #endif public: enum dlist_status { NoError, WasEmpty, TooEarly, TooFar, BadIterator }; enum dlist_remove { All = -1 }; private: CcuDListLink* LastLink; dlist_status StatusFlag; void InsertAfterLink (CcuDListLink*, CcuDListItem*); CcuDListItem* RemoveLink (CcuDListLink*); public: inline CcuDList () : LastLink (0), StatusFlag (NoError) { } CcuDList (CcuDListItem*); CcuDList (const CcuDList&); ~CcuDList (); CcuDList& operator = (const CcuDList&); inline dlist_status GetStatus () const { return StatusFlag; } inline int IsEmpty () const { return !LastLink; } CcuDListItem* First (); CcuDListItem* Last (); CcuDListItem* Nth (int n); int Length () const; int Find (CcuDListItem*) const; void Append (CcuDListItem*); void Prepend (CcuDListItem*); inline CcuDList& operator << (CcuDListItem* it) { Append (it); return *this; } CcuDListItem* RemoveFirst (); CcuDListItem* RemoveLast (); int Remove (CcuDListItem*, int = 1); int Remove (int (*) (CcuDListItem*), int = 1); void Clear (); void InsertAfter (const CcuDListIter&, CcuDListItem*); void InsertBefore (const CcuDListIter&, CcuDListItem*); CcuDListItem* RemoveAfter (const CcuDListIter&); CcuDListItem* RemoveAt (CcuDListIter&); }; class CcuDListIter { friend class CcuDList; public: enum dlistiter_status { Normal, StartOfList, EndOfList }; private: const CcuDList* TheList; #ifdef CPLUS_BUG20 CcuDListLink* CurLink; #else CcuDList::CcuDListLink* CurLink; #endif dlistiter_status StatusFlag; public: inline CcuDListIter (const CcuDList& l) : TheList (&l), CurLink (0), StatusFlag (StartOfList) {} inline void Reset () { CurLink = 0; StatusFlag = StartOfList; } inline void GotoEnd () { CurLink = TheList->LastLink; StatusFlag = CurLink ? EndOfList : StartOfList; } inline CcuDListIter& operator = (const CcuDList& l) { TheList = &l; CurLink = 0; StatusFlag = StartOfList; return *this; } inline CcuDListIter& operator = (const CcuDListIter& li) { TheList = li.TheList; CurLink = li.CurLink; StatusFlag = li.StatusFlag; return *this; } CcuDListIter& operator ++ (); CcuDListIter& operator -- (); int Find (CcuDListItem*); int FindBack (CcuDListItem*); CcuDListItem* operator * () const; inline dlistiter_status GetStatus () const { return StatusFlag; } inline operator int () const { return StatusFlag == Normal; } }; #ifndef CPLUS_BUG19 template class CcuDListIterOf; template class CcuDListOf : public CcuDList { public: inline CcuDListOf () : CcuDList () {} inline CcuDListOf (ITEM* it) : CcuDList (it) {} inline ITEM* First () { return (ITEM*) (CcuDList::First ()); } inline ITEM* Last () { return (ITEM*) (CcuDList::Last ()); } inline ITEM* Nth (int n) { return (ITEM*) (CcuDList::Nth (n)); } inline int Find (ITEM* it) const { return CcuDList::Find (it); } inline void Append (ITEM* it) { CcuDList::Append (it); } inline void Prepend (ITEM* it) { CcuDList::Prepend (it); } inline CcuDListOf & operator << (ITEM* it) { CcuDList::Append (it); return *this; } inline ITEM* RemoveFirst () { return (ITEM*) (CcuDList::RemoveFirst ()); } inline ITEM* RemoveLast () { return (ITEM*) (CcuDList::RemoveLast ()); } inline int Remove (ITEM* it, int nb = 1) { return CcuDList::Remove (it, nb); } inline int Remove (int (*p) (ITEM*), int nb = 1) { return CcuDList::Remove ((int (*) (ITEM*)) p, nb); } inline void InsertAfter (const CcuDListIterOf & li, ITEM*it) { CcuDList::InsertAfter (li, it); } inline void InsertBefore (const CcuDListIterOf & li, ITEM* it) { CcuDList::InsertBefore (li, it); } inline ITEM* RemoveAfter (const CcuDListIterOf & li) { return (ITEM*) CcuDList::RemoveAfter (li); } inline ITEM* RemoveAt (CcuDListIterOf & li) { return (ITEM*) CcuDList::RemoveAfter (li); } }; template class CcuDListIterOf : public CcuDListIter { public: inline CcuDListIterOf (const CcuDListOf & l) : CcuDListIter (l) { } inline CcuDListIterOf & operator = (const CcuDListOf & l) { return (CcuDListIterOf &) CcuDListIter::operator = (l); } inline CcuDListIterOf & operator = (const CcuDListIterOf & li) { return (CcuDListIterOf &) CcuDListIter::operator = (li); } inline ITEM* operator * () const { return (ITEM*) CcuDListIter::operator * (); } inline int Find (ITEM* it) { return CcuDListIter::Find (it); } inline int FindBack (ITEM* it) { return CcuDListIter::FindBack (it); } }; #endif /* CPLUS_BUG19 */ #endif /* DList_H_ */