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  * $Log: dict.h,v $
00030  * Revision 1.38  2007/08/01 05:20:48  rjongbloed
00031  * Changes to container classes to become compatible with advanced DevStudio 2005 "Visualizers".
00032  *
00033  * Revision 1.37  2006/06/30 00:56:31  csoutheren
00034  * Applied 1494931 - various pwlib bug fixes and enhancement
00035  * Thanks to Frederich Heem
00036  *
00037  * Revision 1.36  2006/06/21 03:28:41  csoutheren
00038  * Various cleanups thanks for Frederic Heem
00039  *
00040  * Revision 1.35  2005/11/25 03:43:47  csoutheren
00041  * Fixed function argument comments to be compatible with Doxygen
00042  *
00043  * Revision 1.34  2004/11/23 11:33:08  csoutheren
00044  * Fixed problem with RemoveAt returning invalid pointer in some cases,
00045  * and added extra documentation on this case.
00046  * Thanks to Diego Tartara for pointing out this potential problem
00047  *
00048  * Revision 1.33  2004/04/09 03:42:34  csoutheren
00049  * Removed all usages of "virtual inline" and "inline virtual"
00050  *
00051  * Revision 1.32  2004/04/03 23:53:09  csoutheren
00052  * Added various changes to improce compatibility with the Sun Forte compiler
00053  *   Thanks to Brian Cameron
00054  * Added detection of readdir_r version
00055  *
00056  * Revision 1.31  2003/09/17 01:18:02  csoutheren
00057  * Removed recursive include file system and removed all references
00058  * to deprecated coooperative threading support
00059  *
00060  * Revision 1.30  2003/03/31 01:23:56  robertj
00061  * Added ReadFrom functions for standard container classes such as
00062  *   PIntArray and PStringList etc
00063  *
00064  * Revision 1.29  2002/10/04 01:47:29  robertj
00065  * Added various increment and decrement operators to POrdinalKey.
00066  *
00067  * Revision 1.28  2002/09/16 01:08:59  robertj
00068  * Added #define so can select if #pragma interface/implementation is used on
00069  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00070  *
00071  * Revision 1.27  2002/06/14 13:22:12  robertj
00072  * Fixed ability to remove elements from a PSet by value.
00073  * Added by value add and remove functions to a PSet.
00074  * Added a POrdinalSet class.
00075  * Fixed some documentation.
00076  *
00077  * Revision 1.26  2002/02/06 00:53:25  robertj
00078  * Fixed missing const on PSet::Contains and operator[], thanks Francisco Olarte Sanz
00079  *
00080  * Revision 1.25  1999/11/30 00:22:54  robertj
00081  * Updated documentation for doc++
00082  *
00083  * Revision 1.24  1999/08/22 12:13:43  robertj
00084  * Fixed warning when using inlines on older GNU compiler
00085  *
00086  * Revision 1.23  1999/03/09 02:59:49  robertj
00087  * Changed comments to doc++ compatible documentation.
00088  *
00089  * Revision 1.22  1999/02/16 08:07:11  robertj
00090  * MSVC 6.0 compatibility changes.
00091  *
00092  * Revision 1.21  1998/09/23 06:20:27  robertj
00093  * Added open source copyright license.
00094  *
00095  * Revision 1.20  1998/01/05 10:39:34  robertj
00096  * Fixed "typesafe" templates/macros for dictionaries, especially on GNU.
00097  *
00098  * Revision 1.19  1997/12/11 10:27:16  robertj
00099  * Added type correct Contains() function to dictionaries.
00100  *
00101  * Revision 1.18  1997/07/08 13:15:05  robertj
00102  * DLL support.
00103  *
00104  * Revision 1.17  1997/06/08 04:49:11  robertj
00105  * Fixed non-template class descendent order.
00106  *
00107  * Revision 1.16  1996/08/17 10:00:22  robertj
00108  * Changes for Windows DLL support.
00109  *
00110  * Revision 1.15  1996/03/31 08:44:10  robertj
00111  * Added RemoveAt() function to remove entries from dictionaries.
00112  *
00113  * Revision 1.14  1996/02/08 11:50:01  robertj
00114  * Moved Contains function from PSet to PHashTable so available for dictionaries.
00115  * Added print for dictionaries key=data\n.
00116  * Added GetAt(PINDEX) to template classes to make identical to macro.
00117  *
00118  * Revision 1.13  1996/02/03 11:00:28  robertj
00119  * Temporary removal of SetAt() and GetAt() functions in dictionary macro.
00120  *
00121  * Revision 1.12  1996/01/24 14:43:11  robertj
00122  * Added initialisers to string dictionaries.
00123  *
00124  * Revision 1.11  1996/01/23 13:11:12  robertj
00125  * Mac Metrowerks compiler support.
00126  *
00127  * Revision 1.10  1995/06/17 11:12:29  robertj
00128  * Documentation update.
00129  *
00130  * Revision 1.9  1995/06/04 08:45:57  robertj
00131  * Better C++ compatibility (with BC++)
00132  *
00133  * Revision 1.8  1995/03/14 12:41:19  robertj
00134  * Updated documentation to use HTML codes.
00135  *
00136  * Revision 1.7  1995/02/22  10:50:29  robertj
00137  * Changes required for compiling release (optimised) version.
00138  *
00139  * Revision 1.6  1995/02/11  04:10:35  robertj
00140  * Fixed dictionary MACRO for templates.
00141  *
00142  * Revision 1.5  1995/02/05  00:48:03  robertj
00143  * Fixed template version.
00144  *
00145  * Revision 1.4  1995/01/09  12:35:31  robertj
00146  * Removed unnecesary return value from I/O functions.
00147  * Changes due to Mac port.
00148  *
00149  * Revision 1.3  1994/12/21  11:52:51  robertj
00150  * Documentation and variable normalisation.
00151  *
00152  * Revision 1.2  1994/12/17  01:36:57  robertj
00153  * Fixed memory leak in PStringSet
00154  *
00155  * Revision 1.1  1994/12/12  09:59:32  robertj
00156  * Initial revision
00157  *
00158  */
00159 
00160 
00161 #ifndef __DICT_H__
00162 #define __DICT_H__
00163 
00164 #ifdef P_USE_PRAGMA
00165 #pragma interface
00166 #endif
00167 
00168 #include <ptlib/array.h>
00169 
00171 // PDictionary classes
00172 
00176 class POrdinalKey : public PObject
00177 {
00178   PCLASSINFO(POrdinalKey, PObject);
00179 
00180   public:
00185     PINLINE POrdinalKey(
00186       PINDEX newKey = 0   
00187     );
00188 
00191     PINLINE POrdinalKey & operator=(PINDEX);
00193 
00196 
00197     virtual PObject * Clone() const;
00198 
00199     /* Get the relative rank of the ordinal index. This is a simpel comparison
00200        of the objects PINDEX values.
00201 
00202        @return
00203        comparison of the two objects, #EqualTo# for same,
00204        #LessThan# for #obj# logically less than the
00205        object and #GreaterThan# for #obj# logically
00206        greater than the object.
00207      */
00208     virtual Comparison Compare(const PObject & obj) const;
00209 
00216     virtual PINDEX HashFunction() const;
00217 
00224     virtual void PrintOn(ostream & strm) const;
00226 
00231     PINLINE operator PINDEX() const;
00232 
00235     PINLINE PINDEX operator++();
00236 
00239     PINLINE PINDEX operator++(int);
00240 
00243     PINLINE PINDEX operator--();
00244 
00247     PINLINE PINDEX operator--(int);
00248 
00251     PINLINE POrdinalKey & operator+=(PINDEX);
00252 
00255     PINLINE POrdinalKey & operator-=(PINDEX );
00257 
00258   private:
00259     PINDEX theKey;
00260 };
00261 
00262 
00264 
00265 // Member variables
00266 struct PHashTableElement
00267 {
00268     PObject * key;
00269     PObject * data;
00270     PHashTableElement * next;
00271     PHashTableElement * prev;
00272 };
00273 
00274 PDECLARE_BASEARRAY(PHashTableInfo, PHashTableElement *)
00275 #ifdef DOC_PLUS_PLUS
00276 {
00277 #endif
00278   public:
00279     virtual ~PHashTableInfo() { Destruct(); }
00280     virtual void DestroyContents();
00281 
00282     PINDEX AppendElement(PObject * key, PObject * data);
00283     PObject * RemoveElement(const PObject & key);
00284     BOOL SetLastElementAt(PINDEX index);
00285     PHashTableElement * GetElementAt(const PObject & key);
00286     PINDEX GetElementsIndex(const PObject*obj,BOOL byVal,BOOL keys) const;
00287 
00288     PINDEX lastIndex;
00289     PINDEX lastBucket;
00290     PHashTableElement * lastElement;
00291 
00292     BOOL deleteKeys;
00293 
00294   typedef PHashTableElement Element;
00295   friend class PHashTable;
00296   friend class PAbstractSet;
00297 };
00298 
00299 
00310 class PHashTable : public PCollection
00311 {
00312   PCONTAINERINFO(PHashTable, PCollection);
00313 
00314   public:
00317 
00318     PHashTable();
00320 
00332     virtual Comparison Compare(
00333       const PObject & obj   
00334     ) const;
00336 
00337 
00338   protected:
00348     virtual BOOL SetSize(
00349       PINDEX newSize  
00350     );
00352 
00353 
00364     PINLINE BOOL AbstractContains(
00365       const PObject & key   
00366     ) const;
00367 
00382     virtual const PObject & AbstractGetKeyAt(
00383       PINDEX index  
00384     ) const;
00385 
00400     virtual PObject & AbstractGetDataAt(
00401       PINDEX index  
00402     ) const;
00404 
00405     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00406     typedef PHashTableElement Element;
00407     typedef PHashTableInfo Table;
00408     PHashTableInfo * hashTable;
00409 };
00410 
00411 
00413 
00416 class PAbstractSet : public PHashTable
00417 {
00418   PCONTAINERINFO(PAbstractSet, PHashTable);
00419   public:
00427     PINLINE PAbstractSet();
00429 
00440     virtual PINDEX Append(
00441       PObject * obj   
00442     );
00443 
00456     virtual PINDEX Insert(
00457       const PObject & before,   
00458       PObject * obj             
00459     );
00460 
00473     virtual PINDEX InsertAt(
00474       PINDEX index,   
00475       PObject * obj   
00476     );
00477 
00488     virtual BOOL Remove(
00489       const PObject * obj   
00490     );
00491 
00498     virtual PObject * RemoveAt(
00499       PINDEX index   
00500     );
00501 
00507     virtual PObject * GetAt(
00508       PINDEX index  
00509     ) const;
00510 
00523     virtual BOOL SetAt(
00524       PINDEX index,   
00525       PObject * val   
00526     );
00527 
00539     virtual PINDEX GetObjectsIndex(
00540       const PObject * obj   
00541     ) const;
00542 
00551     virtual PINDEX GetValuesIndex(
00552       const PObject & obj   
00553     ) const;
00555 };
00556 
00557 
00558 #ifdef PHAS_TEMPLATES
00559 
00570 template <class T> class PSet : public PAbstractSet
00571 {
00572   PCLASSINFO(PSet, PAbstractSet);
00573 
00574   public:
00584     inline PSet(BOOL initialDeleteObjects = FALSE)
00585       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
00587 
00593     virtual PObject * Clone() const
00594       { return PNEW PSet(0, this); }
00596 
00608     void Include(
00609       const T * obj   // New object to include in the set.
00610     ) { Append((PObject *)obj); }
00611 
00619     PSet & operator+=(
00620       const T & obj   // New object to include in the set.
00621     ) { Append(obj.Clone()); return *this; }
00622 
00630     void Exclude(
00631       const T * obj   // New object to exclude in the set.
00632     ) { Remove(obj); }
00633 
00641     PSet & operator-=(
00642       const T & obj   // New object to exclude in the set.
00643     ) { RemoveAt(GetValuesIndex(obj)); return *this; }
00644 
00653     BOOL Contains(
00654       const T & key  
00655     ) const { return AbstractContains(key); }
00656 
00665     BOOL operator[](
00666       const T & key  
00667     ) const { return AbstractContains(key); }
00668 
00680     virtual const T & GetKeyAt(
00681       PINDEX index    
00682     ) const
00683       { return (const T &)AbstractGetKeyAt(index); }
00685 
00686 
00687   protected:
00688     PSet(int dummy, const PSet * c)
00689       : PAbstractSet(dummy, c)
00690       { reference->deleteObjects = c->reference->deleteObjects; }
00691 };
00692 
00693 
00705 #define PSET(cls, T) typedef PSet<T> cls
00706 
00707 
00719 #define PDECLARE_SET(cls, T, initDelObj) \
00720   PSET(cls##_PTemplate, T); \
00721   PDECLARE_CLASS(cls, cls##_PTemplate) \
00722   protected: \
00723     cls(int dummy, const cls * c) \
00724       : cls##_PTemplate(dummy, c) { } \
00725   public: \
00726     cls(BOOL initialDeleteObjects = initDelObj) \
00727       : cls##_PTemplate(initialDeleteObjects) { } \
00728     virtual PObject * Clone() const \
00729       { return PNEW cls(0, this); } \
00730 
00731 
00732 #else // PHAS_TEMPLATES
00733 
00734 
00735 #define PSET(cls, K) \
00736   class cls : public PAbstractSet { \
00737   PCLASSINFO(cls, PAbstractSet); \
00738   protected: \
00739     inline cls(int dummy, const cls * c) \
00740       : PAbstractSet(dummy, c) \
00741       { reference->deleteObjects = c->reference->deleteObjects; } \
00742   public: \
00743     inline cls(BOOL initialDeleteObjects = FALSE) \
00744       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); } \
00745     virtual PObject * Clone() const \
00746       { return PNEW cls(0, this); } \
00747     inline void Include(const PObject * key) \
00748       { Append((PObject *)key); } \
00749     inline void Exclude(const PObject * key) \
00750       { Remove(key); } \
00751     inline BOOL operator[](const K & key) const \
00752         { return AbstractContains(key); } \
00753     inline BOOL Contains(const K & key) const \
00754         { return AbstractContains(key); } \
00755     virtual const K & GetKeyAt(PINDEX index) const \
00756       { return (const K &)AbstractGetKeyAt(index); } \
00757   }
00758 
00759 #define PDECLARE_SET(cls, K, initDelObj) \
00760  PSET(cls##_PTemplate, K); \
00761  PDECLARE_CLASS(cls, cls##_PTemplate) \
00762   protected: \
00763     inline cls(int dummy, const cls * c) \
00764       : cls##_PTemplate(dummy, c) { } \
00765   public: \
00766     inline cls(BOOL initialDeleteObjects = initDelObj) \
00767       : cls##_PTemplate() { AllowDeleteObjects(initialDeleteObjects); } \
00768     virtual PObject * Clone() const \
00769       { return PNEW cls(0, this); } \
00770 
00771 
00772 #endif  // PHAS_TEMPLATES
00773 
00774 
00775 PSET(POrdinalSet, POrdinalKey);
00776 
00777 
00779 
00782 class PAbstractDictionary : public PHashTable
00783 {
00784   PCLASSINFO(PAbstractDictionary, PHashTable);
00785   public:
00793     PINLINE PAbstractDictionary();
00795 
00804     virtual void PrintOn(
00805       ostream &strm   
00806     ) const;
00808 
00819     virtual PINDEX Insert(
00820       const PObject & key,   
00821       PObject * obj          
00822     );
00823 
00830     virtual PINDEX InsertAt(
00831       PINDEX index,   
00832       PObject * obj   
00833     );
00834 
00844     virtual PObject * RemoveAt(
00845       PINDEX index   
00846     );
00847 
00856     virtual BOOL SetAt(
00857       PINDEX index,   
00858       PObject * val   
00859     );
00860 
00868     virtual PObject * GetAt(
00869       PINDEX index  
00870     ) const;
00871 
00883     virtual PINDEX GetObjectsIndex(
00884       const PObject * obj  
00885     ) const;
00886 
00895     virtual PINDEX GetValuesIndex(
00896       const PObject & obj  
00897     ) const;
00899 
00900 
00911     virtual BOOL SetDataAt(
00912       PINDEX index,   
00913       PObject * obj   
00914     );
00915 
00927     virtual BOOL AbstractSetAt(
00928       const PObject & key,  
00929       PObject * obj         
00930     );
00931 
00941     virtual PObject & GetRefAt(
00942       const PObject & key   
00943     ) const;
00944 
00951     virtual PObject * AbstractGetAt(
00952       const PObject & key   
00953     ) const;
00955 
00956   protected:
00957     PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
00958 
00959   private:
00960     virtual PINDEX Append(
00961       PObject * obj   // New object to place into the collection.
00962     );
00963     /* This function is meaningless and will assert.
00964 
00965        @return
00966        Always zero.
00967      */
00968 
00969     virtual BOOL Remove(
00970       const PObject * obj   // Existing object to remove from the collection.
00971     );
00972     /* Remove the object from the collection. If the AllowDeleteObjects option
00973        is set then the object is also deleted.
00974 
00975        Note that the comparison for searching for the object in collection is
00976        made by pointer, not by value. Thus the parameter must point to the
00977        same instance of the object that is in the collection.
00978 
00979        @return
00980        TRUE if the object was in the collection.
00981      */
00982 
00983 };
00984 
00985 
00986 #ifdef PHAS_TEMPLATES
00987 
00995 template <class K, class D> class PDictionary : public PAbstractDictionary
00996 {
00997   PCLASSINFO(PDictionary, PAbstractDictionary);
00998 
00999   public:
01008     PDictionary()
01009       : PAbstractDictionary() { }
01011 
01018     virtual PObject * Clone() const
01019       { return PNEW PDictionary(0, this); }
01021 
01034     D & operator[](
01035       const K & key   
01036     ) const
01037       { return (D &)GetRefAt(key); }
01038 
01047     BOOL Contains(
01048       const K & key   
01049     ) const { return AbstractContains(key); }
01050 
01062     virtual D * RemoveAt(
01063       const K & key   
01064     ) {
01065         D * obj = GetAt(key); AbstractSetAt(key, NULL); 
01066         return reference->deleteObjects ? (obj ? (D *)-1 : NULL) : obj;
01067       }
01068 
01080     virtual BOOL SetAt(
01081       const K & key,  // Key for position in dictionary to add object.
01082       D * obj         // New object to put into the dictionary.
01083     ) { return AbstractSetAt(key, obj); }
01084 
01091     virtual D * GetAt(
01092       const K & key   // Key for position in dictionary to get object.
01093     ) const { return (D *)AbstractGetAt(key); }
01094 
01106     const K & GetKeyAt(
01107       PINDEX index  
01108     ) const
01109       { return (const K &)AbstractGetKeyAt(index); }
01110 
01122     D & GetDataAt(
01123       PINDEX index  
01124     ) const
01125       { return (D &)AbstractGetDataAt(index); }
01127 
01128   protected:
01129     PDictionary(int dummy, const PDictionary * c)
01130       : PAbstractDictionary(dummy, c) { }
01131 };
01132 
01133 
01146 #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
01147 
01148 
01161 #define PDECLARE_DICTIONARY(cls, K, D) \
01162   PDICTIONARY(cls##_PTemplate, K, D); \
01163   PDECLARE_CLASS(cls, cls##_PTemplate) \
01164   protected: \
01165     cls(int dummy, const cls * c) \
01166       : cls##_PTemplate(dummy, c) { } \
01167   public: \
01168     cls() \
01169       : cls##_PTemplate() { } \
01170     virtual PObject * Clone() const \
01171       { return PNEW cls(0, this); } \
01172 
01173 
01181 template <class K> class POrdinalDictionary : public PAbstractDictionary
01182 {
01183   PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
01184 
01185   public:
01194     POrdinalDictionary()
01195       : PAbstractDictionary() { }
01197 
01204     virtual PObject * Clone() const
01205       { return PNEW POrdinalDictionary(0, this); }
01207 
01220     PINDEX operator[](
01221       const K & key   // Key to look for in the dictionary.
01222     ) const
01223       { return (POrdinalKey &)GetRefAt(key); }
01224 
01233     BOOL Contains(
01234       const K & key   
01235     ) const { return AbstractContains(key); }
01236 
01237     virtual POrdinalKey * GetAt(
01238       const K & key   
01239     ) const { return (POrdinalKey *)AbstractGetAt(key); }
01240     /* Get the object at the specified key position. If the key was not in the
01241        collection then NULL is returned.
01242 
01243        @return
01244        pointer to object at the specified key.
01245      */
01246 
01255     virtual BOOL SetDataAt(
01256       PINDEX index,   
01257       PINDEX ordinal  
01258       ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
01259 
01271     virtual BOOL SetAt(
01272       const K & key,  
01273       PINDEX ordinal  
01274     ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
01275 
01284     virtual PINDEX RemoveAt(
01285       const K & key   
01286     ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
01287 
01299     const K & GetKeyAt(
01300       PINDEX index  
01301     ) const
01302       { return (const K &)AbstractGetKeyAt(index); }
01303 
01315     PINDEX GetDataAt(
01316       PINDEX index  
01317     ) const
01318       { return (POrdinalKey &)AbstractGetDataAt(index); }
01320 
01321   protected:
01322     POrdinalDictionary(int dummy, const POrdinalDictionary * c)
01323       : PAbstractDictionary(dummy, c) { }
01324 };
01325 
01326 
01339 #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
01340 
01341 
01356 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01357   PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01358   PDECLARE_CLASS(cls, POrdinalDictionary<K>) \
01359   protected: \
01360     cls(int dummy, const cls * c) \
01361       : cls##_PTemplate(dummy, c) { } \
01362   public: \
01363     cls() \
01364       : cls##_PTemplate() { } \
01365     virtual PObject * Clone() const \
01366       { return PNEW cls(0, this); } \
01367 
01368 
01369 #else // PHAS_TEMPLATES
01370 
01371 
01372 #define PDICTIONARY(cls, K, D) \
01373   class cls : public PAbstractDictionary { \
01374   PCLASSINFO(cls, PAbstractDictionary); \
01375   protected: \
01376     inline cls(int dummy, const cls * c) \
01377       : PAbstractDictionary(dummy, c) { } \
01378   public: \
01379     cls() \
01380       : PAbstractDictionary() { } \
01381     virtual PObject * Clone() const \
01382       { return PNEW cls(0, this); } \
01383     D & operator[](const K & key) const \
01384       { return (D &)GetRefAt(key); } \
01385     virtual BOOL Contains(const K & key) const \
01386       { return AbstractContains(key); } \
01387     virtual D * RemoveAt(const K & key) \
01388       { D * obj = GetAt(key); AbstractSetAt(key, NULL); return obj; } \
01389     virtual BOOL SetAt(const K & key, D * obj) \
01390       { return AbstractSetAt(key, obj); } \
01391     virtual D * GetAt(const K & key) const \
01392       { return (D *)AbstractGetAt(key); } \
01393     const K & GetKeyAt(PINDEX index) const \
01394       { return (const K &)AbstractGetKeyAt(index); } \
01395     D & GetDataAt(PINDEX index) const \
01396       { return (D &)AbstractGetDataAt(index); } \
01397   }
01398 
01399 #define PDECLARE_DICTIONARY(cls, K, D) \
01400   PDICTIONARY(cls##_PTemplate, K, D); \
01401   PDECLARE_CLASS(cls, cls##_PTemplate) \
01402   protected: \
01403     cls(int dummy, const cls * c) \
01404       : cls##_PTemplate(dummy, c) { } \
01405   public: \
01406     cls() \
01407       : cls##_PTemplate() { } \
01408     virtual PObject * Clone() const \
01409       { return PNEW cls(0, this); } \
01410 
01411 
01412 #define PORDINAL_DICTIONARY(cls, K) \
01413   class cls : public PAbstractDictionary { \
01414   PCLASSINFO(cls, PAbstractDictionary); \
01415   protected: \
01416     inline cls(int dummy, const cls * c) \
01417       : PAbstractDictionary(dummy, c) { } \
01418   public: \
01419     inline cls() \
01420       : PAbstractDictionary() { } \
01421     virtual PObject * Clone() const \
01422       { return PNEW cls(0, this); } \
01423     inline PINDEX operator[](const K & key) const \
01424       { return (POrdinalKey &)GetRefAt(key); } \
01425     virtual BOOL Contains(const K & key) const \
01426       { return AbstractContains(key); } \
01427     virtual POrdinalKey * GetAt(const K & key) const \
01428       { return (POrdinalKey *)AbstractGetAt(key); } \
01429     virtual BOOL SetDataAt(PINDEX index, PINDEX ordinal) \
01430       { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); } \
01431     virtual BOOL SetAt(const K & key, PINDEX ordinal) \
01432       { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); } \
01433     virtual PINDEX RemoveAt(const K & key) \
01434       { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; } \
01435     inline const K & GetKeyAt(PINDEX index) const \
01436       { return (const K &)AbstractGetKeyAt(index); } \
01437     inline PINDEX GetDataAt(PINDEX index) const \
01438       { return (POrdinalKey &)AbstractGetDataAt(index); } \
01439   }
01440 
01441 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01442   PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01443   PDECLARE_CLASS(cls, cls##_PTemplate) \
01444   protected: \
01445     cls(int dummy, const cls * c) \
01446       : cls##_PTemplate(dummy, c) { } \
01447   public: \
01448     cls() \
01449       : cls##_PTemplate() { } \
01450     virtual PObject * Clone() const \
01451       { return PNEW cls(0, this); } \
01452 
01453 
01454 #endif // PHAS_TEMPLATES
01455 
01456 #endif // #ifndef __DICT_H__
01457 
01458 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1