# array.h

Go to the documentation of this file.

    00001 /*
    00002  * array.h
    00003  *
    00004  * Linear Array Container classes.
    00005  *
    00006  * Portable Tools 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: 25387 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2011-03-22 22:51:09 -0500 (Tue, 22 Mar 2011) $
    00032  */
    00033
    00034 #ifndef PTLIB_ARRAY_H
    00035 #define PTLIB_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   public:
    00082     PAbstractArray(
    00083       PINDEX elementSizeInBytes,
    00084
    00085       PINDEX initialSize = 0
    00086     );
    00087
    00105     PAbstractArray(
    00106       PINDEX elementSizeInBytes,
    00107
    00108       const void *buffer,
    00109       PINDEX bufferSizeInElements,
    00110       PBoolean dynamicAllocation
    00111     );
    00113
    00122     virtual void PrintOn(
    00123       ostream &strm   // Stream to print the object into.
    00124     ) const;
    00125
    00132     virtual void ReadFrom(
    00133       istream &strm   // Stream to read the objects contents from.
    00134     );
    00135
    00155     virtual Comparison Compare(
    00156       const PObject & obj
    00157     ) const;
    00159
    00170     virtual PBoolean SetSize(
    00171       PINDEX newSize
    00172     );
    00174
    00185     void Attach(
    00186       const void *buffer,
    00187       PINDEX bufferSize
    00188     );
    00189
    00203     void * GetPointer(
    00204       PINDEX minSize = 1
    00205     );
    00206
    00219     PBoolean Concatenate(
    00220       const PAbstractArray & array
    00221     );
    00223
    00224   protected:
    00225     PBoolean InternalSetSize(PINDEX newSize, PBoolean force);
    00226
    00227     virtual void PrintElementOn(
    00228       ostream & stream,
    00229       PINDEX index
    00230     ) const;
    00231     virtual void ReadElementFrom(
    00232       istream & stream,
    00233       PINDEX index
    00234     );
    00235
    00236     PAbstractArray(
    00237       PContainerReference & reference,
    00238       PINDEX elementSizeInBytes
    00239     );
    00240
    00242     PINDEX elementSize;
    00243
    00245     char * theArray;
    00246
    00248     PBoolean allocatedDynamically;
    00249
    00250   friend class PArrayObjects;
    00251 };
    00252
    00253
    00255 // An array of some base type
    00256
    00274 template <class T> class PBaseArray : public PAbstractArray
    00275 {
    00276     PCLASSINFO(PBaseArray, PAbstractArray);
    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 = true
    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     PBaseArray(PContainerReference & reference) : PAbstractArray(reference, sizeof(T)) { }
    00450 };
    00451
    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(PContainerReference & reference) \
    00479       : PBaseArray<T>(reference) { } \
    00480     cls(T const * buffer, PINDEX length, PBoolean dynamic = true) \
    00481       : PBaseArray<T>(buffer, length, dynamic) { } \
    00482     virtual PObject * Clone() const \
    00483       { return PNEW cls(*this, GetSize()); } \
    00484
    00485
    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 = true
    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         this->SetAt(index, t);
    00534     }
    00535 };
    00536
    00537
    00546 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls
    00547
    00548
    00550 #ifdef DOC_PLUS_PLUS
    00551 class PCharArray : public PBaseArray {
    00552   public:
    00558     PCharArray(
    00559       PINDEX initialSize = 0
    00560     );
    00561
    00564     PCharArray(
    00565       char const * buffer,
    00566       PINDEX length,
    00567       PBoolean dynamic = true
    00568     );
    00570 #else
    00571 PDECLARE_BASEARRAY(PCharArray, char);
    00572 #endif
    00573   public:
    00576
    00577     virtual void PrintOn(
    00578       ostream & strm
    00579     ) const;
    00581     virtual void ReadFrom(
    00582       istream &strm   // Stream to read the objects contents from.
    00583     );
    00585 };
    00586
    00588 #ifdef DOC_PLUS_PLUS
    00589 class PShortArray : public PBaseArray {
    00590   public:
    00596     PShortArray(
    00597       PINDEX initialSize = 0
    00598     );
    00599
    00602     PShortArray(
    00603       short const * buffer,
    00604       PINDEX length,
    00605       PBoolean dynamic = true
    00606     );
    00608 };
    00609 #else
    00610 PSCALAR_ARRAY(PShortArray, short);
    00611 #endif
    00612
    00613
    00615 #ifdef DOC_PLUS_PLUS
    00616 class PIntArray : public PBaseArray {
    00617   public:
    00623     PIntArray(
    00624       PINDEX initialSize = 0
    00625     );
    00626
    00629     PIntArray(
    00630       int const * buffer,
    00631       PINDEX length,
    00632       PBoolean dynamic = true
    00633     );
    00635 };
    00636 #else
    00637 PSCALAR_ARRAY(PIntArray, int);
    00638 #endif
    00639
    00640
    00642 #ifdef DOC_PLUS_PLUS
    00643 class PLongArray : public PBaseArray {
    00644   public:
    00650     PLongArray(
    00651       PINDEX initialSize = 0
    00652     );
    00653
    00656     PLongArray(
    00657       long const * buffer,
    00658       PINDEX length,
    00659       PBoolean dynamic = true
    00660     );
    00662 };
    00663 #else
    00664 PSCALAR_ARRAY(PLongArray, long);
    00665 #endif
    00666
    00667
    00669 #ifdef DOC_PLUS_PLUS
    00670 class PBYTEArray : public PBaseArray {
    00671   public:
    00677     PBYTEArray(
    00678       PINDEX initialSize = 0
    00679     );
    00680
    00683     PBYTEArray(
    00684       BYTE const * buffer,
    00685       PINDEX length,
    00686       PBoolean dynamic = true
    00687     );
    00689 };
    00690 #else
    00691 PDECLARE_BASEARRAY(PBYTEArray, BYTE);
    00692 #endif
    00693   public:
    00696
    00697     virtual void PrintOn(
    00698       ostream & strm
    00699     ) const;
    00701     virtual void ReadFrom(
    00702       istream &strm
    00703     );
    00705 };
    00706
    00707
    00709 #ifdef DOC_PLUS_PLUS
    00710 class PWORDArray : public PBaseArray {
    00711   public:
    00717     PWORDArray(
    00718       PINDEX initialSize = 0
    00719     );
    00720
    00723     PWORDArray(
    00724       WORD const * buffer,
    00725       PINDEX length,
    00726       PBoolean dynamic = true
    00727     );
    00729 };
    00730 #else
    00731 PSCALAR_ARRAY(PWORDArray, WORD);
    00732 #endif
    00733
    00734
    00736 #ifdef DOC_PLUS_PLUS
    00737 class PUnsignedArray : public PBaseArray {
    00738   public:
    00744     PUnsignedArray(
    00745       PINDEX initialSize = 0
    00746     );
    00747
    00750     PUnsignedArray(
    00751       unsigned const * buffer,
    00752       PINDEX length,
    00753       PBoolean dynamic = true
    00754     );
    00756 };
    00757 #else
    00758 PSCALAR_ARRAY(PUnsignedArray, unsigned);
    00759 #endif
    00760
    00761
    00763 #ifdef DOC_PLUS_PLUS
    00764 class PDWORDArray : public PBaseArray {
    00765   public:
    00771     PDWORDArray(
    00772       PINDEX initialSize = 0
    00773     );
    00774
    00777     PDWORDArray(
    00778       DWORD const * buffer,
    00779       PINDEX length,
    00780       PBoolean dynamic = true
    00781     );
    00783 };
    00784 #else
    00785 PSCALAR_ARRAY(PDWORDArray, DWORD);
    00786 #endif
    00787
    00788
    00790 // Linear array of objects
    00791
    00813 class PArrayObjects : public PCollection
    00814 {
    00815     PCONTAINERINFO(PArrayObjects, PCollection);
    00816   public:
    00825     PINLINE PArrayObjects(
    00826       PINDEX initialSize = 0
    00827     );
    00829
    00859     virtual Comparison Compare(
    00860       const PObject & obj
    00861     ) const;
    00863
    00866
    00867     virtual PINDEX GetSize() const;
    00868
    00877     virtual PBoolean SetSize(
    00878       PINDEX newSize
    00879     );
    00881
    00890     virtual PINDEX Append(
    00891       PObject * obj
    00892     );
    00893
    00909     virtual PINDEX Insert(
    00910       const PObject & before,
    00911       PObject * obj
    00912     );
    00913
    00924     virtual PINDEX InsertAt(
    00925       PINDEX index,
    00926       PObject * obj
    00927     );
    00928
    00937     virtual PBoolean Remove(
    00938       const PObject * obj
    00939     );
    00940
    00952     virtual PObject * RemoveAt(
    00953       PINDEX index
    00954     );
    00955
    00963     virtual PBoolean SetAt(
    00964       PINDEX index,
    00965       PObject * val
    00966     );
    00967
    00974     virtual PObject * GetAt(
    00975       PINDEX index
    00976     ) const;
    00977
    00985     virtual PINDEX GetObjectsIndex(
    00986       const PObject * obj
    00987     ) const;
    00988
    00998     virtual PINDEX GetValuesIndex(
    00999       const PObject & obj   // Object to find equal of.
    01000     ) const;
    01001
    01008     virtual void RemoveAll();
    01010
    01011   protected:
    01012     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
    01013     PBaseArray<PObject *> * theArray;
    01014 };
    01015
    01016
    01024 template <class T> class PArray : public PArrayObjects
    01025 {
    01026     PCLASSINFO(PArray, PArrayObjects);
    01027   public:
    01036     PArray(
    01037       PINDEX initialSize = 0
    01038     ) : PArrayObjects(initialSize) { }
    01040
    01046     virtual PObject * Clone() const
    01047       { return PNEW PArray(0, this); }
    01049
    01059     T & operator[](
    01060       PINDEX index
    01061     ) const {
    01062       PObject * obj = GetAt(index);
    01063       PAssert(obj != NULL, PInvalidArrayElement);
    01064       return (T &)*obj;
    01065     }
    01067
    01068   protected:
    01069     PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
    01070 };
    01071
    01072
    01084 #define PARRAY(cls, T) typedef PArray<T> cls
    01085
    01086
    01099 #define PDECLARE_ARRAY(cls, T) \
    01100   PARRAY(cls##_PTemplate, T); \
    01101   PDECLARE_CLASS(cls, cls##_PTemplate) \
    01102   protected: \
    01103     inline cls(int dummy, const cls * c) \
    01104       : cls##_PTemplate(dummy, c) { } \
    01105   public: \
    01106     inline cls(PINDEX initialSize = 0) \
    01107       : cls##_PTemplate(initialSize) { } \
    01108     virtual PObject * Clone() const \
    01109       { return PNEW cls(0, this); } \
    01110
    01111
    01114 class PBitArray : public PBYTEArray
    01115 {
    01116   PCLASSINFO(PBitArray, PBYTEArray);
    01117
    01118   public:
    01123     PBitArray(
    01124       PINDEX initialSize = 0
    01125     );
    01126
    01129     PBitArray(
    01130       const void * buffer,
    01131       PINDEX length,
    01132       PBoolean dynamic = true
    01133     );
    01135
    01140     virtual PObject * Clone() const;
    01142
    01151     virtual PINDEX GetSize() const;
    01152
    01161     virtual PBoolean SetSize(
    01162       PINDEX newSize
    01163     );
    01164
    01171     PBoolean SetAt(
    01172       PINDEX index,
    01173       PBoolean val
    01174     );
    01175
    01182     PBoolean GetAt(
    01183       PINDEX index
    01184     ) const;
    01185
    01194     void Attach(
    01195       const void * buffer,
    01196       PINDEX bufferSize
    01197     );
    01198
    01212     BYTE * GetPointer(
    01213       PINDEX minSize = 0
    01214     );
    01216
    01228     PBoolean operator[](
    01229       PINDEX index
    01230     ) const { return GetAt(index); }
    01231
    01237     PBitArray & operator+=(
    01238       PINDEX index
    01239     ) { SetAt(index, true); return *this; }
    01240
    01246     PBitArray & operator-=(
    01247       PINDEX index
    01248     ) { SetAt(index, false); return *this; }
    01249
    01261     PBoolean Concatenate(
    01262       const PBitArray & array
    01263     );
    01265 };
    01266
    01267
    01268 #endif // PTLIB_ARRAY_H
    01269
    01270
    01271 // End Of File ///////////////////////////////////////////////////////////////