PTLib  Version 2.10.4
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 ///////////////////////////////////////////////////////////////
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines