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: 19008 $
00030  * $Author: rjongbloed $
00031  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
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 
00254 #ifdef PHAS_TEMPLATES
00255 
00275 template <class T> class PBaseArray : public PAbstractArray
00276 {
00277   PCLASSINFO(PBaseArray, PAbstractArray);
00278 
00279   public:
00287     PBaseArray(
00288       PINDEX initialSize = 0  
00289     ) : PAbstractArray(sizeof(T), initialSize) { }
00290     
00293     PBaseArray(
00294       T const * buffer,   
00295       PINDEX length,      
00296       PBoolean dynamic = PTrue 
00297     ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { }
00299 
00304     virtual PObject * Clone() const
00305     { 
00306       return PNEW PBaseArray<T>(*this, GetSize());
00307     }
00309 
00318     PBoolean SetAt(
00319       PINDEX index,   
00320       T val           
00321     ) {
00322       return SetMinSize(index+1) && val==(((T *)theArray)[index] = val);
00323     }
00324 
00331     T GetAt(
00332       PINDEX index  
00333     ) const {
00334       PASSERTINDEX(index);
00335       return index < GetSize() ? ((T *)theArray)[index] : (T)0;
00336     }
00337 
00346     void Attach(
00347       const T * buffer,   
00348       PINDEX bufferSize   
00349     ) {
00350       PAbstractArray::Attach(buffer, bufferSize);
00351     }
00352 
00366     T * GetPointer(
00367       PINDEX minSize = 0    
00368     ) {
00369       return (T *)PAbstractArray::GetPointer(minSize);
00370     }
00372 
00384     T operator[](
00385       PINDEX index  
00386     ) const {
00387       return GetAt(index);
00388     }
00389 
00400     T & operator[](
00401       PINDEX index  
00402     ) {
00403       PASSERTINDEX(index);
00404       PAssert(SetMinSize(index+1), POutOfMemory);
00405       return ((T *)theArray)[index];
00406     }
00407 
00421     operator T const *() const {
00422       return (T const *)theArray;
00423     }
00424 
00436     PBoolean Concatenate(
00437       const PBaseArray & array  
00438     ) {
00439       return PAbstractArray::Concatenate(array);
00440     }
00442 
00443   protected:
00444     virtual void PrintElementOn(
00445       ostream & stream,
00446       PINDEX index
00447     ) const {
00448       stream << GetAt(index);
00449     }
00450 };
00451 
00452 /*Declare a dynamic array base type.
00453    This macro is used to declare a descendent of PAbstractArray class,
00454    customised for a particular element type {\bf T}. This macro closes the
00455    class declaration off so no additional members can be added.
00456 
00457    If the compilation is using templates then this macro produces a typedef
00458    of the #PBaseArray# template class.
00459  */
00460 #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls
00461 
00474 #define PDECLARE_BASEARRAY(cls, T) \
00475   PDECLARE_CLASS(cls, PBaseArray<T>) \
00476     cls(PINDEX initialSize = 0) \
00477       : PBaseArray<T>(initialSize) { } \
00478     cls(T const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00479       : PBaseArray<T>(buffer, length, dynamic) { } \
00480     virtual PObject * Clone() const \
00481       { return PNEW cls(*this, GetSize()); } \
00482 
00483 
00502 template <class T> class PScalarArray : public PBaseArray<T>
00503 {
00504   public:
00512     PScalarArray(
00513       PINDEX initialSize = 0  
00514     ) : PBaseArray<T>(initialSize) { }
00515     
00518     PScalarArray(
00519       T const * buffer,   
00520       PINDEX length,      
00521       PBoolean dynamic = PTrue 
00522     ) : PBaseArray<T>(buffer, length, dynamic) { }
00524 
00525   protected:
00526     virtual void ReadElementFrom(
00527       istream & stream,
00528       PINDEX index
00529     ) {
00530       T t;
00531       stream >> t;
00532       if (!stream.fail())
00533         SetAt(index, t);
00534     }
00535 };
00536 
00537 
00538 /*Declare a dynamic array base type.
00539    This macro is used to declare a descendent of PAbstractArray class,
00540    customised for a particular element type {\bf T}. This macro closes the
00541    class declaration off so no additional members can be added.
00542 
00543    If the compilation is using templates then this macro produces a typedef
00544    of the #PBaseArray# template class.
00545  */
00546 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls
00547 
00548 #else // PHAS_TEMPLATES
00549 
00550 #define PBASEARRAY(cls, T) \
00551   typedef T P_##cls##_Base_Type; \
00552   class cls : public PAbstractArray { \
00553     PCLASSINFO(cls, PAbstractArray) \
00554   public: \
00555     inline cls(PINDEX initialSize = 0) \
00556       : PAbstractArray(sizeof(P_##cls##_Base_Type), initialSize) { } \
00557     inline cls(P_##cls##_Base_Type const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00558       : PAbstractArray(sizeof(P_##cls##_Base_Type), buffer, length, dynamic) { } \
00559     virtual PObject * Clone() const \
00560       { return PNEW cls(*this, GetSize()); } \
00561     inline PBoolean SetAt(PINDEX index, P_##cls##_Base_Type val) \
00562       { return SetMinSize(index+1) && \
00563                      val==(((P_##cls##_Base_Type *)theArray)[index] = val); } \
00564     inline P_##cls##_Base_Type GetAt(PINDEX index) const \
00565       { PASSERTINDEX(index); return index < GetSize() ? \
00566           ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } \
00567     inline P_##cls##_Base_Type operator[](PINDEX index) const \
00568       { PASSERTINDEX(index); return GetAt(index); } \
00569     inline P_##cls##_Base_Type & operator[](PINDEX index) \
00570       { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); \
00571         return ((P_##cls##_Base_Type *)theArray)[index]; } \
00572     inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) \
00573       { PAbstractArray::Attach(buffer, bufferSize); } \
00574     inline P_##cls##_Base_Type * GetPointer(PINDEX minSize = 0) \
00575       { return (P_##cls##_Base_Type *)PAbstractArray::GetPointer(minSize); } \
00576     inline operator P_##cls##_Base_Type const *() const \
00577       { return (P_##cls##_Base_Type const *)theArray; } \
00578     inline PBoolean Concatenate(cls const & array) \
00579       { return PAbstractArray::Concatenate(array); } \
00580   }
00581 
00582 #define PDECLARE_BASEARRAY(cls, T) \
00583   PBASEARRAY(cls##_PTemplate, T); \
00584   PDECLARE_CLASS(cls, cls##_PTemplate) \
00585     cls(PINDEX initialSize = 0) \
00586       : cls##_PTemplate(initialSize) { } \
00587     cls(T const * buffer, PINDEX length, PBoolean dynamic = PTrue) \
00588       : cls##_PTemplate(buffer, length, dynamic) { } \
00589     virtual PObject * Clone() const \
00590       { return PNEW cls(*this, GetSize()); } \
00591 
00592 #define PSCALAR_ARRAY(cls, T) PBASEARRAY(cls, T)
00593 
00594 #endif // PHAS_TEMPLATES
00595 
00596 
00598 #ifdef DOC_PLUS_PLUS
00599 class PCharArray : public PBaseArray {
00600   public:
00606     PCharArray(
00607       PINDEX initialSize = 0  
00608     );
00609 
00612     PCharArray(
00613       char const * buffer,   
00614       PINDEX length,      
00615       PBoolean dynamic = PTrue 
00616     );
00618 #endif
00619 PDECLARE_BASEARRAY(PCharArray, char);
00620   public:
00623 
00624     virtual void PrintOn(
00625       ostream & strm 
00626     ) const;
00628     virtual void ReadFrom(
00629       istream &strm   // Stream to read the objects contents from.
00630     );
00632 };
00633 
00635 #ifdef DOC_PLUS_PLUS
00636 class PShortArray : public PBaseArray {
00637   public:
00643     PShortArray(
00644       PINDEX initialSize = 0  
00645     );
00646 
00649     PShortArray(
00650       short const * buffer,   
00651       PINDEX length,      
00652       PBoolean dynamic = PTrue 
00653     );
00655 };
00656 #endif
00657 PSCALAR_ARRAY(PShortArray, short);
00658 
00659 
00661 #ifdef DOC_PLUS_PLUS
00662 class PIntArray : public PBaseArray {
00663   public:
00669     PIntArray(
00670       PINDEX initialSize = 0  
00671     );
00672 
00675     PIntArray(
00676       int const * buffer,   
00677       PINDEX length,      
00678       PBoolean dynamic = PTrue 
00679     );
00681 };
00682 #endif
00683 PSCALAR_ARRAY(PIntArray, int);
00684 
00685 
00687 #ifdef DOC_PLUS_PLUS
00688 class PLongArray : public PBaseArray {
00689   public:
00695     PLongArray(
00696       PINDEX initialSize = 0  
00697     );
00698 
00701     PLongArray(
00702       long const * buffer,   
00703       PINDEX length,      
00704       PBoolean dynamic = PTrue 
00705     );
00707 };
00708 #endif
00709 PSCALAR_ARRAY(PLongArray, long);
00710 
00711 
00713 #ifdef DOC_PLUS_PLUS
00714 class PBYTEArray : public PBaseArray {
00715   public:
00721     PBYTEArray(
00722       PINDEX initialSize = 0  
00723     );
00724 
00727     PBYTEArray(
00728       BYTE const * buffer,   
00729       PINDEX length,      
00730       PBoolean dynamic = PTrue 
00731     );
00733 };
00734 #endif
00735 PDECLARE_BASEARRAY(PBYTEArray, BYTE);
00736   public:
00739 
00740     virtual void PrintOn(
00741       ostream & strm 
00742     ) const;
00744     virtual void ReadFrom(
00745       istream &strm   
00746     );
00748 };
00749 
00750 
00752 #ifdef DOC_PLUS_PLUS
00753 class PWORDArray : public PBaseArray {
00754   public:
00760     PWORDArray(
00761       PINDEX initialSize = 0  
00762     );
00763 
00766     PWORDArray(
00767       WORD const * buffer,   
00768       PINDEX length,      
00769       PBoolean dynamic = PTrue 
00770     );
00772 };
00773 #endif
00774 PSCALAR_ARRAY(PWORDArray, WORD);
00775 
00776 
00778 #ifdef DOC_PLUS_PLUS
00779 class PUnsignedArray : public PBaseArray {
00780   public:
00786     PUnsignedArray(
00787       PINDEX initialSize = 0  
00788     );
00789 
00792     PUnsignedArray(
00793       unsigned const * buffer,   
00794       PINDEX length,      
00795       PBoolean dynamic = PTrue 
00796     );
00798 };
00799 #endif
00800 PSCALAR_ARRAY(PUnsignedArray, unsigned);
00801 
00802 
00804 #ifdef DOC_PLUS_PLUS
00805 class PDWORDArray : public PBaseArray {
00806   public:
00812     PDWORDArray(
00813       PINDEX initialSize = 0  
00814     );
00815 
00818     PDWORDArray(
00819       DWORD const * buffer,   
00820       PINDEX length,      
00821       PBoolean dynamic = PTrue 
00822     );
00824 #endif
00825 PSCALAR_ARRAY(PDWORDArray, DWORD);
00826 
00827 
00829 // Linear array of objects
00830 
00852 class PArrayObjects : public PCollection
00853 {
00854   PCONTAINERINFO(PArrayObjects, PCollection);
00855 
00856   public:
00865     PINLINE PArrayObjects(
00866       PINDEX initialSize = 0  
00867     );
00869 
00902     virtual Comparison Compare(
00903       const PObject & obj   
00904     ) const;
00906 
00909 
00910     virtual PINDEX GetSize() const;
00911 
00920     virtual PBoolean SetSize(
00921       PINDEX newSize  
00922     );
00924 
00933     virtual PINDEX Append(
00934       PObject * obj   
00935     );
00936 
00952     virtual PINDEX Insert(
00953       const PObject & before,   
00954       PObject * obj             
00955     );
00956 
00967     virtual PINDEX InsertAt(
00968       PINDEX index,   
00969       PObject * obj   
00970     );
00971 
00980     virtual PBoolean Remove(
00981       const PObject * obj   
00982     );
00983 
00995     virtual PObject * RemoveAt(
00996       PINDEX index   
00997     );
00998 
01006     virtual PBoolean SetAt(
01007       PINDEX index,   
01008       PObject * val   
01009     );
01010 
01017     virtual PObject * GetAt(
01018       PINDEX index  
01019     ) const;
01020 
01028     virtual PINDEX GetObjectsIndex(
01029       const PObject * obj  
01030     ) const;
01031 
01041     virtual PINDEX GetValuesIndex(
01042       const PObject & obj   // Object to find equal of.
01043     ) const;
01044 
01051     virtual void RemoveAll();
01053 
01054   protected:
01055     PBASEARRAY(ObjPtrArray, PObject *);
01056     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
01057     PBaseArray<PObject *> * theArray;
01058 };
01059 
01060 
01061 #ifdef PHAS_TEMPLATES
01062 
01069 template <class T> class PArray : public PArrayObjects
01070 {
01071   PCLASSINFO(PArray, PArrayObjects);
01072 
01073   public:
01082     PArray( 
01083       PINDEX initialSize = 0  
01084     ) : PArrayObjects(initialSize) { }
01086 
01092     virtual PObject * Clone() const
01093       { return PNEW PArray(0, this); }
01095 
01105     T & operator[](
01106       PINDEX index  
01107     ) const {
01108       PObject * obj = GetAt(index);
01109       PAssert(obj != NULL, PInvalidArrayElement);
01110       return (T &)*obj;
01111     }
01113 
01114   protected:
01115     PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
01116 };
01117 
01118 
01130 #define PARRAY(cls, T) typedef PArray<T> cls
01131 
01132 
01145 #define PDECLARE_ARRAY(cls, T) \
01146   PARRAY(cls##_PTemplate, T); \
01147   PDECLARE_CLASS(cls, cls##_PTemplate) \
01148   protected: \
01149     inline cls(int dummy, const cls * c) \
01150       : cls##_PTemplate(dummy, c) { } \
01151   public: \
01152     inline cls(PINDEX initialSize = 0) \
01153       : cls##_PTemplate(initialSize) { } \
01154     virtual PObject * Clone() const \
01155       { return PNEW cls(0, this); } \
01156 
01157 #else // PHAS_TEMPLATES
01158 
01159 
01160 #define PARRAY(cls, T) \
01161   class cls : public PArrayObjects { \
01162   PCLASSINFO(cls, PArrayObjects); \
01163   protected: \
01164     inline cls(int dummy, const cls * c) \
01165       : PArrayObjects(dummy, c) { } \
01166   public: \
01167     inline cls(PINDEX initialSize = 0) \
01168       : PArrayObjects(initialSize) { } \
01169     virtual PObject * Clone() const \
01170       { return PNEW cls(0, this); } \
01171     inline T & operator[](PINDEX index) const\
01172       { PObject * obj = GetAt(index); \
01173         PAssert(obj != NULL, PInvalidArrayElement); \
01174         /* want to do to this, but gcc 3.0 complains --> return *(T *)obj; } */ \
01175         return (T &)*obj; } \
01176   }
01177 
01178 #define PDECLARE_ARRAY(cls, T) \
01179   PARRAY(cls##_PTemplate, T); \
01180   PDECLARE_CLASS(cls, cls##_PTemplate) \
01181   protected: \
01182     inline cls(int dummy, const cls * c) \
01183       : cls##_PTemplate(dummy, c) { } \
01184   public: \
01185     inline cls(PINDEX initialSize = 0) \
01186       : cls##_PTemplate(initialSize) { } \
01187     virtual PObject * Clone() const \
01188       { return PNEW cls(0, this); } \
01189 
01190 #endif // PHAS_TEMPLATES
01191 
01192 
01195 class PBitArray : public PBYTEArray
01196 {
01197   PCLASSINFO(PBitArray, PBYTEArray);
01198 
01199   public:
01204     PBitArray(
01205       PINDEX initialSize = 0  
01206     );
01207     
01210     PBitArray(
01211       const void * buffer,   
01212       PINDEX length,         
01213       PBoolean dynamic = PTrue    
01214     );
01216 
01221     virtual PObject * Clone() const;
01223 
01232     virtual PINDEX GetSize() const;
01233 
01242     virtual PBoolean SetSize(
01243       PINDEX newSize  
01244     );
01245 
01252     PBoolean SetAt(
01253       PINDEX index,   
01254       PBoolean val           
01255     );
01256 
01263     PBoolean GetAt(
01264       PINDEX index  
01265     ) const;
01266 
01275     void Attach(
01276       const void * buffer,   
01277       PINDEX bufferSize      
01278     );
01279 
01293     BYTE * GetPointer(
01294       PINDEX minSize = 0    
01295     );
01297 
01309     PBoolean operator[](
01310       PINDEX index  
01311     ) const { return GetAt(index); }
01312 
01318     PBitArray & operator+=(
01319       PINDEX index  
01320     ) { SetAt(index, PTrue); return *this; }
01321 
01327     PBitArray & operator-=(
01328       PINDEX index  
01329     ) { SetAt(index, PFalse); return *this; }
01330 
01342     PBoolean Concatenate(
01343       const PBitArray & array  
01344     );
01346 };
01347 
01348 
01349 #endif
01350 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Dec 10 11:18:56 2007 for PTLib by  doxygen 1.5.1