# dict.h

Go to the documentation of this file.

    00001 /*
    00002  * dict.h
    00003  *
    00004  * Dictionary (hash table) Container classes.
    00005  *
    00006  * Portable Tools Library
    00007  *
    00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Portable Windows Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00023  *
    00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
    00025  * All Rights Reserved.
    00026  *
    00027  * Contributor(s): ______________________________________.
    00028  *
    00029  * $Revision: 28056 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2012-07-18 03:21:10 -0500 (Wed, 18 Jul 2012) $
    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 // PDictionary classes
    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     /* Get the relative rank of the ordinal index. This is a simpel comparison
    00074        of the objects PINDEX values.
    00075
    00076        @return
    00077        comparison of the two objects, <code>EqualTo</code> for same,
    00078        <code>LessThan</code> for \p obj logically less than the
    00079        object and <code>GreaterThan</code> for \p obj logically
    00080        greater than the object.
    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 // Member variables
    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     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
    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   // New object to include in the set.
    00495     ) { Append((PObject *)obj); }
    00496
    00504     PSet & operator+=(
    00505       const T & obj   // New object to include in the set.
    00506     ) { Append(obj.Clone()); return *this; }
    00507
    00515     void Exclude(
    00516       const T * obj   // New object to exclude in the set.
    00517     ) { Remove(obj); }
    00518
    00526     PSet & operator-=(
    00527       const T & obj   // New object to exclude in the set.
    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,  // Key for position in dictionary to add object.
    00929       D * obj         // New object to put into the dictionary.
    00930     ) { return AbstractSetAt(key, obj); }
    00931
    00938     virtual D * GetAt(
    00939       const K & key   // Key for position in dictionary to get object.
    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   // Key to look for in the dictionary.
    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     /* Get the object at the specified key position. If the key was not in the
    01099        collection then NULL is returned.
    01100
    01101        @return
    01102        pointer to object at the specified key.
    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 // End Of File ///////////////////////////////////////////////////////////////