Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

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 * $Log: array.h,v $ 00030 * Revision 1.31 2004/05/13 02:07:14 dereksmithies 00031 * Fixes, so it works with doc++ 00032 * 00033 * Revision 1.30 2004/04/09 03:42:34 csoutheren 00034 * Removed all usages of "virtual inline" and "inline virtual" 00035 * 00036 * Revision 1.29 2004/04/03 06:54:21 rjongbloed 00037 * Many and various changes to support new Visual C++ 2003 00038 * 00039 * Revision 1.28 2004/03/02 10:29:59 rjongbloed 00040 * Changed base array declaration macro to be consistent with the 00041 * object array one, thanks Guilhem Tardy 00042 * 00043 * Revision 1.27 2003/04/17 07:24:47 robertj 00044 * Fixed GNU 3.x problem (why no other compiler?) 00045 * 00046 * Revision 1.26 2003/04/15 07:08:36 robertj 00047 * Changed read and write from streams for base array classes so operates in 00048 * the same way for both PIntArray and PArray<int> etc 00049 * 00050 * Revision 1.25 2003/03/31 01:23:56 robertj 00051 * Added ReadFrom functions for standard container classes such as 00052 * PIntArray and PStringList etc 00053 * 00054 * Revision 1.24 2002/09/16 01:08:59 robertj 00055 * Added #define so can select if #pragma interface/implementation is used on 00056 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00057 * 00058 * Revision 1.23 2002/06/20 06:08:59 robertj 00059 * Fixed GNU warning 00060 * 00061 * Revision 1.22 2002/06/14 13:20:37 robertj 00062 * Added PBitArray class. 00063 * 00064 * Revision 1.21 2002/02/14 23:37:53 craigs 00065 * Added fix for optimisation for PArray [] operator, thanks to Vyacheslav Frolov 00066 * 00067 * Revision 1.20 2002/02/14 05:11:50 robertj 00068 * Minor optimisation in the operator[] for arrays of PObjects. 00069 * 00070 * Revision 1.19 1999/11/30 00:22:54 robertj 00071 * Updated documentation for doc++ 00072 * 00073 * Revision 1.18 1999/09/03 15:08:38 robertj 00074 * Fixed typo in ancestor class name 00075 * 00076 * Revision 1.17 1999/08/22 12:13:42 robertj 00077 * Fixed warning when using inlines on older GNU compiler 00078 * 00079 * Revision 1.16 1999/08/20 03:07:44 robertj 00080 * Fixed addded Concatenate function for non-template version. 00081 * 00082 * Revision 1.15 1999/08/18 01:45:12 robertj 00083 * Added concatenation function to "base type" arrays. 00084 * 00085 * Revision 1.14 1999/03/09 02:59:49 robertj 00086 * Changed comments to doc++ compatible documentation. 00087 * 00088 * Revision 1.13 1999/02/16 08:07:11 robertj 00089 * MSVC 6.0 compatibility changes. 00090 * 00091 * Revision 1.12 1998/09/23 06:20:16 robertj 00092 * Added open source copyright license. 00093 * 00094 * Revision 1.11 1998/08/21 05:23:57 robertj 00095 * Added hex dump capability to base array types. 00096 * Added ability to have base arrays of static memory blocks. 00097 * 00098 * Revision 1.10 1997/06/08 04:49:10 robertj 00099 * Fixed non-template class descendent order. 00100 * 00101 * Revision 1.9 1996/08/17 09:54:34 robertj 00102 * Optimised RemoveAll() for object arrays. 00103 * 00104 * Revision 1.8 1996/01/02 11:48:46 robertj 00105 * Removed requirement that PArray elements have parameterless constructor.. 00106 * 00107 * Revision 1.7 1995/10/14 14:52:33 robertj 00108 * Changed arrays to not break references. 00109 * 00110 * Revision 1.6 1995/06/17 11:12:18 robertj 00111 * Documentation update. 00112 * 00113 * Revision 1.5 1995/03/14 12:40:58 robertj 00114 * Updated documentation to use HTML codes. 00115 * 00116 * Revision 1.4 1995/02/22 10:50:26 robertj 00117 * Changes required for compiling release (optimised) version. 00118 * 00119 * Revision 1.3 1995/01/15 04:49:09 robertj 00120 * Fixed errors in template version. 00121 * 00122 * Revision 1.2 1994/12/21 11:52:46 robertj 00123 * Documentation and variable normalisation. 00124 * 00125 * Revision 1.1 1994/12/12 09:59:29 robertj 00126 * Initial revision 00127 * 00128 */ 00129 00130 #ifdef P_USE_PRAGMA 00131 #pragma interface 00132 #endif 00133 00135 // The abstract array class 00136 00158 class PAbstractArray : public PContainer 00159 { 00160 PCONTAINERINFO(PAbstractArray, PContainer); 00161 00162 public: 00174 PAbstractArray( 00175 PINDEX elementSizeInBytes, 00179 PINDEX initialSize = 0 00180 ); 00181 00199 PAbstractArray( 00200 PINDEX elementSizeInBytes, 00204 const void *buffer, 00205 PINDEX bufferSizeInElements, 00206 BOOL dynamicAllocation 00207 ); 00209 00218 virtual void PrintOn( 00219 ostream &strm // Stream to print the object into. 00220 ) const; 00221 00228 virtual void ReadFrom( 00229 istream &strm // Stream to read the objects contents from. 00230 ); 00231 00252 virtual Comparison Compare( 00253 const PObject & obj 00254 ) const; 00256 00267 virtual BOOL SetSize( 00268 PINDEX newSize 00269 ); 00271 00282 void Attach( 00283 const void *buffer, 00284 PINDEX bufferSize 00285 ); 00286 00300 void * GetPointer( 00301 PINDEX minSize = 1 00302 ); 00303 00316 BOOL Concatenate( 00317 const PAbstractArray & array 00318 ); 00320 00321 protected: 00322 virtual void PrintElementOn( 00323 ostream & stream, 00324 PINDEX index 00325 ) const; 00326 virtual void ReadElementFrom( 00327 istream & stream, 00328 PINDEX index 00329 ); 00330 00332 PINDEX elementSize; 00333 00335 char * theArray; 00336 00338 BOOL allocatedDynamically; 00339 00340 friend class PArrayObjects; 00341 }; 00342 00343 00345 // An array of some base type 00346 00347 #ifdef PHAS_TEMPLATES 00348 00368 template <class T> class PBaseArray : public PAbstractArray 00369 { 00370 PCLASSINFO(PBaseArray, PAbstractArray); 00371 00372 public: 00380 PBaseArray( 00381 PINDEX initialSize = 0 00382 ) : PAbstractArray(sizeof(T), initialSize) { } 00383 00386 PBaseArray( 00387 T const * buffer, 00388 PINDEX length, 00389 BOOL dynamic = TRUE 00390 ) : PAbstractArray(sizeof(T), buffer, length, dynamic) { } 00392 00397 virtual PObject * Clone() const 00398 { 00399 return PNEW PBaseArray<T>(*this, GetSize()); 00400 } 00402 00411 BOOL SetAt( 00412 PINDEX index, 00413 T val 00414 ) { 00415 return SetMinSize(index+1) && val==(((T *)theArray)[index] = val); 00416 } 00417 00424 T GetAt( 00425 PINDEX index 00426 ) const { 00427 PASSERTINDEX(index); 00428 return index < GetSize() ? ((T *)theArray)[index] : (T)0; 00429 } 00430 00439 void Attach( 00440 const T * buffer, 00441 PINDEX bufferSize 00442 ) { 00443 PAbstractArray::Attach(buffer, bufferSize); 00444 } 00445 00459 T * GetPointer( 00460 PINDEX minSize = 0 00461 ) { 00462 return (T *)PAbstractArray::GetPointer(minSize); 00463 } 00465 00477 T operator[]( 00478 PINDEX index 00479 ) const { 00480 return GetAt(index); 00481 } 00482 00493 T & operator[]( 00494 PINDEX index 00495 ) { 00496 PASSERTINDEX(index); 00497 PAssert(SetMinSize(index+1), POutOfMemory); 00498 return ((T *)theArray)[index]; 00499 } 00500 00514 operator T const *() const { 00515 return (T const *)theArray; 00516 } 00517 00529 BOOL Concatenate( 00530 const PBaseArray & array 00531 ) { 00532 return PAbstractArray::Concatenate(array); 00533 } 00535 00536 protected: 00537 virtual void PrintElementOn( 00538 ostream & stream, 00539 PINDEX index 00540 ) const { 00541 stream << GetAt(index); 00542 } 00543 }; 00544 00545 /*Declare a dynamic array base type. 00546 This macro is used to declare a descendent of PAbstractArray class, 00547 customised for a particular element type {\bf T}. This macro closes the 00548 class declaration off so no additional members can be added. 00549 00550 If the compilation is using templates then this macro produces a typedef 00551 of the #PBaseArray# template class. 00552 */ 00553 #define PBASEARRAY(cls, T) typedef PBaseArray<T> cls 00554 00567 #define PDECLARE_BASEARRAY(cls, T) \ 00568 PDECLARE_CLASS(cls, PBaseArray<T>) \ 00569 cls(PINDEX initialSize = 0) \ 00570 : PBaseArray<T>(initialSize) { } \ 00571 cls(T const * buffer, PINDEX length, BOOL dynamic = TRUE) \ 00572 : PBaseArray<T>(buffer, length, dynamic) { } \ 00573 virtual PObject * Clone() const \ 00574 { return PNEW cls(*this, GetSize()); } \ 00575 00576 00595 template <class T> class PScalarArray : public PBaseArray<T> 00596 { 00597 public: 00605 PScalarArray( 00606 PINDEX initialSize = 0 00607 ) : PBaseArray<T>(initialSize) { } 00608 00611 PScalarArray( 00612 T const * buffer, 00613 PINDEX length, 00614 BOOL dynamic = TRUE 00615 ) : PBaseArray<T>(buffer, length, dynamic) { } 00617 00618 protected: 00619 virtual void ReadElementFrom( 00620 istream & stream, 00621 PINDEX index 00622 ) { 00623 T t; 00624 stream >> t; 00625 if (!stream.fail()) 00626 SetAt(index, t); 00627 } 00628 }; 00629 00630 00631 /*Declare a dynamic array base type. 00632 This macro is used to declare a descendent of PAbstractArray class, 00633 customised for a particular element type {\bf T}. This macro closes the 00634 class declaration off so no additional members can be added. 00635 00636 If the compilation is using templates then this macro produces a typedef 00637 of the #PBaseArray# template class. 00638 */ 00639 #define PSCALAR_ARRAY(cls, T) typedef PScalarArray<T> cls 00640 00641 #else // PHAS_TEMPLATES 00642 00643 #define PBASEARRAY(cls, T) \ 00644 typedef T P_##cls##_Base_Type; \ 00645 class cls : public PAbstractArray { \ 00646 PCLASSINFO(cls, PAbstractArray) \ 00647 public: \ 00648 inline cls(PINDEX initialSize = 0) \ 00649 : PAbstractArray(sizeof(P_##cls##_Base_Type), initialSize) { } \ 00650 inline cls(P_##cls##_Base_Type const * buffer, PINDEX length, BOOL dynamic = TRUE) \ 00651 : PAbstractArray(sizeof(P_##cls##_Base_Type), buffer, length, dynamic) { } \ 00652 virtual PObject * Clone() const \ 00653 { return PNEW cls(*this, GetSize()); } \ 00654 inline BOOL SetAt(PINDEX index, P_##cls##_Base_Type val) \ 00655 { return SetMinSize(index+1) && \ 00656 val==(((P_##cls##_Base_Type *)theArray)[index] = val); } \ 00657 inline P_##cls##_Base_Type GetAt(PINDEX index) const \ 00658 { PASSERTINDEX(index); return index < GetSize() ? \ 00659 ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } \ 00660 inline P_##cls##_Base_Type operator[](PINDEX index) const \ 00661 { PASSERTINDEX(index); return GetAt(index); } \ 00662 inline P_##cls##_Base_Type & operator[](PINDEX index) \ 00663 { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); \ 00664 return ((P_##cls##_Base_Type *)theArray)[index]; } \ 00665 inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) \ 00666 { PAbstractArray::Attach(buffer, bufferSize); } \ 00667 inline P_##cls##_Base_Type * GetPointer(PINDEX minSize = 0) \ 00668 { return (P_##cls##_Base_Type *)PAbstractArray::GetPointer(minSize); } \ 00669 inline operator P_##cls##_Base_Type const *() const \ 00670 { return (P_##cls##_Base_Type const *)theArray; } \ 00671 inline BOOL Concatenate(cls const & array) \ 00672 { return PAbstractArray::Concatenate(array); } \ 00673 } 00674 00675 #define PDECLARE_BASEARRAY(cls, T) \ 00676 PBASEARRAY(cls##_PTemplate, T); \ 00677 PDECLARE_CLASS(cls, cls##_PTemplate) \ 00678 cls(PINDEX initialSize = 0) \ 00679 : cls##_PTemplate(initialSize) { } \ 00680 cls(T const * buffer, PINDEX length, BOOL dynamic = TRUE) \ 00681 : cls##_PTemplate(buffer, length, dynamic) { } \ 00682 virtual PObject * Clone() const \ 00683 { return PNEW cls(*this, GetSize()); } \ 00684 00685 #define PSCALAR_ARRAY(cls, T) PBASEARRAY(cls, T) 00686 00687 #endif // PHAS_TEMPLATES 00688 00689 00691 #ifdef DOC_PLUS_PLUS 00692 class PCharArray : public PBaseArray { 00693 public: 00699 PCharArray( 00700 PINDEX initialSize = 0 00701 ); 00702 00705 PCharArray( 00706 char const * buffer, 00707 PINDEX length, 00708 BOOL dynamic = TRUE 00709 ); 00711 #endif 00712 PDECLARE_BASEARRAY(PCharArray, char); 00713 public: 00716 00717 virtual void PrintOn( 00718 ostream & strm 00719 ) const; 00721 virtual void ReadFrom( 00722 istream &strm // Stream to read the objects contents from. 00723 ); 00725 }; 00726 00728 #ifdef DOC_PLUS_PLUS 00729 class PShortArray : public PBaseArray { 00730 public: 00736 PShortArray( 00737 PINDEX initialSize = 0 00738 ); 00739 00742 PShortArray( 00743 short const * buffer, 00744 PINDEX length, 00745 BOOL dynamic = TRUE 00746 ); 00748 }; 00749 #endif 00750 PSCALAR_ARRAY(PShortArray, short); 00751 00752 00754 #ifdef DOC_PLUS_PLUS 00755 class PIntArray : public PBaseArray { 00756 public: 00762 PIntArray( 00763 PINDEX initialSize = 0 00764 ); 00765 00768 PIntArray( 00769 int const * buffer, 00770 PINDEX length, 00771 BOOL dynamic = TRUE 00772 ); 00774 }; 00775 #endif 00776 PSCALAR_ARRAY(PIntArray, int); 00777 00778 00780 #ifdef DOC_PLUS_PLUS 00781 class PLongArray : public PBaseArray { 00782 public: 00788 PLongArray( 00789 PINDEX initialSize = 0 00790 ); 00791 00794 PLongArray( 00795 long const * buffer, 00796 PINDEX length, 00797 BOOL dynamic = TRUE 00798 ); 00800 }; 00801 #endif 00802 PSCALAR_ARRAY(PLongArray, long); 00803 00804 00806 #ifdef DOC_PLUS_PLUS 00807 class PBYTEArray : public PBaseArray { 00808 public: 00814 PBYTEArray( 00815 PINDEX initialSize = 0 00816 ); 00817 00820 PBYTEArray( 00821 BYTE const * buffer, 00822 PINDEX length, 00823 BOOL dynamic = TRUE 00824 ); 00826 }; 00827 #endif 00828 PDECLARE_BASEARRAY(PBYTEArray, BYTE); 00829 public: 00832 00833 virtual void PrintOn( 00834 ostream & strm 00835 ) const; 00837 virtual void ReadFrom( 00838 istream &strm // Stream to read the objects contents from. 00839 ); 00841 }; 00842 00843 00845 #ifdef DOC_PLUS_PLUS 00846 class PWORDArray : public PBaseArray { 00847 public: 00853 PWORDArray( 00854 PINDEX initialSize = 0 00855 ); 00856 00859 PWORDArray( 00860 WORD const * buffer, 00861 PINDEX length, 00862 BOOL dynamic = TRUE 00863 ); 00865 }; 00866 #endif 00867 PSCALAR_ARRAY(PWORDArray, WORD); 00868 00869 00871 #ifdef DOC_PLUS_PLUS 00872 class PUnsignedArray : public PBaseArray { 00873 public: 00879 PUnsignedArray( 00880 PINDEX initialSize = 0 00881 ); 00882 00885 PUnsignedArray( 00886 unsigned const * buffer, 00887 PINDEX length, 00888 BOOL dynamic = TRUE 00889 ); 00891 }; 00892 #endif 00893 PSCALAR_ARRAY(PUnsignedArray, unsigned); 00894 00895 00897 #ifdef DOC_PLUS_PLUS 00898 class PDWORDArray : public PBaseArray { 00899 public: 00905 PDWORDArray( 00906 PINDEX initialSize = 0 00907 ); 00908 00911 PDWORDArray( 00912 DWORD const * buffer, 00913 PINDEX length, 00914 BOOL dynamic = TRUE 00915 ); 00917 #endif 00918 PSCALAR_ARRAY(PDWORDArray, DWORD); 00919 00920 00922 // Linear array of objects 00923 00945 class PArrayObjects : public PCollection 00946 { 00947 PCONTAINERINFO(PArrayObjects, PCollection); 00948 00949 public: 00958 PINLINE PArrayObjects( 00959 PINDEX initialSize = 0 00960 ); 00962 00995 virtual Comparison Compare( 00996 const PObject & obj 00997 ) const; 00999 01002 01003 virtual PINDEX GetSize() const; 01004 01013 virtual BOOL SetSize( 01014 PINDEX newSize 01015 ); 01017 01026 virtual PINDEX Append( 01027 PObject * obj 01028 ); 01029 01045 virtual PINDEX Insert( 01046 const PObject & before, 01047 PObject * obj 01048 ); 01049 01060 virtual PINDEX InsertAt( 01061 PINDEX index, 01062 PObject * obj 01063 ); 01064 01073 virtual BOOL Remove( 01074 const PObject * obj 01075 ); 01076 01088 virtual PObject * RemoveAt( 01089 PINDEX index 01090 ); 01091 01099 virtual BOOL SetAt( 01100 PINDEX index, 01101 PObject * val 01102 ); 01103 01110 virtual PObject * GetAt( 01111 PINDEX index 01112 ) const; 01113 01121 virtual PINDEX GetObjectsIndex( 01122 const PObject * obj 01123 ) const; 01124 01134 virtual PINDEX GetValuesIndex( 01135 const PObject & obj // Object to find equal of. 01136 ) const; 01137 01144 virtual void RemoveAll(); 01146 01147 protected: 01148 PBASEARRAY(ObjPtrArray, PObject *); 01149 ObjPtrArray * theArray; 01150 }; 01151 01152 01153 #ifdef PHAS_TEMPLATES 01154 01161 template <class T> class PArray : public PArrayObjects 01162 { 01163 PCLASSINFO(PArray, PArrayObjects); 01164 01165 public: 01174 PArray( 01175 PINDEX initialSize = 0 01176 ) : PArrayObjects(initialSize) { } 01178 01184 virtual PObject * Clone() const 01185 { return PNEW PArray(0, this); } 01187 01197 T & operator[]( 01198 PINDEX index 01199 ) const { 01200 PObject * obj = GetAt(index); 01201 PAssert(obj != NULL, PInvalidArrayElement); 01202 return (T &)*obj; 01203 } 01205 01206 protected: 01207 PArray(int dummy, const PArray * c) : PArrayObjects(dummy, c) { } 01208 }; 01209 01210 01222 #define PARRAY(cls, T) typedef PArray<T> cls 01223 01224 01237 #define PDECLARE_ARRAY(cls, T) \ 01238 PARRAY(cls##_PTemplate, T); \ 01239 PDECLARE_CLASS(cls, cls##_PTemplate) \ 01240 protected: \ 01241 inline cls(int dummy, const cls * c) \ 01242 : cls##_PTemplate(dummy, c) { } \ 01243 public: \ 01244 inline cls(PINDEX initialSize = 0) \ 01245 : cls##_PTemplate(initialSize) { } \ 01246 virtual PObject * Clone() const \ 01247 { return PNEW cls(0, this); } \ 01248 01249 #else // PHAS_TEMPLATES 01250 01251 01252 #define PARRAY(cls, T) \ 01253 class cls : public PArrayObjects { \ 01254 PCLASSINFO(cls, PArrayObjects); \ 01255 protected: \ 01256 inline cls(int dummy, const cls * c) \ 01257 : PArrayObjects(dummy, c) { } \ 01258 public: \ 01259 inline cls(PINDEX initialSize = 0) \ 01260 : PArrayObjects(initialSize) { } \ 01261 virtual PObject * Clone() const \ 01262 { return PNEW cls(0, this); } \ 01263 inline T & operator[](PINDEX index) const\ 01264 { PObject * obj = GetAt(index); \ 01265 PAssert(obj != NULL, PInvalidArrayElement); \ 01266 /* want to do to this, but gcc 3.0 complains --> return *(T *)obj; } */ \ 01267 return (T &)*obj; } \ 01268 } 01269 01270 #define PDECLARE_ARRAY(cls, T) \ 01271 PARRAY(cls##_PTemplate, T); \ 01272 PDECLARE_CLASS(cls, cls##_PTemplate) \ 01273 protected: \ 01274 inline cls(int dummy, const cls * c) \ 01275 : cls##_PTemplate(dummy, c) { } \ 01276 public: \ 01277 inline cls(PINDEX initialSize = 0) \ 01278 : cls##_PTemplate(initialSize) { } \ 01279 virtual PObject * Clone() const \ 01280 { return PNEW cls(0, this); } \ 01281 01282 #endif // PHAS_TEMPLATES 01283 01284 01287 class PBitArray : public PBYTEArray 01288 { 01289 PCLASSINFO(PBitArray, PBYTEArray); 01290 01291 public: 01296 PBitArray( 01297 PINDEX initialSize = 0 01298 ); 01299 01302 PBitArray( 01303 const void * buffer, 01304 PINDEX length, 01305 BOOL dynamic = TRUE 01306 ); 01308 01313 virtual PObject * Clone() const; 01315 01324 virtual PINDEX GetSize() const; 01325 01334 virtual BOOL SetSize( 01335 PINDEX newSize 01336 ); 01337 01344 BOOL SetAt( 01345 PINDEX index, 01346 BOOL val 01347 ); 01348 01355 BOOL GetAt( 01356 PINDEX index 01357 ) const; 01358 01367 void Attach( 01368 const void * buffer, 01369 PINDEX bufferSize 01370 ); 01371 01385 BYTE * GetPointer( 01386 PINDEX minSize = 0 01387 ); 01389 01401 BOOL operator[]( 01402 PINDEX index 01403 ) const { return GetAt(index); } 01404 01410 PBitArray & operator+=( 01411 PINDEX index 01412 ) { SetAt(index, TRUE); return *this; } 01413 01419 PBitArray & operator-=( 01420 PINDEX index 01421 ) { SetAt(index, FALSE); return *this; } 01422 01434 BOOL Concatenate( 01435 const PBitArray & array 01436 ); 01438 }; 01439 01440 // End Of File ///////////////////////////////////////////////////////////////

Generated on Sat Jul 24 15:35:56 2004 for PWLib by doxygen 1.3.7