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 ///////////////////////////////////////////////////////////////

Generated on Fri Feb 15 20:58:31 2013 for PTLib by  doxygen 1.4.7