PTLib Version 2.12.9

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lists.h
Go to the documentation of this file.
1 /*
2 * lists.h
3 *
4 * List Container Classes
5 *
6 * Portable Windows Library
7 *
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9 *
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
14 *
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * The Original Code is Portable Windows Library.
21 *
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23 *
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
26 *
27 * Contributor(s): ______________________________________.
28 *
29 * $Revision: 28339 $
30 * $Author: rjongbloed $
31 * $Date: 2012-09-11 17:43:32 +1000 (Tue, 11 Sep 2012) $
32 */
33
34 #ifndef PTLIB_LISTS_H
35 #define PTLIB_LISTS_H
36
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40
41
43 // PList container class
44
45 struct PListElement
46 {
47 PListElement(PObject * theData);
48 PListElement * prev;
49 PListElement * next;
50 PObject * data;
51
52 PDECLARE_POOL_ALLOCATOR();
53 };
54
55 struct PListInfo
56 {
57 PListInfo() { head = tail = NULL; }
58 PListElement * head;
59 PListElement * tail;
60
61 PDECLARE_POOL_ALLOCATOR();
62 };
63
84 class PAbstractList : public PCollection
85 {
86 PCONTAINERINFO(PAbstractList, PCollection);
87
88 public:
96 PINLINE PAbstractList();
98
99 // Overrides from class PObject
126 virtual Comparison Compare(
127 const PObject & obj
128 ) const;
129
139 virtual PBoolean SetSize(
140 PINDEX newSize
141 );
143
152 virtual PINDEX Append(
153 PObject * obj
154 );
155
162 virtual void Prepend(
163 PObject * obj
164 );
165
178 virtual PINDEX Insert(
179 const PObject & before,
180 PObject * obj
181 );
182
190 P_DEPRECATED virtual PINDEX InsertAt(
191 PINDEX index,
192 PObject * obj
193 );
194
201 virtual PBoolean Remove(
202 const PObject * obj
203 );
204
211 virtual PObject * RemoveHead()
212 { return RemoveElement(info->head); }
213
220 virtual PObject * RemoveTail()
221 { return RemoveElement(info->tail); }
222
223
233 P_DEPRECATED virtual PObject * RemoveAt(
234 PINDEX index
235 );
236
248 P_DEPRECATED virtual PBoolean SetAt(
249 PINDEX index,
250 PObject * val
251 );
252
263 P_DEPRECATED virtual PBoolean ReplaceAt(
264 PINDEX index,
265 PObject * val
266 );
267
278 P_DEPRECATED virtual PObject * GetAt(
279 PINDEX index
280 ) const;
281
289 virtual PINDEX GetObjectsIndex(
290 const PObject * obj
291 ) const;
292
301 virtual PINDEX GetValuesIndex(
302 const PObject & obj
303 ) const;
305
306
307 protected:
308 PINLINE PObject & GetReferenceAt(PINDEX index) const;
309 PListElement * FindElement(PINDEX index) const;
310 PListElement * FindElement(const PObject & obj, PINDEX * index) const;
311 void InsertElement(PListElement * element, PObject * obj);
312 PObject * RemoveElement(PListElement * element);
313
314 // The types below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
315 typedef PListElement Element;
316 PListInfo * info;
317 };
318
319
326 template <class T> class PList : public PAbstractList
327 {
328 PCLASSINFO(PList, PAbstractList);
329
330 public:
338 PList()
339 : PAbstractList() { }
341
347 virtual PObject * Clone() const
348 { return PNEW PList(0, this); }
350
353 typedef T value_type;
354
355 class iterator_base : public std::iterator<std::bidirectional_iterator_tag, value_type> {
356 protected:
357 iterator_base(PListElement * e) : element(e) { }
358 PListElement * element;
359
360 void Next() { this->element = PAssertNULL(this->element)->next; }
361 void Prev() { this->element = PAssertNULL(this->element)->prev; }
362 value_type * Ptr() const { return dynamic_cast<value_type *>(PAssertNULL(this->element)->data); }
363
364 public:
365 bool operator==(const iterator_base & it) const { return this->element == it.element; }
366 bool operator!=(const iterator_base & it) const { return this->element != it.element; }
367
368 friend class PList<T>;
369 };
370
371 class iterator : public iterator_base {
372 public:
373 iterator(PListElement * e = NULL) : iterator_base(e) { }
374
375 iterator operator++() { this->Next(); return *this; }
376 iterator operator--() { this->Prev(); return *this; }
377 iterator operator++(int) { iterator it = *this; this->Next(); return it; }
378 iterator operator--(int) { iterator it = *this; this->Prev(); return it; }
379
380 value_type * operator->() const { return this->Ptr(); }
381 value_type & operator* () const { return *this->Ptr(); }
382 };
383
384 iterator begin() { return this->info->head; }
385 iterator end() { return iterator(); }
386 iterator rbegin() { return this->info->tail; }
387 iterator rend() { return iterator(); }
388 iterator find(const value_type & obj) { return this->FindElement(obj, NULL); }
389 void insert(const iterator & pos, value_type * obj) { this->InsertElement(pos.element, obj); }
390
391 class const_iterator : public iterator_base {
392 public:
393 const_iterator(PListElement * e = NULL) : iterator_base(e) { }
394
395 const_iterator operator++() { this->Next(); return *this; }
396 const_iterator operator--() { this->Prev(); return *this; }
397 const_iterator operator++(int) { const_iterator it = *this; this->Next(); return it; }
398 const_iterator operator--(int) { const_iterator it = *this; this->Prev(); return it; }
399
400 const value_type * operator->() const { return this->Ptr(); }
401 const value_type & operator* () const { return *this->Ptr(); }
402 };
403
404 const_iterator begin() const { return this->info->head; }
405 const_iterator end() const { return const_iterator(); }
406 const_iterator rbegin() const { return this->info->tail; }
407 const_iterator rend() const { return iterator(); }
408 const_iterator find(const value_type & obj) const { return this->FindElement(obj, NULL); }
409
410 value_type & front() const { return dynamic_cast<value_type &>(*PAssertNULL(this->info->head)->data); }
411 value_type & back() const { return dynamic_cast<value_type &>(*PAssertNULL(this->info->tail)->data); }
412 void erase(const iterator & it) { this->RemoveElement(it.element); }
413 void erase(const const_iterator & it) { this->RemoveElement(it.element); }
415
429 T & operator[](
430 PINDEX index
431 ) const { return dynamic_cast<T &>(this->GetReferenceAt(index)); }
433
434 protected:
435 PList(int dummy, const PList * c)
436 : PAbstractList(dummy, c) { }
437 };
438
439
451 #define PLIST(cls, T) typedef PList<T> cls
452
464 #define PDECLARE_LIST(cls, T) \
465 PLIST(cls##_PTemplate, T); \
466 PDECLARE_CLASS(cls, PList<T>) \
467 protected: \
468 cls(int dummy, const cls * c) \
469 : PList<T>(dummy, c) { } \
470 public: \
471 cls() \
472 : PList<T>() { } \
473 virtual PObject * Clone() const \
474 { return PNEW cls(0, this); } \
475
476
489 template <class T> class PQueue : public PAbstractList
490 {
491 PCLASSINFO(PQueue, PAbstractList);
492
493 public:
502 PQueue()
503 : PAbstractList() { DisallowDeleteObjects(); }
505
511 virtual PObject * Clone() const
512 { return PNEW PQueue(0, this); }
514
520 virtual void Enqueue(
521 T * obj
522 ) { PAbstractList::Append(obj); }
528 virtual T * Dequeue()
529 { return dynamic_cast<T *>(PAbstractList::RemoveHead()); }
531
532 protected:
533 PQueue(int dummy, const PQueue * c)
534 : PAbstractList(dummy, c)
535 { reference->deleteObjects = c->reference->deleteObjects; }
536 };
537
538
551 #define PQUEUE(cls, T) typedef PQueue<T> cls
552
553
566 #define PDECLARE_QUEUE(cls, T) \
567 PQUEUE(cls##_PTemplate, T); \
568 PDECLARE_CLASS(cls, cls##_PTemplate) \
569 protected: \
570 cls(int dummy, const cls * c) \
571 : cls##_PTemplate(dummy, c) { } \
572 public: \
573 cls() \
574 : cls##_PTemplate() { } \
575 virtual PObject * Clone() const \
576 { return PNEW cls(0, this); } \
577
578
591 template <class T> class PStack : public PAbstractList
592 {
593 PCLASSINFO(PStack, PAbstractList);
594
595 public:
604 PStack()
605 : PAbstractList() { DisallowDeleteObjects(); }
607
613 virtual PObject * Clone() const
614 { return PNEW PStack(0, this); }
616
623 virtual void Push(
624 T * obj
625 ) { PAbstractList::Prepend(obj); }
626
632 virtual T * Pop()
633 { return dynamic_cast<T *>(PAbstractList::RemoveHead()); }
634
641 virtual T & Top()
642 { PAssert(this->GetSize() > 0, PStackEmpty); return dynamic_cast<T &>(*this->info->head->data); }
644
645 protected:
646 PStack(int dummy, const PStack * c)
647 : PAbstractList(dummy, c)
648 { this->reference->deleteObjects = c->reference->deleteObjects; }
649 };
650
651
664 #define PSTACK(cls, T) typedef PStack<T> cls
665
666
679 #define PDECLARE_STACK(cls, T) \
680 PSTACK(cls##_PTemplate, T); \
681 PDECLARE_CLASS(cls, cls##_PTemplate) \
682 protected: \
683 cls(int dummy, const cls * c) \
684 : cls##_PTemplate(dummy, c) { } \
685 public: \
686 cls() \
687 : cls##_PTemplate() { } \
688 virtual PObject * Clone() const \
689 { return PNEW cls(0, this); } \
690
691
693 // Sorted List of PObjects
694
695 struct PSortedListElement
696 {
697 PSortedListElement(PSortedListElement * nil = NULL, PObject * obj = NULL);
698
699 PSortedListElement * m_parent;
700 PSortedListElement * m_left;
701 PSortedListElement * m_right;
702 PObject * m_data;
703 PINDEX m_subTreeSize;
704 enum { Red, Black } m_colour;
705
706 PDECLARE_POOL_ALLOCATOR();
707 };
708
709 struct PSortedListInfo
710 {
711 PSortedListInfo() : m_root(&nil) { }
712
713 PSortedListElement nil;
714 PSortedListElement * m_root;
715
716 PSortedListElement * Successor(PSortedListElement * node) const;
717 PSortedListElement * Predecessor(PSortedListElement * node) const;
718 PSortedListElement * OrderSelect(PSortedListElement * node, PINDEX index) const;
719 PSortedListElement * OrderSelect(PINDEX index) const { return OrderSelect(m_root, index); }
720 PINDEX ValueSelect(PSortedListElement * node, const PObject & obj, PSortedListElement * & element) const;
721 PINDEX ValueSelect(const PObject & obj, PSortedListElement * & element) const { return ValueSelect(m_root, obj, element); }
722
723 PDECLARE_POOL_ALLOCATOR();
724 };
725
752 class PAbstractSortedList : public PCollection
753 {
754 PCONTAINERINFO(PAbstractSortedList, PCollection);
755
756 public:
764 PAbstractSortedList();
766
795 virtual Comparison Compare(const PObject & obj) const;
797
807 virtual PBoolean SetSize(
808 PINDEX newSize // New size for the sorted list, this is ignored.
809 );
811
820 virtual PINDEX Append(
821 PObject * obj // New object to place into the collection.
822 );
823
833 virtual PINDEX Insert(
834 const PObject & before, // Object value to insert before.
835 PObject * obj // New object to place into the collection.
836 );
837
847 virtual PINDEX InsertAt(
848 PINDEX index, // Index position in collection to place the object.
849 PObject * obj // New object to place into the collection.
850 );
851
862 virtual PBoolean Remove(
863 const PObject * obj // Existing object to remove from the collection.
864 );
865
875 virtual PObject * RemoveAt(
876 PINDEX index // Index position in collection to place the object.
877 );
878
885 virtual void RemoveAll();
886
893 virtual PBoolean SetAt(
894 PINDEX index, // Index position in collection to set.
895 PObject * val // New value to place into the collection.
896 );
897
904 virtual PObject * GetAt(
905 PINDEX index // Index position in the collection of the object.
906 ) const;
907
919 virtual PINDEX GetObjectsIndex(
920 const PObject * obj
921 ) const;
922
931 virtual PINDEX GetValuesIndex(
932 const PObject & obj
933 ) const;
935
936 protected:
937
938 // New functions for class
939 void RemoveElement(PSortedListElement * node);
940 void LeftRotate(PSortedListElement * node);
941 void RightRotate(PSortedListElement * node);
942 void DeleteSubTrees(PSortedListElement * node, bool deleteObject);
943 PSortedListElement * FindElement(const PObject & obj, PINDEX * index) const;
944 PSortedListElement * FindElement(const PObject * obj, PINDEX * index) const;
945
946 // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
947 PSortedListInfo * m_info;
948 };
949
950
958 template <class T> class PSortedList : public PAbstractSortedList
959 {
960 PCLASSINFO(PSortedList, PAbstractSortedList);
961
962 public:
970 PSortedList()
971 : PAbstractSortedList() { }
973
979 virtual PObject * Clone() const
980 { return PNEW PSortedList(0, this); }
982
995 T & operator[](
996 PINDEX index
997 ) const { return dynamic_cast<T &>(*this->GetAt(index)); }
999
1002 typedef T value_type;
1003 friend class iterator_base;
1004
1005 private:
1006 void NextElement(PSortedListElement * & element)
1007 {
1008 element = this->m_info->Successor(element);
1009 if (element == &this->m_info->nil)
1010 element = NULL;
1011 }
1012
1013 void PrevElement(PSortedListElement * & element)
1014 {
1015 element = this->m_info->Predecessor(element);
1016 if (element == &this->m_info->nil)
1017 element = NULL;
1018 }
1019
1020 class iterator_base : public std::iterator<std::bidirectional_iterator_tag, value_type> {
1021 protected:
1022 PSortedList<T> * m_list;
1023 PSortedListElement * m_element;
1024
1025 iterator_base(PSortedList<T> * l, PSortedListElement * e) : m_list(l), m_element(e) { }
1026
1027 bool Valid() const { return PAssert(this->m_list != NULL && this->m_element != NULL && this->m_element != &m_list->m_info->nil, PInvalidArrayIndex); }
1028 void Next() { if (Valid()) this->m_list->NextElement(this->m_element); }
1029 void Prev() { if (Valid()) this->m_list->PrevElement(this->m_element); }
1030 value_type * Ptr() const { return dynamic_cast<value_type *>(Valid() ? this->m_element->m_data : NULL); }
1031
1032 public:
1033 bool operator==(const iterator_base & it) const { return this->m_element == it.m_element; }
1034 bool operator!=(const iterator_base & it) const { return this->m_element != it.m_element; }
1035
1036 friend class PSortedList<T>;
1037 };
1038
1039 public:
1040 class iterator : public iterator_base {
1041 public:
1042 iterator() : iterator_base(NULL, NULL) { }
1043 iterator(PSortedList<T> * l, PSortedListElement * e) : iterator_base(l, e) { }
1044
1045 iterator operator++() { this->Next(); return *this; }
1046 iterator operator--() { this->Prev(); return *this; }
1047 iterator operator++(int) { iterator it = *this; this->Next(); return it; }
1048 iterator operator--(int) { iterator it = *this; this->Prev(); return it; }
1049
1050 value_type * operator->() const { return this->Ptr(); }
1051 value_type & operator* () const { return *this->Ptr(); }
1052 };
1053
1054 iterator begin() { return IsEmpty() ? iterator() : iterator(this, this->m_info->OrderSelect(1)); }
1055 iterator end() { return iterator(); }
1056 iterator rbegin() { return IsEmpty() ? iterator() : iterator(this, this->m_info->OrderSelect(this->GetSize())); }
1057 iterator rend() { return iterator(); }
1058
1059 class const_iterator : public iterator_base {
1060 public:
1061 const_iterator() : iterator_base(NULL, NULL) { }
1062 const_iterator(PSortedList<T> * l, PSortedListElement * e) : iterator_base(l, e) { }
1063
1064 const_iterator operator++() { this->Next(); return *this; }
1065 const_iterator operator--() { this->Prev(); return *this; }
1066 const_iterator operator++(int) { const_iterator it = *this; this->Next(); return it; }
1067 const_iterator operator--(int) { const_iterator it = *this; this->Prev(); return it; }
1068
1069 const value_type * operator->() const { return this->Ptr(); }
1070 const value_type & operator* () const { return *this->Ptr(); }
1071 };
1072
1073 const_iterator begin() const { return IsEmpty() ? const_iterator() : const_iterator(this, this->m_info->OrderSelect(1)); }
1074 const_iterator end() const { return const_iterator(); }
1075 const_iterator rbegin() const { return IsEmpty() ? const_iterator() : const_iterator(this, this->m_info->OrderSelect(this->GetSize())); }
1076 const_iterator rend() const { return const_iterator(); }
1077
1078 value_type & front() { return *this->begin(); }
1079 value_type & back() { return *this->rbegin(); }
1080 const value_type & front() const { return *this->begin(); }
1081 const value_type & back() const { return *this->rbegin(); }
1082
1083 iterator find(const value_type & obj) { return iterator(this, this->FindElement(obj, NULL)); }
1084 const_iterator find(const value_type & obj) const { return const_iterator(this, this->FindElement(obj, NULL)); }
1085
1086 void erase(const iterator & it) { PAssert(this == it.m_list, PLogicError); this->RemoveElement(it.m_element); }
1087 void erase(const const_iterator & it) { PAssert(this == it.m_list, PLogicError); this->RemoveElement(it.m_element); }
1089
1090 protected:
1091 PSortedList(int dummy, const PSortedList * c)
1092 : PAbstractSortedList(dummy, c) { }
1093 };
1094
1095
1107 #define PSORTED_LIST(cls, T) typedef PSortedList<T> cls
1108
1109
1122 #define PDECLARE_SORTED_LIST(cls, T) \
1123 PSORTED_LIST(cls##_PTemplate, T); \
1124 PDECLARE_CLASS(cls, PSortedList<T>) \
1125 protected: \
1126 cls(int dummy, const cls * c) \
1127 : PSortedList<T>(dummy, c) { } \
1128 public: \
1129 cls() \
1130 : PSortedList<T>() { } \
1131 virtual PObject * Clone() const \
1132 { return PNEW cls(0, this); } \
1133
1134
1135 #endif // PTLIB_LISTS_H
1136
1137
1138 // End Of File ///////////////////////////////////////////////////////////////