dict.h

Go to the documentation of this file.
00001 /*
00002  * dict.h
00003  *
00004  * Dictionary (hash table) Container classes.
00005  *
00006  * Portable Windows 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: 19008 $
00030  * $Author: rjongbloed $
00031  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
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 // 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, #EqualTo# for same,
00078        #LessThan# for #obj# logically less than the
00079        object and #GreaterThan# for #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 
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     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
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   // New object to include in the set.
00484     ) { Append((PObject *)obj); }
00485 
00493     PSet & operator+=(
00494       const T & obj   // New object to include in the set.
00495     ) { Append(obj.Clone()); return *this; }
00496 
00504     void Exclude(
00505       const T * obj   // New object to exclude in the set.
00506     ) { Remove(obj); }
00507 
00515     PSet & operator-=(
00516       const T & obj   // New object to exclude in the set.
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   // New object to place into the collection.
00836     );
00837     /* This function is meaningless and will assert.
00838 
00839        @return
00840        Always zero.
00841      */
00842 
00843     virtual PBoolean Remove(
00844       const PObject * obj   // Existing object to remove from the collection.
00845     );
00846     /* Remove the object from the collection. If the AllowDeleteObjects option
00847        is set then the object is also deleted.
00848 
00849        Note that the comparison for searching for the object in collection is
00850        made by pointer, not by value. Thus the parameter must point to the
00851        same instance of the object that is in the collection.
00852 
00853        @return
00854        PTrue if the object was in the collection.
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,  // Key for position in dictionary to add object.
00956       D * obj         // New object to put into the dictionary.
00957     ) { return AbstractSetAt(key, obj); }
00958 
00965     virtual D * GetAt(
00966       const K & key   // Key for position in dictionary to get object.
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   // Key to look for in the dictionary.
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     /* Get the object at the specified key position. If the key was not in the
01115        collection then NULL is returned.
01116 
01117        @return
01118        pointer to object at the specified key.
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 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Dec 10 11:18:56 2007 for PTLib by  doxygen 1.5.1