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: 20385 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-06-04 10:40:38 +0000 (Wed, 04 Jun 2008) $
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, 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:
00786     virtual PINDEX Append(
00787       PObject * obj   // New object to place into the collection.
00788     );
00789     /* This function is meaningless and will assert.
00790 
00791        @return
00792        Always zero.
00793      */
00794 
00795     virtual PBoolean Remove(
00796       const PObject * obj   // Existing object to remove from the collection.
00797     );
00798     /* Remove the object from the collection. If the AllowDeleteObjects option
00799        is set then the object is also deleted.
00800 
00801        Note that the comparison for searching for the object in collection is
00802        made by pointer, not by value. Thus the parameter must point to the
00803        same instance of the object that is in the collection.
00804 
00805        @return
00806        PTrue if the object was in the collection.
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 // #ifndef __DICT_H__
01196 
01197 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Feb 23 01:57:54 2009 for PTLib by  doxygen 1.5.1