PTLib
Version 2.10.4
|
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 ///////////////////////////////////////////////////////////////