PTLib  Version 2.12.9
 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 
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 
391  class const_iterator : public iterator_base {
392  public:
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 
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:
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)
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:
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)
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 
696 {
697  PSortedListElement(PSortedListElement * nil = NULL, PObject * obj = NULL);
698 
704  enum { Red, Black } m_colour;
705 
707 };
708 
710 {
712 
715 
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 
724 };
725 
753 {
754  PCONTAINERINFO(PAbstractSortedList, PCollection);
755 
756  public:
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
948 };
949 
950 
958 template <class T> class PSortedList : public PAbstractSortedList
959 {
960  PCLASSINFO(PSortedList, PAbstractSortedList);
961 
962  public:
971  : PAbstractSortedList() { }
973 
979  virtual PObject * Clone() const
980  { return PNEW PSortedList(0, this); }
982 
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 
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 ///////////////////////////////////////////////////////////////