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: 21788 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-12-11 23:42:13 -0600 (Thu, 11 Dec 2008) $
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, #EqualTo for same,
00078        #LessThan for \p obj logically less than the
00079        object and #GreaterThan 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 
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, PHashTableElement * & lastElement);
00159     PHashTableElement * GetElementAt(const PObject & key);
00160     PINDEX GetElementsIndex(const PObject*obj,PBoolean byVal,PBoolean keys) const;
00161 
00162     PBoolean deleteKeys;
00163 
00164   typedef PHashTableElement Element;
00165   friend class PHashTable;
00166   friend class PAbstractSet;
00167 };
00168 
00169 
00180 class PHashTable : public PCollection
00181 {
00182   PCONTAINERINFO(PHashTable, PCollection);
00183 
00184   public:
00187 
00188     PHashTable();
00190 
00202     virtual Comparison Compare(
00203       const PObject & obj   
00204     ) const;
00206 
00207 
00208   protected:
00218     virtual PBoolean SetSize(
00219       PINDEX newSize  
00220     );
00222 
00223 
00234     PINLINE PBoolean AbstractContains(
00235       const PObject & key   
00236     ) const;
00237 
00252     virtual const PObject & AbstractGetKeyAt(
00253       PINDEX index  
00254     ) const;
00255 
00270     virtual PObject & AbstractGetDataAt(
00271       PINDEX index  
00272     ) const;
00274 
00275     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
00276     typedef PHashTableElement Element;
00277     typedef PHashTableInfo Table;
00278     PHashTableInfo * hashTable;
00279 };
00280 
00281 
00283 
00286 class PAbstractSet : public PHashTable
00287 {
00288   PCONTAINERINFO(PAbstractSet, PHashTable);
00289   public:
00297     PINLINE PAbstractSet();
00299 
00310     virtual PINDEX Append(
00311       PObject * obj   
00312     );
00313 
00326     virtual PINDEX Insert(
00327       const PObject & before,   
00328       PObject * obj             
00329     );
00330 
00343     virtual PINDEX InsertAt(
00344       PINDEX index,   
00345       PObject * obj   
00346     );
00347 
00358     virtual PBoolean Remove(
00359       const PObject * obj   
00360     );
00361 
00368     virtual PObject * RemoveAt(
00369       PINDEX index   
00370     );
00371 
00377     virtual PObject * GetAt(
00378       PINDEX index  
00379     ) const;
00380 
00393     virtual PBoolean SetAt(
00394       PINDEX index,   
00395       PObject * val   
00396     );
00397 
00409     virtual PINDEX GetObjectsIndex(
00410       const PObject * obj   
00411     ) const;
00412 
00421     virtual PINDEX GetValuesIndex(
00422       const PObject & obj   
00423     ) const;
00425 };
00426 
00427 
00438 template <class T> class PSet : public PAbstractSet
00439 {
00440   PCLASSINFO(PSet, PAbstractSet);
00441 
00442   public:
00452     inline PSet(PBoolean initialDeleteObjects = PFalse)
00453       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
00455 
00461     virtual PObject * Clone() const
00462       { return PNEW PSet(0, this); }
00464 
00476     void Include(
00477       const T * obj   // New object to include in the set.
00478     ) { Append((PObject *)obj); }
00479 
00487     PSet & operator+=(
00488       const T & obj   // New object to include in the set.
00489     ) { Append(obj.Clone()); return *this; }
00490 
00498     void Exclude(
00499       const T * obj   // New object to exclude in the set.
00500     ) { Remove(obj); }
00501 
00509     PSet & operator-=(
00510       const T & obj   // New object to exclude in the set.
00511     ) { RemoveAt(GetValuesIndex(obj)); return *this; }
00512 
00521     PBoolean Contains(
00522       const T & key  
00523     ) const { return AbstractContains(key); }
00524 
00533     PBoolean operator[](
00534       const T & key  
00535     ) const { return AbstractContains(key); }
00536 
00548     virtual const T & GetKeyAt(
00549       PINDEX index    
00550     ) const
00551       { return (const T &)AbstractGetKeyAt(index); }
00553 
00554 
00555   protected:
00556     PSet(int dummy, const PSet * c)
00557       : PAbstractSet(dummy, c)
00558       { reference->deleteObjects = c->reference->deleteObjects; }
00559 };
00560 
00561 
00573 #define PSET(cls, T) typedef PSet<T> cls
00574 
00575 
00587 #define PDECLARE_SET(cls, T, initDelObj) \
00588   PSET(cls##_PTemplate, T); \
00589   PDECLARE_CLASS(cls, cls##_PTemplate) \
00590   protected: \
00591     cls(int dummy, const cls * c) \
00592       : cls##_PTemplate(dummy, c) { } \
00593   public: \
00594     cls(PBoolean initialDeleteObjects = initDelObj) \
00595       : cls##_PTemplate(initialDeleteObjects) { } \
00596     virtual PObject * Clone() const \
00597       { return PNEW cls(0, this); } \
00598 
00599 
00600 
00601 PSET(POrdinalSet, POrdinalKey);
00602 
00603 
00605 
00608 class PAbstractDictionary : public PHashTable
00609 {
00610   PCLASSINFO(PAbstractDictionary, PHashTable);
00611   public:
00619     PINLINE PAbstractDictionary();
00621 
00630     virtual void PrintOn(
00631       ostream &strm   
00632     ) const;
00634 
00645     virtual PINDEX Insert(
00646       const PObject & key,   
00647       PObject * obj          
00648     );
00649 
00656     virtual PINDEX InsertAt(
00657       PINDEX index,   
00658       PObject * obj   
00659     );
00660 
00670     virtual PObject * RemoveAt(
00671       PINDEX index   
00672     );
00673 
00682     virtual PBoolean SetAt(
00683       PINDEX index,   
00684       PObject * val   
00685     );
00686 
00694     virtual PObject * GetAt(
00695       PINDEX index  
00696     ) const;
00697 
00709     virtual PINDEX GetObjectsIndex(
00710       const PObject * obj  
00711     ) const;
00712 
00721     virtual PINDEX GetValuesIndex(
00722       const PObject & obj  
00723     ) const;
00725 
00726 
00737     virtual PBoolean SetDataAt(
00738       PINDEX index,   
00739       PObject * obj   
00740     );
00741 
00753     virtual PBoolean AbstractSetAt(
00754       const PObject & key,  
00755       PObject * obj         
00756     );
00757 
00767     virtual PObject & GetRefAt(
00768       const PObject & key   
00769     ) const;
00770 
00777     virtual PObject * AbstractGetAt(
00778       const PObject & key   
00779     ) const;
00781 
00782   protected:
00783     PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
00784 
00785   private:
00791     virtual PINDEX Append(
00792       PObject * obj   
00793     );
00794 
00805     virtual PBoolean Remove(
00806       const PObject * obj   
00807     );
00808 
00809 };
00810 
00811 
00819 template <class K, class D> class PDictionary : public PAbstractDictionary
00820 {
00821   PCLASSINFO(PDictionary, PAbstractDictionary);
00822 
00823   public:
00832     PDictionary()
00833       : PAbstractDictionary() { }
00835 
00842     virtual PObject * Clone() const
00843       { return PNEW PDictionary(0, this); }
00845 
00858     D & operator[](
00859       const K & key   
00860     ) const
00861       { return (D &)GetRefAt(key); }
00862 
00871     PBoolean Contains(
00872       const K & key   
00873     ) const { return AbstractContains(key); }
00874 
00886     virtual D * RemoveAt(
00887       const K & key   
00888     ) {
00889         D * obj = GetAt(key); AbstractSetAt(key, NULL);
00890         return reference->deleteObjects ? (obj ? (D *)-1 : NULL) : obj;
00891       }
00892 
00904     virtual PBoolean SetAt(
00905       const K & key,  // Key for position in dictionary to add object.
00906       D * obj         // New object to put into the dictionary.
00907     ) { return AbstractSetAt(key, obj); }
00908 
00915     virtual D * GetAt(
00916       const K & key   // Key for position in dictionary to get object.
00917     ) const { return (D *)AbstractGetAt(key); }
00918 
00930     const K & GetKeyAt(
00931       PINDEX index  
00932     ) const
00933       { return (const K &)AbstractGetKeyAt(index); }
00934 
00946     D & GetDataAt(
00947       PINDEX index  
00948     ) const
00949       { return (D &)AbstractGetDataAt(index); }
00951 
00952     typedef std::pair<K, D *> value_type;
00953 
00954   protected:
00955     PDictionary(int dummy, const PDictionary * c)
00956       : PAbstractDictionary(dummy, c) { }
00957 };
00958 
00959 
00972 #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
00973 
00974 
00987 #define PDECLARE_DICTIONARY(cls, K, D) \
00988   PDICTIONARY(cls##_PTemplate, K, D); \
00989   PDECLARE_CLASS(cls, cls##_PTemplate) \
00990   protected: \
00991     cls(int dummy, const cls * c) \
00992       : cls##_PTemplate(dummy, c) { } \
00993   public: \
00994     cls() \
00995       : cls##_PTemplate() { } \
00996     virtual PObject * Clone() const \
00997       { return PNEW cls(0, this); } \
00998 
00999 
01007 template <class K> class POrdinalDictionary : public PAbstractDictionary
01008 {
01009   PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
01010 
01011   public:
01020     POrdinalDictionary()
01021       : PAbstractDictionary() { }
01023 
01030     virtual PObject * Clone() const
01031       { return PNEW POrdinalDictionary(0, this); }
01033 
01046     PINDEX operator[](
01047       const K & key   // Key to look for in the dictionary.
01048     ) const
01049       { return (POrdinalKey &)GetRefAt(key); }
01050 
01059     PBoolean Contains(
01060       const K & key   
01061     ) const { return AbstractContains(key); }
01062 
01063     virtual POrdinalKey * GetAt(
01064       const K & key   
01065     ) const { return (POrdinalKey *)AbstractGetAt(key); }
01066     /* Get the object at the specified key position. If the key was not in the
01067        collection then NULL is returned.
01068 
01069        @return
01070        pointer to object at the specified key.
01071      */
01072 
01081     virtual PBoolean SetDataAt(
01082       PINDEX index,   
01083       PINDEX ordinal  
01084       ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
01085 
01097     virtual PBoolean SetAt(
01098       const K & key,  
01099       PINDEX ordinal  
01100     ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
01101 
01110     virtual PINDEX RemoveAt(
01111       const K & key   
01112     ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
01113 
01125     const K & GetKeyAt(
01126       PINDEX index  
01127     ) const
01128       { return (const K &)AbstractGetKeyAt(index); }
01129 
01141     PINDEX GetDataAt(
01142       PINDEX index  
01143     ) const
01144       { return (POrdinalKey &)AbstractGetDataAt(index); }
01146 
01147   protected:
01148     POrdinalDictionary(int dummy, const POrdinalDictionary * c)
01149       : PAbstractDictionary(dummy, c) { }
01150 };
01151 
01152 
01165 #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
01166 
01167 
01182 #define PDECLARE_ORDINAL_DICTIONARY(cls, K) \
01183   PORDINAL_DICTIONARY(cls##_PTemplate, K); \
01184   PDECLARE_CLASS(cls, POrdinalDictionary<K>) \
01185   protected: \
01186     cls(int dummy, const cls * c) \
01187       : cls##_PTemplate(dummy, c) { } \
01188   public: \
01189     cls() \
01190       : cls##_PTemplate() { } \
01191     virtual PObject * Clone() const \
01192       { return PNEW cls(0, this); } \
01193 
01194 
01195 #endif // PTLIB_DICT_H
01196 
01197 // End Of File ///////////////////////////////////////////////////////////////

Generated on Thu May 27 01:36:47 2010 for PTLib by  doxygen 1.4.7