00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
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
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
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
00704
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
00799 );
00801
00810 virtual PINDEX Append(
00811 PObject * obj
00812 );
00813
00823 virtual PINDEX Insert(
00824 const PObject & before,
00825 PObject * obj
00826 );
00827
00837 virtual PINDEX InsertAt(
00838 PINDEX index,
00839 PObject * obj
00840 );
00841
00852 virtual PBoolean Remove(
00853 const PObject * obj
00854 );
00855
00865 virtual PObject * RemoveAt(
00866 PINDEX index
00867 );
00868
00875 virtual void RemoveAll();
00876
00883 virtual PBoolean SetAt(
00884 PINDEX index,
00885 PObject * val
00886 );
00887
00894 virtual PObject * GetAt(
00895 PINDEX index
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
00931 typedef PSortedListElement Element;
00932
00933 protected:
00934
00935
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
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