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: 24177 $
00030  * $Author: rjongbloed $
00031  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
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 
00237     PINDEX elementSize;
00238 
00240     char * theArray;
00241 
00243     PBoolean allocatedDynamically;
00244 
00245   friend class PArrayObjects;
00246 };
00247 
00248 
00250 // An array of some base type
00251 
00269 template <class T> class PBaseArray : public PAbstractArray
00270 {
00271     PCLASSINFO(PBaseArray, PAbstractArray);
00272   public:
00280     PBaseArray(
00281       PINDEX initialSize = 0  
00282     ) : PAbstractArray(sizeof(T), initialSize) { }
00283 
00286     PBaseArray(
00287       T const * buffer,   
00288       PINDEX length,      
00289       PBoolean dynamic = true 
00290     ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { }
00292 
00297     virtual PObject * Clone() const
00298     {
00299       return PNEW PBaseArray<T>(*this, GetSize());
00300     }
00302 
00311     PBoolean SetAt(
00312       PINDEX index,   
00313       T val           
00314     ) {
00315       return SetMinSize(index+1) && val==(((T *)theArray)[index] = val);
00316     }
00317 
00324     T GetAt(
00325       PINDEX index  
00326     ) const {
00327       PASSERTINDEX(index);
00328       return index < GetSize() ? ((T *)theArray)[index] : (T)0;
00329     }
00330 
00339     void Attach(
00340       const T * buffer,   
00341       PINDEX bufferSize   
00342     ) {
00343       PAbstractArray::Attach(buffer, bufferSize);
00344     }
00345 
00359     T * GetPointer(
00360       PINDEX minSize = 0    
00361     ) {
00362       return (T *)PAbstractArray::GetPointer(minSize);
00363     }
00365 
00377     T operator[](
00378       PINDEX index  
00379     ) const {
00380       return GetAt(index);
00381     }
00382 
00393     T & operator[](
00394       PINDEX index  
00395     ) {
00396       PASSERTINDEX(index);
00397       PAssert(SetMinSize(index+1), POutOfMemory);
00398       return ((T *)theArray)[index];
00399     }
00400 
00414     operator T const *() const {
00415       return (T const *)theArray;
00416     }
00417 
00429     PBoolean Concatenate(
00430       const PBaseArray & array  
00431     ) {
00432       return PAbstractArray::Concatenate(array);
00433     }
00435 
00436   protected:
00437     virtual void PrintElementOn(
00438       ostream & stream,
00439       PINDEX index
00440     ) const {
00441       stream << GetAt(index);
00442     }
00443 };
00444 
00453 #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls
00454 
00467 #define PDECLARE_BASEARRAY(cls, T) \
00468   PDECLARE_CLASS(cls, PBaseArray<T>) \
00469     cls(PINDEX initialSize = 0) \
00470       : PBaseArray<T>(initialSize) { } \
00471     cls(T const * buffer, PINDEX length, PBoolean dynamic = true) \
00472       : PBaseArray<T>(buffer, length, dynamic) { } \
00473     virtual PObject * Clone() const \
00474       { return PNEW cls(*this, GetSize()); } \
00475 
00476 
00493 template <class T> class PScalarArray : public PBaseArray<T>
00494 {
00495   public:
00503     PScalarArray(
00504       PINDEX initialSize = 0  
00505     ) : PBaseArray<T>(initialSize) { }
00506 
00509     PScalarArray(
00510       T const * buffer,   
00511       PINDEX length,      
00512       PBoolean dynamic = true 
00513     ) : PBaseArray<T>(buffer, length, dynamic) { }
00515 
00516   protected:
00517     virtual void ReadElementFrom(
00518       istream & stream,
00519       PINDEX index
00520     ) {
00521       T t;
00522       stream >> t;
00523       if (!stream.fail())
00524         SetAt(index, t);
00525     }
00526 };
00527 
00528 
00537 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls
00538 
00539 
00541 #ifdef DOC_PLUS_PLUS
00542 class PCharArray : public PBaseArray {
00543   public:
00549     PCharArray(
00550       PINDEX initialSize = 0  
00551     );
00552 
00555     PCharArray(
00556       char const * buffer,   
00557       PINDEX length,      
00558       PBoolean dynamic = true 
00559     );
00561 #else
00562 PDECLARE_BASEARRAY(PCharArray, char);
00563 #endif
00564   public:
00567 
00568     virtual void PrintOn(
00569       ostream & strm 
00570     ) const;
00572     virtual void ReadFrom(
00573       istream &strm   // Stream to read the objects contents from.
00574     );
00576 };
00577 
00579 #ifdef DOC_PLUS_PLUS
00580 class PShortArray : public PBaseArray {
00581   public:
00587     PShortArray(
00588       PINDEX initialSize = 0  
00589     );
00590 
00593     PShortArray(
00594       short const * buffer,   
00595       PINDEX length,      
00596       PBoolean dynamic = true 
00597     );
00599 };
00600 #else
00601 PSCALAR_ARRAY(PShortArray, short);
00602 #endif
00603 
00604 
00606 #ifdef DOC_PLUS_PLUS
00607 class PIntArray : public PBaseArray {
00608   public:
00614     PIntArray(
00615       PINDEX initialSize = 0  
00616     );
00617 
00620     PIntArray(
00621       int const * buffer,   
00622       PINDEX length,      
00623       PBoolean dynamic = true 
00624     );
00626 };
00627 #else
00628 PSCALAR_ARRAY(PIntArray, int);
00629 #endif
00630 
00631 
00633 #ifdef DOC_PLUS_PLUS
00634 class PLongArray : public PBaseArray {
00635   public:
00641     PLongArray(
00642       PINDEX initialSize = 0  
00643     );
00644 
00647     PLongArray(
00648       long const * buffer,   
00649       PINDEX length,      
00650       PBoolean dynamic = true 
00651     );
00653 };
00654 #else
00655 PSCALAR_ARRAY(PLongArray, long);
00656 #endif
00657 
00658 
00660 #ifdef DOC_PLUS_PLUS
00661 class PBYTEArray : public PBaseArray {
00662   public:
00668     PBYTEArray(
00669       PINDEX initialSize = 0  
00670     );
00671 
00674     PBYTEArray(
00675       BYTE const * buffer,   
00676       PINDEX length,      
00677       PBoolean dynamic = true 
00678     );
00680 };
00681 #else
00682 PDECLARE_BASEARRAY(PBYTEArray, BYTE);
00683 #endif
00684   public:
00687 
00688     virtual void PrintOn(
00689       ostream & strm 
00690     ) const;
00692     virtual void ReadFrom(
00693       istream &strm   
00694     );
00696 };
00697 
00698 
00700 #ifdef DOC_PLUS_PLUS
00701 class PWORDArray : public PBaseArray {
00702   public:
00708     PWORDArray(
00709       PINDEX initialSize = 0  
00710     );
00711 
00714     PWORDArray(
00715       WORD const * buffer,   
00716       PINDEX length,      
00717       PBoolean dynamic = true 
00718     );
00720 };
00721 #else
00722 PSCALAR_ARRAY(PWORDArray, WORD);
00723 #endif
00724 
00725 
00727 #ifdef DOC_PLUS_PLUS
00728 class PUnsignedArray : public PBaseArray {
00729   public:
00735     PUnsignedArray(
00736       PINDEX initialSize = 0  
00737     );
00738 
00741     PUnsignedArray(
00742       unsigned const * buffer,  
00743       PINDEX length,            
00744       PBoolean dynamic = true   
00745     );
00747 };
00748 #else
00749 PSCALAR_ARRAY(PUnsignedArray, unsigned);
00750 #endif
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 = true 
00772     );
00774 };
00775 #else
00776 PSCALAR_ARRAY(PDWORDArray, DWORD);
00777 #endif
00778 
00779 
00781 // Linear array of objects
00782 
00804 class PArrayObjects : public PCollection
00805 {
00806     PCONTAINERINFO(PArrayObjects, PCollection);
00807   public:
00816     PINLINE PArrayObjects(
00817       PINDEX initialSize = 0  
00818     );
00820 
00850     virtual Comparison Compare(
00851       const PObject & obj   
00852     ) const;
00854 
00857 
00858     virtual PINDEX GetSize() const;
00859 
00868     virtual PBoolean SetSize(
00869       PINDEX newSize  
00870     );
00872 
00881     virtual PINDEX Append(
00882       PObject * obj   
00883     );
00884 
00900     virtual PINDEX Insert(
00901       const PObject & before,   
00902       PObject * obj             
00903     );
00904 
00915     virtual PINDEX InsertAt(
00916       PINDEX index,   
00917       PObject * obj   
00918     );
00919 
00928     virtual PBoolean Remove(
00929       const PObject * obj   
00930     );
00931 
00943     virtual PObject * RemoveAt(
00944       PINDEX index   
00945     );
00946 
00954     virtual PBoolean SetAt(
00955       PINDEX index,   
00956       PObject * val   
00957     );
00958 
00965     virtual PObject * GetAt(
00966       PINDEX index  
00967     ) const;
00968 
00976     virtual PINDEX GetObjectsIndex(
00977       const PObject * obj  
00978     ) const;
00979 
00989     virtual PINDEX GetValuesIndex(
00990       const PObject & obj   // Object to find equal of.
00991     ) const;
00992 
00999     virtual void RemoveAll();
01001 
01002   protected:
01003     // The type below cannot be nested as DevStudio 2005 AUTOEXP.DAT doesn't like it
01004     PBaseArray<PObject *> * theArray;
01005 };
01006 
01007 
01015 template <class T> class PArray : public PArrayObjects
01016 {
01017     PCLASSINFO(PArray, PArrayObjects);
01018   public:
01027     PArray(
01028       PINDEX initialSize = 0  
01029     ) : PArrayObjects(initialSize) { }
01031 
01037     virtual PObject * Clone() const
01038       { return PNEW PArray(0, this); }
01040 
01050     T & operator[](
01051       PINDEX index  
01052     ) const {
01053       PObject * obj = GetAt(index);
01054       PAssert(obj != NULL, PInvalidArrayElement);
01055       return (T &)*obj;
01056     }
01058 
01059   protected:
01060     PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { }
01061 };
01062 
01063 
01075 #define PARRAY(cls, T) typedef PArray<T> cls
01076 
01077 
01090 #define PDECLARE_ARRAY(cls, T) \
01091   PARRAY(cls##_PTemplate, T); \
01092   PDECLARE_CLASS(cls, cls##_PTemplate) \
01093   protected: \
01094     inline cls(int dummy, const cls * c) \
01095       : cls##_PTemplate(dummy, c) { } \
01096   public: \
01097     inline cls(PINDEX initialSize = 0) \
01098       : cls##_PTemplate(initialSize) { } \
01099     virtual PObject * Clone() const \
01100       { return PNEW cls(0, this); } \
01101 
01102 
01105 class PBitArray : public PBYTEArray
01106 {
01107   PCLASSINFO(PBitArray, PBYTEArray);
01108 
01109   public:
01114     PBitArray(
01115       PINDEX initialSize = 0  
01116     );
01117 
01120     PBitArray(
01121       const void * buffer,   
01122       PINDEX length,         
01123       PBoolean dynamic = true    
01124     );
01126 
01131     virtual PObject * Clone() const;
01133 
01142     virtual PINDEX GetSize() const;
01143 
01152     virtual PBoolean SetSize(
01153       PINDEX newSize  
01154     );
01155 
01162     PBoolean SetAt(
01163       PINDEX index,   
01164       PBoolean val           
01165     );
01166 
01173     PBoolean GetAt(
01174       PINDEX index  
01175     ) const;
01176 
01185     void Attach(
01186       const void * buffer,   
01187       PINDEX bufferSize      
01188     );
01189 
01203     BYTE * GetPointer(
01204       PINDEX minSize = 0    
01205     );
01207 
01219     PBoolean operator[](
01220       PINDEX index  
01221     ) const { return GetAt(index); }
01222 
01228     PBitArray & operator+=(
01229       PINDEX index  
01230     ) { SetAt(index, true); return *this; }
01231 
01237     PBitArray & operator-=(
01238       PINDEX index  
01239     ) { SetAt(index, false); return *this; }
01240 
01252     PBoolean Concatenate(
01253       const PBitArray & array  
01254     );
01256 };
01257 
01258 
01259 #endif // PTLIB_ARRAY_H
01260 
01261 
01262 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7