lists.h

Go to the documentation of this file.
00001 /*
00002  * lists.h
00003  *
00004  * List Container Classes
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
00025  * All Rights Reserved.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Log: lists.h,v $
00030  * Revision 1.33  2007/08/01 05:20:48  rjongbloed
00031  * Changes to container classes to become compatible with advanced DevStudio 2005 "Visualizers".
00032  *
00033  * Revision 1.32  2005/11/25 03:43:47  csoutheren
00034  * Fixed function argument comments to be compatible with Doxygen
00035  *
00036  * Revision 1.31  2005/01/25 06:35:27  csoutheren
00037  * Removed warnings under MSVC
00038  *
00039  * Revision 1.30  2005/01/09 06:35:03  rjongbloed
00040  * Fixed ability to make Clone() or MakeUnique() of a sorted list.
00041  *
00042  * Revision 1.29  2004/04/09 03:42:34  csoutheren
00043  * Removed all usages of "virtual inline" and "inline virtual"
00044  *
00045  * Revision 1.28  2004/04/04 07:39:57  csoutheren
00046  * Fixed cut-and-paste typo in VS.net 2003 changes that made all PLists sorted. Yikes!
00047  *
00048  * Revision 1.27  2004/04/03 23:53:09  csoutheren
00049  * Added various changes to improce compatibility with the Sun Forte compiler
00050  *   Thanks to Brian Cameron
00051  * Added detection of readdir_r version
00052  *
00053  * Revision 1.26  2004/04/03 06:54:21  rjongbloed
00054  * Many and various changes to support new Visual C++ 2003
00055  *
00056  * Revision 1.25  2004/02/15 03:04:52  rjongbloed
00057  * Fixed problem with PSortedList nil variable and assignment between instances,
00058  *   pointed out by Ben Lear.
00059  *
00060  * Revision 1.24  2004/02/09 06:23:32  csoutheren
00061  * Added fix for gcc 3.3.1 problem. Apparently, it is unable to correctly resolve
00062  * a function argument that is a reference to a const pointer. Changing the argument
00063  * to be a pointer to a pointer solves the problem. Go figure
00064  *
00065  * Revision 1.23  2004/02/08 11:13:10  rjongbloed
00066  * Fixed crash in heavily loaded multi-threaded systems using simultaneous sorted
00067  *   lists, Thanks Federico Pinna, Fabrizio Ammollo and the gang at Reitek S.p.A.
00068  *
00069  * Revision 1.22  2003/08/31 22:11:29  dereksmithies
00070  * Fix from Diego Tartara for the SetAt function. Many thanks.
00071  *
00072  * Revision 1.21  2002/11/12 08:55:53  robertj
00073  * Changed scope of PAbstraSortedList::Element class so descendant classes
00074  *   can get at it.
00075  *
00076  * Revision 1.20  2002/09/16 01:08:59  robertj
00077  * Added #define so can select if #pragma interface/implementation is used on
00078  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00079  *
00080  * Revision 1.19  2000/04/14 07:19:32  craigs
00081  * Fixed problem with assert when dequeueing from an empty queue
00082  *
00083  * Revision 1.18  1999/08/22 12:13:43  robertj
00084  * Fixed warning when using inlines on older GNU compiler
00085  *
00086  * Revision 1.17  1999/03/09 02:59:50  robertj
00087  * Changed comments to doc++ compatible documentation.
00088  *
00089  * Revision 1.16  1999/02/16 08:12:00  robertj
00090  * MSVC 6.0 compatibility changes.
00091  *
00092  * Revision 1.15  1998/09/23 06:20:49  robertj
00093  * Added open source copyright license.
00094  *
00095  * Revision 1.14  1997/06/08 04:49:12  robertj
00096  * Fixed non-template class descendent order.
00097  *
00098  * Revision 1.13  1997/04/27 05:50:10  robertj
00099  * DLL support.
00100  *
00101  * Revision 1.12  1997/02/14 13:53:59  robertj
00102  * Major rewrite of sorted list to use sentinel record instead of NULL pointers.
00103  *
00104  * Revision 1.11  1996/07/15 10:32:50  robertj
00105  * Fixed bug in sorted list (crash on remove).
00106  *
00107  * Revision 1.10  1996/05/26 03:25:13  robertj
00108  * Compatibility to GNU 2.7.x
00109  *
00110  * Revision 1.9  1996/01/23 13:13:32  robertj
00111  * Fixed bug in sorted list GetObjectsIndex not checking if is same object
00112  *
00113  * Revision 1.8  1995/08/24 12:35:00  robertj
00114  * Added assert for list index out of bounds.
00115  *
00116  * Revision 1.7  1995/06/17 11:12:43  robertj
00117  * Documentation update.
00118  *
00119  * Revision 1.6  1995/03/14 12:41:41  robertj
00120  * Updated documentation to use HTML codes.
00121  *
00122  * Revision 1.5  1995/02/22  10:50:30  robertj
00123  * Changes required for compiling release (optimised) version.
00124  *
00125  * Revision 1.4  1995/02/05  00:48:05  robertj
00126  * Fixed template version.
00127  *
00128  * Revision 1.3  1995/01/15  04:49:23  robertj
00129  * Fixed errors in template version.
00130  *
00131  * Revision 1.2  1994/12/21  11:53:12  robertj
00132  * Documentation and variable normalisation.
00133  *
00134  * Revision 1.1  1994/12/12  09:59:35  robertj
00135  * Initial revision
00136  *
00137  */
00138 
00139 #ifdef P_USE_PRAGMA
00140 #pragma interface
00141 #endif
00142 
00143 
00145 // PList container class
00146 
00147 struct PListElement
00148 {
00149     PListElement(PObject * theData);
00150     PListElement * prev;
00151     PListElement * next;
00152     PObject * data;
00153 };
00154 
00155 struct PListInfo
00156 {
00157     PListInfo() { head = tail = lastElement = NULL; }
00158     PListElement * head;
00159     PListElement * tail;
00160     PListElement * lastElement;
00161     PINDEX    lastIndex;
00162 };
00163 
00184 class PAbstractList : public PCollection
00185 {
00186   PCONTAINERINFO(PAbstractList, PCollection);
00187 
00188   public:
00196     PINLINE PAbstractList();
00198 
00199   // Overrides from class PObject
00227     virtual Comparison Compare(const PObject & obj) const;
00228 
00238     virtual BOOL SetSize(
00239       PINDEX newSize  
00240     );
00242 
00251     virtual PINDEX Append(
00252       PObject * obj   
00253     );
00254 
00267     virtual PINDEX Insert(
00268       const PObject & before,   
00269       PObject * obj             
00270     );
00271 
00279     virtual PINDEX InsertAt(
00280       PINDEX index,   
00281       PObject * obj   
00282     );
00283 
00290     virtual BOOL Remove(
00291       const PObject * obj   
00292     );
00293 
00303     virtual PObject * RemoveAt(
00304       PINDEX index   
00305     );
00306 
00318     virtual BOOL SetAt(
00319       PINDEX index,   
00320       PObject * val   
00321     );
00322     
00333     virtual BOOL ReplaceAt(
00334       PINDEX index,   
00335       PObject * val   
00336     );
00337 
00348     virtual PObject * GetAt(
00349       PINDEX index  
00350     ) const;
00351 
00359     virtual PINDEX GetObjectsIndex(
00360       const PObject * obj  
00361     ) const;
00362 
00371     virtual PINDEX GetValuesIndex(
00372       const PObject & obj  
00373     ) const;
00375 
00376 
00377   protected:
00388     PINLINE PObject & GetReferenceAt(
00389       PINDEX index  
00390     ) const;
00391 
00401     BOOL SetCurrent(
00402       PINDEX index  
00403     ) const;
00404 
00405     // The types below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00406     typedef PListElement Element;
00407     PListInfo * info;
00408 };
00409 
00410 
00411 #ifdef PHAS_TEMPLATES
00412 
00419 template <class T> class PList : public PAbstractList
00420 {
00421   PCLASSINFO(PList, PAbstractList);
00422 
00423   public:
00431     PList()
00432       : PAbstractList() { }
00434 
00440     virtual PObject * Clone() const
00441       { return PNEW PList(0, this); }
00443 
00457     T & operator[](PINDEX index) const
00458       { return (T &)GetReferenceAt(index); }
00460 
00461   protected:
00462     PList(int dummy, const PList * c)
00463       : PAbstractList(dummy, c) { }
00464 };
00465 
00466 
00478 #define PLIST(cls, T) typedef PList<T> cls
00479 
00491 #define PDECLARE_LIST(cls, T) \
00492   PLIST(cls##_PTemplate, T); \
00493   PDECLARE_CLASS(cls, PList<T>) \
00494   protected: \
00495     cls(int dummy, const cls * c) \
00496       : PList<T>(dummy, c) { } \
00497   public: \
00498     cls() \
00499       : PList<T>() { } \
00500     virtual PObject * Clone() const \
00501       { return PNEW cls(0, this); } \
00502 
00503 
00516 template <class T> class PQueue : public PAbstractList
00517 {
00518   PCLASSINFO(PQueue, PAbstractList);
00519 
00520   public:
00529     PQueue()
00530       : PAbstractList() { DisallowDeleteObjects(); }
00532 
00538     virtual PObject * Clone() const
00539       { return PNEW PQueue(0, this); }
00541 
00547     virtual void Enqueue(
00548       T * obj   
00549     ) { PAbstractList::Append(obj); }
00555     virtual T * Dequeue()
00556       { if (GetSize() == 0) return NULL; else return (T *)PAbstractList::RemoveAt(0);}
00558 
00559   protected:
00560     PQueue(int dummy, const PQueue * c)
00561       : PAbstractList(dummy, c)
00562       { reference->deleteObjects = c->reference->deleteObjects; }
00563 };
00564 
00565 
00578 #define PQUEUE(cls, T) typedef PQueue<T> cls
00579 
00580 
00593 #define PDECLARE_QUEUE(cls, T) \
00594   PQUEUE(cls##_PTemplate, T); \
00595   PDECLARE_CLASS(cls, cls##_PTemplate) \
00596   protected: \
00597     cls(int dummy, const cls * c) \
00598       : cls##_PTemplate(dummy, c) { } \
00599   public: \
00600     cls() \
00601       : cls##_PTemplate() { } \
00602     virtual PObject * Clone() const \
00603       { return PNEW cls(0, this); } \
00604 
00605 
00618 template <class T> class PStack : public PAbstractList
00619 {
00620   PCLASSINFO(PStack, PAbstractList);
00621 
00622   public:
00631     PStack()
00632       : PAbstractList() { DisallowDeleteObjects(); }
00634 
00640     virtual PObject * Clone() const
00641       { return PNEW PStack(0, this); }
00643 
00650     virtual void Push(
00651       T * obj    
00652     ) { PAbstractList::InsertAt(0, obj); }
00653 
00659     virtual T * Pop()
00660       { return (T *)PAbstractList::RemoveAt(0); }
00661 
00668     virtual T & Top()
00669       { PAssert(GetSize() > 0, PStackEmpty); return *(T *)GetAt(0); }
00671 
00672   protected:
00673     PStack(int dummy, const PStack * c)
00674       : PAbstractList(dummy, c)
00675       { reference->deleteObjects = c->reference->deleteObjects; }
00676 };
00677 
00678 
00691 #define PSTACK(cls, T) typedef PStack<T> cls
00692 
00693 
00706 #define PDECLARE_STACK(cls, T) \
00707   PSTACK(cls##_PTemplate, T); \
00708   PDECLARE_CLASS(cls, cls##_PTemplate) \
00709   protected: \
00710     cls(int dummy, const cls * c) \
00711       : cls##_PTemplate(dummy, c) { } \
00712   public: \
00713     cls() \
00714       : cls##_PTemplate() { } \
00715     virtual PObject * Clone() const \
00716       { return PNEW cls(0, this); } \
00717 
00718 
00719 #else // PHAS_TEMPLATES
00720 
00721 
00722 #define PLIST(cls, T) \
00723   class cls : public PAbstractList { \
00724   PCLASSINFO(cls, PAbstractList); \
00725   protected: \
00726     inline cls(int dummy, const cls * c) \
00727       : PAbstractList(dummy, c) { } \
00728   public: \
00729     inline cls() \
00730       : PAbstractList() { } \
00731     virtual PObject * Clone() const \
00732       { return PNEW cls(0, this); } \
00733     inline T & operator[](PINDEX index) const \
00734       { return (T &)GetReferenceAt(index); } \
00735   }
00736 
00737 #define PDECLARE_LIST(cls, T) \
00738   PLIST(cls##_PTemplate, T); \
00739   PDECLARE_CLASS(cls, cls##_PTemplate) \
00740   protected: \
00741     cls(int dummy, const cls * c) \
00742       : cls##_PTemplate(dummy, c) { } \
00743   public: \
00744     cls() \
00745       : cls##_PTemplate() { } \
00746     virtual PObject * Clone() const \
00747       { return PNEW cls(0, this); } \
00748 
00749 
00750 #define PQUEUE(cls, T) \
00751   class cls : public PAbstractList { \
00752   PCLASSINFO(cls, PAbstractList); \
00753   protected: \
00754     inline cls(int dummy, const cls * c) \
00755       : PAbstractList(dummy, c) \
00756       { reference->deleteObjects = c->reference->deleteObjects; } \
00757   public: \
00758     inline cls() \
00759       : PAbstractList() { DisallowDeleteObjects(); } \
00760     virtual PObject * Clone() const \
00761       { return PNEW cls(0, this); } \
00762     virtual void Enqueue(T * t) \
00763       { PAbstractList::Append(t); } \
00764     virtual T * Dequeue() \
00765       { if (GetSize() == 0) return NULL; else return (T *)PAbstractList::RemoveAt(0);} \
00766   }
00767 
00768 #define PDECLARE_QUEUE(cls, T) \
00769   PQUEUE(cls##_PTemplate, T); \
00770   PDECLARE_CLASS(cls, cls##_PTemplate) \
00771   protected: \
00772     cls(int dummy, const cls * c) \
00773       : cls##_PTemplate(dummy, c) { } \
00774   public: \
00775     cls() \
00776       : cls##_PTemplate() { } \
00777     virtual PObject * Clone() const \
00778       { return PNEW cls(0, this); } \
00779 
00780 #define PSTACK(cls, T) \
00781   class cls : public PAbstractList { \
00782   PCLASSINFO(cls, PAbstractList); \
00783   protected: \
00784     inline cls(int dummy, const cls * c) \
00785       : PAbstractList(dummy, c) \
00786       { reference->deleteObjects = c->reference->deleteObjects; } \
00787   public: \
00788     inline cls() \
00789       : PAbstractList() { DisallowDeleteObjects(); } \
00790     virtual PObject * Clone() const \
00791       { return PNEW cls(0, this); } \
00792     virtual void Push(T * t) \
00793       { PAbstractList::InsertAt(0, t); } \
00794     virtual T * Pop() \
00795       { PAssert(GetSize() > 0, PStackEmpty); return (T *)PAbstractList::RemoveAt(0); } \
00796     virtual T & Top() \
00797       { PAssert(GetSize() > 0, PStackEmpty); return *(T *)GetAt(0); } \
00798   }
00799 
00800 #define PDECLARE_STACK(cls, T) \
00801   PSTACK(cls##_PTemplate, T); \
00802   PDECLARE_CLASS(cls, cls##_PTemplate) \
00803   protected: \
00804     cls(int dummy, const cls * c) \
00805       : cls##_PTemplate(dummy, c) { } \
00806   public: \
00807     cls() \
00808       : cls##_PTemplate() { } \
00809     virtual PObject * Clone() const \
00810       { return PNEW cls(0, this); } \
00811 
00812 
00813 #endif // PHAS_TEMPLATES
00814 
00815 
00817 // Sorted List of PObjects
00818 
00819 struct PSortedListElement
00820 {
00821   PSortedListElement * parent;
00822   PSortedListElement * left;
00823   PSortedListElement * right;
00824   PObject            * data;
00825   PINDEX               subTreeSize;
00826   enum { Red, Black }  colour;
00827 };
00828 
00829 struct PSortedListInfo
00830 {
00831   PSortedListInfo();
00832 
00833   PSortedListElement * root;
00834   PSortedListElement * lastElement;
00835   PINDEX               lastIndex;
00836   PSortedListElement   nil;
00837 
00838   PSortedListElement * Successor(const PSortedListElement * node) const;
00839   PSortedListElement * Predecessor(const PSortedListElement * node) const;
00840   PSortedListElement * OrderSelect(PSortedListElement * node, PINDEX index) const;
00841 
00842   typedef PSortedListElement Element;
00843 };
00844 
00871 class PAbstractSortedList : public PCollection
00872 {
00873   PCONTAINERINFO(PAbstractSortedList, PCollection);
00874 
00875   public:
00883     PAbstractSortedList();
00885 
00915     virtual Comparison Compare(const PObject & obj) const;
00917 
00927     virtual BOOL SetSize(
00928       PINDEX newSize  // New size for the sorted list, this is ignored.
00929     );
00931 
00940     virtual PINDEX Append(
00941       PObject * obj   // New object to place into the collection.
00942     );
00943 
00953     virtual PINDEX Insert(
00954       const PObject & before,   // Object value to insert before.
00955       PObject * obj             // New object to place into the collection.
00956     );
00957 
00967     virtual PINDEX InsertAt(
00968       PINDEX index,   // Index position in collection to place the object.
00969       PObject * obj   // New object to place into the collection.
00970     );
00971 
00982     virtual BOOL Remove(
00983       const PObject * obj   // Existing object to remove from the collection.
00984     );
00985 
00995     virtual PObject * RemoveAt(
00996       PINDEX index   // Index position in collection to place the object.
00997     );
00998 
01005     virtual void RemoveAll();
01006 
01013     virtual BOOL SetAt(
01014       PINDEX index,   // Index position in collection to set.
01015       PObject * val   // New value to place into the collection.
01016     );
01017 
01024     virtual PObject * GetAt(
01025       PINDEX index  // Index position in the collection of the object.
01026     ) const;
01027 
01039     virtual PINDEX GetObjectsIndex(
01040       const PObject * obj
01041     ) const;
01042 
01051     virtual PINDEX GetValuesIndex(
01052       const PObject & obj
01053     ) const;
01055 
01056     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
01057     typedef PSortedListElement Element;
01058 
01059   protected:
01060     
01061     // New functions for class
01062     void RemoveElement(Element * node);
01063     void LeftRotate(Element * node);
01064     void RightRotate(Element * node);
01065     void DeleteSubTrees(Element * node, BOOL deleteObject);
01066     PINDEX ValueSelect(const Element * node, const PObject & obj, const Element ** lastElement) const;
01067 
01068     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
01069     PSortedListInfo * info;
01070 };
01071 
01072 
01073 #ifdef PHAS_TEMPLATES
01074 
01082 template <class T> class PSortedList : public PAbstractSortedList
01083 {
01084   PCLASSINFO(PSortedList, PAbstractSortedList);
01085 
01086   public:
01094     PSortedList()
01095       : PAbstractSortedList() { }
01097 
01103     virtual PObject * Clone() const
01104       { return PNEW PSortedList(0, this); }
01106 
01119     T & operator[](PINDEX index) const
01120       { return *(T *)GetAt(index); }
01122 
01123   protected:
01124     PSortedList(int dummy, const PSortedList * c)
01125       : PAbstractSortedList(dummy, c) { }
01126 };
01127 
01128 
01140 #define PSORTED_LIST(cls, T) typedef PSortedList<T> cls
01141 
01142 
01155 #define PDECLARE_SORTED_LIST(cls, T) \
01156   PSORTED_LIST(cls##_PTemplate, T); \
01157   PDECLARE_CLASS(cls, PSortedList<T>) \
01158   protected: \
01159     cls(int dummy, const cls * c) \
01160       : PSortedList<T>(dummy, c) { } \
01161   public: \
01162     cls() \
01163       : PSortedList<T>() { } \
01164     virtual PObject * Clone() const \
01165       { return PNEW cls(0, this); } \
01166 
01167 
01168 #else // PHAS_TEMPLATES
01169 
01170 
01171 #define PSORTED_LIST(cls, T) \
01172   class cls : public PAbstractSortedList { \
01173   PCLASSINFO(cls, PAbstractSortedList); \
01174   protected: \
01175     inline cls(int dummy, const cls * c) \
01176       : PAbstractSortedList(dummy, c) { } \
01177   public: \
01178     inline cls() \
01179       : PAbstractSortedList() { } \
01180     virtual PObject * Clone() const \
01181       { return PNEW cls(0, this); } \
01182     inline T & operator[](PINDEX index) const \
01183       { return *(T *)GetAt(index); } \
01184   }
01185 
01186 #define PDECLARE_SORTED_LIST(cls, T) \
01187   PSORTED_LIST(cls##_PTemplate, T); \
01188   PDECLARE_CLASS(cls, cls##_PTemplate) \
01189   protected: \
01190     cls(int dummy, const cls * c) \
01191       : cls##_PTemplate(dummy, c) { } \
01192   public: \
01193     cls() \
01194       : cls##_PTemplate() { } \
01195     virtual PObject * Clone() const \
01196       { return PNEW cls(0, this); } \
01197 
01198 
01199 #endif  // PHAS_TEMPLATES
01200 
01201 
01202 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1