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 __DICT_H__
00036 #define __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
00148 PDECLARE_BASEARRAY(PHashTableInfo, PHashTableElement *)
00149 #ifdef DOC_PLUS_PLUS
00150 {
00151 #endif
00152 public:
00153 virtual ~PHashTableInfo() { Destruct(); }
00154 virtual void DestroyContents();
00155
00156 PINDEX AppendElement(PObject * key, PObject * data);
00157 PObject * RemoveElement(const PObject & key);
00158 PBoolean SetLastElementAt(PINDEX index);
00159 PHashTableElement * GetElementAt(const PObject & key);
00160 PINDEX GetElementsIndex(const PObject*obj,PBoolean byVal,PBoolean keys) const;
00161
00162 PINDEX lastIndex;
00163 PINDEX lastBucket;
00164 PHashTableElement * lastElement;
00165
00166 PBoolean deleteKeys;
00167
00168 typedef PHashTableElement Element;
00169 friend class PHashTable;
00170 friend class PAbstractSet;
00171 };
00172
00173
00184 class PHashTable : public PCollection
00185 {
00186 PCONTAINERINFO(PHashTable, PCollection);
00187
00188 public:
00191
00192 PHashTable();
00194
00206 virtual Comparison Compare(
00207 const PObject & obj
00208 ) const;
00210
00211
00212 protected:
00222 virtual PBoolean SetSize(
00223 PINDEX newSize
00224 );
00226
00227
00238 PINLINE PBoolean AbstractContains(
00239 const PObject & key
00240 ) const;
00241
00256 virtual const PObject & AbstractGetKeyAt(
00257 PINDEX index
00258 ) const;
00259
00274 virtual PObject & AbstractGetDataAt(
00275 PINDEX index
00276 ) const;
00278
00279
00280 typedef PHashTableElement Element;
00281 typedef PHashTableInfo Table;
00282 PHashTableInfo * hashTable;
00283 };
00284
00285
00287
00290 class PAbstractSet : public PHashTable
00291 {
00292 PCONTAINERINFO(PAbstractSet, PHashTable);
00293 public:
00301 PINLINE PAbstractSet();
00303
00314 virtual PINDEX Append(
00315 PObject * obj
00316 );
00317
00330 virtual PINDEX Insert(
00331 const PObject & before,
00332 PObject * obj
00333 );
00334
00347 virtual PINDEX InsertAt(
00348 PINDEX index,
00349 PObject * obj
00350 );
00351
00362 virtual PBoolean Remove(
00363 const PObject * obj
00364 );
00365
00372 virtual PObject * RemoveAt(
00373 PINDEX index
00374 );
00375
00381 virtual PObject * GetAt(
00382 PINDEX index
00383 ) const;
00384
00397 virtual PBoolean SetAt(
00398 PINDEX index,
00399 PObject * val
00400 );
00401
00413 virtual PINDEX GetObjectsIndex(
00414 const PObject * obj
00415 ) const;
00416
00425 virtual PINDEX GetValuesIndex(
00426 const PObject & obj
00427 ) const;
00429 };
00430
00431
00432 #ifdef PHAS_TEMPLATES
00433
00444 template <class T> class PSet : public PAbstractSet
00445 {
00446 PCLASSINFO(PSet, PAbstractSet);
00447
00448 public:
00458 inline PSet(PBoolean initialDeleteObjects = PFalse)
00459 : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
00461
00467 virtual PObject * Clone() const
00468 { return PNEW PSet(0, this); }
00470
00482 void Include(
00483 const T * obj
00484 ) { Append((PObject *)obj); }
00485
00493 PSet & operator+=(
00494 const T & obj
00495 ) { Append(obj.Clone()); return *this; }
00496
00504 void Exclude(
00505 const T * obj
00506 ) { Remove(obj); }
00507
00515 PSet & operator-=(
00516 const T & obj
00517 ) { RemoveAt(GetValuesIndex(obj)); return *this; }
00518
00527 PBoolean Contains(
00528 const T & key
00529 ) const { return AbstractContains(key); }
00530
00539 PBoolean operator[](
00540 const T & key
00541 ) const { return AbstractContains(key); }
00542
00554 virtual const T & GetKeyAt(
00555 PINDEX index
00556 ) const
00557 { return (const T &)AbstractGetKeyAt(index); }
00559
00560
00561 protected:
00562 PSet(int dummy, const PSet * c)
00563 : PAbstractSet(dummy, c)
00564 { reference->deleteObjects = c->reference->deleteObjects; }
00565 };
00566
00567
00579 #define PSET(cls, T) typedef PSet<T> cls
00580
00581
00593 #define PDECLARE_SET(cls, T, initDelObj) \
00594 PSET(cls##_PTemplate, T); \
00595 PDECLARE_CLASS(cls, cls##_PTemplate) \
00596 protected: \
00597 cls(int dummy, const cls * c) \
00598 : cls##_PTemplate(dummy, c) { } \
00599 public: \
00600 cls(PBoolean initialDeleteObjects = initDelObj) \
00601 : cls##_PTemplate(initialDeleteObjects) { } \
00602 virtual PObject * Clone() const \
00603 { return PNEW cls(0, this); } \
00604
00605
00606 #else // PHAS_TEMPLATES
00607
00608
00609 #define PSET(cls, K) \
00610 class cls : public PAbstractSet { \
00611 PCLASSINFO(cls, PAbstractSet); \
00612 protected: \
00613 inline cls(int dummy, const cls * c) \
00614 : PAbstractSet(dummy, c) \
00615 { reference->deleteObjects = c->reference->deleteObjects; } \
00616 public: \
00617 inline cls(PBoolean initialDeleteObjects = PFalse) \
00618 : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); } \
00619 virtual PObject * Clone() const \
00620 { return PNEW cls(0, this); } \
00621 inline void Include(const PObject * key) \
00622 { Append((PObject *)key); } \
00623 inline void Exclude(const PObject * key) \
00624 { Remove(key); } \
00625 inline PBoolean operator[](const K & key) const \
00626 { return AbstractContains(key); } \
00627 inline PBoolean Contains(const K & key) const \
00628 { return AbstractContains(key); } \
00629 virtual const K & GetKeyAt(PINDEX index) const \
00630 { return (const K &)AbstractGetKeyAt(index); } \
00631 }
00632
00633 #define PDECLARE_SET(cls, K, initDelObj) \
00634 PSET(cls##_PTemplate, K); \
00635 PDECLARE_CLASS(cls, cls##_PTemplate) \
00636 protected: \
00637 inline cls(int dummy, const cls * c) \
00638 : cls##_PTemplate(dummy, c) { } \
00639 public: \
00640 inline cls(PBoolean initialDeleteObjects = initDelObj) \
00641 : cls##_PTemplate() { AllowDeleteObjects(initialDeleteObjects); } \
00642 virtual PObject * Clone() const \
00643 { return PNEW cls(0, this); } \
00644
00645
00646 #endif // PHAS_TEMPLATES
00647
00648
00649 PSET(POrdinalSet, POrdinalKey);
00650
00651
00653
00656 class PAbstractDictionary : public PHashTable
00657 {
00658 PCLASSINFO(PAbstractDictionary, PHashTable);
00659 public:
00667 PINLINE PAbstractDictionary();
00669
00678 virtual void PrintOn(
00679 ostream &strm
00680 ) const;
00682
00693 virtual PINDEX Insert(
00694 const PObject & key,
00695 PObject * obj
00696 );
00697
00704 virtual PINDEX InsertAt(
00705 PINDEX index,
00706 PObject * obj
00707 );
00708
00718 virtual PObject * RemoveAt(
00719 PINDEX index
00720 );
00721
00730 virtual PBoolean SetAt(
00731 PINDEX index,
00732 PObject * val
00733 );
00734
00742 virtual PObject * GetAt(
00743 PINDEX index
00744 ) const;
00745
00757 virtual PINDEX GetObjectsIndex(
00758 const PObject * obj
00759 ) const;
00760
00769 virtual PINDEX GetValuesIndex(
00770 const PObject & obj
00771 ) const;
00773
00774
00785 virtual PBoolean SetDataAt(
00786 PINDEX index,
00787 PObject * obj
00788 );
00789
00801 virtual PBoolean AbstractSetAt(
00802 const PObject & key,
00803 PObject * obj
00804 );
00805
00815 virtual PObject & GetRefAt(
00816 const PObject & key
00817 ) const;
00818
00825 virtual PObject * AbstractGetAt(
00826 const PObject & key
00827 ) const;
00829
00830 protected:
00831 PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
00832
00833 private:
00834 virtual PINDEX Append(
00835 PObject * obj
00836 );
00837
00838
00839
00840
00841
00842
00843 virtual PBoolean Remove(
00844 const PObject * obj
00845 );
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 };
00858
00859
00860 #ifdef PHAS_TEMPLATES
00861
00869 template <class K, class D> class PDictionary : public PAbstractDictionary
00870 {
00871 PCLASSINFO(PDictionary, PAbstractDictionary);
00872
00873 public:
00882 PDictionary()
00883 : PAbstractDictionary() { }
00885
00892 virtual PObject * Clone() const
00893 { return PNEW PDictionary(0, this); }
00895
00908 D & operator[](
00909 const K & key
00910 ) const
00911 { return (D &)GetRefAt(key); }
00912
00921 PBoolean Contains(
00922 const K & key
00923 ) const { return AbstractContains(key); }
00924
00936 virtual D * RemoveAt(
00937 const K & key
00938 ) {
00939 D * obj = GetAt(key); AbstractSetAt(key, NULL);
00940 return reference->deleteObjects ? (obj ? (D *)-1 : NULL) : obj;
00941 }
00942
00954 virtual PBoolean SetAt(
00955 const K & key,
00956 D * obj
00957 ) { return AbstractSetAt(key, obj); }
00958
00965 virtual D * GetAt(
00966 const K & key
00967 ) const { return (D *)AbstractGetAt(key); }
00968
00980 const K & GetKeyAt(
00981 PINDEX index
00982 ) const
00983 { return (const K &)AbstractGetKeyAt(index); }
00984
00996 D & GetDataAt(
00997 PINDEX index
00998 ) const
00999 { return (D &)AbstractGetDataAt(index); }
01001
01002 protected:
01003 PDictionary(int dummy, const PDictionary * c)
01004 : PAbstractDictionary(dummy, c) { }
01005 };
01006
01007
01020 #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
01021
01022
01035 #define PDECLARE_DICTIONARY(cls, K, D) \
01036 PDICTIONARY(cls##_PTemplate, K, D); \
01037 PDECLARE_CLASS(cls, cls##_PTemplate) \
01038 protected: \
01039 cls(int dummy, const cls * c) \
01040 : cls##_PTemplate(dummy, c) { } \
01041 public: \
01042 cls() \
01043 : cls##_PTemplate() { } \
01044 virtual PObject * Clone() const \
01045 { return PNEW cls(0, this); } \
01046
01047
01055 template <class K> class POrdinalDictionary : public PAbstractDictionary
01056 {
01057 PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
01058
01059 public:
01068 POrdinalDictionary()
01069 : PAbstractDictionary() { }
01071
01078 virtual PObject * Clone() const
01079 { return PNEW POrdinalDictionary(0, this); }
01081
01094 PINDEX operator[](
01095 const K & key
01096 ) const
01097 { return (POrdinalKey &)GetRefAt(key); }
01098
01107 PBoolean Contains(
01108 const K & key
01109 ) const { return AbstractContains(key); }
01110
01111 virtual POrdinalKey * GetAt(
01112 const K & key
01113 ) const { return (POrdinalKey *)AbstractGetAt(key); }
01114
01115
01116
01117
01118
01119
01120
01129 virtual PBoolean SetDataAt(
01130 PINDEX index,
01131 PINDEX ordinal
01132 ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
01133
01145 virtual PBoolean SetAt(
01146 const K & key,
01147 PINDEX ordinal
01148 ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
01149
01158 virtual PINDEX RemoveAt(
01159 const K & key
01160 ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
01161
01173 const K & GetKeyAt(
01174 PINDEX index
01175 ) const
01176 { return (const K &)AbstractGetKeyAt(index); }
01177
01189 PINDEX GetDataAt(
01190 PINDEX index
01191 ) const
01192 { return (POrdinalKey &)AbstractGetDataAt(index); }
01194
01195 protected:
01196 POrdinalDictionary(int dummy, const POrdinalDictionary * c)
01197 : PAbstractDictionary(dummy, c) { }
01198 };
01199
01200
01213 #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
01214
01215
01230 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01231 PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01232 PDECLARE_CLASS(cls, POrdinalDictionary<K>) \
01233 protected: \
01234 cls(int dummy, const cls * c) \
01235 : cls##_PTemplate(dummy, c) { } \
01236 public: \
01237 cls() \
01238 : cls##_PTemplate() { } \
01239 virtual PObject * Clone() const \
01240 { return PNEW cls(0, this); } \
01241
01242
01243 #else // PHAS_TEMPLATES
01244
01245
01246 #define PDICTIONARY(cls, K, D) \
01247 class cls : public PAbstractDictionary { \
01248 PCLASSINFO(cls, PAbstractDictionary); \
01249 protected: \
01250 inline cls(int dummy, const cls * c) \
01251 : PAbstractDictionary(dummy, c) { } \
01252 public: \
01253 cls() \
01254 : PAbstractDictionary() { } \
01255 virtual PObject * Clone() const \
01256 { return PNEW cls(0, this); } \
01257 D & operator[](const K & key) const \
01258 { return (D &)GetRefAt(key); } \
01259 virtual PBoolean Contains(const K & key) const \
01260 { return AbstractContains(key); } \
01261 virtual D * RemoveAt(const K & key) \
01262 { D * obj = GetAt(key); AbstractSetAt(key, NULL); return obj; } \
01263 virtual PBoolean SetAt(const K & key, D * obj) \
01264 { return AbstractSetAt(key, obj); } \
01265 virtual D * GetAt(const K & key) const \
01266 { return (D *)AbstractGetAt(key); } \
01267 const K & GetKeyAt(PINDEX index) const \
01268 { return (const K &)AbstractGetKeyAt(index); } \
01269 D & GetDataAt(PINDEX index) const \
01270 { return (D &)AbstractGetDataAt(index); } \
01271 }
01272
01273 #define PDECLARE_DICTIONARY(cls, K, D) \
01274 PDICTIONARY(cls##_PTemplate, K, D); \
01275 PDECLARE_CLASS(cls, cls##_PTemplate) \
01276 protected: \
01277 cls(int dummy, const cls * c) \
01278 : cls##_PTemplate(dummy, c) { } \
01279 public: \
01280 cls() \
01281 : cls##_PTemplate() { } \
01282 virtual PObject * Clone() const \
01283 { return PNEW cls(0, this); } \
01284
01285
01286 #define PORDINAL_DICTIONARY(cls, K) \
01287 class cls : public PAbstractDictionary { \
01288 PCLASSINFO(cls, PAbstractDictionary); \
01289 protected: \
01290 inline cls(int dummy, const cls * c) \
01291 : PAbstractDictionary(dummy, c) { } \
01292 public: \
01293 inline cls() \
01294 : PAbstractDictionary() { } \
01295 virtual PObject * Clone() const \
01296 { return PNEW cls(0, this); } \
01297 inline PINDEX operator[](const K & key) const \
01298 { return (POrdinalKey &)GetRefAt(key); } \
01299 virtual PBoolean Contains(const K & key) const \
01300 { return AbstractContains(key); } \
01301 virtual POrdinalKey * GetAt(const K & key) const \
01302 { return (POrdinalKey *)AbstractGetAt(key); } \
01303 virtual PBoolean SetDataAt(PINDEX index, PINDEX ordinal) \
01304 { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); } \
01305 virtual PBoolean SetAt(const K & key, PINDEX ordinal) \
01306 { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); } \
01307 virtual PINDEX RemoveAt(const K & key) \
01308 { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; } \
01309 inline const K & GetKeyAt(PINDEX index) const \
01310 { return (const K &)AbstractGetKeyAt(index); } \
01311 inline PINDEX GetDataAt(PINDEX index) const \
01312 { return (POrdinalKey &)AbstractGetDataAt(index); } \
01313 }
01314
01315 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01316 PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01317 PDECLARE_CLASS(cls, cls##_PTemplate) \
01318 protected: \
01319 cls(int dummy, const cls * c) \
01320 : cls##_PTemplate(dummy, c) { } \
01321 public: \
01322 cls() \
01323 : cls##_PTemplate() { } \
01324 virtual PObject * Clone() const \
01325 { return PNEW cls(0, this); } \
01326
01327
01328 #endif // PHAS_TEMPLATES
01329
01330 #endif // #ifndef __DICT_H__
01331
01332