PTLib  Version 2.14.3
 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: 32262 $
30  * $Author: rjongbloed $
31  * $Date: 2014-06-30 18:11:12 +1000 (Mon, 30 Jun 2014) $
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 
46 {
47  PListElement(PObject * theData);
51 
53 };
54 
55 struct PListInfo
56 {
57  PListInfo() { head = tail = NULL; }
60 
62 };
63 
84 class PAbstractList : public PCollection
85 {
86  PCONTAINERINFO(PAbstractList, PCollection);
87 
88  public:
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 
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
317 };
318 
319 
326 template <class T> class PList : public PAbstractList
327 {
328  PCLASSINFO(PList, PAbstractList);
329 
330  public:
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:
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  void insert(const iterator & pos, const value_type & obj) { this->InsertElement(pos.element, obj.Clone()); }
391 
392  class const_iterator : public iterator_base {
393  public:
395 
396  const_iterator operator++() { this->Next(); return *this; }
397  const_iterator operator--() { this->Prev(); return *this; }
398  const_iterator operator++(int) { const_iterator it = *this; this->Next(); return it; }
399  const_iterator operator--(int) { const_iterator it = *this; this->Prev(); return it; }
400 
401  const value_type * operator->() const { return this->Ptr(); }
402  const value_type & operator* () const { return *this->Ptr(); }
403  };
404 
405  const_iterator begin() const { return this->info->head; }
406  const_iterator end() const { return const_iterator(); }
407  const_iterator rbegin() const { return this->info->tail; }
408  const_iterator rend() const { return const_iterator(); }
409  const_iterator find(const value_type & obj) const { return this->FindElement(obj, NULL); }
410 
411  value_type & front() const { return dynamic_cast<value_type &>(*PAssertNULL(this->info->head)->data); }
412  value_type & back() const { return dynamic_cast<value_type &>(*PAssertNULL(this->info->tail)->data); }
413  void erase(const iterator & it) { this->RemoveElement(it.element); }
414  void erase(const const_iterator & it) { this->RemoveElement(it.element); }
415  __inline void pop_front() { this->RemoveHead(); }
416  __inline void pop_back() { this->RemoveTail(); }
418 
433  PINDEX index
434  ) const { return dynamic_cast<T &>(this->GetReferenceAt(index)); }
436 
437  protected:
438  PList(int dummy, const PList * c)
439  : PAbstractList(dummy, c) { }
440 };
441 
442 
454 #define PLIST(cls, T) typedef PList<T> cls
455 
467 #define PDECLARE_LIST(cls, T) \
468  PLIST(cls##_PTemplate, T); \
469  PDECLARE_CLASS(cls, PList<T>) \
470  protected: \
471  cls(int dummy, const cls * c) \
472  : PList<T>(dummy, c) { } \
473  public: \
474  cls() \
475  : PList<T>() { } \
476  virtual PObject * Clone() const \
477  { return PNEW cls(0, this); } \
478 
479 
492 template <class T> class PQueue : public PAbstractList
493 {
494  PCLASSINFO(PQueue, PAbstractList);
495 
496  public:
508 
514  virtual PObject * Clone() const
515  { return PNEW PQueue(0, this); }
517 
523  virtual void Enqueue(
524  T * obj
525  ) { PAbstractList::Append(obj); }
531  virtual T * Dequeue()
532  { return dynamic_cast<T *>(PAbstractList::RemoveHead()); }
534 
535  protected:
536  PQueue(int dummy, const PQueue * c)
537  : PAbstractList(dummy, c)
539 };
540 
541 
554 #define PQUEUE(cls, T) typedef PQueue<T> cls
555 
556 
569 #define PDECLARE_QUEUE(cls, T) \
570  PQUEUE(cls##_PTemplate, T); \
571  PDECLARE_CLASS(cls, cls##_PTemplate) \
572  protected: \
573  cls(int dummy, const cls * c) \
574  : cls##_PTemplate(dummy, c) { } \
575  public: \
576  cls() \
577  : cls##_PTemplate() { } \
578  virtual PObject * Clone() const \
579  { return PNEW cls(0, this); } \
580 
581 
594 template <class T> class PStack : public PAbstractList
595 {
596  PCLASSINFO(PStack, PAbstractList);
597 
598  public:
610 
616  virtual PObject * Clone() const
617  { return PNEW PStack(0, this); }
619 
626  virtual void Push(
627  T * obj
628  ) { PAbstractList::Prepend(obj); }
629  __inline void push(T * obj) { Push(obj); }
630 
636  virtual T * Pop()
637  { return dynamic_cast<T *>(PAbstractList::RemoveHead()); }
638  __inline void pop() { Pop(); }
639 
646  virtual T & Top()
647  { PAssert(this->GetSize() > 0, PStackEmpty); return dynamic_cast<T &>(*this->info->head->data); }
648  __inline T & front() { Top(); }
650 
651  protected:
652  PStack(int dummy, const PStack * c)
653  : PAbstractList(dummy, c)
655 };
656 
657 
670 #define PSTACK(cls, T) typedef PStack<T> cls
671 
672 
685 #define PDECLARE_STACK(cls, T) \
686  PSTACK(cls##_PTemplate, T); \
687  PDECLARE_CLASS(cls, cls##_PTemplate) \
688  protected: \
689  cls(int dummy, const cls * c) \
690  : cls##_PTemplate(dummy, c) { } \
691  public: \
692  cls() \
693  : cls##_PTemplate() { } \
694  virtual PObject * Clone() const \
695  { return PNEW cls(0, this); } \
696 
697 
699 // Sorted List of PObjects
700 
702 {
703  PSortedListElement(PSortedListElement * nil = NULL, PObject * obj = NULL);
704 
710  enum { Red, Black } m_colour;
711 
713 };
714 
716 {
718 
721 
724  PSortedListElement * OrderSelect(PSortedListElement * node, PINDEX index) const;
725  PSortedListElement * OrderSelect(PINDEX index) const { return OrderSelect(m_root, index); }
726  PINDEX ValueSelect(PSortedListElement * node, const PObject & obj, PSortedListElement * & element) const;
727  PINDEX ValueSelect(const PObject & obj, PSortedListElement * & element) const { return ValueSelect(m_root, obj, element); }
728 
730 };
731 
759 {
760  PCONTAINERINFO(PAbstractSortedList, PCollection);
761 
762  public:
772 
801  virtual Comparison Compare(const PObject & obj) const;
803 
813  virtual PBoolean SetSize(
814  PINDEX newSize // New size for the sorted list, this is ignored.
815  );
817 
826  virtual PINDEX Append(
827  PObject * obj // New object to place into the collection.
828  );
829 
839  virtual PINDEX Insert(
840  const PObject & before, // Object value to insert before.
841  PObject * obj // New object to place into the collection.
842  );
843 
853  virtual PINDEX InsertAt(
854  PINDEX index, // Index position in collection to place the object.
855  PObject * obj // New object to place into the collection.
856  );
857 
868  virtual PBoolean Remove(
869  const PObject * obj // Existing object to remove from the collection.
870  );
871 
881  virtual PObject * RemoveAt(
882  PINDEX index // Index position in collection to place the object.
883  );
884 
891  virtual void RemoveAll();
892 
899  virtual PBoolean SetAt(
900  PINDEX index, // Index position in collection to set.
901  PObject * val // New value to place into the collection.
902  );
903 
910  virtual PObject * GetAt(
911  PINDEX index // Index position in the collection of the object.
912  ) const;
913 
925  virtual PINDEX GetObjectsIndex(
926  const PObject * obj
927  ) const;
928 
937  virtual PINDEX GetValuesIndex(
938  const PObject & obj
939  ) const;
941 
942  protected:
943 
944  // New functions for class
945  void RemoveElement(PSortedListElement * node);
946  void LeftRotate(PSortedListElement * node);
947  void RightRotate(PSortedListElement * node);
948  void DeleteSubTrees(PSortedListElement * node, bool deleteObject);
949  PSortedListElement * FindElement(const PObject & obj, PINDEX * index) const;
950  PSortedListElement * FindElement(const PObject * obj, PINDEX * index) const;
951 
952  // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
954 };
955 
956 
964 template <class T> class PSortedList : public PAbstractSortedList
965 {
966  PCLASSINFO(PSortedList, PAbstractSortedList);
967 
968  public:
977  : PAbstractSortedList() { }
979 
985  virtual PObject * Clone() const
986  { return PNEW PSortedList(0, this); }
988 
1002  PINDEX index
1003  ) const { return dynamic_cast<T &>(*this->GetAt(index)); }
1005 
1008  typedef T value_type;
1009  friend class iterator_base;
1010 
1011  private:
1012  void NextElement(PSortedListElement * & element) const
1013  {
1014  element = this->m_info->Successor(element);
1015  if (element == &this->m_info->nil)
1016  element = NULL;
1017  }
1018 
1019  void PrevElement(PSortedListElement * & element) const
1020  {
1021  element = this->m_info->Predecessor(element);
1022  if (element == &this->m_info->nil)
1023  element = NULL;
1024  }
1025 
1026  class iterator_base : public std::iterator<std::bidirectional_iterator_tag, value_type> {
1027  protected:
1028  const PSortedList<T> * m_list;
1029  PSortedListElement * m_element;
1030 
1031  iterator_base(const PSortedList<T> * l, PSortedListElement * e) : m_list(l), m_element(e) { }
1032 
1033  bool Valid() const { return PAssert(this->m_list != NULL && this->m_element != NULL && this->m_element != &m_list->m_info->nil, PInvalidArrayIndex); }
1034  void Next() { if (Valid()) this->m_list->NextElement(this->m_element); }
1035  void Prev() { if (Valid()) this->m_list->PrevElement(this->m_element); }
1036  value_type * Ptr() const { return dynamic_cast<value_type *>(Valid() ? this->m_element->m_data : NULL); }
1037 
1038  public:
1039  bool operator==(const iterator_base & it) const { return this->m_element == it.m_element; }
1040  bool operator!=(const iterator_base & it) const { return this->m_element != it.m_element; }
1041 
1042  friend class PSortedList<T>;
1043  };
1044 
1045  public:
1046  class iterator : public iterator_base {
1047  public:
1048  iterator() : iterator_base(NULL, NULL) { }
1049  iterator(PSortedList<T> * l, PSortedListElement * e) : iterator_base(l, e) { }
1050 
1051  iterator operator++() { this->Next(); return *this; }
1052  iterator operator--() { this->Prev(); return *this; }
1053  iterator operator++(int) { iterator it = *this; this->Next(); return it; }
1054  iterator operator--(int) { iterator it = *this; this->Prev(); return it; }
1055 
1056  value_type * operator->() const { return this->Ptr(); }
1057  value_type & operator* () const { return *this->Ptr(); }
1058  };
1059 
1060  iterator begin() { return IsEmpty() ? iterator() : iterator(this, this->m_info->OrderSelect(1)); }
1061  iterator end() { return iterator(); }
1062  iterator rbegin() { return IsEmpty() ? iterator() : iterator(this, this->m_info->OrderSelect(this->GetSize())); }
1063  iterator rend() { return iterator(); }
1064 
1066  public:
1067  const_iterator() : iterator_base(NULL, NULL) { }
1068  const_iterator(const PSortedList<T> * l, PSortedListElement * e) : iterator_base(l, e) { }
1069 
1070  const_iterator operator++() { this->Next(); return *this; }
1071  const_iterator operator--() { this->Prev(); return *this; }
1072  const_iterator operator++(int) { const_iterator it = *this; this->Next(); return it; }
1073  const_iterator operator--(int) { const_iterator it = *this; this->Prev(); return it; }
1074 
1075  const value_type * operator->() const { return this->Ptr(); }
1076  const value_type & operator* () const { return *this->Ptr(); }
1077  };
1078 
1079  const_iterator begin() const { return IsEmpty() ? const_iterator() : const_iterator(this, this->m_info->OrderSelect(1)); }
1080  const_iterator end() const { return const_iterator(); }
1081  const_iterator rbegin() const { return IsEmpty() ? const_iterator() : const_iterator(this, this->m_info->OrderSelect(this->GetSize())); }
1082  const_iterator rend() const { return const_iterator(); }
1083 
1084  value_type & front() { return *this->begin(); }
1085  value_type & back() { return *this->rbegin(); }
1086  const value_type & front() const { return *this->begin(); }
1087  const value_type & back() const { return *this->rbegin(); }
1088 
1089  iterator find(const value_type & obj) { return iterator(this, this->FindElement(obj, NULL)); }
1090  const_iterator find(const value_type & obj) const { return const_iterator(this, this->FindElement(obj, NULL)); }
1091 
1092  void erase(const iterator & it) { PAssert(this == it.m_list, PLogicError); this->RemoveElement(it.m_element); }
1093  void erase(const const_iterator & it) { PAssert(this == it.m_list, PLogicError); this->RemoveElement(it.m_element); }
1094  void pop_front() { erase(begin()); }
1095  void pop_back() { erase(rbegin()); }
1097 
1098  protected:
1099  PSortedList(int dummy, const PSortedList * c)
1100  : PAbstractSortedList(dummy, c) { }
1101 };
1102 
1103 
1115 #define PSORTED_LIST(cls, T) typedef PSortedList<T> cls
1116 
1117 
1130 #define PDECLARE_SORTED_LIST(cls, T) \
1131  PSORTED_LIST(cls##_PTemplate, T); \
1132  PDECLARE_CLASS(cls, PSortedList<T>) \
1133  protected: \
1134  cls(int dummy, const cls * c) \
1135  : PSortedList<T>(dummy, c) { } \
1136  public: \
1137  cls() \
1138  : PSortedList<T>() { } \
1139  virtual PObject * Clone() const \
1140  { return PNEW cls(0, this); } \
1141 
1142 
1143 #endif // PTLIB_LISTS_H
1144 
1145 
1146 // End Of File ///////////////////////////////////////////////////////////////