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

object.h

Go to the documentation of this file.
00001 /*
00002  * object.h
00003  *
00004  * Mother of all ancestor 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: object.h,v $
00030  * Revision 1.110  2004/08/14 14:17:29  csoutheren
00031  * Fixed problem with PAssert and associated functions caused by using expressions
00032  * as statements. inline functions are your friend :)
00033  *
00034  * Revision 1.109  2004/08/05 12:09:35  rjongbloed
00035  * Added macros for "remove const" and "down cast" funcions with and without RTTI.
00036  * Added ability to disable Asserts.
00037  * Change PAssert macros so pass through the boolean result so that they can be used
00038  *   in if statements, allowing a chance to continue if ignore assert.
00039  *
00040  * Revision 1.108  2004/07/11 07:56:35  csoutheren
00041  * Applied jumbo VxWorks patch, thanks to Eize Slange
00042  *
00043  * Revision 1.107  2004/07/03 06:49:49  rjongbloed
00044  * Added PTRACE_PARAM() macro to fix warnings on parameters used in PTRACE
00045  *  macros only.
00046  *
00047  * Revision 1.106  2004/06/01 07:42:19  csoutheren
00048  * Restored memory allocation checking
00049  * Added configure flag to enable, thanks to Derek Smithies
00050  *
00051  * Revision 1.105  2004/06/01 05:22:43  csoutheren
00052  * Restored memory check functionality
00053  *
00054  * Revision 1.104  2004/05/12 04:36:17  csoutheren
00055  * Fixed problems with using sem_wait and friends on systems that do not
00056  * support atomic integers
00057  *
00058  * Revision 1.103  2004/04/18 04:33:36  rjongbloed
00059  * Changed all operators that return BOOL to return standard type bool. This is primarily
00060  *   for improved compatibility with std STL usage removing many warnings.
00061  *
00062  * Revision 1.102  2004/04/11 13:26:25  csoutheren
00063  * Removed namespace problems and removed warnings for Windows <string>
00064  *
00065  * Revision 1.101  2004/04/11 03:20:41  csoutheren
00066  * Added Unix implementation of PCriticalSection
00067  *
00068  * Revision 1.100  2004/04/11 02:55:17  csoutheren
00069  * Added PCriticalSection for Windows
00070  * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
00071  *
00072  * Revision 1.99  2004/04/09 11:54:46  csoutheren
00073  * Added configure.in check for STL streams, and tested with gcc 2.95.3,
00074  * gcc 3.3.1, and gcc 3.3.3
00075  *
00076  * Revision 1.98  2004/04/09 07:53:51  rjongbloed
00077  * Fixed backward compatibility after STL streams change
00078  *
00079  * Revision 1.97  2004/04/09 00:56:35  csoutheren
00080  * Fixed problem with new class name code
00081  *
00082  * Revision 1.96  2004/04/09 00:42:58  csoutheren
00083  * Changed Unix build to use slightly different method for
00084  * keep class names, as GCC does not use actual class names for typeinfo
00085  *
00086  * Revision 1.95  2004/04/04 13:24:18  rjongbloed
00087  * Changes to support native C++ Run Time Type Information
00088  *
00089  * Revision 1.94  2004/04/03 08:57:31  csoutheren
00090  * Replaced pseudo-RTTI with real RTTI
00091  *
00092  * Revision 1.93  2004/04/03 08:22:20  csoutheren
00093  * Remove pseudo-RTTI and replaced with real RTTI
00094  *
00095  * Revision 1.92  2004/04/03 07:41:00  csoutheren
00096  * Fixed compile problem with ostringstream/ostrstream
00097  *
00098  * Revision 1.91  2004/04/03 07:16:05  rjongbloed
00099  * Fixed backward compatibility with MSVC 6
00100  *
00101  * Revision 1.90  2004/04/03 06:54:22  rjongbloed
00102  * Many and various changes to support new Visual C++ 2003
00103  *
00104  * Revision 1.89  2003/09/17 09:00:59  csoutheren
00105  * Moved PSmartPointer and PNotifier into seperate files
00106  * Added detection for system regex libraries on all platforms
00107  *
00108  * Revision 1.88  2003/09/17 05:41:58  csoutheren
00109  * Removed recursive includes
00110  *
00111  * Revision 1.87  2003/09/17 01:18:02  csoutheren
00112  * Removed recursive include file system and removed all references
00113  * to deprecated coooperative threading support
00114  *
00115  * Revision 1.86  2002/10/14 21:42:37  rogerh
00116  * Only use malloc.h on Windows
00117  *
00118  * Revision 1.85  2002/10/10 04:43:43  robertj
00119  * VxWorks port, thanks Martijn Roest
00120  *
00121  * Revision 1.84  2002/10/08 12:41:51  robertj
00122  * Changed for IPv6 support, thanks Sébastien Josset.
00123  *
00124  * Revision 1.83  2002/09/16 01:08:59  robertj
00125  * Added #define so can select if #pragma interface/implementation is used on
00126  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00127  *
00128  * Revision 1.82  2002/08/06 02:27:58  robertj
00129  * GNU C++ v3 compatibility.
00130  *
00131  * Revision 1.81  2002/06/25 02:22:47  robertj
00132  * Improved assertion system to allow C++ class name to be displayed if
00133  *   desired, especially relevant to container classes.
00134  *
00135  * Revision 1.80  2002/06/14 10:29:43  rogerh
00136  * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de>
00137  *
00138  * Revision 1.79  2002/06/13 08:34:05  rogerh
00139  * gcc 3.1 needs iostream instead of iostream.h
00140  *
00141  * Revision 1.78  2002/05/22 00:23:31  craigs
00142  * Added GMTTime flag to tracing options
00143  *
00144  * Revision 1.77  2002/04/19 00:20:51  craigs
00145  * Added option to append to log file rather than create anew each time
00146  *
00147  * Revision 1.76  2002/01/26 23:55:55  craigs
00148  * Changed for GCC 3.0 compatibility, thanks to manty@manty.net
00149  *
00150  * Revision 1.75  2001/10/18 19:56:26  yurik
00151  * Fixed WinCE x86 compilation problems with memory check off
00152  *
00153  * Revision 1.74  2001/08/12 11:26:07  robertj
00154  * Put back PMEMORY_CHECK taken out by the Carbon port.
00155  *
00156  * Revision 1.73  2001/08/11 07:57:30  rogerh
00157  * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
00158  *
00159  * Revision 1.72  2001/05/03 06:27:29  robertj
00160  * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state.
00161  *
00162  * Revision 1.71  2001/03/24 01:11:10  robertj
00163  * Added missing PTRACE_IF define in non PTRACING mode.
00164  *
00165  * Revision 1.70  2001/03/23 05:34:09  robertj
00166  * Added PTRACE_IF to output trace if a conditional is TRUE.
00167  *
00168  * Revision 1.69  2001/03/01 02:15:16  robertj
00169  * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise.
00170  *
00171  * Revision 1.68  2001/02/22 08:16:41  robertj
00172  * Added standard trace file setup subroutine.
00173  *
00174  * Revision 1.67  2001/02/13 03:27:24  robertj
00175  * Added function to do heap validation.
00176  *
00177  * Revision 1.66  2001/02/09 04:41:27  robertj
00178  * Removed added non memrycheck implementations of new/delete when using GNU C++.
00179  *
00180  * Revision 1.65  2001/02/07 04:47:49  robertj
00181  * Added changes for possible random crashes in multi DLL environment
00182  *   due to memory allocation wierdness, thanks Milan Dimitrijevic.
00183  *
00184  * Revision 1.64  2001/01/24 06:15:44  yurik
00185  * Windows CE port-related declarations
00186  *
00187  * Revision 1.63  2000/07/28 05:13:47  robertj
00188  * Fixed silly mistake in runtime_malloc() function, should return a pointer!
00189  *
00190  * Revision 1.62  2000/07/20 05:46:34  robertj
00191  * Added runtime_malloc() function for cases where memory check code must be bypassed.
00192  *
00193  * Revision 1.61  2000/07/13 15:45:35  robertj
00194  * Removed #define std that causes everyone so much grief!
00195  *
00196  * Revision 1.60  2000/06/26 11:17:19  robertj
00197  * Nucleus++ port (incomplete).
00198  *
00199  * Revision 1.59  2000/02/29 12:26:14  robertj
00200  * Added named threads to tracing, thanks to Dave Harvey
00201  *
00202  * Revision 1.58  2000/01/07 12:31:12  robertj
00203  * Fixed 8 byte alignment on memory heap checking.
00204  *
00205  * Revision 1.57  2000/01/05 00:29:12  robertj
00206  * Fixed alignment problems in memory checking debug functions.
00207  *
00208  * Revision 1.56  1999/11/30 00:22:54  robertj
00209  * Updated documentation for doc++
00210  *
00211  * Revision 1.55  1999/11/01 00:10:27  robertj
00212  * Added override of new functions for MSVC memory check code.
00213  *
00214  * Revision 1.54  1999/10/19 09:21:30  robertj
00215  * Added functions to get current trace options and level.
00216  *
00217  * Revision 1.53  1999/09/13 13:15:06  robertj
00218  * Changed PTRACE so will output to system log in PServiceProcess applications.
00219  *
00220  * Revision 1.52  1999/08/24 08:15:23  robertj
00221  * Added missing operator on smart pointer to return the pointer!
00222  *
00223  * Revision 1.51  1999/08/24 06:54:36  robertj
00224  * Cleaned up the smart pointer code (macros).
00225  *
00226  * Revision 1.50  1999/08/22 13:38:39  robertj
00227  * Fixed termination hang up problem with memory check code under unix pthreads.
00228  *
00229  * Revision 1.49  1999/08/17 03:46:40  robertj
00230  * Fixed usage of inlines in optimised version.
00231  *
00232  * Revision 1.48  1999/08/10 10:45:09  robertj
00233  * Added mutex in memory check detection code.
00234  *
00235  * Revision 1.47  1999/07/18 15:08:24  robertj
00236  * Fixed 64 bit compatibility
00237  *
00238  * Revision 1.46  1999/06/14 07:59:37  robertj
00239  * Enhanced tracing again to add options to trace output (timestamps etc).
00240  *
00241  * Revision 1.45  1999/05/01 11:29:19  robertj
00242  * Alpha linux port changes.
00243  *
00244  * Revision 1.44  1999/04/18 12:58:39  robertj
00245  * MSVC 5 backward compatibility
00246  *
00247  * Revision 1.43  1999/03/09 10:30:17  robertj
00248  * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions.
00249  *
00250  * Revision 1.42  1999/03/09 02:59:50  robertj
00251  * Changed comments to doc++ compatible documentation.
00252  *
00253  * Revision 1.41  1999/02/23 07:11:26  robertj
00254  * Improved trace facility adding trace levels and #define to remove all trace code.
00255  *
00256  * Revision 1.40  1999/02/22 10:48:14  robertj
00257  * Fixed delete operator prototypes for MSVC6 and GNU compatibility.
00258  *
00259  * Revision 1.39  1999/02/19 11:33:02  robertj
00260  * Fixed compatibility problems with GNU/MSVC6
00261  *
00262  * Revision 1.38  1999/02/16 08:12:22  robertj
00263  * MSVC 6.0 compatibility changes.
00264  *
00265  * Revision 1.37  1999/01/07 03:35:35  robertj
00266  * Added default for PCHAR8 to ANSI, removes need for compiler option.
00267  *
00268  * Revision 1.36  1998/12/15 09:00:29  robertj
00269  * Fixed 8 byte alignment problem in memory leak check code for sparc.
00270  *
00271  * Revision 1.35  1998/11/03 00:57:19  robertj
00272  * Added allocation breakpoint variable.
00273  *
00274  * Revision 1.34  1998/10/26 11:05:26  robertj
00275  * Added raw free for things allocated within the runtime library.
00276  *
00277  * Revision 1.33  1998/10/18 14:26:55  robertj
00278  * Improved tracing functions.
00279  *
00280  * Revision 1.32  1998/10/15 07:47:21  robertj
00281  * Added ability to ignore G++lib memory leaks.
00282  *
00283  * Revision 1.31  1998/10/15 01:53:58  robertj
00284  * GNU compatibility.
00285  *
00286  * Revision 1.30  1998/10/13 14:23:29  robertj
00287  * Complete rewrite of memory leak detection.
00288  *
00289  * Revision 1.29  1998/09/23 06:20:57  robertj
00290  * Added open source copyright license.
00291  *
00292  * Revision 1.28  1998/09/14 12:29:11  robertj
00293  * Fixed memory leak dump under windows to not include static globals.
00294  * Fixed problem with notifier declaration not allowing implementation inline after macro.
00295  *
00296  * Revision 1.27  1997/07/08 13:13:45  robertj
00297  * DLL support.
00298  *
00299  * Revision 1.26  1997/04/27 05:50:11  robertj
00300  * DLL support.
00301  *
00302  * Revision 1.25  1997/02/05 11:54:10  robertj
00303  * Fixed problems with memory check and leak detection.
00304  *
00305  * Revision 1.24  1996/09/16 12:57:23  robertj
00306  * DLL support
00307  *
00308  * Revision 1.23  1996/08/17 10:00:23  robertj
00309  * Changes for Windows DLL support.
00310  *
00311  * Revision 1.22  1996/07/15 10:27:51  robertj
00312  * Changed endian classes to be memory mapped.
00313  *
00314  * Revision 1.21  1996/05/09 12:14:48  robertj
00315  * Fixed up 64 bit integer class for Mac platform.
00316  *
00317  * Revision 1.20  1996/02/24 14:19:29  robertj
00318  * Fixed bug in endian independent integer code for memory transfers.
00319  *
00320  * Revision 1.19  1996/01/28 02:46:43  robertj
00321  * Removal of MemoryPointer classes as usage didn't work for GNU.
00322  * Added missing bit shift operators to 64 bit integer class.
00323  *
00324  * Revision 1.18  1996/01/23 13:14:32  robertj
00325  * Added const version of PMemoryPointer.
00326  * Added constructor to endian classes for the base type.
00327  *
00328  * Revision 1.17  1996/01/02 11:54:11  robertj
00329  * Mac OS compatibility changes.
00330  *
00331  * Revision 1.16  1995/11/09 12:17:10  robertj
00332  * Added platform independent base type access classes.
00333  *
00334  * Revision 1.15  1995/06/17 11:12:47  robertj
00335  * Documentation update.
00336  *
00337  * Revision 1.14  1995/06/04 12:34:19  robertj
00338  * Added trace functions.
00339  *
00340  * Revision 1.13  1995/04/25 12:04:35  robertj
00341  * Fixed borland compatibility.
00342  * Fixed function hiding ancestor virtuals.
00343  *
00344  * Revision 1.12  1995/03/14 12:41:54  robertj
00345  * Updated documentation to use HTML codes.
00346  *
00347  * Revision 1.11  1995/03/12  04:40:55  robertj
00348  * Changed standard error code for not open from file to channel.
00349  *
00350  * Revision 1.10  1995/02/19  04:19:14  robertj
00351  * Added dynamically linked command processing.
00352  *
00353  * Revision 1.9  1995/02/05  00:48:07  robertj
00354  * Fixed template version.
00355  *
00356  * Revision 1.8  1995/01/15  04:51:31  robertj
00357  * Mac compatibility.
00358  * Added levels of memory checking.
00359  *
00360  * Revision 1.7  1995/01/09  12:38:31  robertj
00361  * Changed variable names around during documentation run.
00362  * Fixed smart pointer comparison.
00363  * Fixed serialisation stuff.
00364  * Documentation.
00365  *
00366  * Revision 1.6  1995/01/03  09:39:06  robertj
00367  * Put standard malloc style memory allocation etc into memory check system.
00368  *
00369  * Revision 1.5  1994/12/12  10:08:30  robertj
00370  * Renamed PWrapper to PSmartPointer..
00371  *
00372  * Revision 1.4  1994/12/05  11:23:28  robertj
00373  * Fixed PWrapper macros.
00374  *
00375  * Revision 1.3  1994/11/19  00:22:55  robertj
00376  * Changed PInteger to be INT, ie standard type like BOOL/WORD etc.
00377  * Moved null object check in notifier to construction rather than use.
00378  * Added virtual to the callback function in notifier destination class.
00379  *
00380  * Revision 1.2  1994/11/03  09:25:30  robertj
00381  * Made notifier destination object not to be descendent of PObject.
00382  *
00383  * Revision 1.1  1994/10/30  12:01:37  robertj
00384  * Initial revision
00385  *
00386  */
00387 
00388 #ifndef _POBJECT_H
00389 #define _POBJECT_H
00390 
00391 #ifdef P_USE_PRAGMA
00392 #pragma interface
00393 #endif
00394 
00395 #ifdef _WIN32
00396 #include "msos/ptlib/contain.h"
00397 #else
00398 #include "unix/ptlib/contain.h"
00399 #endif
00400 
00401 #if defined(P_VXWORKS)
00402 #include <private/stdiop.h>
00403 #endif
00404 
00405 #include <stdio.h>
00406 #include <stdarg.h>
00407 #include <stdlib.h>
00408 
00409 #ifdef _WIN32
00410   #include <malloc.h>
00411 #endif
00412 
00413 #include <string.h>
00414 
00415 #ifdef __USE_STL__
00416   #include <string>
00417   #include <iomanip>
00418   #include <iostream>
00419   #if (__GNUC__ >= 3)
00420     #include <sstream>
00421     //typedef std::ostringstream ostrstream;
00422   #else
00423     #include <strstream>
00424   #endif
00425   //using namespace std;
00426 #else
00427   #if (__GNUC__ >= 3)
00428     #include <iostream>
00429     #ifndef __MWERKS__
00430       #include <iomanip>
00431     #endif
00432   #else
00433     #include <iostream.h>
00434     #ifdef __GNUC__
00435       #include <strstream.h>
00436     #else
00437       #include <strstrea.h>
00438     #endif
00439     #ifndef __MWERKS__
00440       #include <iomanip.h>
00441     #endif
00442   #endif
00443 #endif
00444 
00445 #ifdef _WIN32_WCE
00446   #include <stdlibx.h>
00447 #endif
00448 
00449 #if (__GNUC__ < 3)
00450 typedef long _Ios_Fmtflags;
00451 #endif
00452 
00453 #if _MSC_VER<1300
00454 #define _BADOFF -1
00455 #endif
00456 
00458 // Disable inlines when debugging for faster compiles (the compiler doesn't
00459 // actually inline the function with debug on any way).
00460 
00461 #ifndef P_USE_INLINES
00462 #ifdef _DEBUG
00463 #define P_USE_INLINES 0
00464 #else
00465 #define P_USE_INLINES 0
00466 #endif
00467 #endif
00468 
00469 #if P_USE_INLINES
00470 #define PINLINE inline
00471 #else
00472 #define PINLINE
00473 #endif
00474 
00475 
00477 // Declare the debugging support
00478 
00479 #ifndef P_USE_ASSERTS
00480 #define P_USE_ASSERTS 1
00481 #endif
00482 
00483 #if !P_USE_ASSERTS
00484 
00485 #define PAssert(b, m) (b)
00486 #define PAssert2(b, c, m) (b)
00487 #define PAssertOS(b) (b)
00488 #define PAssertNULL(p) (p)
00489 #define PAssertAlways(m)
00490 #define PAssertAlways2(c, m)
00491 
00492 #else // P_USE_ASSERTS
00493 
00495 enum PStandardAssertMessage {
00496   PLogicError,              // A logic error occurred.
00497   POutOfMemory,             // A new or malloc failed.
00498   PNullPointerReference,    // A reference was made through a NULL pointer.
00499   PInvalidCast,             // An invalid cast to descendant is required.
00500   PInvalidArrayIndex,       // An index into an array was negative.
00501   PInvalidArrayElement,     // A NULL array element object was accessed.
00502   PStackEmpty,              // A Pop() was made of a stack with no elements.
00503   PUnimplementedFunction,   // Funtion is not implemented.
00504   PInvalidParameter,        // Invalid parameter was passed to a function.
00505   POperatingSystemError,    // Error was returned by Operating System.
00506   PChannelNotOpen,          // Operation attempted when channel not open.
00507   PUnsupportedFeature,      // Feature is not supported.
00508   PInvalidWindow,           // Access through invalid window.
00509   PMaxStandardAssertMessage
00510 };
00511 
00512 #define __CLASS__ NULL
00513 
00514 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00515 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00516 void PAssertFunc(const char * full_msg);
00517 
00518 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00519 {
00520   if (!b) 
00521     PAssertFunc(file, line, className, msg);
00522   return b;
00523 }
00524 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00525 {
00526   if (!b) 
00527     PAssertFunc(file, line, className, msg);
00528   return b;
00529 }
00530 
00537 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00538 
00546 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00547 
00554 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00555 
00565 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p): \
00566                      (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00567 
00574 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00575 
00582 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00583 
00584 #endif // P_USE_ASSERTS
00585 
00586 
00591 ostream & PGetErrorStream();
00592 
00596 void PSetErrorStream(ostream * strm  );
00597 
00612 #define PError (PGetErrorStream())
00613 
00614 
00615 
00617 // Debug and tracing
00618 
00619 #ifndef PTRACING
00620 #ifndef _DEBUG
00621 #define PTRACING 0
00622 #else
00623 #define PTRACING 1
00624 #endif
00625 #endif
00626 
00631 class PTrace
00632 {
00633 public:
00635   enum Options {
00641     Blocks = 1,
00643     DateAndTime = 2,
00645     Timestamp = 4,
00647     Thread = 8,
00649     TraceLevel = 16,
00651     FileAndLine = 32,
00653     ThreadAddress = 64,
00655     AppendToFile = 128,
00659     GMTTime = 256,
00662     SystemLogStream = 32768
00663   };
00664 
00672   static void Initialise(
00673     unsigned level,
00674     const char * filename = NULL,
00675     unsigned options = Timestamp | Thread | Blocks
00676   );
00677 
00684   static void SetOptions(unsigned options  );
00685 
00693   static void ClearOptions(unsigned options  );
00694 
00699   static unsigned GetOptions();
00700 
00706   static void SetLevel(unsigned level  );
00707 
00713   static unsigned GetLevel();
00714 
00719   static BOOL CanTrace(unsigned level );
00720 
00725   static void SetStream(ostream * out  );
00726 
00742   static ostream & Begin(
00743     unsigned level,         
00744     const char * fileName,  
00745     int lineNum             
00746   );
00747 
00764   static ostream & End(ostream & strm );
00765 
00766 
00772   class Block {
00773     public:
00775       Block(
00776         const char * fileName, 
00777         int lineNum,           
00778         const char * traceName
00780        );
00782       ~Block();
00783     private:
00784       const char * file;
00785       int          line;
00786       const char * name;
00787   };
00788 };
00789 
00790 #if !PTRACING
00791 
00792 #define PTRACE_PARAM(param)
00793 #define PTRACE_BLOCK(n)
00794 #define PTRACE_LINE()
00795 #define PTRACE(level, arg)
00796 #define PTRACE_IF(level, cond, args)
00797 
00798 #else
00799 
00800 /* Macro to conditionally declare a parameter to a function to avoid compiler
00801    warning due that parameter only being used in a PTRACE */
00802 #define PTRACE_PARAM(param) param
00803 
00810 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00811 
00815 #define PTRACE_LINE() \
00816     if (!PTrace::CanTrace(1)) ; else \
00817       PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00818 
00824 #define PTRACE(level, args) \
00825     if (!PTrace::CanTrace(level)) ; else \
00826       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00827 
00835 #define PTRACE_IF(level, cond, args) \
00836     if (!(PTrace::CanTrace(level)  && (cond))) ; else \
00837       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00838 
00839 #endif
00840 
00841 #if PMEMORY_CHECK
00842 
00849 class PMemoryHeap {
00850   protected:
00852     PMemoryHeap();
00853 
00854   public:
00855     // Clear up the memory checking subsystem, dumping memory leaks.
00856     ~PMemoryHeap();
00857 
00864     static void * Allocate(
00865       size_t nSize,           
00866       const char * file,      
00867       int line,               
00868       const char * className  
00869     );
00876     static void * Allocate(
00877       size_t count,       
00878       size_t iSize,       
00879       const char * file,  
00880       int line            
00881     );
00882 
00890     static void * Reallocate(
00891       void * ptr,         
00892       size_t nSize,       
00893       const char * file,  
00894       int line            
00895     );
00896 
00902     static void Deallocate(
00903       void * ptr,             
00904       const char * className  
00905     );
00906 
00909     enum Validation {
00910       Ok, Bad, Trashed
00911     };
00919     static Validation Validate(
00920       void * ptr,             
00921       const char * className, 
00922       ostream * error         
00923     );
00924 
00929     static BOOL ValidateHeap(
00930       ostream * error = NULL  // Stream to output, use default if NULL
00931     );
00932 
00938     static BOOL SetIgnoreAllocations(
00939       BOOL ignore  
00940     );
00941 
00945     static void DumpStatistics();
00949     static void DumpStatistics(ostream & strm );
00950 
00951     /* Get number of allocation.
00952       Each allocation is counted and if desired the next allocation request
00953       number may be obtained via this function.
00954       @return Allocation request number.
00955      */
00956     static DWORD GetAllocationRequest();
00957 
00965     static void DumpObjectsSince(
00966       DWORD objectNumber    
00967     );
00968 
00974     static void DumpObjectsSince(
00975       DWORD objectNumber,   
00976       ostream & strm        
00977     );
00978 
00984     static void SetAllocationBreakpoint(
00985       DWORD point   
00986     );
00987 
00988   protected:
00989     void * InternalAllocate(
00990       size_t nSize,           // Number of bytes to allocate.
00991       const char * file,      // Source file name for allocating function.
00992       int line,               // Source file line for allocating function.
00993       const char * className  // Class name for allocating function.
00994     );
00995     Validation InternalValidate(
00996       void * ptr,             // Pointer to memory block to check
00997       const char * className, // Class name it should be.
00998       ostream * error         // Stream to receive error message (may be NULL)
00999     );
01000     void InternalDumpStatistics(ostream & strm);
01001     void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01002 
01003     class Wrapper {
01004       public:
01005         Wrapper();
01006         ~Wrapper();
01007         PMemoryHeap * operator->() const { return instance; }
01008       private:
01009         PMemoryHeap * instance;
01010     };
01011     friend class Wrapper;
01012 
01013     enum Flags {
01014       NoLeakPrint = 1
01015     };
01016 
01017 #pragma pack(1)
01018     struct Header {
01019       enum {
01020         // Assure that the Header struct is aligned to 8 byte boundary
01021         NumGuardBytes = 16 - (sizeof(Header *) +
01022                               sizeof(Header *) +
01023                               sizeof(const char *) +
01024                               sizeof(const char *) +
01025                               sizeof(size_t) +
01026                               sizeof(DWORD) +
01027                               sizeof(WORD) +
01028                               sizeof(BYTE))%8
01029       };
01030 
01031       Header     * prev;
01032       Header     * next;
01033       const char * className;
01034       const char * fileName;
01035       size_t       size;
01036       DWORD        request;
01037       WORD         line;
01038       BYTE         flags;
01039       char         guard[NumGuardBytes];
01040 
01041       static char GuardBytes[NumGuardBytes];
01042     };
01043 #pragma pack()
01044 
01045     BOOL isDestroyed;
01046 
01047     Header * listHead;
01048     Header * listTail;
01049 
01050     static DWORD allocationBreakpoint;
01051     DWORD allocationRequest;
01052     DWORD firstRealObject;
01053     BYTE  flags;
01054 
01055     char  allocFillChar;
01056     char  freeFillChar;
01057 
01058     DWORD currentMemoryUsage;
01059     DWORD peakMemoryUsage;
01060     DWORD currentObjects;
01061     DWORD peakObjects;
01062     DWORD totalObjects;
01063 
01064     ostream * leakDumpStream;
01065 
01066 #if defined(_WIN32)
01067     CRITICAL_SECTION mutex;
01068 #elif defined(P_PTHREADS)
01069     pthread_mutex_t mutex;
01070 #elif defined(P_VXWORKS)
01071     void * mutex;
01072 #endif
01073 };
01074 
01075 
01080 inline void * runtime_malloc(size_t bytes  ) { return malloc(bytes); }
01081 
01086 inline void runtime_free(void * ptr  ) { free(ptr); }
01087 
01088 
01095 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01096 
01103 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01104 
01111 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01112 
01113 
01120 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01121 
01122 
01129 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01130 
01131 
01146 #define PNEW  new (__FILE__, __LINE__)
01147 
01148 #if !defined(_MSC_VER) || _MSC_VER<1200
01149 #define PSPECIAL_DELETE_FUNCTION
01150 #else
01151 #define PSPECIAL_DELETE_FUNCTION \
01152     void operator delete(void * ptr, const char *, int) \
01153       { PMemoryHeap::Deallocate(ptr, Class()); } \
01154     void operator delete[](void * ptr, const char *, int) \
01155       { PMemoryHeap::Deallocate(ptr, Class()); }
01156 #endif
01157 
01158 #define PNEW_AND_DELETE_FUNCTIONS \
01159     void * operator new(size_t nSize, const char * file, int line) \
01160       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01161     void * operator new(size_t nSize) \
01162       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01163     void operator delete(void * ptr) \
01164       { PMemoryHeap::Deallocate(ptr, Class()); } \
01165     void * operator new[](size_t nSize, const char * file, int line) \
01166       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01167     void * operator new[](size_t nSize) \
01168       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01169     void operator delete[](void * ptr) \
01170       { PMemoryHeap::Deallocate(ptr, Class()); } \
01171     PSPECIAL_DELETE_FUNCTION
01172 
01173 
01174 inline void * operator new(size_t nSize, const char * file, int line)
01175   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01176 
01177 inline void * operator new[](size_t nSize, const char * file, int line)
01178   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01179 
01180 #ifndef __GNUC__
01181 void * operator new(size_t nSize);
01182 void * operator new[](size_t nSize);
01183 
01184 void operator delete(void * ptr);
01185 void operator delete[](void * ptr);
01186 
01187 #if defined(_MSC_VER) && _MSC_VER>=1200
01188 inline void operator delete(void * ptr, const char *, int)
01189   { PMemoryHeap::Deallocate(ptr, NULL); }
01190 
01191 inline void operator delete[](void * ptr, const char *, int)
01192   { PMemoryHeap::Deallocate(ptr, NULL); }
01193 #endif
01194 #endif
01195 
01196 
01197 #else // PMEMORY_CHECK
01198 
01199 #define PNEW new
01200 
01201 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01202 
01203 #define PNEW_AND_DELETE_FUNCTIONS
01204 
01205 #else
01206 
01207 #define PNEW_AND_DELETE_FUNCTIONS \
01208     void * operator new(size_t nSize) \
01209       { return malloc(nSize); } \
01210     void operator delete(void * ptr) \
01211       { free(ptr); } \
01212     void * operator new[](size_t nSize) \
01213       { return malloc(nSize); } \
01214     void operator delete[](void * ptr) \
01215       { free(ptr); }
01216 
01217 void * operator new(size_t nSize);
01218 void * operator new[](size_t nSize);
01219 
01220 void operator delete(void * ptr);
01221 void operator delete[](void * ptr);
01222 
01223 #endif
01224 
01225 #define runtime_malloc(s) malloc(s)
01226 #define runtime_free(p) free(p)
01227 
01228 #endif // PMEMORY_CHECK
01229 
01230 
01241 /*
01242 
01243   ORIGINAL
01244 
01245 #define PCLASSINFO(cls, par) \
01246   public: \
01247     static const char * Class() \
01248       { return #cls; } \
01249     virtual const char * GetClass(unsigned ancestor = 0) const \
01250       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01251     virtual BOOL IsClass(const char * clsName) const \
01252       { return strcmp(clsName, cls::Class()) == 0; } \
01253     virtual BOOL IsDescendant(const char * clsName) const \
01254       { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \
01255     virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01256       { return (Comparison)memcmp(this, &obj, sizeof(cls)); } 
01257 */
01258 
01259 
01260 #if P_HAS_TYPEINFO
01261 
01262 #define PIsDescendant(ptr, cls)    (dynamic_cast<const cls *>(ptr) != NULL) 
01263 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 
01264 
01265 #define PRemoveConst(cls, ptr)  (const_cast<cls*>(ptr))
01266 
01267 #if P_USE_ASSERTS
01268 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line) 
01269   { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01270 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01271 #else
01272 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01273 #endif
01274 
01275 #include <typeinfo>
01276 
01277 #ifndef PCLASSNAME
01278 #error  "Must define PCLASSNAME"
01279 #endif
01280 
01281 #define PBASECLASSINFO(cls, par) \
01282   public: \
01283     static inline const char * Class() \
01284       { return PCLASSNAME(cls); } \
01285     virtual BOOL InternalIsDescendant(const char * clsName) const \
01286       { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01287 
01288 #else // P_HAS_TYPEINFO
01289 
01290 #define PIsDescendant(ptr, cls)    ((ptr)->InternalIsDescendant(cls::Class()))
01291 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01292 
01293 #define PRemoveConst(cls, ptr)  ((cls*)(ptr))
01294 
01295 #if P_USE_ASSERTS
01296 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line) 
01297   { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01298 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01299 #else
01300 #define PDownCast(cls, ptr) ((cls*)(ptr))
01301 #endif
01302 
01303 #define PBASECLASSINFO(cls, par) \
01304   public: \
01305     static const char * Class() \
01306       { return #cls; } \
01307     virtual BOOL InternalIsDescendant(const char * clsName) const \
01308       { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01309 
01310 #endif // P_HAS_TYPEINFO
01311 
01312 
01313 #define PCLASSINFO(cls, par) \
01314     PBASECLASSINFO(cls, par) \
01315     virtual const char * GetClass(unsigned ancestor = 0) const \
01316       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01317     virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01318       { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01319 
01320 
01328 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01329 #ifdef DOC_PLUS_PLUS
01330 } Match previous opening brace in doc++
01331 #endif
01332 
01334 // The root of all evil ... umm classes
01335 
01340 class PObject {
01341 
01342   protected:
01346     PObject() { }
01347 
01348   public:
01349     /* Destructor required to get the "virtual". A PObject really has nothing
01350        to destroy.
01351      */
01352     virtual ~PObject() { }
01353 
01366     static inline const char * Class()    { return PCLASSNAME(PObject); }
01367 
01380     virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); }
01381 
01382     BOOL IsClass(const char * cls) const 
01383     { return strcmp(cls, GetClass()) == 0; }
01384 
01394     virtual BOOL InternalIsDescendant(
01395       const char * clsName    // Ancestor class name to compare against.
01396     ) const
01397     { return IsClass(clsName); }
01398 
01400 
01406     enum Comparison {
01407       LessThan = -1,
01408       EqualTo = 0,
01409       GreaterThan = 1
01410     };
01411 
01423     virtual Comparison Compare(
01424       const PObject & obj   // Object to compare against.
01425     ) const;
01426     
01438     virtual Comparison CompareObjectMemoryDirect(
01439       const PObject & obj   // Object to compare against.
01440     ) const;
01441 
01447     bool operator==(
01448       const PObject & obj   // Object to compare against.
01449     ) const { return Compare(obj) == EqualTo; }
01450 
01456     bool operator!=(
01457       const PObject & obj   // Object to compare against.
01458     ) const { return Compare(obj) != EqualTo; }
01459 
01465     bool operator<(
01466       const PObject & obj   // Object to compare against.
01467     ) const { return Compare(obj) == LessThan; }
01468 
01474     bool operator>(
01475       const PObject & obj   // Object to compare against.
01476     ) const { return Compare(obj) == GreaterThan; }
01477 
01483     bool operator<=(
01484       const PObject & obj   // Object to compare against.
01485     ) const { return Compare(obj) != GreaterThan; }
01486 
01492     bool operator>=(
01493       const PObject & obj   // Object to compare against.
01494     ) const { return Compare(obj) != LessThan; }
01496 
01505     virtual void PrintOn(
01506       ostream &strm   // Stream to print the object into.
01507     ) const;
01508 
01515     virtual void ReadFrom(
01516       istream &strm   // Stream to read the objects contents from.
01517     );
01518 
01519 
01525     inline friend ostream & operator<<(
01526       ostream &strm,       // Stream to print the object into.
01527       const PObject & obj  // Object to print to the stream.
01528     ) { obj.PrintOn(strm); return strm; }
01529 
01535     inline friend istream & operator>>(
01536       istream &strm,   // Stream to read the objects contents from.
01537       PObject & obj    // Object to read inormation into.
01538     ) { obj.ReadFrom(strm); return strm; }
01539 
01540 
01555     virtual PObject * Clone() const;
01556 
01568     virtual PINDEX HashFunction() const;
01570 };
01571 
01573 // Platform independent types
01574 
01575 // All these classes encapsulate primitive types such that they may be
01576 // transfered in a platform independent manner. In particular it is used to
01577 // do byte swapping for little endien and big endien processor architectures
01578 // as well as accommodating structure packing rules for memory structures.
01579 
01580 #define PANSI_CHAR 1
01581 #define PLITTLE_ENDIAN 2
01582 #define PBIG_ENDIAN 3
01583 
01584 
01585 #if 0
01586 class PStandardType
01587 /* Encapsulate a standard 8 bit character into a portable format. This would
01588    rarely need to do translation, only if the target platform uses EBCDIC
01589    would it do anything.
01590 
01591    The platform independent form here is always 8 bit ANSI.
01592  */
01593 {
01594   public:
01595     PStandardType(
01596       type newVal   // Value to initialise data in platform dependent form.
01597     ) { data = newVal; }
01598     /* Create a new instance of the platform independent type using platform
01599        dependent data, or platform independent streams.
01600      */
01601 
01602     operator type() { return data; }
01603     /* Get the platform dependent value for the type.
01604 
01605        @return
01606        data for instance.
01607      */
01608 
01609     friend ostream & operator<<(ostream & strm, const PStandardType & val)
01610       { return strm << (type)val; }
01611     /* Output the platform dependent value for the type to the stream.
01612 
01613        @return
01614        the stream output was made to.
01615      */
01616 
01617     friend istream & operator>>(istream & strm, PStandardType & val)
01618       { type data; strm >> data; val = PStandardType(data); return strm; }
01619     /* Input the platform dependent value for the type from the stream.
01620 
01621        @return
01622        the stream input was made from.
01623      */
01624 
01625 
01626   private:
01627     type data;
01628 };
01629 #endif
01630 
01631 
01632 #define PI_SAME(name, type) \
01633   struct name { \
01634     name() { } \
01635     name(type value) { data = value; } \
01636     name(const name & value) { data = value.data; } \
01637     name & operator =(type value) { data = value; return *this; } \
01638     name & operator =(const name & value) { data = value.data; return *this; } \
01639     operator type() const { return data; } \
01640     friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01641     friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01642     private: type data; \
01643   }
01644 
01645 #define PI_LOOP(src, dst) \
01646     BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01647     while (s != (BYTE *)&src) *d++ = *--s;
01648 
01649 #define PI_DIFF(name, type) \
01650   struct name { \
01651     name() { } \
01652     name(type value) { operator=(value); } \
01653     name(const name & value) { data = value.data; } \
01654     name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01655     name & operator =(const name & value) { data = value.data; return *this; } \
01656     operator type() const { type value; PI_LOOP(data, value); return value; } \
01657     friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01658     friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01659     private: type data; \
01660   }
01661 
01662 #ifndef PCHAR8
01663 #define PCHAR8 PANSI_CHAR
01664 #endif
01665 
01666 #if PCHAR8==PANSI_CHAR
01667 PI_SAME(PChar8, char);
01668 #endif
01669 
01670 PI_SAME(PInt8, signed char);
01671 
01672 PI_SAME(PUInt8, unsigned char);
01673 
01674 #if PBYTE_ORDER==PLITTLE_ENDIAN
01675 PI_SAME(PInt16l, PInt16);
01676 #elif PBYTE_ORDER==PBIG_ENDIAN
01677 PI_DIFF(PInt16l, PInt16);
01678 #endif
01679 
01680 #if PBYTE_ORDER==PLITTLE_ENDIAN
01681 PI_DIFF(PInt16b, PInt16);
01682 #elif PBYTE_ORDER==PBIG_ENDIAN
01683 PI_SAME(PInt16b, PInt16);
01684 #endif
01685 
01686 #if PBYTE_ORDER==PLITTLE_ENDIAN
01687 PI_SAME(PUInt16l, WORD);
01688 #elif PBYTE_ORDER==PBIG_ENDIAN
01689 PI_DIFF(PUInt16l, WORD);
01690 #endif
01691 
01692 #if PBYTE_ORDER==PLITTLE_ENDIAN
01693 PI_DIFF(PUInt16b, WORD);
01694 #elif PBYTE_ORDER==PBIG_ENDIAN
01695 PI_SAME(PUInt16b, WORD);
01696 #endif
01697 
01698 #if PBYTE_ORDER==PLITTLE_ENDIAN
01699 PI_SAME(PInt32l, PInt32);
01700 #elif PBYTE_ORDER==PBIG_ENDIAN
01701 PI_DIFF(PInt32l, PInt32);
01702 #endif
01703 
01704 #if PBYTE_ORDER==PLITTLE_ENDIAN
01705 PI_DIFF(PInt32b, PInt32);
01706 #elif PBYTE_ORDER==PBIG_ENDIAN
01707 PI_SAME(PInt32b, PInt32);
01708 #endif
01709 
01710 #if PBYTE_ORDER==PLITTLE_ENDIAN
01711 PI_SAME(PUInt32l, DWORD);
01712 #elif PBYTE_ORDER==PBIG_ENDIAN
01713 PI_DIFF(PUInt32l, DWORD);
01714 #endif
01715 
01716 #if PBYTE_ORDER==PLITTLE_ENDIAN
01717 PI_DIFF(PUInt32b, DWORD);
01718 #elif PBYTE_ORDER==PBIG_ENDIAN
01719 PI_SAME(PUInt32b, DWORD);
01720 #endif
01721 
01722 #if PBYTE_ORDER==PLITTLE_ENDIAN
01723 PI_SAME(PInt64l, PInt64);
01724 #elif PBYTE_ORDER==PBIG_ENDIAN
01725 PI_DIFF(PInt64l, PInt64);
01726 #endif
01727 
01728 #if PBYTE_ORDER==PLITTLE_ENDIAN
01729 PI_DIFF(PInt64b, PInt64);
01730 #elif PBYTE_ORDER==PBIG_ENDIAN
01731 PI_SAME(PInt64b, PInt64);
01732 #endif
01733 
01734 #if PBYTE_ORDER==PLITTLE_ENDIAN
01735 PI_SAME(PUInt64l, PUInt64);
01736 #elif PBYTE_ORDER==PBIG_ENDIAN
01737 PI_DIFF(PUInt64l, PUInt64);
01738 #endif
01739 
01740 #if PBYTE_ORDER==PLITTLE_ENDIAN
01741 PI_DIFF(PUInt64b, PUInt64);
01742 #elif PBYTE_ORDER==PBIG_ENDIAN
01743 PI_SAME(PUInt64b, PUInt64);
01744 #endif
01745 
01746 #if PBYTE_ORDER==PLITTLE_ENDIAN
01747 PI_SAME(PFloat32l, float);
01748 #elif PBYTE_ORDER==PBIG_ENDIAN
01749 PI_DIFF(PFloat32l, float);
01750 #endif
01751 
01752 #if PBYTE_ORDER==PLITTLE_ENDIAN
01753 PI_DIFF(PFloat32b, float);
01754 #elif PBYTE_ORDER==PBIG_ENDIAN
01755 PI_SAME(PFloat32b, float);
01756 #endif
01757 
01758 #if PBYTE_ORDER==PLITTLE_ENDIAN
01759 PI_SAME(PFloat64l, double);
01760 #elif PBYTE_ORDER==PBIG_ENDIAN
01761 PI_DIFF(PFloat64l, double);
01762 #endif
01763 
01764 #if PBYTE_ORDER==PLITTLE_ENDIAN
01765 PI_DIFF(PFloat64b, double);
01766 #elif PBYTE_ORDER==PBIG_ENDIAN
01767 PI_SAME(PFloat64b, double);
01768 #endif
01769 
01770 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01771 #if PBYTE_ORDER==PLITTLE_ENDIAN
01772 PI_SAME(PFloat80l, long double);
01773 #elif PBYTE_ORDER==PBIG_ENDIAN
01774 PI_DIFF(PFloat80l, long double);
01775 #endif
01776 
01777 #if PBYTE_ORDER==PLITTLE_ENDIAN
01778 PI_DIFF(PFloat80b, long double);
01779 #elif PBYTE_ORDER==PBIG_ENDIAN
01780 PI_SAME(PFloat80b, long double);
01781 #endif
01782 #endif
01783 
01784 #undef PI_LOOP
01785 #undef PI_SAME
01786 #undef PI_DIFF
01787 
01788 
01790 // Miscellaneous
01791 
01792 /*$MACRO PARRAYSIZE(array)
01793    This macro is used to calculate the number of array elements in a static
01794    array.
01795  */
01796 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01797 
01798 /*$MACRO PMIN(v1, v2)
01799    This macro is used to calculate the minimum of two values. As this is a
01800    macro the expression in #v1# or #v2# is executed
01801    twice so extreme care should be made in its use.
01802  */
01803 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01804 
01805 /*$MACRO PMAX(v1, v2)
01806    This macro is used to calculate the maximum of two values. As this is a
01807    macro the expression in #v1# or #v2# is executed
01808    twice so extreme care should be made in its use.
01809  */
01810 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01811 
01812 /*$MACRO PABS(val)
01813    This macro is used to calculate an absolute value. As this is a macro the
01814    expression in #val# is executed twice so extreme care should be
01815    made in its use.
01816  */
01817 #define PABS(v) ((v) < 0 ? -(v) : (v))
01818 
01819 #endif // _POBJECT_H
01820 
01821 // End Of File ///////////////////////////////////////////////////////////////

Generated on Tue Mar 15 10:44:52 2005 for PWLib by  doxygen 1.4.0