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: 24177 $
00030  * $Author: rjongbloed $
00031  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
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 
00210   protected:
00220     virtual PBoolean SetSize(
00221       PINDEX newSize  
00222     );
00224 
00225 
00236     PINLINE PBoolean AbstractContains(
00237       const PObject & key   
00238     ) const;
00239 
00254     virtual const PObject & AbstractGetKeyAt(
00255       PINDEX index  
00256     ) const;
00257 
00272     virtual PObject & AbstractGetDataAt(
00273       PINDEX index  
00274     ) const;
00276 
00277     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00278     typedef PHashTableElement Element;
00279     typedef PHashTableInfo Table;
00280     PHashTableInfo * hashTable;
00281 };
00282 
00283 
00285 
00288 class PAbstractSet : public PHashTable
00289 {
00290   PCONTAINERINFO(PAbstractSet, PHashTable);
00291   public:
00299     PINLINE PAbstractSet();
00301 
00312     virtual PINDEX Append(
00313       PObject * obj   
00314     );
00315 
00328     virtual PINDEX Insert(
00329       const PObject & before,   
00330       PObject * obj             
00331     );
00332 
00345     virtual PINDEX InsertAt(
00346       PINDEX index,   
00347       PObject * obj   
00348     );
00349 
00360     virtual PBoolean Remove(
00361       const PObject * obj   
00362     );
00363 
00370     virtual PObject * RemoveAt(
00371       PINDEX index   
00372     );
00373 
00379     virtual PObject * GetAt(
00380       PINDEX index  
00381     ) const;
00382 
00395     virtual PBoolean SetAt(
00396       PINDEX index,   
00397       PObject * val   
00398     );
00399 
00411     virtual PINDEX GetObjectsIndex(
00412       const PObject * obj   
00413     ) const;
00414 
00423     virtual PINDEX GetValuesIndex(
00424       const PObject & obj   
00425     ) const;
00427 };
00428 
00429 
00440 template <class T> class PSet : public PAbstractSet
00441 {
00442   PCLASSINFO(PSet, PAbstractSet);
00443 
00444   public:
00454     inline PSet(PBoolean initialDeleteObjects = false)
00455       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
00457 
00463     virtual PObject * Clone() const
00464       { return PNEW PSet(0, this); }
00466 
00478     void Include(
00479       const T * obj   // New object to include in the set.
00480     ) { Append((PObject *)obj); }
00481 
00489     PSet & operator+=(
00490       const T & obj   // New object to include in the set.
00491     ) { Append(obj.Clone()); return *this; }
00492 
00500     void Exclude(
00501       const T * obj   // New object to exclude in the set.
00502     ) { Remove(obj); }
00503 
00511     PSet & operator-=(
00512       const T & obj   // New object to exclude in the set.
00513     ) { RemoveAt(GetValuesIndex(obj)); return *this; }
00514 
00523     PBoolean Contains(
00524       const T & key  
00525     ) const { return AbstractContains(key); }
00526 
00535     PBoolean operator[](
00536       const T & key  
00537     ) const { return AbstractContains(key); }
00538 
00550     virtual const T & GetKeyAt(
00551       PINDEX index    
00552     ) const
00553       { return (const T &)AbstractGetKeyAt(index); }
00555 
00556 
00557   protected:
00558     PSet(int dummy, const PSet * c)
00559       : PAbstractSet(dummy, c)
00560       { reference->deleteObjects = c->reference->deleteObjects; }
00561 };
00562 
00563 
00575 #define PSET(cls, T) typedef PSet<T> cls
00576 
00577 
00589 #define PDECLARE_SET(cls, T, initDelObj) \
00590   PSET(cls##_PTemplate, T); \
00591   PDECLARE_CLASS(cls, cls##_PTemplate) \
00592   protected: \
00593     cls(int dummy, const cls * c) \
00594       : cls##_PTemplate(dummy, c) { } \
00595   public: \
00596     cls(PBoolean initialDeleteObjects = initDelObj) \
00597       : cls##_PTemplate(initialDeleteObjects) { } \
00598     virtual PObject * Clone() const \
00599       { return PNEW cls(0, this); } \
00600 
00601 
00602 
00603 PSET(POrdinalSet, POrdinalKey);
00604 
00605 
00607 
00610 class PAbstractDictionary : public PHashTable
00611 {
00612   PCLASSINFO(PAbstractDictionary, PHashTable);
00613   public:
00621     PINLINE PAbstractDictionary();
00623 
00632     virtual void PrintOn(
00633       ostream &strm   
00634     ) const;
00636 
00647     virtual PINDEX Insert(
00648       const PObject & key,   
00649       PObject * obj          
00650     );
00651 
00658     virtual PINDEX InsertAt(
00659       PINDEX index,   
00660       PObject * obj   
00661     );
00662 
00672     virtual PObject * RemoveAt(
00673       PINDEX index   
00674     );
00675 
00684     virtual PBoolean SetAt(
00685       PINDEX index,   
00686       PObject * val   
00687     );
00688 
00695     virtual PObject * GetAt(
00696       PINDEX index  
00697     ) const;
00698 
00710     virtual PINDEX GetObjectsIndex(
00711       const PObject * obj  
00712     ) const;
00713 
00722     virtual PINDEX GetValuesIndex(
00723       const PObject & obj  
00724     ) const;
00726 
00727 
00738     virtual PBoolean SetDataAt(
00739       PINDEX index,   
00740       PObject * obj   
00741     );
00742 
00754     virtual PBoolean AbstractSetAt(
00755       const PObject & key,  
00756       PObject * obj         
00757     );
00758 
00768     virtual PObject & GetRefAt(
00769       const PObject & key   
00770     ) const;
00771 
00778     virtual PObject * AbstractGetAt(
00779       const PObject & key   
00780     ) const;
00782 
00783   protected:
00784     PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
00785 
00786   private:
00792     virtual PINDEX Append(
00793       PObject * obj   
00794     );
00795 
00806     virtual PBoolean Remove(
00807       const PObject * obj   
00808     );
00809 
00810 };
00811 
00812 
00820 template <class K, class D> class PDictionary : public PAbstractDictionary
00821 {
00822   PCLASSINFO(PDictionary, PAbstractDictionary);
00823 
00824   public:
00833     PDictionary()
00834       : PAbstractDictionary() { }
00836 
00843     virtual PObject * Clone() const
00844       { return PNEW PDictionary(0, this); }
00846 
00859     D & operator[](
00860       const K & key   
00861     ) const
00862       { return (D &)GetRefAt(key); }
00863 
00872     PBoolean Contains(
00873       const K & key   
00874     ) const { return AbstractContains(key); }
00875 
00887     virtual D * RemoveAt(
00888       const K & key   
00889     ) {
00890         D * obj = GetAt(key); AbstractSetAt(key, NULL);
00891         return reference->deleteObjects ? (obj ? (D *)-1 : NULL) : obj;
00892       }
00893 
00905     virtual PBoolean SetAt(
00906       const K & key,  // Key for position in dictionary to add object.
00907       D * obj         // New object to put into the dictionary.
00908     ) { return AbstractSetAt(key, obj); }
00909 
00916     virtual D * GetAt(
00917       const K & key   // Key for position in dictionary to get object.
00918     ) const { return (D *)AbstractGetAt(key); }
00919 
00931     const K & GetKeyAt(
00932       PINDEX index  
00933     ) const
00934       { return (const K &)AbstractGetKeyAt(index); }
00935 
00947     D & GetDataAt(
00948       PINDEX index  
00949     ) const
00950       { return (D &)AbstractGetDataAt(index); }
00952 
00953     typedef std::pair<K, D *> value_type;
00954 
00955   protected:
00956     PDictionary(int dummy, const PDictionary * c)
00957       : PAbstractDictionary(dummy, c) { }
00958 };
00959 
00960 
00973 #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
00974 
00975 
00988 #define PDECLARE_DICTIONARY(cls, K, D) \
00989   PDICTIONARY(cls##_PTemplate, K, D); \
00990   PDECLARE_CLASS(cls, cls##_PTemplate) \
00991   protected: \
00992     cls(int dummy, const cls * c) \
00993       : cls##_PTemplate(dummy, c) { } \
00994   public: \
00995     cls() \
00996       : cls##_PTemplate() { } \
00997     virtual PObject * Clone() const \
00998       { return PNEW cls(0, this); } \
00999 
01000 
01008 template <class K> class POrdinalDictionary : public PAbstractDictionary
01009 {
01010   PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
01011 
01012   public:
01021     POrdinalDictionary()
01022       : PAbstractDictionary() { }
01024 
01031     virtual PObject * Clone() const
01032       { return PNEW POrdinalDictionary(0, this); }
01034 
01047     PINDEX operator[](
01048       const K & key   // Key to look for in the dictionary.
01049     ) const
01050       { return (POrdinalKey &)GetRefAt(key); }
01051 
01060     PBoolean Contains(
01061       const K & key   
01062     ) const { return AbstractContains(key); }
01063 
01064     virtual POrdinalKey * GetAt(
01065       const K & key   
01066     ) const { return (POrdinalKey *)AbstractGetAt(key); }
01067     /* Get the object at the specified key position. If the key was not in the
01068        collection then NULL is returned.
01069 
01070        @return
01071        pointer to object at the specified key.
01072      */
01073 
01082     virtual PBoolean SetDataAt(
01083       PINDEX index,   
01084       PINDEX ordinal  
01085       ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
01086 
01098     virtual PBoolean SetAt(
01099       const K & key,  
01100       PINDEX ordinal  
01101     ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
01102 
01111     virtual PINDEX RemoveAt(
01112       const K & key   
01113     ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
01114 
01126     const K & GetKeyAt(
01127       PINDEX index  
01128     ) const
01129       { return (const K &)AbstractGetKeyAt(index); }
01130 
01142     PINDEX GetDataAt(
01143       PINDEX index  
01144     ) const
01145       { return (POrdinalKey &)AbstractGetDataAt(index); }
01147 
01148   protected:
01149     POrdinalDictionary(int dummy, const POrdinalDictionary * c)
01150       : PAbstractDictionary(dummy, c) { }
01151 };
01152 
01153 
01166 #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
01167 
01168 
01183 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01184   PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01185   PDECLARE_CLASS(cls, POrdinalDictionary<K>) \
01186   protected: \
01187     cls(int dummy, const cls * c) \
01188       : cls##_PTemplate(dummy, c) { } \
01189   public: \
01190     cls() \
01191       : cls##_PTemplate() { } \
01192     virtual PObject * Clone() const \
01193       { return PNEW cls(0, this); } \
01194 
01195 
01196 #endif // PTLIB_DICT_H
01197 
01198 // End Of File ///////////////////////////////////////////////////////////////

Generated on Thu May 27 01:49:40 2010 for PTLib by  doxygen 1.4.7