dict.h
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:45k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * dict.h
  3.  *
  4.  * Dictionary (hash table) Container classes.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: dict.h,v $
  30.  * Revision 1.25  1999/11/30 00:22:54  robertj
  31.  * Updated documentation for doc++
  32.  *
  33.  * Revision 1.24  1999/08/22 12:13:43  robertj
  34.  * Fixed warning when using inlines on older GNU compiler
  35.  *
  36.  * Revision 1.23  1999/03/09 02:59:49  robertj
  37.  * Changed comments to doc++ compatible documentation.
  38.  *
  39.  * Revision 1.22  1999/02/16 08:07:11  robertj
  40.  * MSVC 6.0 compatibility changes.
  41.  *
  42.  * Revision 1.21  1998/09/23 06:20:27  robertj
  43.  * Added open source copyright license.
  44.  *
  45.  * Revision 1.20  1998/01/05 10:39:34  robertj
  46.  * Fixed "typesafe" templates/macros for dictionaries, especially on GNU.
  47.  *
  48.  * Revision 1.19  1997/12/11 10:27:16  robertj
  49.  * Added type correct Contains() function to dictionaries.
  50.  *
  51.  * Revision 1.18  1997/07/08 13:15:05  robertj
  52.  * DLL support.
  53.  *
  54.  * Revision 1.17  1997/06/08 04:49:11  robertj
  55.  * Fixed non-template class descendent order.
  56.  *
  57.  * Revision 1.16  1996/08/17 10:00:22  robertj
  58.  * Changes for Windows DLL support.
  59.  *
  60.  * Revision 1.15  1996/03/31 08:44:10  robertj
  61.  * Added RemoveAt() function to remove entries from dictionaries.
  62.  *
  63.  * Revision 1.14  1996/02/08 11:50:01  robertj
  64.  * Moved Contains function from PSet to PHashTable so available for dictionaries.
  65.  * Added print for dictionaries key=datan.
  66.  * Added GetAt(PINDEX) to template classes to make identical to macro.
  67.  *
  68.  * Revision 1.13  1996/02/03 11:00:28  robertj
  69.  * Temporary removal of SetAt() and GetAt() functions in dictionary macro.
  70.  *
  71.  * Revision 1.12  1996/01/24 14:43:11  robertj
  72.  * Added initialisers to string dictionaries.
  73.  *
  74.  * Revision 1.11  1996/01/23 13:11:12  robertj
  75.  * Mac Metrowerks compiler support.
  76.  *
  77.  * Revision 1.10  1995/06/17 11:12:29  robertj
  78.  * Documentation update.
  79.  *
  80.  * Revision 1.9  1995/06/04 08:45:57  robertj
  81.  * Better C++ compatibility (with BC++)
  82.  *
  83.  * Revision 1.8  1995/03/14 12:41:19  robertj
  84.  * Updated documentation to use HTML codes.
  85.  *
  86.  * Revision 1.7  1995/02/22  10:50:29  robertj
  87.  * Changes required for compiling release (optimised) version.
  88.  *
  89.  * Revision 1.6  1995/02/11  04:10:35  robertj
  90.  * Fixed dictionary MACRO for templates.
  91.  *
  92.  * Revision 1.5  1995/02/05  00:48:03  robertj
  93.  * Fixed template version.
  94.  *
  95.  * Revision 1.4  1995/01/09  12:35:31  robertj
  96.  * Removed unnecesary return value from I/O functions.
  97.  * Changes due to Mac port.
  98.  *
  99.  * Revision 1.3  1994/12/21  11:52:51  robertj
  100.  * Documentation and variable normalisation.
  101.  *
  102.  * Revision 1.2  1994/12/17  01:36:57  robertj
  103.  * Fixed memory leak in PStringSet
  104.  *
  105.  * Revision 1.1  1994/12/12  09:59:32  robertj
  106.  * Initial revision
  107.  *
  108.  */
  109. #ifdef __GNUC__
  110. #pragma interface
  111. #endif
  112. ///////////////////////////////////////////////////////////////////////////////
  113. // PDictionary classes
  114. /**This class is used when an ordinal index value is the key for #PSet#
  115.    and #PDictionary# classes.
  116.  */
  117. class POrdinalKey : public PObject
  118. {
  119.   PCLASSINFO(POrdinalKey, PObject);
  120.   public:
  121.   /**@name Construction */
  122.   //@{
  123.     /** Create a new key for ordinal index values.
  124.      */
  125.     PINLINE POrdinalKey(
  126.       PINDEX newKey   /// Ordinal index value to use as a key.
  127.     );
  128.   //@}
  129.   /**@name Overrides from class PObject */
  130.   //@{
  131.     /// Create a duplicate of the POrdinalKey.
  132.     virtual PObject * Clone() const;
  133.     /* Get the relative rank of the ordinal index. This is a simpel comparison
  134.        of the objects PINDEX values.
  135.        @return
  136.        comparison of the two objects, #EqualTo# for same,
  137.        #LessThan# for #obj# logically less than the
  138.        object and #GreaterThan# for #obj# logically
  139.        greater than the object.
  140.      */
  141.     virtual Comparison Compare(const PObject & obj) const;
  142.     /**This function calculates a hash table index value for the implementation
  143.        of #PSet# and #PDictionary# classes.
  144.        @return
  145.        hash table bucket number.
  146.      */
  147.     virtual PINDEX HashFunction() const;
  148.     /**Output the ordinal index to the specified stream. This is identical to
  149.        outputting the PINDEX, ie integer, value.
  150.        @return
  151.        stream that the index was output to.
  152.      */
  153.     virtual void PrintOn(ostream & strm) const;
  154.   //@}
  155.   /**@name New functions for class */
  156.   //@{
  157.     /** Operator so that a POrdinalKey can be used as a PINDEX value.
  158.      */
  159.     PINLINE operator PINDEX() const;
  160.   //@}
  161.   private:
  162.     PINDEX theKey;
  163. };
  164. //////////////////////////////////////////////////////////////////////////////
  165. /**The hash table class is the basis for implementing the #PSet# and
  166.    #PDictionary# classes.
  167.    The hash table allows for very fast searches for an object based on a "hash
  168.    function". This function yields an index into an array which is directly
  169.    looked up to locate the object. When two key values have the same hash
  170.    function value, then a linear search of a linked list is made to locate
  171.    the object. Thus the efficiency of the hash table is highly dependent on the
  172.    quality of the hash function for the data being used as keys.
  173.  */
  174. class PHashTable : public PCollection
  175. {
  176.   PCONTAINERINFO(PHashTable, PCollection);
  177.   public:
  178.   /**@name Construction */
  179.   //@{
  180.     /// Create a new, empty, hash table.
  181.     PHashTable();
  182.   //@}
  183.   /**@name Overrides from class PObject */
  184.   //@{
  185.     /**Get the relative rank of the two hash tables. Actally ranking hash
  186.        tables is really meaningless, so only equality is returned by the
  187.        comparison. Equality is only achieved if the two instances reference the
  188.        same hash table.
  189.        @return
  190.        comparison of the two objects, #EqualTo# if the same
  191.        reference and #GreaterThan# if not.
  192.      */
  193.     virtual Comparison Compare(
  194.       const PObject & obj   /// Other PHashTable to compare against.
  195.     ) const;
  196.   //@}
  197.   protected:
  198.   /**@name Overrides from class PContainer */
  199.   //@{
  200.     /**This function is meaningless for hash table. The size of the collection
  201.        is determined by the addition and removal of objects. The size cannot be
  202.        set in any other way.
  203.        @return
  204.        Always TRUE.
  205.      */
  206.     virtual BOOL SetSize(
  207.       PINDEX newSize  /// New size for the hash table, this is ignored.
  208.     );
  209.   //@}
  210.   /**@name New functions for class */
  211.   //@{
  212.     /**Determine if the value of the object is contained in the hash table. The
  213.        object values are compared, not the pointers.  So the objects in the
  214.        collection must correctly implement the #PObject::Compare()#
  215.        function. The hash table is used to locate the entry.
  216.        @return
  217.        TRUE if the object value is in the set.
  218.      */
  219.     PINLINE BOOL AbstractContains(
  220.       const PObject & key   /// Key to look for in the set.
  221.     ) const;
  222.     /**Get the key in the hash table at the ordinal index position.
  223.     
  224.        The ordinal position in the hash table is determined by the hash values
  225.        of the keys and the order of insertion.
  226.        The last key/data pair is remembered by the class so that subseqent
  227.        access is very fast.
  228.        This function is primarily used by the descendent template classes, or
  229.        macro, with the appropriate type conversion.
  230.        @return
  231.        reference to key at the index position.
  232.      */
  233.     virtual const PObject & AbstractGetKeyAt(
  234.       PINDEX index  /// Ordinal position in the hash table.
  235.     ) const;
  236.     /**Get the data in the hash table at the ordinal index position.
  237.     
  238.        The ordinal position in the hash table is determined by the hash values
  239.        of the keys and the order of insertion.
  240.        The last key/data pair is remembered by the class so that subseqent
  241.        access is very fast.
  242.        This function is primarily used by the descendent template classes, or
  243.        macro, with the appropriate type conversion.
  244.        @return
  245.        reference to key at the index position.
  246.      */
  247.     virtual PObject & AbstractGetDataAt(
  248.       PINDEX index  /// Ordinal position in the hash table.
  249.     ) const;
  250.   //@}
  251.     // Member variables
  252.     class Element {
  253.       public:
  254.         PObject * key;
  255.         PObject * data;
  256.         Element * next;
  257.         Element * prev;
  258.     };
  259.     PDECLARE_BASEARRAY(Table, Element *)
  260. #ifdef DOC_PLUS_PLUS
  261.     {
  262. #endif
  263.       public:
  264.         virtual ~Table() { Destruct(); }
  265.         virtual void DestroyContents();
  266.         PINDEX AppendElement(PObject * key, PObject * data);
  267.         PObject * RemoveElement(const PObject & key);
  268.         BOOL SetLastElementAt(PINDEX index);
  269.         Element * GetElementAt(const PObject & key);
  270.         PINDEX GetElementsIndex(const PObject*obj,BOOL byVal,BOOL keys) const;
  271.         PINDEX    lastIndex;
  272.         PINDEX    lastBucket;
  273.         Element * lastElement;
  274.         BOOL deleteKeys;
  275.       friend class PHashTable;
  276.       friend class PAbstractSet;
  277.     };
  278.     friend class Table;
  279.     Table * hashTable;
  280. };
  281. //////////////////////////////////////////////////////////////////////////////
  282. /** Abstract set of PObjects.
  283.  */
  284. class PAbstractSet : public PHashTable
  285. {
  286.   PCONTAINERINFO(PAbstractSet, PHashTable);
  287.   public:
  288.   /**@name Construction */
  289.   //@{
  290.     /**Create a new, empty, set.
  291.        Note that by default, objects placed into the list will be deleted when
  292.        removed or when all references to the list are destroyed.
  293.      */
  294.     PINLINE PAbstractSet();
  295.   //@}
  296.   /**@name Overrides from class PCollection */
  297.   //@{
  298.     /**Add a new object to the collection. If the objects value is already in
  299.        the set then the object is {bf not} included. If the
  300.        #AllowDeleteObjects# option is set then the #obj# parameter
  301.        is also deleted.
  302.        @return
  303.        hash function value of the newly added object.
  304.      */
  305.     virtual PINDEX Append(
  306.       PObject * obj   /// New object to place into the collection.
  307.     );
  308.     /**Add a new object to the collection. If the objects value is already in
  309.        the set then the object is {bf not} included. If the
  310.        AllowDeleteObjects option is set then the #obj# parameter is
  311.        also deleted.
  312.        
  313.        The object is always placed in the an ordinal position dependent on its
  314.        hash function. It is not placed at the specified position. The
  315.        #before# parameter is ignored.
  316.        @return
  317.        hash function value of the newly added object.
  318.      */
  319.     virtual PINDEX Insert(
  320.       const PObject & before,   /// Object value to insert before.
  321.       PObject * obj             /// New object to place into the collection.
  322.     );
  323.     /**Add a new object to the collection. If the objects value is already in
  324.        the set then the object is {bf not} included. If the
  325.        AllowDeleteObjects option is set then the #obj# parameter is
  326.        also deleted.
  327.        
  328.        The object is always placed in the an ordinal position dependent on its
  329.        hash function. It is not placed at the specified position. The
  330.        #index# parameter is ignored.
  331.        @return
  332.        hash function value of the newly added object.
  333.      */
  334.     virtual PINDEX InsertAt(
  335.       PINDEX index,   /// Index position in collection to place the object.
  336.       PObject * obj   /// New object to place into the collection.
  337.     );
  338.     /**Remove the object from the collection. If the AllowDeleteObjects option
  339.        is set then the object is also deleted.
  340.        Note that the comparison for searching for the object in collection is
  341.        made by pointer, not by value. Thus the parameter must point to the
  342.        same instance of the object that is in the collection.
  343.        @return
  344.        TRUE if the object was in the collection.
  345.      */
  346.     virtual BOOL Remove(
  347.       const PObject * obj   /// Existing object to remove from the collection.
  348.     );
  349.     /**This function is the same as PHashTable::AbstractGetKeyAt().
  350.        @return
  351.        Always NULL.
  352.      */
  353.     virtual PObject * GetAt(
  354.       PINDEX index  /// Index position in the collection of the object.
  355.     ) const;
  356.     /**Add a new object to the collection. If the objects value is already in
  357.        the set then the object is {bf not} included. If the
  358.        AllowDeleteObjects option is set then the #obj# parameter is
  359.        also deleted.
  360.        The object is always placed in the an ordinal position dependent on its
  361.        hash function. It is not placed at the specified position. The
  362.        #index# parameter is ignored.
  363.        @return
  364.        TRUE if the object was successfully added.
  365.      */
  366.     virtual BOOL SetAt(
  367.       PINDEX index,   /// Index position in collection to set.
  368.       PObject * val   /// New value to place into the collection.
  369.     );
  370.     /**Search the collection for the specific instance of the object. The
  371.        object pointers are compared, not the values. The hash table is used
  372.        to locate the entry.
  373.        Note that that will require value comparisons to be made to find the
  374.        equivalent entry and then a final check is made with the pointers to
  375.        see if they are the same instance.
  376.        @return
  377.        ordinal index position of the object, or P_MAX_INDEX.
  378.      */
  379.     virtual PINDEX GetObjectsIndex(
  380.       const PObject * obj   /// Object to find.
  381.     ) const;
  382.     /**Search the collection for the specified value of the object. The object
  383.        values are compared, not the pointers.  So the objects in the
  384.        collection must correctly implement the #PObject::Compare()#
  385.        function. The hash table is used to locate the entry.
  386.        @return
  387.        ordinal index position of the object, or P_MAX_INDEX.
  388.      */
  389.     virtual PINDEX GetValuesIndex(
  390.       const PObject & obj   /// Object to find equal value.
  391.     ) const;
  392.   //@}
  393.   private:
  394.     virtual PObject * RemoveAt(
  395.       PINDEX index   // Index position in collection to place the object.
  396.     );
  397.     /* This function is meaningless and will assert if executed.
  398.        @return
  399.        Always NULL.
  400.      */
  401. };
  402. #ifdef PHAS_TEMPLATES
  403. /**This template class maps the PAbstractSet to a specific object type. The
  404.    functions in this class primarily do all the appropriate casting of types.
  405.    By default, objects placed into the set will {bf not} be deleted when
  406.    removed or when all references to the set are destroyed. This is different
  407.    from the default on most collection classes.
  408.    Note that if templates are not used the #PDECLARE_SET# macro will
  409.    simulate the template instantiation.
  410.  */
  411. template <class T> class PSet : public PAbstractSet
  412. {
  413.   PCLASSINFO(PSet, PAbstractSet);
  414.   public:
  415.   /**@name Construction */
  416.   //@{
  417.     /**Create a new, empty, dictionary. The parameter indicates whether to
  418.        delete objects that are removed from the set.
  419.        Note that by default, objects placed into the set will {bf not} be
  420.        deleted when removed or when all references to the set are destroyed.
  421.        This is different from the default on most collection classes.
  422.      */
  423.     inline PSet(BOOL initialDeleteObjects = FALSE)
  424.       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); }
  425.   //@}
  426.   /**@name Overrides from class PObject */
  427.   //@{
  428.     /**Make a complete duplicate of the set. Note that all objects in the
  429.        array are also cloned, so this will make a complete copy of the set.
  430.      */
  431.     virtual PObject * Clone() const
  432.       { return PNEW PSet(0, this); }
  433.   //@}
  434.   /**@name New functions for class */
  435.   //@{
  436.     /**Include the spcified object into the set. If the objects value is
  437.        already in the set then the object is {bf not} included. If the
  438.        AllowDeleteObjects option is set then the #obj# parameter is
  439.        also deleted.
  440.        The object values are compared, not the pointers.  So the objects in
  441.        the collection must correctly implement the #PObject::Compare()#
  442.        function. The hash table is used to locate the entry.
  443.      */
  444.     void Include(
  445.       const T * obj   // New object to include in the set.
  446.     ) { Append((PObject *)obj); }
  447.     /**Remove the object from the set. If the AllowDeleteObjects option is set
  448.        then the object is also deleted.
  449.        The object values are compared, not the pointers.  So the objects in
  450.        the collection must correctly implement the #PObject::Compare()#
  451.        function. The hash table is used to locate the entry.
  452.      */
  453.     void Exclude(
  454.       const T * obj   // New object to exclude in the set.
  455.     ) { Remove(obj); }
  456.     /**Determine if the value of the object is contained in the set. The
  457.        object values are compared, not the pointers.  So the objects in the
  458.        collection must correctly implement the #PObject::Compare()#
  459.        function. The hash table is used to locate the entry.
  460.        @return
  461.        TRUE if the object value is in the set.
  462.      */
  463.     BOOL operator[](
  464.       const T & key  /// Key to look for in the set.
  465.     ) { return AbstractContains(key); }
  466.     /**Determine if the value of the object is contained in the set. The
  467.        object values are compared, not the pointers.  So the objects in the
  468.        collection must correctly implement the #PObject::Compare()#
  469.        function. The hash table is used to locate the entry.
  470.        @return
  471.        TRUE if the object value is in the set.
  472.      */
  473.     BOOL Contains(
  474.       const T & key  /// Key to look for in the set.
  475.     ) { return AbstractContains(key); }
  476.     /**Get the key in the set at the ordinal index position.
  477.     
  478.        The ordinal position in the set is determined by the hash values of the
  479.        keys and the order of insertion.
  480.        The last key/data pair is remembered by the class so that subseqent
  481.        access is very fast.
  482.        @return
  483.        reference to key at the index position.
  484.      */
  485.     virtual const T & GetKeyAt(
  486.       PINDEX index    /// Index of value to get.
  487.     ) const
  488.       { return (const T &)AbstractGetKeyAt(index); }
  489.   //@}
  490.   protected:
  491.     PSet(int dummy, const PSet * c)
  492.       : PAbstractSet(dummy, c)
  493.       { reference->deleteObjects = c->reference->deleteObjects; }
  494. };
  495. /**Declare set class.
  496.    This macro is used to declare a descendent of PAbstractSet class,
  497.    customised for a particular object type {bf T}. This macro closes the
  498.    class declaration off so no additional members can be added.
  499.    If the compilation is using templates then this macro produces a typedef
  500.    of the #PSet# template class.
  501.    See the #PSet# class and #PDECLARE_SET# macro for more
  502.    information.
  503.  */
  504. #define PSET(cls, T) typedef PSet<T> cls
  505. /**Begin declaration of a set class.
  506.    This macro is used to declare a descendent of PAbstractSet class,
  507.    customised for a particular object type {bf T}.
  508.    If the compilation is using templates then this macro produces a descendent
  509.    of the #PSet# template class. If templates are not being used then the
  510.    macro defines a set of inline functions to do all casting of types. The
  511.    resultant classes have an identical set of functions in either case.
  512.    See the #PSet# and #PAbstractSet# classes for more information.
  513.  */
  514. #define PDECLARE_SET(cls, T, initDelObj) 
  515.   PSET(cls##_PTemplate, T); 
  516.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  517.   protected: 
  518.     cls(int dummy, const cls * c) 
  519.       : cls##_PTemplate(dummy, c) { } 
  520.   public: 
  521.     cls(BOOL initialDeleteObjects = initDelObj) 
  522.       : cls##_PTemplate(initialDeleteObjects) { } 
  523.     virtual PObject * Clone() const 
  524.       { return PNEW cls(0, this); } 
  525. #else // PHAS_TEMPLATES
  526. #define PSET(cls, K) 
  527.   class cls : public PAbstractSet { 
  528.   PCLASSINFO(cls, PAbstractSet); 
  529.   protected: 
  530.     inline cls(int dummy, const cls * c) 
  531.       : PAbstractSet(dummy, c) 
  532.       { reference->deleteObjects = c->reference->deleteObjects; } 
  533.   public: 
  534.     inline cls(BOOL initialDeleteObjects = FALSE) 
  535.       : PAbstractSet() { AllowDeleteObjects(initialDeleteObjects); } 
  536.     inline virtual PObject * Clone() const 
  537.       { return PNEW cls(0, this); } 
  538.     inline void Include(const PObject * key) 
  539.       { Append((PObject *)key); } 
  540.     inline void Exclude(const PObject * key) 
  541.       { Remove(key); } 
  542.     inline BOOL operator[](const K & key) 
  543.         { return AbstractContains(key); } 
  544.     inline BOOL Contains(const K & key) 
  545.         { return AbstractContains(key); } 
  546.     virtual const K & GetKeyAt(PINDEX index) const 
  547.       { return (const K &)AbstractGetKeyAt(index); } 
  548.   }
  549. #define PDECLARE_SET(cls, K, initDelObj) 
  550.  PSET(cls##_PTemplate, K); 
  551.  PDECLARE_CLASS(cls, cls##_PTemplate) 
  552.   protected: 
  553.     inline cls(int dummy, const cls * c) 
  554.       : cls##_PTemplate(dummy, c) { } 
  555.   public: 
  556.     inline cls(BOOL initialDeleteObjects = initDelObj) 
  557.       : cls##_PTemplate() { AllowDeleteObjects(initialDeleteObjects); } 
  558.     inline virtual PObject * Clone() const 
  559.       { return PNEW cls(0, this); } 
  560. #endif  // PHAS_TEMPLATES
  561. //////////////////////////////////////////////////////////////////////////////
  562. /**An abstract dictionary container.
  563. */
  564. class PAbstractDictionary : public PHashTable
  565. {
  566.   PCLASSINFO(PAbstractDictionary, PHashTable);
  567.   public:
  568.   /**@name Construction */
  569.   //@{
  570.     /**Create a new, empty, dictionary.
  571.        Note that by default, objects placed into the dictionary will be deleted
  572.        when removed or when all references to the dictionary are destroyed.
  573.      */
  574.     PINLINE PAbstractDictionary();
  575.   //@}
  576.   /**@name Overrides from class PObject */
  577.   //@{
  578.     /**Output the contents of the object to the stream. The exact output is
  579.        dependent on the exact semantics of the descendent class. This is
  580.        primarily used by the standard ##operator<<## function.
  581.        The default behaviour is to print the class name.
  582.      */
  583.     virtual void PrintOn(
  584.       ostream &strm   /// Stream to print the object into.
  585.     ) const;
  586.   //@}
  587.   /**@name Overrides from class PCollection */
  588.   //@{
  589.     /**Insert a new object into the dictionary. The semantics of this function
  590.        is different from that of the #PCollection# class. This function is
  591.        exactly equivalent to the SetAt() function that sets a data value at
  592.        the key value location.
  593.        @return
  594.        Always zero.
  595.      */
  596.     virtual PINDEX Insert(
  597.       const PObject & key,   /// Object value to use as the key.
  598.       PObject * obj          /// New object to place into the collection.
  599.     );
  600.     /**Insert a new object at the specified index. The index is converted to
  601.        a #POrdinalKey# type before being used in the #SetAt()#
  602.        function.
  603.        @return
  604.        #index# parameter.
  605.      */
  606.     virtual PINDEX InsertAt(
  607.       PINDEX index,   /// Index position in collection to place the object.
  608.       PObject * obj   /// New object to place into the collection.
  609.     );
  610.     /**Remove an object at the specified index. The index is converted to
  611.        a #POrdinalKey# type before being used in the #GetAt()#
  612.        function. The returned pointer is then removed using the #SetAt()#
  613.        function to set that key value to NULL. If the
  614.        #AllowDeleteObjects# option is set then the object is also
  615.        deleted.
  616.        @return
  617.        pointer to the object being removed, or NULL if it was deleted.
  618.      */
  619.     virtual PObject * RemoveAt(
  620.       PINDEX index   /// Index position in collection to place the object.
  621.     );
  622.     /**Set the object at the specified index to the new value. The index is
  623.        converted to a #POrdinalKey# type before being used.This will
  624.        overwrite the existing entry. If the AllowDeleteObjects option is set
  625.        then the old object is also deleted.
  626.        @return
  627.        TRUE if the object was successfully added.
  628.      */
  629.     virtual BOOL SetAt(
  630.       PINDEX index,   /// Index position in collection to set.
  631.       PObject * val   /// New value to place into the collection.
  632.     );
  633.     /**Get the object at the specified index position. The index is converted
  634.        to a #POrdinalKey# type before being used. If the index was not in
  635.        the collection then NULL is returned.
  636.        @return
  637.        pointer to object at the specified index.
  638.      */
  639.     virtual PObject * GetAt(
  640.       PINDEX index  /// Index position in the collection of the object.
  641.     ) const;
  642.     /**Search the collection for the specific instance of the object. The
  643.        object pointers are compared, not the values. The hash table is used
  644.        to locate the entry.
  645.        Note that that will require value comparisons to be made to find the
  646.        equivalent entry and then a final check is made with the pointers to
  647.        see if they are the same instance.
  648.        @return
  649.        ordinal index position of the object, or P_MAX_INDEX.
  650.      */
  651.     virtual PINDEX GetObjectsIndex(
  652.       const PObject * obj  /// Object to find.
  653.     ) const;
  654.     /**Search the collection for the specified value of the object. The object
  655.        values are compared, not the pointers.  So the objects in the
  656.        collection must correctly implement the #PObject::Compare()#
  657.        function. The hash table is used to locate the entry.
  658.        @return
  659.        ordinal index position of the object, or P_MAX_INDEX.
  660.      */
  661.     virtual PINDEX GetValuesIndex(
  662.       const PObject & obj  /// Object to find value of.
  663.     ) const;
  664.   //@}
  665.   /**@name New functions for class */
  666.   //@{
  667.     /**Set the data at the specified ordinal index position in the dictionary.
  668.        The ordinal position in the dictionary is determined by the hash values
  669.        of the keys and the order of insertion.
  670.        @return
  671.        TRUE if the new object could be placed into the dictionary.
  672.      */
  673.     virtual BOOL SetDataAt(
  674.       PINDEX index,   /// Ordinal index in the dictionary.
  675.       PObject * obj   /// New object to put into the dictionary.
  676.     );
  677.     /**Add a new object to the collection. If the objects value is already in
  678.        the dictionary then the object is overrides the previous value. If the
  679.        AllowDeleteObjects option is set then the old object is also deleted.
  680.        The object is placed in the an ordinal position dependent on the keys
  681.        hash function. Subsequent searches use the has function to speed access
  682.        to the data item.
  683.        @return
  684.        TRUE if the object was successfully added.
  685.      */
  686.     virtual BOOL AbstractSetAt(
  687.       const PObject & key,  /// Key for position in dictionary to add object.
  688.       PObject * obj         /// New object to put into the dictionary.
  689.     );
  690.     /**Get the object at the specified key position. If the key was not in the
  691.        collection then this function asserts.
  692.        This function is primarily for use by the #operator[]# function is
  693.        descendent template classes.
  694.        @return
  695.        reference to object at the specified key.
  696.      */
  697.     virtual PObject & GetRefAt(
  698.       const PObject & key   /// Key for position in dictionary to get object.
  699.     ) const;
  700.     /**Get the object at the specified key position. If the key was not in the
  701.        collection then NULL is returned.
  702.        @return
  703.        pointer to object at the specified key.
  704.      */
  705.     virtual PObject * AbstractGetAt(
  706.       const PObject & key   /// Key for position in dictionary to get object.
  707.     ) const;
  708.   //@}
  709.   protected:
  710.     PINLINE PAbstractDictionary(int dummy, const PAbstractDictionary * c);
  711.   private:
  712.     virtual PINDEX Append(
  713.       PObject * obj   // New object to place into the collection.
  714.     );
  715.     /* This function is meaningless and will assert.
  716.        @return
  717.        Always zero.
  718.      */
  719.     virtual BOOL Remove(
  720.       const PObject * obj   // Existing object to remove from the collection.
  721.     );
  722.     /* Remove the object from the collection. If the AllowDeleteObjects option
  723.        is set then the object is also deleted.
  724.        Note that the comparison for searching for the object in collection is
  725.        made by pointer, not by value. Thus the parameter must point to the
  726.        same instance of the object that is in the collection.
  727.        @return
  728.        TRUE if the object was in the collection.
  729.      */
  730. };
  731. #ifdef PHAS_TEMPLATES
  732. /**This template class maps the PAbstractDictionary to a specific key and data
  733.    types. The functions in this class primarily do all the appropriate casting
  734.    of types.
  735.    Note that if templates are not used the #PDECLARE_DICTIONARY# macro
  736.    will simulate the template instantiation.
  737.  */
  738. template <class K, class D> class PDictionary : public PAbstractDictionary
  739. {
  740.   PCLASSINFO(PDictionary, PAbstractDictionary);
  741.   public:
  742.   /**@name Construction */
  743.   //@{
  744.     /**Create a new, empty, dictionary.
  745.        Note that by default, objects placed into the dictionary will be
  746.        deleted when removed or when all references to the dictionary are
  747.        destroyed.
  748.      */
  749.     PDictionary()
  750.       : PAbstractDictionary() { }
  751.   //@}
  752.   /**@name Overrides from class PObject */
  753.   //@{
  754.     /**Make a complete duplicate of the dictionary. Note that all objects in
  755.        the array are also cloned, so this will make a complete copy of the
  756.        dictionary.
  757.      */
  758.     virtual PObject * Clone() const
  759.       { return PNEW PDictionary(0, this); }
  760.   //@}
  761.   /**@name New functions for class */
  762.   //@{
  763.     /**Get the object contained in the dictionary at the #key#
  764.        position. The hash table is used to locate the data quickly via the
  765.        hash function provided by the #key#.
  766.        The last key/data pair is remembered by the class so that subseqent
  767.        access is very fast.
  768.        @return
  769.        reference to the object indexed by the key.
  770.      */
  771.     D & operator[](
  772.       const K & key   /// Key to look for in the dictionary.
  773.     ) const
  774.       { return (D &)GetRefAt(key); }
  775.     /**Determine if the value of the object is contained in the hash table. The
  776.        object values are compared, not the pointers.  So the objects in the
  777.        collection must correctly implement the #PObject::Compare()#
  778.        function. The hash table is used to locate the entry.
  779.        @return
  780.        TRUE if the object value is in the dictionary.
  781.      */
  782.     BOOL Contains(
  783.       const K & key   /// Key to look for in the dictionary.
  784.     ) const { return AbstractContains(key); }
  785.     /**Remove an object at the specified key. The returned pointer is then
  786.        removed using the #SetAt()# function to set that key value to
  787.        NULL. If the #AllowDeleteObjects# option is set then the
  788.        object is also deleted.
  789.        @return
  790.        pointer to the object being removed, or NULL if it was deleted.
  791.      */
  792.     virtual D * RemoveAt(
  793.       const K & key   /// Key for position in dictionary to get object.
  794.     ) { D * obj = GetAt(key); AbstractSetAt(key, NULL); return obj; }
  795.     /**Add a new object to the collection. If the objects value is already in
  796.        the dictionary then the object is overrides the previous value. If the
  797.        AllowDeleteObjects option is set then the old object is also deleted.
  798.        The object is placed in the an ordinal position dependent on the keys
  799.        hash function. Subsequent searches use the has function to speed access
  800.        to the data item.
  801.        @return
  802.        TRUE if the object was successfully added.
  803.      */
  804.     virtual BOOL SetAt(
  805.       const K & key,  // Key for position in dictionary to add object.
  806.       D * obj         // New object to put into the dictionary.
  807.     ) { return AbstractSetAt(key, obj); }
  808.     /**Get the object at the specified key position. If the key was not in the
  809.        collection then NULL is returned.
  810.        @return
  811.        pointer to object at the specified key.
  812.      */
  813.     virtual D * GetAt(
  814.       const K & key   // Key for position in dictionary to get object.
  815.     ) const { return (D *)AbstractGetAt(key); }
  816.     /**Get the key in the dictionary at the ordinal index position.
  817.     
  818.        The ordinal position in the dictionary is determined by the hash values
  819.        of the keys and the order of insertion.
  820.        The last key/data pair is remembered by the class so that subseqent
  821.        access is very fast.
  822.        @return
  823.        reference to key at the index position.
  824.      */
  825.     const K & GetKeyAt(
  826.       PINDEX index  /// Ordinal position in dictionary for key.
  827.     ) const
  828.       { return (const K &)AbstractGetKeyAt(index); }
  829.     /**Get the data in the dictionary at the ordinal index position.
  830.     
  831.        The ordinal position in the dictionary is determined by the hash values
  832.        of the keys and the order of insertion.
  833.        The last key/data pair is remembered by the class so that subseqent
  834.        access is very fast.
  835.        @return
  836.        reference to data at the index position.
  837.      */
  838.     D & GetDataAt(
  839.       PINDEX index  /// Ordinal position in dictionary for data.
  840.     ) const
  841.       { return (D &)AbstractGetDataAt(index); }
  842.   //@}
  843.   protected:
  844.     PDictionary(int dummy, const PDictionary * c)
  845.       : PAbstractDictionary(dummy, c) { }
  846. };
  847. /**Declare a dictionary class.
  848.    This macro is used to declare a descendent of PAbstractDictionary class,
  849.    customised for a particular key type {bf K} and data object type {bf D}.
  850.    This macro closes the class declaration off so no additional members can
  851.    be added.
  852.    If the compilation is using templates then this macro produces a typedef
  853.    of the #PDictionary# template class.
  854.    See the #PDictionary# class and #PDECLARE_DICTIONARY# macro for
  855.    more information.
  856.  */
  857. #define PDICTIONARY(cls, K, D) typedef PDictionary<K, D> cls
  858. /**Begin declaration of dictionary class.
  859.    This macro is used to declare a descendent of PAbstractDictionary class,
  860.    customised for a particular key type {bf K} and data object type {bf D}.
  861.    If the compilation is using templates then this macro produces a descendent
  862.    of the #PDictionary# template class. If templates are not being used
  863.    then the macro defines a set of inline functions to do all casting of types.
  864.    The resultant classes have an identical set of functions in either case.
  865.    See the #PDictionary# and #PAbstractDictionary# classes for more
  866.    information.
  867.  */
  868. #define PDECLARE_DICTIONARY(cls, K, D) 
  869.   PDICTIONARY(cls##_PTemplate, K, D); 
  870.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  871.   protected: 
  872.     cls(int dummy, const cls * c) 
  873.       : cls##_PTemplate(dummy, c) { } 
  874.   public: 
  875.     cls() 
  876.       : cls##_PTemplate() { } 
  877.     virtual PObject * Clone() const 
  878.       { return PNEW cls(0, this); } 
  879. /**This template class maps the #PAbstractDictionary# to a specific key
  880.    type and a #POrdinalKey# data type. The functions in this class
  881.    primarily do all the appropriate casting of types.
  882.    Note that if templates are not used the #PDECLARE_ORDINAL_DICTIONARY#
  883.    macro will simulate the template instantiation.
  884.  */
  885. template <class K> class POrdinalDictionary : public PAbstractDictionary
  886. {
  887.   PCLASSINFO(POrdinalDictionary, PAbstractDictionary);
  888.   public:
  889.   /**@name Construction */
  890.   //@{
  891.     /**Create a new, empty, dictionary.
  892.        Note that by default, objects placed into the dictionary will be
  893.        deleted when removed or when all references to the dictionary are
  894.        destroyed.
  895.      */
  896.     POrdinalDictionary()
  897.       : PAbstractDictionary() { }
  898.   //@}
  899.   /**@name Overrides from class PObject */
  900.   //@{
  901.     /**Make a complete duplicate of the dictionary. Note that all objects in
  902.        the array are also cloned, so this will make a complete copy of the
  903.        dictionary.
  904.      */
  905.     virtual PObject * Clone() const
  906.       { return PNEW POrdinalDictionary(0, this); }
  907.   //@}
  908.   /**@name New functions for class */
  909.   //@{
  910.     /**Get the object contained in the dictionary at the #key#
  911.        position. The hash table is used to locate the data quickly via the
  912.        hash function provided by the key.
  913.        The last key/data pair is remembered by the class so that subseqent
  914.        access is very fast.
  915.        @return
  916.        reference to the object indexed by the key.
  917.      */
  918.     PINDEX operator[](
  919.       const K & key   // Key to look for in the dictionary.
  920.     ) const
  921.       { return (POrdinalKey &)GetRefAt(key); }
  922.     /**Determine if the value of the object is contained in the hash table. The
  923.        object values are compared, not the pointers.  So the objects in the
  924.        collection must correctly implement the #PObject::Compare()#
  925.        function. The hash table is used to locate the entry.
  926.        @return
  927.        TRUE if the object value is in the dictionary.
  928.      */
  929.     BOOL Contains(
  930.       const K & key   /// Key to look for in the dictionary.
  931.     ) const { return AbstractContains(key); }
  932.     virtual POrdinalKey * GetAt(
  933.       const K & key   /// Key for position in dictionary to get object.
  934.     ) const { return (POrdinalKey *)AbstractGetAt(key); }
  935.     /* Get the object at the specified key position. If the key was not in the
  936.        collection then NULL is returned.
  937.        @return
  938.        pointer to object at the specified key.
  939.      */
  940.     /**Set the data at the specified ordinal index position in the dictionary.
  941.        The ordinal position in the dictionary is determined by the hash values
  942.        of the keys and the order of insertion.
  943.        @return
  944.        TRUE if the new object could be placed into the dictionary.
  945.      */
  946.     virtual BOOL SetDataAt(
  947.       PINDEX index,   /// Ordinal index in the dictionary.
  948.       PINDEX ordinal  /// New ordinal value to put into the dictionary.
  949.       ) { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); }
  950.     /**Add a new object to the collection. If the objects value is already in
  951.        the dictionary then the object is overrides the previous value. If the
  952.        AllowDeleteObjects option is set then the old object is also deleted.
  953.        The object is placed in the an ordinal position dependent on the keys
  954.        hash function. Subsequent searches use the has function to speed access
  955.        to the data item.
  956.        @return
  957.        TRUE if the object was successfully added.
  958.      */
  959.     virtual BOOL SetAt(
  960.       const K & key,  /// Key for position in dictionary to add object.
  961.       PINDEX ordinal  /// New ordinal value to put into the dictionary.
  962.     ) { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); }
  963.     /**Remove an object at the specified key. The returned pointer is then
  964.        removed using the #SetAt()# function to set that key value to
  965.        NULL. If the #AllowDeleteObjects# option is set then the
  966.        object is also deleted.
  967.        @return
  968.        pointer to the object being removed, or NULL if it was deleted.
  969.      */
  970.     virtual PINDEX RemoveAt(
  971.       const K & key   /// Key for position in dictionary to get object.
  972.     ) { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; }
  973.     /**Get the key in the dictionary at the ordinal index position.
  974.     
  975.        The ordinal position in the dictionary is determined by the hash values
  976.        of the keys and the order of insertion.
  977.        The last key/data pair is remembered by the class so that subseqent
  978.        access is very fast.
  979.        @return
  980.        reference to key at the index position.
  981.      */
  982.     const K & GetKeyAt(
  983.       PINDEX index  /// Ordinal position in dictionary for key.
  984.     ) const
  985.       { return (const K &)AbstractGetKeyAt(index); }
  986.     /**Get the data in the dictionary at the ordinal index position.
  987.     
  988.        The ordinal position in the dictionary is determined by the hash values
  989.        of the keys and the order of insertion.
  990.        The last key/data pair is remembered by the class so that subseqent
  991.        access is very fast.
  992.        @return
  993.        reference to data at the index position.
  994.      */
  995.     PINDEX GetDataAt(
  996.       PINDEX index  /// Ordinal position in dictionary for data.
  997.     ) const
  998.       { return (POrdinalKey &)AbstractGetDataAt(index); }
  999.   //@}
  1000.   protected:
  1001.     POrdinalDictionary(int dummy, const POrdinalDictionary * c)
  1002.       : PAbstractDictionary(dummy, c) { }
  1003. };
  1004. /**Declare an ordinal dictionary class.
  1005.    This macro is used to declare a descendent of PAbstractDictionary class,
  1006.    customised for a particular key type {bf K} and data object type of
  1007.    #POrdinalKey#. This macro closes the class declaration off so no
  1008.    additional members can be added.
  1009.    If the compilation is using templates then this macro produces a typedef
  1010.    of the #POrdinalDictionary# template class.
  1011.    See the #POrdinalDictionary# class and
  1012.    #PDECLARE_ORDINAL_DICTIONARY# macro for more information.
  1013.  */
  1014. #define PORDINAL_DICTIONARY(cls, K) typedef POrdinalDictionary<K> cls
  1015. /**Begin declaration of an ordinal dictionary class.
  1016.    This macro is used to declare a descendent of PAbstractList class,
  1017.    customised for a particular key type {bf K} and data object type of
  1018.    #POrdinalKey#.
  1019.    If the compilation is using templates then this macro produces a descendent
  1020.    of the #POrdinalDictionary# template class. If templates are not being
  1021.    used then the macro defines a set of inline functions to do all casting of
  1022.    types. The resultant classes have an identical set of functions in either
  1023.    case.
  1024.    See the #POrdinalDictionary# and #PAbstractDictionary# classes
  1025.    for more information.
  1026.  */
  1027. #define PDECLARE_ORDINAL_DICTIONARY(cls, K) 
  1028.   PORDINAL_DICTIONARY(cls##_PTemplate, K); 
  1029.   PDECLARE_CLASS(cls, POrdinalDictionary<K>) 
  1030.   protected: 
  1031.     cls(int dummy, const cls * c) 
  1032.       : cls##_PTemplate(dummy, c) { } 
  1033.   public: 
  1034.     cls() 
  1035.       : cls##_PTemplate() { } 
  1036.     virtual PObject * Clone() const 
  1037.       { return PNEW cls(0, this); } 
  1038. #else // PHAS_TEMPLATES
  1039. #define PDICTIONARY(cls, K, D) 
  1040.   class cls : public PAbstractDictionary { 
  1041.   PCLASSINFO(cls, PAbstractDictionary); 
  1042.   protected: 
  1043.     inline cls(int dummy, const cls * c) 
  1044.       : PAbstractDictionary(dummy, c) { } 
  1045.   public: 
  1046.     cls() 
  1047.       : PAbstractDictionary() { } 
  1048.     virtual PObject * Clone() const 
  1049.       { return PNEW cls(0, this); } 
  1050.     D & operator[](const K & key) const 
  1051.       { return (D &)GetRefAt(key); } 
  1052.     virtual BOOL Contains(const K & key) const 
  1053.       { return AbstractContains(key); } 
  1054.     virtual D * RemoveAt(const K & key) 
  1055.       { D * obj = GetAt(key); AbstractSetAt(key, NULL); return obj; } 
  1056.     virtual BOOL SetAt(const K & key, D * obj) 
  1057.       { return AbstractSetAt(key, obj); } 
  1058.     virtual D * GetAt(const K & key) const 
  1059.       { return (D *)AbstractGetAt(key); } 
  1060.     const K & GetKeyAt(PINDEX index) const 
  1061.       { return (const K &)AbstractGetKeyAt(index); } 
  1062.     D & GetDataAt(PINDEX index) const 
  1063.       { return (D &)AbstractGetDataAt(index); } 
  1064.   }
  1065. #define PDECLARE_DICTIONARY(cls, K, D) 
  1066.   PDICTIONARY(cls##_PTemplate, K, D); 
  1067.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  1068.   protected: 
  1069.     cls(int dummy, const cls * c) 
  1070.       : cls##_PTemplate(dummy, c) { } 
  1071.   public: 
  1072.     cls() 
  1073.       : cls##_PTemplate() { } 
  1074.     virtual PObject * Clone() const 
  1075.       { return PNEW cls(0, this); } 
  1076. #define PORDINAL_DICTIONARY(cls, K) 
  1077.   class cls : public PAbstractDictionary { 
  1078.   PCLASSINFO(cls, PAbstractDictionary); 
  1079.   protected: 
  1080.     inline cls(int dummy, const cls * c) 
  1081.       : PAbstractDictionary(dummy, c) { } 
  1082.   public: 
  1083.     inline cls() 
  1084.       : PAbstractDictionary() { } 
  1085.     inline virtual PObject * Clone() const 
  1086.       { return PNEW cls(0, this); } 
  1087.     inline PINDEX operator[](const K & key) const 
  1088.       { return (POrdinalKey &)GetRefAt(key); } 
  1089.     virtual BOOL Contains(const K & key) const 
  1090.       { return AbstractContains(key); } 
  1091.     inline virtual POrdinalKey * GetAt(const K & key) const 
  1092.       { return (POrdinalKey *)AbstractGetAt(key); } 
  1093.     inline virtual BOOL SetDataAt(PINDEX index, PINDEX ordinal) 
  1094.       { return PAbstractDictionary::SetDataAt(index, PNEW POrdinalKey(ordinal)); } 
  1095.     inline virtual BOOL SetAt(const K & key, PINDEX ordinal) 
  1096.       { return AbstractSetAt(key, PNEW POrdinalKey(ordinal)); } 
  1097.     inline virtual PINDEX RemoveAt(const K & key) 
  1098.       { PINDEX ord = *GetAt(key); AbstractSetAt(key, NULL); return ord; } 
  1099.     inline const K & GetKeyAt(PINDEX index) const 
  1100.       { return (const K &)AbstractGetKeyAt(index); } 
  1101.     inline PINDEX GetDataAt(PINDEX index) const 
  1102.       { return (POrdinalKey &)AbstractGetDataAt(index); } 
  1103.   }
  1104. #define PDECLARE_ORDINAL_DICTIONARY(cls, K) 
  1105.   PORDINAL_DICTIONARY(cls##_PTemplate, K); 
  1106.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  1107.   protected: 
  1108.     cls(int dummy, const cls * c) 
  1109.       : cls##_PTemplate(dummy, c) { } 
  1110.   public: 
  1111.     cls() 
  1112.       : cls##_PTemplate() { } 
  1113.     virtual PObject * Clone() const 
  1114.       { return PNEW cls(0, this); } 
  1115. #endif // PHAS_TEMPLATES
  1116. // End Of File ///////////////////////////////////////////////////////////////