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

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * array.h
  3.  *
  4.  * Linear Array 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: array.h,v $
  30.  * Revision 1.19  1999/11/30 00:22:54  robertj
  31.  * Updated documentation for doc++
  32.  *
  33.  * Revision 1.18  1999/09/03 15:08:38  robertj
  34.  * Fixed typo in ancestor class name
  35.  *
  36.  * Revision 1.17  1999/08/22 12:13:42  robertj
  37.  * Fixed warning when using inlines on older GNU compiler
  38.  *
  39.  * Revision 1.16  1999/08/20 03:07:44  robertj
  40.  * Fixed addded Concatenate function for non-template version.
  41.  *
  42.  * Revision 1.15  1999/08/18 01:45:12  robertj
  43.  * Added concatenation function to "base type" arrays.
  44.  *
  45.  * Revision 1.14  1999/03/09 02:59:49  robertj
  46.  * Changed comments to doc++ compatible documentation.
  47.  *
  48.  * Revision 1.13  1999/02/16 08:07:11  robertj
  49.  * MSVC 6.0 compatibility changes.
  50.  *
  51.  * Revision 1.12  1998/09/23 06:20:16  robertj
  52.  * Added open source copyright license.
  53.  *
  54.  * Revision 1.11  1998/08/21 05:23:57  robertj
  55.  * Added hex dump capability to base array types.
  56.  * Added ability to have base arrays of static memory blocks.
  57.  *
  58.  * Revision 1.10  1997/06/08 04:49:10  robertj
  59.  * Fixed non-template class descendent order.
  60.  *
  61.  * Revision 1.9  1996/08/17 09:54:34  robertj
  62.  * Optimised RemoveAll() for object arrays.
  63.  *
  64.  * Revision 1.8  1996/01/02 11:48:46  robertj
  65.  * Removed requirement that PArray elements have parameterless constructor..
  66.  *
  67.  * Revision 1.7  1995/10/14 14:52:33  robertj
  68.  * Changed arrays to not break references.
  69.  *
  70.  * Revision 1.6  1995/06/17 11:12:18  robertj
  71.  * Documentation update.
  72.  *
  73.  * Revision 1.5  1995/03/14 12:40:58  robertj
  74.  * Updated documentation to use HTML codes.
  75.  *
  76.  * Revision 1.4  1995/02/22  10:50:26  robertj
  77.  * Changes required for compiling release (optimised) version.
  78.  *
  79.  * Revision 1.3  1995/01/15  04:49:09  robertj
  80.  * Fixed errors in template version.
  81.  *
  82.  * Revision 1.2  1994/12/21  11:52:46  robertj
  83.  * Documentation and variable normalisation.
  84.  *
  85.  * Revision 1.1  1994/12/12  09:59:29  robertj
  86.  * Initial revision
  87.  *
  88.  */
  89. #ifdef __GNUC__
  90. #pragma interface
  91. #endif
  92. ///////////////////////////////////////////////////////////////////////////////
  93. // The abstract array class
  94. /**This class contains a variable length array of arbitrary memory blocks.
  95.    These can be anything from individual bytes to large structures. Note that
  96.    that does {bf not} include class objects that require construction or
  97.    destruction. Elements in this array will not execute the contructors or
  98.    destructors of objects.
  99.    An abstract array consists of a linear block of memory sufficient to hold
  100.    #PContainer::GetSize()# elements of #elementSize# bytes
  101.    each. The memory block itself will atuomatically be resized when required
  102.    and freed when no more references to it are present.
  103.    The PAbstractArray class would very rarely be descended from directly by
  104.    the user. The #PBASEARRAY# macro would normally be used to create
  105.    a class and any new classes descended from that. That will instantiate the
  106.    template based on #PBaseArray# or directly declare and define a class
  107.    (using inline functions) if templates are not being used.
  108.    The #PBaseArray# class or #PBASEARRAY# macro will define the correctly
  109.    typed operators for pointer access (#operator const T *#) and subscript
  110.    access (#operator[]#).
  111.  */
  112. class PAbstractArray : public PContainer
  113. {
  114.   PCONTAINERINFO(PAbstractArray, PContainer);
  115.   public:
  116.   /**@name Construction */
  117.   //@{
  118.     /**Create a new dynamic array of #initalSize# elements of
  119.        #elementSizeInBytes# bytes each. The array memory is
  120.        initialised to zeros.
  121.        If the initial size is zero then no memory is allocated. Note that the
  122.        internal pointer is set to NULL, not to a pointer to zero bytes of
  123.        memory. This can be an important distinction when the pointer is
  124.        obtained via an operator created in the #PBASEARRAY# macro.
  125.      */
  126.     PAbstractArray(
  127.       PINDEX elementSizeInBytes,
  128.       /**Size of each element in the array. This must be > 0 or the
  129.          constructor will assert.
  130.        */
  131.       PINDEX initialSize = 0      /// Number of elements to allocate initially.
  132.     );
  133.     /**Create a new dynamic array of #bufferSizeInElements#
  134.        elements of #elementSizeInBytes# bytes each. The contents of
  135.        the memory pointed to by buffer is then used to initialise the newly
  136.        allocated array.
  137.        If the initial size is zero then no memory is allocated. Note that the
  138.        internal pointer is set to NULL, not to a pointer to zero bytes of
  139.        memory. This can be an important distinction when the pointer is
  140.        obtained via an operator created in the #PBASEARRAY# macro.
  141.        If the #dynamicAllocation# parameter is FALSE then the
  142.        pointer is used directly by the container. It will not be copied to a
  143.        dynamically allocated buffer. If the #SetSize()# function is used to
  144.        change the size of the buffer, the object will be converted to a
  145.        dynamic form with the contents of the static buffer copied to the
  146.        allocated buffer.
  147.      */
  148.     PAbstractArray(
  149.       PINDEX elementSizeInBytes,
  150.       /**Size of each element in the array. This must be > 0 or the
  151.          constructor will assert.
  152.        */
  153.       const void *buffer,          /// Pointer to an array of elements.
  154.       PINDEX bufferSizeInElements, /// Number of elements pointed to by buffer.
  155.       BOOL dynamicAllocation       /// Buffer is copied and dynamically allocated.
  156.     );
  157.   //@}
  158.   /**@name Overrides from class PObject */
  159.   //@{
  160.     /**Get the relative rank of the two arrays. The following algorithm is
  161.        employed for the comparison:
  162. begin{description}
  163.           item[EqualTo]     if the two array memory blocks are identical in
  164.                               length and contents.
  165.           item[LessThan]    if the array length is less than the
  166.                               #obj# parameters array length.
  167.           item[GreaterThan] if the array length is greater than the
  168.                               #obj# parameters array length.
  169. end{description}
  170.         If the array sizes are identical then the #memcmp()#
  171.         function is used to rank the two arrays.
  172.        @return
  173.        comparison of the two objects, #EqualTo# for same,
  174.        #LessThan# for #obj# logically less than the
  175.        object and #GreaterThan# for #obj# logically
  176.        greater than the object.
  177.      */
  178.     virtual Comparison Compare(
  179.       const PObject & obj   /// Other PAbstractArray to compare against.
  180.     ) const;
  181.   //@}
  182.   /**@name Overrides from class PContainer */
  183.   //@{
  184.     /**Set the size of the array in elements. A new array may be allocated to
  185.        accomodate the new number of elements. If the array increases in size
  186.        then the new bytes are initialised to zero. If the array is made smaller
  187.        then the data beyond the new size is lost.
  188.        @return
  189.        TRUE if the memory for the array was allocated successfully.
  190.      */
  191.     virtual BOOL SetSize(
  192.       PINDEX newSize  /// New size of the array in elements.
  193.     );
  194.   //@}
  195.   /**@name New functions for class */
  196.   //@{
  197.     /**Attach a pointer to a static block to the base array type. The pointer
  198.        is used directly and will not be copied to a dynamically allocated
  199.        buffer. If the SetSize() function is used to change the size of the
  200.        buffer, the object will be converted to a dynamic form with the
  201.        contents of the static buffer copied to the allocated buffer.
  202.        
  203.        Any dynamically allocated buffer will be freed.
  204.      */
  205.     void Attach(
  206.       const void *buffer, /// Pointer to an array of elements.
  207.       PINDEX bufferSize   /// Number of elements pointed to by buffer.
  208.     );
  209.     /**Get a pointer to the internal array and assure that it is of at least
  210.        the specified size. This is useful when the array contents are being
  211.        set by some external or system function eg file read.
  212.        It is unsafe to assume that the pointer is valid for very long after
  213.        return from this function. The array may be resized or otherwise
  214.        changed and the pointer returned invalidated. It should be used for
  215.        simple calls to atomic functions, or very careful examination of the
  216.        program logic must be performed.
  217.        @return
  218.        pointer to the array memory.
  219.      */
  220.     void * GetPointer(
  221.       PINDEX minSize = 1  /// Minimum size the array must be.
  222.     );
  223.     /**Concatenate one array to the end of this array.
  224.        This function will allocate a new array large enough for the existing 
  225.        contents and the contents of the parameter. The paramters contents is then
  226.        copied to the end of the existing array.
  227.        
  228.        Note this does nothing and returns FALSE if the target array is not
  229.        dynamically allocated, or if the two arrays are of base elements of
  230.        different sizes.
  231.        @return
  232.        TRUE if the memory allocation succeeded.
  233.      */
  234.     BOOL Concatenate(
  235.       const PAbstractArray & array  /// Array to concatenate.
  236.     );
  237.   //@}
  238.   protected:
  239.     void PrintNumbersOn(ostream & strm, PINDEX size, BOOL is_signed) const;
  240.     virtual long GetNumberValueAt(PINDEX idx) const;
  241.     /// Size of an element in bytes
  242.     PINDEX elementSize;
  243.     /// Pointer to the allocated block of memory.
  244.     char * theArray;
  245.     /// Flag indicating the array was allocated on the heap.
  246.     BOOL allocatedDynamically;
  247.   friend class PArrayObjects;
  248. };
  249. ///////////////////////////////////////////////////////////////////////////////
  250. // An array of some base type
  251. #ifdef PHAS_TEMPLATES
  252. /**This template class maps the #PAbstractArray# to a specific element type. The
  253.    functions in this class primarily do all the appropriate casting of types.
  254.    Note that if templates are not used the #PBASEARRAY# macro will
  255.    simulate the template instantiation.
  256.    The following classes are instantiated automatically for the basic scalar
  257.    types:
  258. begin{itemize}
  259.         item #PCharArray#
  260.         item #PBYTEArray#
  261.         item #PShortArray#
  262.         item #PWORDArray#
  263.         item #PIntArray#
  264.         item #PUnsignedArray#
  265.         item #PLongArray#
  266.         item #PDWORDArray#
  267. end{itemize}
  268.  */
  269. template <class T> class PBaseArray : public PAbstractArray
  270. {
  271.   PCLASSINFO(PBaseArray, PAbstractArray);
  272.   public:
  273.   /**@name Construction */
  274.   //@{
  275.     /**Construct a new dynamic array of elements of the specified type. The
  276.        array is initialised to all zero bytes. Note that this may not be
  277.        logically equivalent to the zero value for the type, though this would
  278.        be very rare.
  279.      */
  280.     PBaseArray(
  281.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  282.     ) : PAbstractArray(sizeof(T), initialSize) { }
  283.     
  284.     /**Construct a new dynamic array of elements of the specified type.
  285.      */
  286.     PBaseArray(
  287.       T const * buffer,   /// Pointer to an array of the elements of type {bf T}.
  288.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  289.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  290.     ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { }
  291.   //@}
  292.   /**@name Overrides from class PObject */
  293.   //@{
  294.     /** Clone the object.
  295.      */
  296.     virtual PObject * Clone() const
  297.       { return PNEW PBaseArray<T>(*this, GetSize()); }
  298.   //@}
  299.   /**@name Overrides from class PContainer */
  300.   //@{
  301.     /**Set the specific element in the array. The array will automatically
  302.        expand, if necessary, to fit the new element in.
  303.        @return
  304.        TRUE if new memory for the array was successfully allocated.
  305.      */
  306.     BOOL SetAt(
  307.       PINDEX index,   /// Position in the array to set the new value.
  308.       T val           /// Value to set in the array.
  309.     ) { return SetMinSize(index+1) && val==(((T *)theArray)[index] = val); }
  310.     /**Get a value from the array. If the #index# is beyond the end
  311.        of the allocated array then a zero value is returned.
  312.        @return
  313.        value at the array position.
  314.      */
  315.     T GetAt(
  316.       PINDEX index  /// Position on the array to get value from.
  317.     ) const { PASSERTINDEX(index);
  318.                     return index < GetSize() ? ((T *)theArray)[index] : (T)0; }
  319.     /**Attach a pointer to a static block to the base array type. The pointer
  320.        is used directly and will not be copied to a dynamically allocated
  321.        buffer. If the SetSize() function is used to change the size of the
  322.        buffer, the object will be converted to a dynamic form with the
  323.        contents of the static buffer copied to the allocated buffer.
  324.        
  325.        Any dynamically allocated buffer will be freed.
  326.      */
  327.     void Attach(
  328.       const T * buffer,   /// Pointer to an array of elements.
  329.       PINDEX bufferSize   /// Number of elements pointed to by buffer.
  330.     ) { PAbstractArray::Attach(buffer, bufferSize); }
  331.     /**Get a pointer to the internal array and assure that it is of at least
  332.        the specified size. This is useful when the array contents are being
  333.        set by some external or system function eg file read.
  334.        It is unsafe to assume that the pointer is valid for very long after
  335.        return from this function. The array may be resized or otherwise
  336.        changed and the pointer returned invalidated. It should be used for
  337.        simple calls to atomic functions, or very careful examination of the
  338.        program logic must be performed.
  339.        @return
  340.        pointer to the array memory.
  341.      */
  342.     T * GetPointer(
  343.       PINDEX minSize = 0    /// Minimum size for returned buffer pointer.
  344.     ) { return (T *)PAbstractArray::GetPointer(minSize); }
  345.   //@}
  346.   /**@name New functions for class */
  347.   //@{
  348.     /**Get a value from the array. If the #index# is beyond the end
  349.        of the allocated array then a zero value is returned.
  350.        This is functionally identical to the #PContainer::GetAt()#
  351.        function.
  352.        @return
  353.        value at the array position.
  354.      */
  355.     T operator[](
  356.       PINDEX index  /// Position on the array to get value from.
  357.     ) const { return GetAt(index); }
  358.     /**Get a reference to value from the array. If the #index# is
  359.        beyond the end of the allocated array then the array is expanded. If a
  360.        memory allocation failure occurs the function asserts.
  361.        This is functionally similar to the #SetAt()# function and allows
  362.        the array subscript to be an lvalue.
  363.        @return
  364.        reference to value at the array position.
  365.      */
  366.     T & operator[](
  367.       PINDEX index  /// Position on the array to get value from.
  368.     ) { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory);
  369.         return ((T *)theArray)[index]; }
  370.     /**Get a pointer to the internal array. The user may not modify the
  371.        contents of this pointer/ This is useful when the array contents are
  372.        required by some external or system function eg file write.
  373.        It is unsafe to assume that the pointer is valid for very long after
  374.        return from this function. The array may be resized or otherwise
  375.        changed and the pointer returned invalidated. It should be used for
  376.        simple calls to atomic functions, or very careful examination of the
  377.        program logic must be performed.
  378.        @return
  379.        constant pointer to the array memory.
  380.      */
  381.     operator T const *() const { return (T const *)theArray; }
  382.     /**Concatenate one array to the end of this array.
  383.        This function will allocate a new array large enough for the existing 
  384.        contents and the contents of the parameter. The paramters contents is then
  385.        copied to the end of the existing array.
  386.        
  387.        Note this does nothing and returns FALSE if the target array is not
  388.        dynamically allocated.
  389.        @return
  390.        TRUE if the memory allocation succeeded.
  391.      */
  392.     BOOL Concatenate(
  393.       const PBaseArray & array  /// Other array to concatenate
  394.     ) { return PAbstractArray::Concatenate(array); }
  395.   //@}
  396. };
  397. /*Declare a dynamic array base type.
  398.    This macro is used to declare a descendent of PAbstractArray class,
  399.    customised for a particular element type {bf T}. This macro closes the
  400.    class declaration off so no additional members can be added.
  401.    If the compilation is using templates then this macro produces a typedef
  402.    of the #PBaseArray# template class.
  403.  */
  404. #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls
  405. /**Begin a declaration of an array of base types.
  406.    This macro is used to declare a descendent of PAbstractArray class,
  407.    customised for a particular element type {bf T}.
  408.    If the compilation is using templates then this macro produces a descendent
  409.    of the #PBaseArray# template class. If templates are not being used
  410.    then the macro defines a set of inline functions to do all casting of types.
  411.    The resultant classes have an identical set of functions in either case.
  412.    See the #PBaseArray# and #PAbstractArray# classes for more
  413.    information.
  414.  */
  415. #define PDECLARE_BASEARRAY(cls, T) 
  416.   PBASEARRAY(PBaseArray_##cls, T); 
  417.   PDECLARE_CLASS(cls, PBaseArray_##cls) 
  418.     cls(PINDEX initialSize = 0) 
  419.       : PBaseArray_##cls(initialSize) { } 
  420.     cls(T const * buffer, PINDEX length, BOOL dynamic = TRUE) 
  421.       : PBaseArray_##cls(buffer, length, dynamic) { } 
  422.     virtual PObject * Clone() const 
  423.       { return PNEW cls(*this, GetSize()); } 
  424. #else // PHAS_TEMPLATES
  425. #define PBASEARRAY(cls, T) 
  426.   typedef T P_##cls##_Base_Type; 
  427.   class cls : public PAbstractArray { 
  428.     PCLASSINFO(cls, PAbstractArray) 
  429.   public: 
  430.     inline cls(PINDEX initialSize = 0) 
  431.       : PAbstractArray(sizeof(P_##cls##_Base_Type), initialSize) { } 
  432.     inline cls(P_##cls##_Base_Type const * buffer, PINDEX length, BOOL dynamic = TRUE) 
  433.       : PAbstractArray(sizeof(P_##cls##_Base_Type), buffer, length, dynamic) { } 
  434.     virtual PObject * Clone() const 
  435.       { return PNEW cls(*this, GetSize()); } 
  436.     inline BOOL SetAt(PINDEX index, P_##cls##_Base_Type val) 
  437.       { return SetMinSize(index+1) && 
  438.                      val==(((P_##cls##_Base_Type *)theArray)[index] = val); } 
  439.     inline P_##cls##_Base_Type GetAt(PINDEX index) const 
  440.       { PASSERTINDEX(index); return index < GetSize() ? 
  441.           ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } 
  442.     inline P_##cls##_Base_Type operator[](PINDEX index) const 
  443.       { PASSERTINDEX(index); return GetAt(index); } 
  444.     inline P_##cls##_Base_Type & operator[](PINDEX index) 
  445.       { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); 
  446.         return ((P_##cls##_Base_Type *)theArray)[index]; } 
  447.     inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) 
  448.       { PAbstractArray::Attach(buffer, bufferSize); } 
  449.     inline P_##cls##_Base_Type * GetPointer(PINDEX minSize = 0) 
  450.       { return (P_##cls##_Base_Type *)PAbstractArray::GetPointer(minSize); } 
  451.     inline operator P_##cls##_Base_Type const *() const 
  452.       { return (P_##cls##_Base_Type const *)theArray; } 
  453.     inline BOOL Concatenate(cls const & array) 
  454.       { return PAbstractArray::Concatenate(array); } 
  455.   }
  456. #define PDECLARE_BASEARRAY(cls, T) 
  457.   PBASEARRAY(cls##_PTemplate, T); 
  458.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  459.     cls(PINDEX initialSize = 0) 
  460.       : cls##_PTemplate(initialSize) { } 
  461.     cls(T const * buffer, PINDEX length, BOOL dynamic = TRUE) 
  462.       : cls##_PTemplate(buffer, length, dynamic) { } 
  463.     virtual PObject * Clone() const 
  464.       { return PNEW cls(*this, GetSize()); } 
  465. #endif // PHAS_TEMPLATES
  466. /// Array of characters.
  467. #ifdef DOC_PLUS_PLUS
  468. class PCharArray : public PBaseArray {
  469.   public:
  470.   /**@name Construction */
  471.   //@{
  472.     /**Construct a new dynamic array of char.
  473.        The array is initialised to all zero bytes.
  474.      */
  475.     PBaseArray(
  476.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  477.     );
  478.     /**Construct a new dynamic array of char.
  479.      */
  480.     PBaseArray(
  481.       char const * buffer,   /// Pointer to an array of chars.
  482.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  483.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  484.     );
  485.   //@}
  486. #endif
  487. PDECLARE_BASEARRAY(PCharArray, char);
  488.   public:
  489.   /**@name Overrides from class PObject */
  490.   //@{
  491.     /// Print the array
  492.     virtual void PrintOn(
  493.       ostream & strm /// Stream to output to.
  494.     ) const;
  495.   //@}
  496. };
  497. /// Array of short integers.
  498. #ifdef DOC_PLUS_PLUS
  499. class PShortArray : public PBaseArray {
  500.   public:
  501.   /**@name Construction */
  502.   //@{
  503.     /**Construct a new dynamic array of shorts.
  504.        The array is initialised to all zeros.
  505.      */
  506.     PBaseArray(
  507.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  508.     );
  509.     /**Construct a new dynamic array of shorts.
  510.      */
  511.     PBaseArray(
  512.       short const * buffer,   /// Pointer to an array of shorts.
  513.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  514.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  515.     );
  516.   //@}
  517. #endif
  518. PDECLARE_BASEARRAY(PShortArray, short);
  519.   public:
  520.   /**@name Overrides from class PObject */
  521.   //@{
  522.     /// Print the array
  523.     virtual void PrintOn(
  524.       ostream & strm /// Stream to output to.
  525.     ) const;
  526.   //@}
  527.     virtual long GetNumberValueAt(PINDEX idx) const;
  528. };
  529. /// Array of integers.
  530. #ifdef DOC_PLUS_PLUS
  531. class PIntArray : public PBaseArray {
  532.   public:
  533.   /**@name Construction */
  534.   //@{
  535.     /**Construct a new dynamic array of ints.
  536.        The array is initialised to all zeros.
  537.      */
  538.     PBaseArray(
  539.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  540.     );
  541.     /**Construct a new dynamic array of ints.
  542.      */
  543.     PBaseArray(
  544.       int const * buffer,   /// Pointer to an array of ints.
  545.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  546.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  547.     );
  548.   //@}
  549. #endif
  550. PDECLARE_BASEARRAY(PIntArray, int);
  551.   public:
  552.   /**@name Overrides from class PObject */
  553.   //@{
  554.     /// Print the array
  555.     virtual void PrintOn(
  556.       ostream & strm /// Stream to output to.
  557.     ) const;
  558.   //@}
  559.     virtual long GetNumberValueAt(PINDEX idx) const;
  560. };
  561. /// Array of long integers.
  562. #ifdef DOC_PLUS_PLUS
  563. class PLongArray : public PBaseArray {
  564.   public:
  565.   /**@name Construction */
  566.   //@{
  567.     /**Construct a new dynamic array of longs.
  568.        The array is initialised to all zeros.
  569.      */
  570.     PBaseArray(
  571.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  572.     );
  573.     /**Construct a new dynamic array of longs.
  574.      */
  575.     PBaseArray(
  576.       long const * buffer,   /// Pointer to an array of longs.
  577.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  578.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  579.     );
  580.   //@}
  581. #endif
  582. PDECLARE_BASEARRAY(PLongArray, long);
  583.   public:
  584.   /**@name Overrides from class PObject */
  585.   //@{
  586.     /// Print the array
  587.     virtual void PrintOn(
  588.       ostream & strm /// Stream to output to.
  589.     ) const;
  590.   //@}
  591.     virtual long GetNumberValueAt(PINDEX idx) const;
  592. };
  593. /// Array of unsigned characters.
  594. #ifdef DOC_PLUS_PLUS
  595. class PBYTEArray : public PBaseArray {
  596.   public:
  597.   /**@name Construction */
  598.   //@{
  599.     /**Construct a new dynamic array of unsigned chars.
  600.        The array is initialised to all zeros.
  601.      */
  602.     PBaseArray(
  603.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  604.     );
  605.     /**Construct a new dynamic array of unsigned chars.
  606.      */
  607.     PBaseArray(
  608.       BYTE const * buffer,   /// Pointer to an array of BYTEs.
  609.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  610.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  611.     );
  612.   //@}
  613. #endif
  614. PDECLARE_BASEARRAY(PBYTEArray, BYTE);
  615.   public:
  616.   /**@name Overrides from class PObject */
  617.   //@{
  618.     /// Print the array
  619.     virtual void PrintOn(
  620.       ostream & strm /// Stream to output to.
  621.     ) const;
  622.   //@}
  623.     virtual long GetNumberValueAt(PINDEX idx) const;
  624. };
  625. /// Array of unsigned short integers.
  626. #ifdef DOC_PLUS_PLUS
  627. class PWORDArray : public PBaseArray {
  628.   public:
  629.   /**@name Construction */
  630.   //@{
  631.     /**Construct a new dynamic array of unsigned shorts.
  632.        The array is initialised to all zeros.
  633.      */
  634.     PBaseArray(
  635.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  636.     );
  637.     /**Construct a new dynamic array of unsigned shorts.
  638.      */
  639.     PBaseArray(
  640.       WORD const * buffer,   /// Pointer to an array of WORDs.
  641.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  642.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  643.     );
  644.   //@}
  645. #endif
  646. PDECLARE_BASEARRAY(PWORDArray, WORD);
  647.   public:
  648.   /**@name Overrides from class PObject */
  649.   //@{
  650.     /// Print the array
  651.     virtual void PrintOn(
  652.       ostream & strm /// Stream to output to.
  653.     ) const;
  654.   //@}
  655.     virtual long GetNumberValueAt(PINDEX idx) const;
  656. };
  657. /// Array of unsigned integers.
  658. #ifdef DOC_PLUS_PLUS
  659. class PUnsignedArray : public PBaseArray {
  660.   public:
  661.   /**@name Construction */
  662.   //@{
  663.     /**Construct a new dynamic array of unsigned ints.
  664.        The array is initialised to all zeros.
  665.      */
  666.     PBaseArray(
  667.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  668.     );
  669.     /**Construct a new dynamic array of unsigned ints.
  670.      */
  671.     PBaseArray(
  672.       unsigned const * buffer,   /// Pointer to an array of unsigned ints.
  673.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  674.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  675.     );
  676.   //@}
  677. #endif
  678. PDECLARE_BASEARRAY(PUnsignedArray, unsigned);
  679.   public:
  680.   /**@name Overrides from class PObject */
  681.   //@{
  682.     /// Print the array
  683.     virtual void PrintOn(
  684.       ostream & strm /// Stream to output to.
  685.     ) const;
  686.   //@}
  687.     virtual long GetNumberValueAt(PINDEX idx) const;
  688. };
  689. /// Array of unsigned long integers.
  690. #ifdef DOC_PLUS_PLUS
  691. class PDWORDArray : public PBaseArray {
  692.   public:
  693.   /**@name Construction */
  694.   //@{
  695.     /**Construct a new dynamic array of unsigned longs.
  696.        The array is initialised to all zeros.
  697.      */
  698.     PBaseArray(
  699.       PINDEX initialSize = 0  /// Initial number of elements in the array.
  700.     );
  701.     /**Construct a new dynamic array of DWORDs.
  702.      */
  703.     PBaseArray(
  704.       DWORD const * buffer,   /// Pointer to an array of DWORDs.
  705.       PINDEX length,      /// Number of elements pointed to by #buffer#.
  706.       BOOL dynamic = TRUE /// Buffer is copied and dynamically allocated.
  707.     );
  708.   //@}
  709. #endif
  710. PDECLARE_BASEARRAY(PDWORDArray, DWORD);
  711.   public:
  712.   /**@name Overrides from class PObject */
  713.   //@{
  714.     /// Print the array
  715.     virtual void PrintOn(
  716.       ostream & strm /// Stream to output to.
  717.     ) const;
  718.   //@}
  719.     virtual long GetNumberValueAt(PINDEX idx) const;
  720. };
  721. ///////////////////////////////////////////////////////////////////////////////
  722. // Linear array of objects
  723. /** An array of objects.
  724. This class is a collection of objects which are descendents of the
  725. #PObject# class. It is implemeted as a dynamic, linear array of
  726. pointers to the objects.
  727. The implementation of an array allows very fast random access to items in
  728. the collection, but has severe penalties for inserting and deleting objects
  729. as all other objects must be moved to accommodate the change.
  730. An array of objects may have "gaps" in it. These are array entries that
  731. contain NULL as the object pointer.
  732. The PArrayObjects class would very rarely be descended from directly by
  733. the user. The #PARRAY# macro would normally be used to create a class.
  734. That will instantiate the template based on #PArray# or directly declare
  735. and define the class (using inline functions) if templates are not being used.
  736. The #PArray# class or #PARRAY# macro will define the
  737. correctly typed operators for pointer access (#operator const T *#) and
  738. subscript access (#operator[]#).
  739. */
  740. class PArrayObjects : public PCollection
  741. {
  742.   PCONTAINERINFO(PArrayObjects, PCollection);
  743.   public:
  744.   /**@name Construction */
  745.   //@{
  746.     /**Create a new array of objects. The array is initially set to the
  747.        specified size with each entry having NULL as is pointer value.
  748.        Note that by default, objects placed into the list will be deleted when
  749.        removed or when all references to the list are destroyed.
  750.      */
  751.     PINLINE PArrayObjects(
  752.       PINDEX initialSize = 0  /// Initial number of objects in the array.
  753.     );
  754.   //@}
  755.   /**@name Overrides from class PObject */
  756.   //@{
  757.     /**Get the relative rank of the two arrays. The following algorithm is
  758.        employed for the comparison:
  759. begin{description}
  760.         item[EqualTo]      if the two array memory blocks are identical in
  761.                             length and each objects values, not pointer, are
  762.                             equal.
  763.         item[LessThan]     if the instances object value at an ordinal
  764.                             position is less than the corresponding objects
  765.                             value in the #obj# parameters array.
  766.                           
  767.                             This is also returned if all objects are equal and
  768.                             the instances array length is less than the
  769.                             #obj# parameters array length.
  770.         item[GreaterThan]  if the instances object value at an ordinal
  771.                             position is greater than the corresponding objects
  772.                             value in the #obj# parameters array.
  773.                           
  774.                             This is also returned if all objects are equal and
  775.                             the instances array length is greater than the
  776.                             #obj# parameters array length.
  777. end{description}
  778.        @return
  779.        comparison of the two objects, #EqualTo# for same,
  780.        #LessThan# for #obj# logically less than the
  781.        object and #GreaterThan# for #obj# logically
  782.        greater than the object.
  783.      */
  784.     virtual Comparison Compare(
  785.       const PObject & obj   /// Other #PAbstractArray# to compare against.
  786.     ) const;
  787.   //@}
  788.   /**@name Overrides from class PContainer */
  789.   //@{
  790.     /// Get size of array
  791.     virtual PINDEX GetSize() const;
  792.     /**Set the size of the array in objects. A new array may be allocated to
  793.        accomodate the new number of objects. If the array increases in size
  794.        then the new object pointers are initialised to NULL. If the array is
  795.        made smaller then the data beyond the new size is lost.
  796.        @return
  797.        TRUE if the memory for the array was allocated successfully.
  798.      */
  799.     virtual BOOL SetSize(
  800.       PINDEX newSize  /// New size of the array in objects.
  801.     );
  802.   //@}
  803.   /**@name Overrides from class PCollection */
  804.   //@{
  805.     /**Append a new object to the collection. This will increase the size of
  806.        the array by one and place the new object at that position.
  807.     
  808.        @return
  809.        index of the newly added object.
  810.      */
  811.     virtual PINDEX Append(
  812.       PObject * obj   /// New object to place into the collection.
  813.     );
  814.     /**Insert a new object immediately before the specified object. If the
  815.        object to insert before is not in the collection then the equivalent of
  816.        the #Append()# function is performed.
  817.        All objects, including the #before# object are shifted up
  818.        one in the array.
  819.        Note that the object values are compared for the search of the
  820.        #before# parameter, not the pointers. So the objects in the
  821.        collection must correctly implement the #PObject::Compare()#
  822.        function.
  823.        @return
  824.        index of the newly inserted object.
  825.      */
  826.     virtual PINDEX Insert(
  827.       const PObject & before,   /// Object value to insert before.
  828.       PObject * obj             /// New object to place into the collection.
  829.     );
  830.     /** Insert a new object at the specified ordinal index. If the index is
  831.        greater than the number of objects in the collection then the
  832.        equivalent of the #Append()# function is performed.
  833.        All objects, including the #index# position object are
  834.        shifted up one in the array.
  835.        @return
  836.        index of the newly inserted object.
  837.      */
  838.     virtual PINDEX InsertAt(
  839.       PINDEX index,   /// Index position in collection to place the object.
  840.       PObject * obj   /// New object to place into the collection.
  841.     );
  842.     /**Remove the object from the collection. If the AllowDeleteObjects option
  843.        is set then the object is also deleted.
  844.        All objects are shifted down to fill the vacated position.
  845.        @return
  846.        TRUE if the object was in the collection.
  847.      */
  848.     virtual BOOL Remove(
  849.       const PObject * obj   /// Existing object to remove from the collection.
  850.     );
  851.     /**Remove the object at the specified ordinal index from the collection.
  852.        If the AllowDeleteObjects option is set then the object is also deleted.
  853.        All objects are shifted down to fill the vacated position.
  854.        Note if the index is beyond the size of the collection then the
  855.        function will assert.
  856.        @return
  857.        pointer to the object being removed, or NULL if it was deleted.
  858.      */
  859.     virtual PObject * RemoveAt(
  860.       PINDEX index   /// Index position in collection to place the object.
  861.     );
  862.     /**Set the object at the specified ordinal position to the new value. This
  863.        will overwrite the existing entry. If the AllowDeleteObjects option is
  864.        set then the old object is also deleted.
  865.        @return
  866.        TRUE if the object was successfully added.
  867.      */
  868.     virtual BOOL SetAt(
  869.       PINDEX index,   /// Index position in collection to set.
  870.       PObject * val   /// New value to place into the collection.
  871.     );
  872.     /**Get the object at the specified ordinal position. If the index was
  873.        greater than the size of the collection then NULL is returned.
  874.        @return
  875.        pointer to object at the specified index.
  876.      */
  877.     virtual PObject * GetAt(
  878.       PINDEX index  /// Index position in the collection of the object.
  879.     ) const;
  880.     /**Search the collection for the specific instance of the object. The
  881.        object pointers are compared, not the values. A simple linear search
  882.        from ordinal position zero is performed.
  883.        @return
  884.        ordinal index position of the object, or P_MAX_INDEX.
  885.      */
  886.     virtual PINDEX GetObjectsIndex(
  887.       const PObject * obj  /// Object to find.
  888.     ) const;
  889.     /**Search the collection for the specified value of the object. The object
  890.        values are compared, not the pointers.  So the objects in the
  891.        collection must correctly implement the #PObject::Compare()#
  892.        function. A simple linear search from ordinal position zero is
  893.        performed.
  894.        @return
  895.        ordinal index position of the object, or P_MAX_INDEX.
  896.      */
  897.     virtual PINDEX GetValuesIndex(
  898.       const PObject & obj   // Object to find equal of.
  899.     ) const;
  900.     /**Remove all of the elements in the collection. This operates by
  901.        continually calling #RemoveAt()# until there are no objects left.
  902.        The objects are removed from the last, at index
  903.        #(GetSize()-1)# toward the first at index zero.
  904.      */
  905.     virtual void RemoveAll();
  906.   //@}
  907.   protected:
  908.     PBASEARRAY(ObjPtrArray, PObject *);
  909.     ObjPtrArray * theArray;
  910. };
  911. #ifdef PHAS_TEMPLATES
  912. /**This template class maps the PArrayObjects to a specific object type.
  913. The functions in this class primarily do all the appropriate casting of types.
  914. Note that if templates are not used the #PARRAY# macro will
  915. simulate the template instantiation.
  916. */
  917. template <class T> class PArray : public PArrayObjects
  918. {
  919.   PCLASSINFO(PArray, PArrayObjects);
  920.   public:
  921.   /**@name Construction */
  922.   //@{
  923.     /**Create a new array of objects. The array is initially set to the
  924.        specified size with each entry having NULL as is pointer value.
  925.        Note that by default, objects placed into the list will be deleted when
  926.        removed or when all references to the list are destroyed.
  927.      */
  928.     PArray( 
  929.       PINDEX initialSize = 0  /// Initial number of objects in the array.
  930.     ) : PArrayObjects(initialSize) { }
  931.   //@}
  932.   /**@name Overrides from class PObject */
  933.   //@{
  934.     /** Make a complete duplicate of the array. Note that all objects in the
  935.        array are also cloned, so this will make a complete copy of the array.
  936.      */
  937.     virtual PObject * Clone() const
  938.       { return PNEW PArray(0, this); }
  939.   //@}
  940.   /**@name New functions for class */
  941.   //@{
  942.     /**Retrieve a reference  to the object in the array. If there was not an
  943.        object at that ordinal position or the index was beyond the size of the
  944.        array then the function asserts.
  945.        @return
  946.        reference to the object at #index# position.
  947.      */
  948.     T & operator[](
  949.       PINDEX index  /// Index position in the collection of the object.
  950.     ) const { PAssert(GetAt(index) != NULL, PInvalidArrayElement);
  951.                                                    return *(T *)GetAt(index); }
  952.   //@}
  953.   protected:
  954.     PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
  955. };
  956. /** Declare an array to a specific type of object.
  957. This macro is used to declare a descendent of PArrayObjects class,
  958. customised for a particular object type {bf T}. This macro closes the
  959. class declaration off so no additional members can be added.
  960. If the compilation is using templates then this macro produces a typedef
  961. of the #PArray# template class.
  962. See the #PBaseArray# class and #PDECLARE_ARRAY# macro for more
  963. information.
  964. */
  965. #define PARRAY(cls, T) typedef PArray<T> cls
  966. /** Begin declaration an array to a specific type of object.
  967. This macro is used to declare a descendent of PArrayObjects class,
  968. customised for a particular object type {bf T}.
  969. If the compilation is using templates then this macro produces a descendent
  970. of the #PArray# template class. If templates are not being used then
  971. the macro defines a set of inline functions to do all casting of types. The
  972. resultant classes have an identical set of functions in either case.
  973. See the #PBaseArray# and #PAbstractArray# classes for more
  974. information.
  975. */
  976. #define PDECLARE_ARRAY(cls, T) 
  977.   PARRAY(cls##_PTemplate, T); 
  978.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  979.   protected: 
  980.     inline cls(int dummy, const cls * c) 
  981.       : cls##_PTemplate(dummy, c) { } 
  982.   public: 
  983.     inline cls(PINDEX initialSize = 0) 
  984.       : cls##_PTemplate(initialSize) { } 
  985.     inline virtual PObject * Clone() const 
  986.       { return PNEW cls(0, this); } 
  987. #else // PHAS_TEMPLATES
  988. #define PARRAY(cls, T) 
  989.   class cls : public PArrayObjects { 
  990.   PCLASSINFO(cls, PArrayObjects); 
  991.   protected: 
  992.     inline cls(int dummy, const cls * c) 
  993.       : PArrayObjects(dummy, c) { } 
  994.   public: 
  995.     inline cls(PINDEX initialSize = 0) 
  996.       : PArrayObjects(initialSize) { } 
  997.     inline virtual PObject * Clone() const 
  998.       { return PNEW cls(0, this); } 
  999.     inline T & operator[](PINDEX index) const
  1000.       { PAssert((*theArray)[index] != NULL, PInvalidArrayElement); 
  1001.                                            return *(T *)(*theArray)[index]; } 
  1002.   }
  1003. #define PDECLARE_ARRAY(cls, T) 
  1004.   PARRAY(cls##_PTemplate, T); 
  1005.   PDECLARE_CLASS(cls, cls##_PTemplate) 
  1006.   protected: 
  1007.     inline cls(int dummy, const cls * c) 
  1008.       : cls##_PTemplate(dummy, c) { } 
  1009.   public: 
  1010.     inline cls(PINDEX initialSize = 0) 
  1011.       : cls##_PTemplate(initialSize) { } 
  1012.     inline virtual PObject * Clone() const 
  1013.       { return PNEW cls(0, this); } 
  1014. #endif // PHAS_TEMPLATES
  1015. // End Of File ///////////////////////////////////////////////////////////////