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  * $Revision: 24177 $
00030  * $Author: rjongbloed $
00031  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
00032  */
00033 
00034 #ifndef PTLIB_LISTS_H
00035 #define PTLIB_LISTS_H
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 
00043 // PList container class
00044 
00045 struct PListElement
00046 {
00047     PListElement(PObject * theData);
00048     PListElement * prev;
00049     PListElement * next;
00050     PObject * data;
00051 
00052     PDECLARE_POOL_ALLOCATOR();
00053 };
00054 
00055 struct PListInfo
00056 {
00057     PListInfo() { head = tail = NULL; }
00058     PListElement * head;
00059     PListElement * tail;
00060 
00061     PDECLARE_POOL_ALLOCATOR();
00062 };
00063 
00084 class PAbstractList : public PCollection
00085 {
00086   PCONTAINERINFO(PAbstractList, PCollection);
00087 
00088   public:
00096     PINLINE PAbstractList();
00098 
00099   // Overrides from class PObject
00126     virtual Comparison Compare(
00127       const PObject & obj   
00128     ) const;
00129 
00139     virtual PBoolean SetSize(
00140       PINDEX newSize  
00141     );
00143 
00152     virtual PINDEX Append(
00153       PObject * obj   
00154     );
00155 
00168     virtual PINDEX Insert(
00169       const PObject & before,   
00170       PObject * obj             
00171     );
00172 
00180     virtual PINDEX InsertAt(
00181       PINDEX index,   
00182       PObject * obj   
00183     );
00184 
00191     virtual PBoolean Remove(
00192       const PObject * obj   
00193     );
00194 
00204     virtual PObject * RemoveAt(
00205       PINDEX index   
00206     );
00207 
00219     virtual PBoolean SetAt(
00220       PINDEX index,   
00221       PObject * val   
00222     );
00223     
00234     virtual PBoolean ReplaceAt(
00235       PINDEX index,   
00236       PObject * val   
00237     );
00238 
00249     virtual PObject * GetAt(
00250       PINDEX index  
00251     ) const;
00252 
00260     virtual PINDEX GetObjectsIndex(
00261       const PObject * obj  
00262     ) const;
00263 
00272     virtual PINDEX GetValuesIndex(
00273       const PObject & obj  
00274     ) const;
00276 
00277 
00278   protected:
00289     PINLINE PObject & GetReferenceAt(
00290       PINDEX index  
00291     ) const;
00292 
00302     PBoolean SetCurrent(
00303       PINDEX index,           
00304       PListElement * & lastElement 
00305     ) const;
00306 
00307     PObject * RemoveElement(PListElement * element);
00308 
00309     // The types below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00310     typedef PListElement Element;
00311     PListInfo * info;
00312 };
00313 
00314 
00321 template <class T> class PList : public PAbstractList
00322 {
00323   PCLASSINFO(PList, PAbstractList);
00324 
00325   public:
00333     PList()
00334       : PAbstractList() { }
00336 
00342     virtual PObject * Clone() const
00343       { return PNEW PList(0, this); }
00345 
00348     class iterator_base : public std::iterator<std::bidirectional_iterator_tag, T> {
00349     protected:
00350       iterator_base(PListElement * e) : element(e) { }
00351       PListElement * element;
00352 
00353       void Next() { element = PAssertNULL(element)->next; }
00354       void Prev() { element = PAssertNULL(element)->prev; }
00355       T * Ptr() const { return  (T *)PAssertNULL(element)->data; }
00356 
00357     public:
00358       bool operator==(const iterator_base & it) const { return element == it.element; }
00359       bool operator!=(const iterator_base & it) const { return element != it.element; }
00360     };
00361 
00362     class iterator : public iterator_base {
00363     public:
00364       iterator(PListElement * e = NULL) : iterator_base(e) { }
00365 
00366       iterator operator++()    {                      iterator_base::Next(); return *this; }
00367       iterator operator--()    {                      iterator_base::Prev(); return *this; }
00368       iterator operator++(int) { iterator it = *this; iterator_base::Next(); return it;    }
00369       iterator operator--(int) { iterator it = *this; iterator_base::Prev(); return it;    }
00370 
00371       T * operator->() const { return  iterator_base::Ptr(); }
00372       T & operator* () const { return *iterator_base::Ptr(); }
00373     };
00374 
00375     iterator begin()  { return info->head; }
00376     iterator end()    { return iterator(); }
00377     iterator rbegin() { return info->tail; }
00378     iterator rend()   { return iterator(); }
00379 
00380 
00381     class const_iterator : public iterator_base {
00382     public:
00383       const_iterator(PListElement * e = NULL) : iterator_base(e) { }
00384 
00385       const_iterator operator++()    {                            iterator_base::Next(); return *this; }
00386       const_iterator operator--()    {                            iterator_base::Prev(); return *this; }
00387       const_iterator operator++(int) { const_iterator it = *this; iterator_base::Next(); return it;    }
00388       const_iterator operator--(int) { const_iterator it = *this; iterator_base::Prev(); return it;    }
00389 
00390       const T * operator->() const { return  iterator_base::Ptr(); }
00391       const T & operator* () const { return *iterator_base::Ptr(); }
00392     };
00393 
00394     const_iterator begin()  const { return info->head; }
00395     const_iterator end()    const { return const_iterator(); }
00396     const_iterator rbegin() const { return info->tail; }
00397     const_iterator rend()   const { return iterator(); }
00398 
00399     T & front() const { return *(T *)PAssertNULL(info->head)->data; }
00400     T & back() const { return *(T *)PAssertNULL(info->tail)->data; }
00401     void erase(const iterator & it) { Remove(&*it); }
00402     void erase(const const_iterator & it) { Remove(&*it); }
00403 
00404     typedef T value_type;
00406 
00420     T & operator[](
00421       PINDEX index  
00422     ) const { return (T &)GetReferenceAt(index); }
00424 
00425   protected:
00426     PList(int dummy, const PList * c)
00427       : PAbstractList(dummy, c) { }
00428 };
00429 
00430 
00442 #define PLIST(cls, T) typedef PList<T> cls
00443 
00455 #define PDECLARE_LIST(cls, T) \
00456   PLIST(cls##_PTemplate, T); \
00457   PDECLARE_CLASS(cls, PList<T>) \
00458   protected: \
00459     cls(int dummy, const cls * c) \
00460       : PList<T>(dummy, c) { } \
00461   public: \
00462     cls() \
00463       : PList<T>() { } \
00464     virtual PObject * Clone() const \
00465       { return PNEW cls(0, this); } \
00466 
00467 
00480 template <class T> class PQueue : public PAbstractList
00481 {
00482   PCLASSINFO(PQueue, PAbstractList);
00483 
00484   public:
00493     PQueue()
00494       : PAbstractList() { DisallowDeleteObjects(); }
00496 
00502     virtual PObject * Clone() const
00503       { return PNEW PQueue(0, this); }
00505 
00511     virtual void Enqueue(
00512       T * obj   
00513     ) { PAbstractList::Append(obj); }
00519     virtual T * Dequeue()
00520       { if (GetSize() == 0) return NULL; else return (T *)PAbstractList::RemoveAt(0);}
00522 
00523   protected:
00524     PQueue(int dummy, const PQueue * c)
00525       : PAbstractList(dummy, c)
00526       { reference->deleteObjects = c->reference->deleteObjects; }
00527 };
00528 
00529 
00542 #define PQUEUE(cls, T) typedef PQueue<T> cls
00543 
00544 
00557 #define PDECLARE_QUEUE(cls, T) \
00558   PQUEUE(cls##_PTemplate, T); \
00559   PDECLARE_CLASS(cls, cls##_PTemplate) \
00560   protected: \
00561     cls(int dummy, const cls * c) \
00562       : cls##_PTemplate(dummy, c) { } \
00563   public: \
00564     cls() \
00565       : cls##_PTemplate() { } \
00566     virtual PObject * Clone() const \
00567       { return PNEW cls(0, this); } \
00568 
00569 
00582 template <class T> class PStack : public PAbstractList
00583 {
00584   PCLASSINFO(PStack, PAbstractList);
00585 
00586   public:
00595     PStack()
00596       : PAbstractList() { DisallowDeleteObjects(); }
00598 
00604     virtual PObject * Clone() const
00605       { return PNEW PStack(0, this); }
00607 
00614     virtual void Push(
00615       T * obj    
00616     ) { PAbstractList::InsertAt(0, obj); }
00617 
00623     virtual T * Pop()
00624       { return (T *)PAbstractList::RemoveAt(0); }
00625 
00632     virtual T & Top()
00633       { PAssert(GetSize() > 0, PStackEmpty); return *(T *)GetAt(0); }
00635 
00636   protected:
00637     PStack(int dummy, const PStack * c)
00638       : PAbstractList(dummy, c)
00639       { reference->deleteObjects = c->reference->deleteObjects; }
00640 };
00641 
00642 
00655 #define PSTACK(cls, T) typedef PStack<T> cls
00656 
00657 
00670 #define PDECLARE_STACK(cls, T) \
00671   PSTACK(cls##_PTemplate, T); \
00672   PDECLARE_CLASS(cls, cls##_PTemplate) \
00673   protected: \
00674     cls(int dummy, const cls * c) \
00675       : cls##_PTemplate(dummy, c) { } \
00676   public: \
00677     cls() \
00678       : cls##_PTemplate() { } \
00679     virtual PObject * Clone() const \
00680       { return PNEW cls(0, this); } \
00681 
00682 
00684 // Sorted List of PObjects
00685 
00686 struct PSortedListElement
00687 {
00688   PSortedListElement * parent;
00689   PSortedListElement * left;
00690   PSortedListElement * right;
00691   PObject            * data;
00692   PINDEX               subTreeSize;
00693   enum { Red, Black }  colour;
00694 
00695   PDECLARE_POOL_ALLOCATOR();
00696 };
00697 
00698 struct PSortedListInfo
00699 {
00700   PSortedListInfo();
00701 
00702   PSortedListElement * root;
00703   //PSortedListElement * lastElement;
00704   //PINDEX               lastIndex;
00705   PSortedListElement   nil;
00706 
00707   PSortedListElement * Successor(const PSortedListElement * node) const;
00708   PSortedListElement * Predecessor(const PSortedListElement * node) const;
00709   PSortedListElement * OrderSelect(PSortedListElement * node, PINDEX index) const;
00710 
00711   typedef PSortedListElement Element;
00712 
00713   PDECLARE_POOL_ALLOCATOR();
00714 };
00715 
00742 class PAbstractSortedList : public PCollection
00743 {
00744   PCONTAINERINFO(PAbstractSortedList, PCollection);
00745 
00746   public:
00754     PAbstractSortedList();
00756 
00785     virtual Comparison Compare(const PObject & obj) const;
00787 
00797     virtual PBoolean SetSize(
00798       PINDEX newSize  // New size for the sorted list, this is ignored.
00799     );
00801 
00810     virtual PINDEX Append(
00811       PObject * obj   // New object to place into the collection.
00812     );
00813 
00823     virtual PINDEX Insert(
00824       const PObject & before,   // Object value to insert before.
00825       PObject * obj             // New object to place into the collection.
00826     );
00827 
00837     virtual PINDEX InsertAt(
00838       PINDEX index,   // Index position in collection to place the object.
00839       PObject * obj   // New object to place into the collection.
00840     );
00841 
00852     virtual PBoolean Remove(
00853       const PObject * obj   // Existing object to remove from the collection.
00854     );
00855 
00865     virtual PObject * RemoveAt(
00866       PINDEX index   // Index position in collection to place the object.
00867     );
00868 
00875     virtual void RemoveAll();
00876 
00883     virtual PBoolean SetAt(
00884       PINDEX index,   // Index position in collection to set.
00885       PObject * val   // New value to place into the collection.
00886     );
00887 
00894     virtual PObject * GetAt(
00895       PINDEX index  // Index position in the collection of the object.
00896     ) const;
00897 
00909     virtual PINDEX GetObjectsIndex(
00910       const PObject * obj
00911     ) const;
00912     virtual PINDEX GetObjectsIndex(
00913       const PObject * obj,
00914       PSortedListElement * & lastElement
00915     ) const;
00916 
00925     virtual PINDEX GetValuesIndex(
00926       const PObject & obj
00927     ) const;
00929 
00930     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00931     typedef PSortedListElement Element;
00932 
00933   protected:
00934     
00935     // New functions for class
00936     void RemoveElement(Element * node);
00937     void LeftRotate(Element * node);
00938     void RightRotate(Element * node);
00939     void DeleteSubTrees(Element * node, PBoolean deleteObject);
00940     PINDEX ValueSelect(const Element * node, const PObject & obj, const Element ** lastElement) const;
00941 
00942     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00943     PSortedListInfo * info;
00944 };
00945 
00946 
00954 template <class T> class PSortedList : public PAbstractSortedList
00955 {
00956   PCLASSINFO(PSortedList, PAbstractSortedList);
00957 
00958   public:
00966     PSortedList()
00967       : PAbstractSortedList() { }
00969 
00975     virtual PObject * Clone() const
00976       { return PNEW PSortedList(0, this); }
00978 
00991     T & operator[](
00992       PINDEX index  
00993     ) const { return *(T *)GetAt(index); }
00995 
00996   protected:
00997     PSortedList(int dummy, const PSortedList * c)
00998       : PAbstractSortedList(dummy, c) { }
00999 };
01000 
01001 
01013 #define PSORTED_LIST(cls, T) typedef PSortedList<T> cls
01014 
01015 
01028 #define PDECLARE_SORTED_LIST(cls, T) \
01029   PSORTED_LIST(cls##_PTemplate, T); \
01030   PDECLARE_CLASS(cls, PSortedList<T>) \
01031   protected: \
01032     cls(int dummy, const cls * c) \
01033       : PSortedList<T>(dummy, c) { } \
01034   public: \
01035     cls() \
01036       : PSortedList<T>() { } \
01037     virtual PObject * Clone() const \
01038       { return PNEW cls(0, this); } \
01039 
01040 
01041 #endif // PTLIB_LISTS_H
01042 
01043 
01044 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7