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
00035 #ifndef PTLIB_DICT_H
00036 #define PTLIB_DICT_H
00037
00038 #ifdef P_USE_PRAGMA
00039 #pragma interface
00040 #endif
00041
00042 #include <ptlib/array.h>
00043
00045
00046
00050 class POrdinalKey : public PObject
00051 {
00052 PCLASSINFO(POrdinalKey, PObject);
00053
00054 public:
00059 PINLINE POrdinalKey(
00060 PINDEX newKey = 0
00061 );
00062
00065 PINLINE POrdinalKey & operator=(PINDEX);
00067
00070
00071 virtual PObject * Clone() const;
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 virtual Comparison Compare(const PObject & obj) const;
00083
00090 virtual PINDEX HashFunction() const;
00091
00098 virtual void PrintOn(ostream & strm) const;
00100
00105 PINLINE operator PINDEX() const;
00106
00109 PINLINE PINDEX operator++();
00110
00113 PINLINE PINDEX operator++(int);
00114
00117 PINLINE PINDEX operator--();
00118
00121 PINLINE PINDEX operator--(int);
00122
00125 PINLINE POrdinalKey & operator+=(PINDEX);
00126
00129 PINLINE POrdinalKey & operator-=(PINDEX );
00131
00132 private:
00133 PINDEX theKey;
00134 };
00135
00136
00138
00139
00140 struct PHashTableElement
00141 {
00142 PObject * key;
00143 PObject * data;
00144 PHashTableElement * next;
00145 PHashTableElement * prev;
00146
00147 PDECLARE_POOL_ALLOCATOR();
00148 };
00149
00150 PDECLARE_BASEARRAY(PHashTableInfo, PHashTableElement *)
00151 #ifdef DOC_PLUS_PLUS
00152 {
00153 #endif
00154 public:
00155 virtual ~PHashTableInfo() { Destruct(); }
00156 virtual void DestroyContents();
00157
00158 PINDEX AppendElement(PObject * key, PObject * data);
00159 PObject * RemoveElement(const PObject & key);
00160 PBoolean SetLastElementAt(PINDEX index, PHashTableElement * & lastElement);
00161 PHashTableElement * GetElementAt(const PObject & key);
00162 PINDEX GetElementsIndex(const PObject*obj,PBoolean byVal,PBoolean keys) const;
00163
00164 PBoolean deleteKeys;
00165
00166 typedef PHashTableElement Element;
00167 friend class PHashTable;
00168 friend class PAbstractSet;
00169 };
00170
00171
00182 class PHashTable : public PCollection
00183 {
00184 PCONTAINERINFO(PHashTable, PCollection);
00185
00186 public:
00189
00190 PHashTable();
00192
00204 virtual Comparison Compare(
00205 const PObject & obj
00206 ) const;
00208
00209
00219 virtual PBoolean SetSize(
00220 PINDEX newSize
00221 );
00223
00224
00235 PINLINE PBoolean AbstractContains(
00236 const PObject & key
00237 ) const;
00238
00253 virtual const PObject & AbstractGetKeyAt(
00254 PINDEX index
00255 ) const;
00256
00271 virtual PObject & AbstractGetDataAt(
00272 PINDEX index
00273 ) const;
00275
00276
00277 typedef PHashTableElement Element;
00278 typedef PHashTableInfo Table;
00279 PHashTableInfo * hashTable;
00280 };
00281
00282
00284
00287 class PAbstractSet : public PHashTable
00288 {
00289 PCONTAINERINFO(PAbstractSet, PHashTable);
00290 public:
00298 PINLINE PAbstractSet();
00300
00311 virtual PINDEX Append(
00312 PObject * obj
00313 );
00314
00327 virtual PINDEX Insert(
00328 const PObject & before,
00329 PObject * obj
00330 );
00331
00344 virtual PINDEX InsertAt(
00345 PINDEX index,
00346 PObject * obj
00347 );
00348
00359 virtual PBoolean Remove(
00360 const PObject * obj
00361 );
00362
00369 virtual PObject * RemoveAt(
00370 PINDEX index
00371 );
00372
00378 virtual PObject * GetAt(
00379 PINDEX index
00380 ) const;
00381
00394 virtual PBoolean SetAt(
00395 PINDEX index,
00396 PObject * val
00397 );
00398
00410 virtual PINDEX GetObjectsIndex(
00411 const PObject * obj
00412 ) const;
00413
00422 virtual PINDEX GetValuesIndex(
00423 const PObject & obj
00424 ) const;
00425
00429 bool Union(
00430 const PAbstractSet & set
00431 );
00432
00436 static bool Intersection(
00437 const PAbstractSet & set1,
00438 const PAbstractSet & set2,
00439 PAbstractSet * intersection = NULL
00440 );
00442 };
00443
00444
00455 template <class T> class PSet : public PAbstractSet
00456 {
00457 PCLASSINFO(PSet, PAbstractSet);
00458
00459 public:
00469 inline PSet(PBoolean initialDeleteObjects = false)
00470 : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
00472
00478 virtual PObject * Clone() const
00479 { return PNEW PSet(0, this); }
00481
00493 void Include(
00494 const T * obj
00495 ) { Append((PObject *)obj); }
00496
00504 PSet & operator+=(
00505 const T & obj
00506 ) { Append(obj.Clone()); return *this; }
00507
00515 void Exclude(
00516 const T * obj
00517 ) { Remove(obj); }
00518
00526 PSet & operator-=(
00527 const T & obj
00528 ) { RemoveAt(GetValuesIndex(obj)); return *this; }
00529
00538 PBoolean Contains(
00539 const T & key
00540 ) const { return AbstractContains(key); }
00541
00550 PBoolean operator[](
00551 const T & key
00552 ) const { return AbstractContains(key); }
00553
00565 virtual const T & GetKeyAt(
00566 PINDEX index
00567 ) const
00568 { return (const T &)AbstractGetKeyAt(index); }
00570
00571
00572 protected:
00573 PSet(int dummy, const PSet * c)
00574 : PAbstractSet(dummy, c)
00575 { reference->deleteObjects = c->reference->deleteObjects; }
00576 };
00577
00578
00590 #define PSET(cls, T) typedef PSet<T> cls
00591
00592
00604 #define PDECLARE_SET(cls, T, initDelObj) \
00605 class cls : public PSet<T> { \
00606 typedef PSet<T> BaseClass; PCLASSINFO(cls, BaseClass) \
00607 protected: \
00608 cls(int dummy, const cls * c) \
00609 : BaseClass(dummy, c) { } \
00610 public: \
00611 cls(PBoolean initialDeleteObjects = initDelObj) \
00612 : BaseClass(initialDeleteObjects) { } \
00613 virtual PObject * Clone() const \
00614 { return PNEW cls(0, this); } \
00615
00616
00617
00618 PDECLARE_SET(POrdinalSet, POrdinalKey, true)
00619 };
00620
00621
00623
00626 class PAbstractDictionary : public PHashTable
00627 {
00628 PCLASSINFO(PAbstractDictionary, PHashTable);
00629 public:
00637 PINLINE PAbstractDictionary();
00639
00648 virtual void PrintOn(
00649 ostream &strm
00650 ) const;
00652
00663 virtual PINDEX Insert(
00664 const PObject & key,
00665 PObject * obj
00666 );
00667
00674 virtual PINDEX InsertAt(
00675 PINDEX index,
00676 PObject * obj
00677 );
00678
00688 virtual PObject * RemoveAt(
00689 PINDEX index
00690 );
00691
00700 virtual PBoolean SetAt(
00701 PINDEX index,
00702 PObject * val
00703 );
00704
00711 virtual PObject * GetAt(
00712 PINDEX index
00713 ) const;
00714
00726 virtual PINDEX GetObjectsIndex(
00727 const PObject * obj
00728 ) const;
00729
00738 virtual PINDEX GetValuesIndex(
00739 const PObject & obj
00740 ) const;
00742
00743
00754 virtual PBoolean SetDataAt(
00755 PINDEX index,
00756 PObject * obj
00757 );
00758
00770 virtual PBoolean AbstractSetAt(
00771 const PObject & key,
00772 PObject * obj
00773 );
00774
00784 virtual PObject & GetRefAt(
00785 const PObject & key
00786 ) const;
00787
00794 virtual PObject * AbstractGetAt(
00795 const PObject & key
00796 ) const;
00797
00800 virtual void AbstractGetKeys(
00801 PArrayObjects & keys
00802 ) const;
00804
00805 protected:
00806 PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
00807
00808 private:
00814 virtual PINDEX Append(
00815 PObject * obj
00816 );
00817
00828 virtual PBoolean Remove(
00829 const PObject * obj
00830 );
00831
00832 };
00833
00834
00842 template <class K, class D> class PDictionary : public PAbstractDictionary
00843 {
00844 PCLASSINFO(PDictionary, PAbstractDictionary);
00845
00846 public:
00855 PDictionary()
00856 : PAbstractDictionary() { }
00858
00865 virtual PObject * Clone() const
00866 { return PNEW PDictionary(0, this); }
00868
00881 D & operator[](
00882 const K & key
00883 ) const
00884 { return (D &)GetRefAt(key); }
00885
00894 PBoolean Contains(
00895 const K & key
00896 ) const { return AbstractContains(key); }
00897
00909 virtual D * RemoveAt(
00910 const K & key
00911 ) {
00912 D * obj = GetAt(key); AbstractSetAt(key, NULL);
00913 return reference->deleteObjects ? (obj ? (D *)-1 : NULL) : obj;
00914 }
00915
00927 virtual PBoolean SetAt(
00928 const K & key,
00929 D * obj
00930 ) { return AbstractSetAt(key, obj); }
00931
00938 virtual D * GetAt(
00939 const K & key
00940 ) const { return (D *)AbstractGetAt(key); }
00941
00953 const K & GetKeyAt(
00954 PINDEX index
00955 ) const
00956 { return (const K &)AbstractGetKeyAt(index); }
00957
00969 D & GetDataAt(
00970 PINDEX index
00971 ) const
00972 { return (D &)AbstractGetDataAt(index); }
00973
00976 PArray<K> GetKeys() const
00977 {
00978 PArray<K> keys;
00979 AbstractGetKeys(keys);
00980 return keys;
00981 }
00983
00984 typedef std::pair<K, D *> value_type;
00985
00986 protected:
00987 PDictionary(int dummy, const PDictionary * c)
00988 : PAbstractDictionary(dummy, c) { }
00989 };
00990
00991
01004 #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
01005
01006
01019 #define PDECLARE_DICTIONARY(cls, K, D) \
01020 PDICTIONARY(cls##_PTemplate, K, D); \
01021 PDECLARE_CLASS(cls, cls##_PTemplate) \
01022 protected: \
01023 cls(int dummy, const cls * c) \
01024 : cls##_PTemplate(dummy, c) { } \
01025 public: \
01026 cls() \
01027 : cls##_PTemplate() { } \
01028 virtual PObject * Clone() const \
01029 { return PNEW cls(0, this); } \
01030
01031
01039 template <class K> class POrdinalDictionary : public PAbstractDictionary
01040 {
01041 PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
01042
01043 public:
01052 POrdinalDictionary()
01053 : PAbstractDictionary() { }
01055
01062 virtual PObject * Clone() const
01063 { return PNEW POrdinalDictionary(0, this); }
01065
01078 PINDEX operator[](
01079 const K & key
01080 ) const
01081 { return (POrdinalKey &)GetRefAt(key); }
01082
01091 PBoolean Contains(
01092 const K & key
01093 ) const { return AbstractContains(key); }
01094
01095 virtual POrdinalKey * GetAt(
01096 const K & key
01097 ) const { return (POrdinalKey *)AbstractGetAt(key); }
01098
01099
01100
01101
01102
01103
01104
01113 virtual PBoolean SetDataAt(
01114 PINDEX index,
01115 PINDEX ordinal
01116 ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
01117
01129 virtual PBoolean SetAt(
01130 const K & key,
01131 PINDEX ordinal
01132 ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
01133
01142 virtual PINDEX RemoveAt(
01143 const K & key
01144 ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
01145
01157 const K & GetKeyAt(
01158 PINDEX index
01159 ) const
01160 { return (const K &)AbstractGetKeyAt(index); }
01161
01173 PINDEX GetDataAt(
01174 PINDEX index
01175 ) const
01176 { return (POrdinalKey &)AbstractGetDataAt(index); }
01178
01179 protected:
01180 POrdinalDictionary(int dummy, const POrdinalDictionary * c)
01181 : PAbstractDictionary(dummy, c) { }
01182 };
01183
01184
01197 #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
01198
01199
01214 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01215 PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01216 PDECLARE_CLASS(cls, POrdinalDictionary<K>) \
01217 protected: \
01218 cls(int dummy, const cls * c) \
01219 : cls##_PTemplate(dummy, c) { } \
01220 public: \
01221 cls() \
01222 : cls##_PTemplate() { } \
01223 virtual PObject * Clone() const \
01224 { return PNEW cls(0, this); } \
01225
01226
01227 #endif // PTLIB_DICT_H
01228
01229