array.h

Go to the documentation of this file.
00001 /*
00002  * array.h
00003  *
00004  * Linear Array Container classes.
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
00025  * All Rights Reserved.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Revision: 19406 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-02-06 02:57:35 +0000 (Wed, 06 Feb 2008) $
00032  */
00033 
00034 #ifndef _ARRAY_H_
00035 #define _ARRAY_H_
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 #include <ptlib/contain.h>
00042 
00044 // The abstract array class
00045 
00067 class PAbstractArray : public PContainer
00068 {
00069   PCONTAINERINFO(PAbstractArray, PContainer);
00070 
00071   public:
00083     PAbstractArray(
00084       PINDEX elementSizeInBytes,  
00085 
00086       PINDEX initialSize = 0      
00087     );
00088 
00106     PAbstractArray(
00107       PINDEX elementSizeInBytes,   
00108 
00109       const void *buffer,          
00110       PINDEX bufferSizeInElements, 
00111       PBoolean dynamicAllocation       
00112     );
00114 
00123     virtual void PrintOn(
00124       ostream &strm   // Stream to print the object into.
00125     ) const;
00126 
00133     virtual void ReadFrom(
00134       istream &strm   // Stream to read the objects contents from.
00135     );
00136 
00157     virtual Comparison Compare(
00158       const PObject & obj   
00159     ) const;
00161 
00172     virtual PBoolean SetSize(
00173       PINDEX newSize  
00174     );
00176 
00187     void Attach(
00188       const void *buffer, 
00189       PINDEX bufferSize   
00190     );
00191 
00205     void * GetPointer(
00206       PINDEX minSize = 1  
00207     );
00208 
00221     PBoolean Concatenate(
00222       const PAbstractArray & array  
00223     );
00225 
00226   protected:
00227     PBoolean InternalSetSize(PINDEX newSize, PBoolean force);
00228 
00229     virtual void PrintElementOn(
00230       ostream & stream,
00231       PINDEX index
00232     ) const;
00233     virtual void ReadElementFrom(
00234       istream & stream,
00235       PINDEX index
00236     );
00237 
00239     PINDEX elementSize;
00240 
00242     char * theArray;
00243 
00245     PBoolean allocatedDynamically;
00246 
00247   friend class PArrayObjects;
00248 };
00249 
00250 
00252 // An array of some base type
00253 
00273 template <class T> class PBaseArray : public PAbstractArray
00274 {
00275   PCLASSINFO(PBaseArray, PAbstractArray);
00276 
00277   public:
00285     PBaseArray(
00286       PINDEX initialSize = 0  
00287     ) : PAbstractArray(sizeof(T), initialSize) { }
00288     
00291     PBaseArray(
00292       T const * buffer,   
00293       PINDEX length,      
00294       PBoolean dynamic = PTrue 
00295     ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { }
00297 
00302     virtual PObject * Clone() const
00303     { 
00304       return PNEW PBaseArray<T>(*this, GetSize());
00305     }
00307 
00316     PBoolean SetAt(
00317       PINDEX index,   
00318       T val           
00319     ) {
00320       return SetMinSize(index+1) && val==(((T *)theArray)[index] = val);
00321     }
00322 
00329     T GetAt(
00330       PINDEX index  
00331     ) const {
00332       PASSERTINDEX(index);
00333       return index < GetSize() ? ((T *)theArray)[index] : (T)0;
00334     }
00335 
00344     void Attach(
00345       const T * buffer,   
00346       PINDEX bufferSize   
00347     ) {
00348       PAbstractArray::Attach(buffer, bufferSize);
00349     }
00350 
00364     T * GetPointer(
00365       PINDEX minSize = 0    
00366     ) {
00367       return (T *)PAbstractArray::GetPointer(minSize);
00368     }
00370 
00382     T operator[](
00383       PINDEX index  
00384     ) const {
00385       return GetAt(index);
00386     }
00387 
00398     T & operator[](
00399       PINDEX index  
00400     ) {
00401       PASSERTINDEX(index);
00402       PAssert(SetMinSize(index+1), POutOfMemory);
00403       return ((T *)theArray)[index];
00404     }
00405 
00419     operator T const *() const {
00420       return (T const *)theArray;
00421     }
00422 
00434     PBoolean Concatenate(
00435       const PBaseArray & array  
00436     ) {
00437       return PAbstractArray::Concatenate(array);
00438     }
00440 
00441   protected:
00442     virtual void PrintElementOn(
00443       ostream & stream,
00444       PINDEX index
00445     ) const {
00446       stream << GetAt(index);
00447     }
00448 };
00449 
00450 /*Declare a dynamic array base type.
00451    This macro is used to declare a descendent of PAbstractArray class,
00452    customised for a particular element type {\bf T}. This macro closes the
00453    class declaration off so no additional members can be added.
00454 
00455    If the compilation is using templates then this macro produces a typedef
00456    of the #PBaseArray# template class.
00457  */
00458 #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls
00459 
00472 #define PDECLARE_BASEARRAY(cls, T) \
00473   PDECLARE_CLASS(cls, PBaseArray<T>) \
00474     cls(PINDEX initialSize = 0) \
00475       : PBaseArray<T>(initialSize) { } \
00476     cls(T const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00477       : PBaseArray<T>(buffer, length, dynamic) { } \
00478     virtual PObject * Clone() const \
00479       { return PNEW cls(*this, GetSize()); } \
00480 
00481 
00500 template <class T> class PScalarArray : public PBaseArray<T>
00501 {
00502   public:
00510     PScalarArray(
00511       PINDEX initialSize = 0  
00512     ) : PBaseArray<T>(initialSize) { }
00513     
00516     PScalarArray(
00517       T const * buffer,   
00518       PINDEX length,      
00519       PBoolean dynamic = PTrue 
00520     ) : PBaseArray<T>(buffer, length, dynamic) { }
00522 
00523   protected:
00524     virtual void ReadElementFrom(
00525       istream & stream,
00526       PINDEX index
00527     ) {
00528       T t;
00529       stream >> t;
00530       if (!stream.fail())
00531         SetAt(index, t);
00532     }
00533 };
00534 
00535 
00536 /*Declare a dynamic array base type.
00537    This macro is used to declare a descendent of PAbstractArray class,
00538    customised for a particular element type {\bf T}. This macro closes the
00539    class declaration off so no additional members can be added.
00540 
00541    If the compilation is using templates then this macro produces a typedef
00542    of the #PBaseArray# template class.
00543  */
00544 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls
00545 
00546 
00548 #ifdef DOC_PLUS_PLUS
00549 class PCharArray : public PBaseArray {
00550   public:
00556     PCharArray(
00557       PINDEX initialSize = 0  
00558     );
00559 
00562     PCharArray(
00563       char const * buffer,   
00564       PINDEX length,      
00565       PBoolean dynamic = PTrue 
00566     );
00568 #endif
00569 PDECLARE_BASEARRAY(PCharArray, char);
00570   public:
00573 
00574     virtual void PrintOn(
00575       ostream & strm 
00576     ) const;
00578     virtual void ReadFrom(
00579       istream &strm   // Stream to read the objects contents from.
00580     );
00582 };
00583 
00585 #ifdef DOC_PLUS_PLUS
00586 class PShortArray : public PBaseArray {
00587   public:
00593     PShortArray(
00594       PINDEX initialSize = 0  
00595     );
00596 
00599     PShortArray(
00600       short const * buffer,   
00601       PINDEX length,      
00602       PBoolean dynamic = PTrue 
00603     );
00605 };
00606 #endif
00607 PSCALAR_ARRAY(PShortArray, short);
00608 
00609 
00611 #ifdef DOC_PLUS_PLUS
00612 class PIntArray : public PBaseArray {
00613   public:
00619     PIntArray(
00620       PINDEX initialSize = 0  
00621     );
00622 
00625     PIntArray(
00626       int const * buffer,   
00627       PINDEX length,      
00628       PBoolean dynamic = PTrue 
00629     );
00631 };
00632 #endif
00633 PSCALAR_ARRAY(PIntArray, int);
00634 
00635 
00637 #ifdef DOC_PLUS_PLUS
00638 class PLongArray : public PBaseArray {
00639   public:
00645     PLongArray(
00646       PINDEX initialSize = 0  
00647     );
00648 
00651     PLongArray(
00652       long const * buffer,   
00653       PINDEX length,      
00654       PBoolean dynamic = PTrue 
00655     );
00657 };
00658 #endif
00659 PSCALAR_ARRAY(PLongArray, long);
00660 
00661 
00663 #ifdef DOC_PLUS_PLUS
00664 class PBYTEArray : public PBaseArray {
00665   public:
00671     PBYTEArray(
00672       PINDEX initialSize = 0  
00673     );
00674 
00677     PBYTEArray(
00678       BYTE const * buffer,   
00679       PINDEX length,      
00680       PBoolean dynamic = PTrue 
00681     );
00683 };
00684 #endif
00685 PDECLARE_BASEARRAY(PBYTEArray, BYTE);
00686   public:
00689 
00690     virtual void PrintOn(
00691       ostream & strm 
00692     ) const;
00694     virtual void ReadFrom(
00695       istream &strm   
00696     );
00698 };
00699 
00700 
00702 #ifdef DOC_PLUS_PLUS
00703 class PWORDArray : public PBaseArray {
00704   public:
00710     PWORDArray(
00711       PINDEX initialSize = 0  
00712     );
00713 
00716     PWORDArray(
00717       WORD const * buffer,   
00718       PINDEX length,      
00719       PBoolean dynamic = PTrue 
00720     );
00722 };
00723 #endif
00724 PSCALAR_ARRAY(PWORDArray, WORD);
00725 
00726 
00728 #ifdef DOC_PLUS_PLUS
00729 class PUnsignedArray : public PBaseArray {
00730   public:
00736     PUnsignedArray(
00737       PINDEX initialSize = 0  
00738     );
00739 
00742     PUnsignedArray(
00743       unsigned const * buffer,   
00744       PINDEX length,      
00745       PBoolean dynamic = PTrue 
00746     );
00748 };
00749 #endif
00750 PSCALAR_ARRAY(PUnsignedArray, unsigned);
00751 
00752 
00754 #ifdef DOC_PLUS_PLUS
00755 class PDWORDArray : public PBaseArray {
00756   public:
00762     PDWORDArray(
00763       PINDEX initialSize = 0  
00764     );
00765 
00768     PDWORDArray(
00769       DWORD const * buffer,   
00770       PINDEX length,      
00771       PBoolean dynamic = PTrue 
00772     );
00774 #endif
00775 PSCALAR_ARRAY(PDWORDArray, DWORD);
00776 
00777 
00779 // Linear array of objects
00780 
00802 class PArrayObjects : public PCollection
00803 {
00804   PCONTAINERINFO(PArrayObjects, PCollection);
00805 
00806   public:
00815     PINLINE PArrayObjects(
00816       PINDEX initialSize = 0  
00817     );
00819 
00852     virtual Comparison Compare(
00853       const PObject & obj   
00854     ) const;
00856 
00859 
00860     virtual PINDEX GetSize() const;
00861 
00870     virtual PBoolean SetSize(
00871       PINDEX newSize  
00872     );
00874 
00883     virtual PINDEX Append(
00884       PObject * obj   
00885     );
00886 
00902     virtual PINDEX Insert(
00903       const PObject & before,   
00904       PObject * obj             
00905     );
00906 
00917     virtual PINDEX InsertAt(
00918       PINDEX index,   
00919       PObject * obj   
00920     );
00921 
00930     virtual PBoolean Remove(
00931       const PObject * obj   
00932     );
00933 
00945     virtual PObject * RemoveAt(
00946       PINDEX index   
00947     );
00948 
00956     virtual PBoolean SetAt(
00957       PINDEX index,   
00958       PObject * val   
00959     );
00960 
00967     virtual PObject * GetAt(
00968       PINDEX index  
00969     ) const;
00970 
00978     virtual PINDEX GetObjectsIndex(
00979       const PObject * obj  
00980     ) const;
00981 
00991     virtual PINDEX GetValuesIndex(
00992       const PObject & obj   // Object to find equal of.
00993     ) const;
00994 
01001     virtual void RemoveAll();
01003 
01004   protected:
01005     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
01006     PBaseArray<PObject *> * theArray;
01007 };
01008 
01009 
01016 template <class T> class PArray : public PArrayObjects
01017 {
01018   PCLASSINFO(PArray, PArrayObjects);
01019 
01020   public:
01029     PArray( 
01030       PINDEX initialSize = 0  
01031     ) : PArrayObjects(initialSize) { }
01033 
01039     virtual PObject * Clone() const
01040       { return PNEW PArray(0, this); }
01042 
01052     T & operator[](
01053       PINDEX index  
01054     ) const {
01055       PObject * obj = GetAt(index);
01056       PAssert(obj != NULL, PInvalidArrayElement);
01057       return (T &)*obj;
01058     }
01060 
01061   protected:
01062     PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
01063 };
01064 
01065 
01077 #define PARRAY(cls, T) typedef PArray<T> cls
01078 
01079 
01092 #define PDECLARE_ARRAY(cls, T) \
01093   PARRAY(cls##_PTemplate, T); \
01094   PDECLARE_CLASS(cls, cls##_PTemplate) \
01095   protected: \
01096     inline cls(int dummy, const cls * c) \
01097       : cls##_PTemplate(dummy, c) { } \
01098   public: \
01099     inline cls(PINDEX initialSize = 0) \
01100       : cls##_PTemplate(initialSize) { } \
01101     virtual PObject * Clone() const \
01102       { return PNEW cls(0, this); } \
01103 
01104 
01107 class PBitArray : public PBYTEArray
01108 {
01109   PCLASSINFO(PBitArray, PBYTEArray);
01110 
01111   public:
01116     PBitArray(
01117       PINDEX initialSize = 0  
01118     );
01119     
01122     PBitArray(
01123       const void * buffer,   
01124       PINDEX length,         
01125       PBoolean dynamic = PTrue    
01126     );
01128 
01133     virtual PObject * Clone() const;
01135 
01144     virtual PINDEX GetSize() const;
01145 
01154     virtual PBoolean SetSize(
01155       PINDEX newSize  
01156     );
01157 
01164     PBoolean SetAt(
01165       PINDEX index,   
01166       PBoolean val           
01167     );
01168 
01175     PBoolean GetAt(
01176       PINDEX index  
01177     ) const;
01178 
01187     void Attach(
01188       const void * buffer,   
01189       PINDEX bufferSize      
01190     );
01191 
01205     BYTE * GetPointer(
01206       PINDEX minSize = 0    
01207     );
01209 
01221     PBoolean operator[](
01222       PINDEX index  
01223     ) const { return GetAt(index); }
01224 
01230     PBitArray & operator+=(
01231       PINDEX index  
01232     ) { SetAt(index, PTrue); return *this; }
01233 
01239     PBitArray & operator-=(
01240       PINDEX index  
01241     ) { SetAt(index, PFalse); return *this; }
01242 
01254     PBoolean Concatenate(
01255       const PBitArray & array  
01256     );
01258 };
01259 
01260 
01261 #endif
01262 // End Of File ///////////////////////////////////////////////////////////////

Generated on Wed May 7 00:47:55 2008 for PTLib by  doxygen 1.5.1