ref: f6c5b60489d8183f607f25ec87001969682a02d8
dir: /wingui/listobj.h/
// list class // Copyright 1999, Torsten Landmann // successfully compiled and tested under MSVC 6.0 // // revised 2001 by Torsten Landmann // successfully compiled and tested under MSVC 6.0 // ////////////////////////////////////////////////////// #ifndef __Listobj_h__ #define __Listobj_h__ #include "stdafx.h" typedef signed long TBListErr; const long iMaxNumberOfCBListItems=100000000; const TBListErr siListNoErr=0; const TBListErr siListErr=-1; // error codes const TBListErr siListSavErr=-2; const long lMaxNumRS=256; // maximum number of reading sessions // public use of this type is obsolete; use CBListReader instead typedef signed long HRead; // objects of this class can be compared with a moving pointer to // a certain element in a list; it's used during sequential reading // of lists; // this class wraps HRead and automatically finishes the read // session once an instance becomes destructed class CBListReader { friend class CBList; public: // simplest way to get a reader CBListReader(CBList &oList); // copy constructor CBListReader(const CBListReader &oSource); virtual ~CBListReader(); // makes this class compatible with former HRead operator HRead() const { return m_hRead; } CBListReader& operator=(const CBListReader &oRight); void EndReaderSession() { AbandonCurrentContent(); } protected: CBListReader(CBList *poList, HRead hRead); private: CBList *m_poList; HRead m_hRead; int *m_piUsageStack; void AbandonCurrentContent(); }; enum ESortMode { eAscending, eDescending }; class CBList; class CBBaseElem { friend class CBList; public: class CBBaseElem *GetNext() const { return pNext; } class CBBaseElem *GetPrevious() const { return pPrevious; } long GetIndex() const { return lIndex; } class CBList *GetParentList() const { return pParentList; } // -1: parameter element is higher // 0: same // 1: parameter element is smaller // in this base class elements are sorted by their index virtual signed long IsHigher(class CBBaseElem *pElem); protected: CBBaseElem(); // only allowed for derivations and for CBList (=friend) virtual ~CBBaseElem(); // override these members if you want to put your list // to a stream or retreive it from there; // do never forget to call these ones if you override them virtual bool PutToArchive(CArchive &oArchive, long lSaveParams) const; virtual bool GetFromArchive(CArchive &oArchive, long lLoadParams); private: long lIndex; class CBBaseElem *pNext, *pPrevious; class CBList *pParentList; }; typedef CBBaseElem *PBBaseElem; class CBList { public: CBList(); virtual ~CBList(); TBListErr DeleteAll(); TBListErr DeleteElem(long lIndex); bool Exists(long lIndex) const; // number of elements; error: siListErr signed long GetNumber() const; // error: 0 PBBaseElem GetElem(long lIndex) const; // returns the element that is at the 0-based position // that's given by parameter; always count from first Element // on; error: 0 PBBaseElem GetPos(long lPos) const; // finds out the position of the element with the specified // index; siListErr in case of errors long GetIndexPos(long lIndex) const; // sort using method "IsHigher()" // error: siListErr TBListErr Sort(ESortMode eSortMode=eAscending); // returns old state bool SetSortBeforeReading(bool bNewValue); PBBaseElem GetFirst() { return pFirst; } PBBaseElem GetLast() { return pLast; } // ******************************************* // using the following methods you get the elements in the order // in which they are in the list // if a call of SetSortBeforeReading(true) has taken place, the // list is sorted beforehands; // as long as reading sessions are open the list is locked // and no data can be changed!! this includes that you cannot // sort or change the sort-before-reading-state // initializes a new reading session // returns a handle to this reading session // list is sorted if set using method "setsortbeforereading()" // error: siListErr // maximum number of reading sessions is limited by constant // iMaxNumRS HRead BeginRead(); // obsolete; use CBListReader BeginReadEx() instead! CBListReader BeginReadEx(); // error: 0 PBBaseElem ReadElem(HRead hRead); // end reading session designated by hRead TBListErr EndRead(HRead hRead); // usually you do not need to call this method; you have the choice to // call oReader.EndReaderSession() instead or not explicitely ending the // sessiion at all; // explicitely ending the session might be useful if you know that the // parent list will be destructed before the reader; TBListErr EndRead(CBListReader &oReader); // performs calls the OnMapHandle() member exactly one time for // each of the list element in the order in which they are in // the list; if SetSortBeforeReading(true) has been done the list is // sorted; // the return value is true if each call of OnMapHandle() returned // true, false otherwise; // note that the first sentence in this comment isn't quite correct; // if OnMapHandle() returns false, the operation is not continued bool Map(long lTask, long lHint); // puts the whole list with all its data to a stream // or retreives it from there TBListErr PutToArchive(CArchive &oArchive, long lSaveParams=-1) const; TBListErr GetFromArchive(CArchive &oArchive, long lLoadParams=-1); // self explaining TBListErr SaveToFile(const char *lpszFileName, long lSaveParams=-1); TBListErr LoadFromFile(const char *lpszFileName, long lLoadParams=-1); protected: // properly inserts a new element in the list // a pointer to it is given back; // the new element has an index between (including) // 1 and iMaxNumberOfCBListItems PBBaseElem Add(); // this version tries to give the given index // to the new element, if possible; negative values and 0 // are NOT used! PBBaseElem Add(long lDesiredIndex); // this member works together with the Map() member; look there for // further information virtual bool OnMapHandle(CBBaseElem *poElem, long lTask, long lHint); // the following method must be overriden by every // subclass returning an element of the type of the particular // subclass of PBBaseElem virtual PBBaseElem CreateElem()=0; // this method is called immediately before and element is // to be deleted via delete; // it does nothing here but you may override it to free // other variables the content is referring to // !!! EXTREMELY IMPORTANT: !!! // if you override this method you MUST call // DeleteAll() in the destructor of your class virtual void OnPreDeleteItem(PBBaseElem poElem); private: // content of elements is not changed; their position in the list // is exchanged; error: siListErr TBListErr Exchange(PBBaseElem pOne, PBBaseElem pTwo); // Performs a bubble sort on the given interval // note that there is no validation checking (e.g. if // pLeft is really left of pRight) // (sorting algorithms like quicksort or heapsort are not // useful on lists. They work only good and fast on arrays, // so I decided to implement bubble sort) // pLeft and pRight refer to the pointers; a pNext-Pointer // always points right, so by only using pNext-Pointers on // pLeft you MUST reach pRight at some time; otherwise // the programm will be going to crash with an access // violation // return value siListErr: error (e.g. no element in list) TBListErr DoBubbleSort(PBBaseElem pLeft, PBBaseElem pRight, ESortMode eSortMode); // finds the lowest available index that can be given to // a new element; used by method "Add()" signed long GetSmallestIndex(); // finds an open reading position; used by method BeginRead() signed long FindOpenReadPos() const; // finds the lowest element in the list; used by "DoBubbleSort()" PBBaseElem FindLowest(PBBaseElem pBeginFrom, PBBaseElem pGoTo, ESortMode eSortMode); PBBaseElem pFirst, pLast; PBBaseElem pReadPos[256]; bool bReadEntryUsed[256]; long lNumOfOpenReadingSessions; bool SortBeforeReading; // saves the last index number that has been given // to a new element long lCurrentIndex; }; typedef CBList *PBList; #endif // #ifndef __Listobj_h__