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.119  2006/07/14 04:55:09  csoutheren
00031  * Applied 1520151 - Adds PID to tracefile + Rolling Date pattern
00032  * Thanks to Paul Nader
00033  *
00034  * Revision 1.118  2006/06/20 09:49:16  csoutheren
00035  * Applied 1489468
00036  * Fix stlport on old gcc/non-gcc compilers
00037  * Thanks to Adam Butcher
00038  *
00039  * Revision 1.117  2006/04/10 23:57:27  csoutheren
00040  * Checked in changes to remove some warnings with gcc effc++ flag
00041  *
00042  * Revision 1.116  2006/03/20 00:24:56  csoutheren
00043  * Applied patch #1446482
00044  * Thanks to Adam Butcher
00045  *
00046  * Revision 1.115  2005/11/30 12:47:37  csoutheren
00047  * Removed tabs, reformatted some code, and changed tags for Doxygen
00048  *
00049  * Revision 1.114  2005/11/25 03:43:47  csoutheren
00050  * Fixed function argument comments to be compatible with Doxygen
00051  *
00052  * Revision 1.113  2005/09/18 11:05:36  dominance
00053  * include/ptlib/channel.h, include/ptlib/pstring.h, src/ptlib/common/contain.cxx,
00054  * src/ptlib/common/pchannel.cxx:
00055  *   correct the STL defined checking to use proper syntax.
00056  *
00057  * include/ptlib/object.h:
00058  *   re-add typedef to compile on mingw
00059  *
00060  * make/ptlib-config.in:
00061  *   import a long-standing fix from the Debian packs which allows usage of
00062  *   ptlib-config without manually adding -lpt for each of the subsequent
00063  *   projects
00064  *
00065  * Revision 1.112  2005/08/30 06:36:39  csoutheren
00066  * Added ability to rotate output logs on a daily basis
00067  *
00068  * Revision 1.111  2005/03/10 06:37:20  csoutheren
00069  * Removed use of typeid on WIndows to get class name because it is not threadsafe
00070  * In fact, lets just use #classname everywhere because that will always work
00071  * Thanks to Vyacheslav Frolov
00072  *
00073  * Revision 1.110  2004/08/14 14:17:29  csoutheren
00074  * Fixed problem with PAssert and associated functions caused by using expressions
00075  * as statements. inline functions are your friend :)
00076  *
00077  * Revision 1.109  2004/08/05 12:09:35  rjongbloed
00078  * Added macros for "remove const" and "down cast" funcions with and without RTTI.
00079  * Added ability to disable Asserts.
00080  * Change PAssert macros so pass through the boolean result so that they can be used
00081  *   in if statements, allowing a chance to continue if ignore assert.
00082  *
00083  * Revision 1.108  2004/07/11 07:56:35  csoutheren
00084  * Applied jumbo VxWorks patch, thanks to Eize Slange
00085  *
00086  * Revision 1.107  2004/07/03 06:49:49  rjongbloed
00087  * Added PTRACE_PARAM() macro to fix warnings on parameters used in PTRACE
00088  *  macros only.
00089  *
00090  * Revision 1.106  2004/06/01 07:42:19  csoutheren
00091  * Restored memory allocation checking
00092  * Added configure flag to enable, thanks to Derek Smithies
00093  *
00094  * Revision 1.105  2004/06/01 05:22:43  csoutheren
00095  * Restored memory check functionality
00096  *
00097  * Revision 1.104  2004/05/12 04:36:17  csoutheren
00098  * Fixed problems with using sem_wait and friends on systems that do not
00099  * support atomic integers
00100  *
00101  * Revision 1.103  2004/04/18 04:33:36  rjongbloed
00102  * Changed all operators that return BOOL to return standard type bool. This is primarily
00103  *   for improved compatibility with std STL usage removing many warnings.
00104  *
00105  * Revision 1.102  2004/04/11 13:26:25  csoutheren
00106  * Removed namespace problems and removed warnings for Windows <string>
00107  *
00108  * Revision 1.101  2004/04/11 03:20:41  csoutheren
00109  * Added Unix implementation of PCriticalSection
00110  *
00111  * Revision 1.100  2004/04/11 02:55:17  csoutheren
00112  * Added PCriticalSection for Windows
00113  * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
00114  *
00115  * Revision 1.99  2004/04/09 11:54:46  csoutheren
00116  * Added configure.in check for STL streams, and tested with gcc 2.95.3,
00117  * gcc 3.3.1, and gcc 3.3.3
00118  *
00119  * Revision 1.98  2004/04/09 07:53:51  rjongbloed
00120  * Fixed backward compatibility after STL streams change
00121  *
00122  * Revision 1.97  2004/04/09 00:56:35  csoutheren
00123  * Fixed problem with new class name code
00124  *
00125  * Revision 1.96  2004/04/09 00:42:58  csoutheren
00126  * Changed Unix build to use slightly different method for
00127  * keep class names, as GCC does not use actual class names for typeinfo
00128  *
00129  * Revision 1.95  2004/04/04 13:24:18  rjongbloed
00130  * Changes to support native C++ Run Time Type Information
00131  *
00132  * Revision 1.94  2004/04/03 08:57:31  csoutheren
00133  * Replaced pseudo-RTTI with real RTTI
00134  *
00135  * Revision 1.93  2004/04/03 08:22:20  csoutheren
00136  * Remove pseudo-RTTI and replaced with real RTTI
00137  *
00138  * Revision 1.92  2004/04/03 07:41:00  csoutheren
00139  * Fixed compile problem with ostringstream/ostrstream
00140  *
00141  * Revision 1.91  2004/04/03 07:16:05  rjongbloed
00142  * Fixed backward compatibility with MSVC 6
00143  *
00144  * Revision 1.90  2004/04/03 06:54:22  rjongbloed
00145  * Many and various changes to support new Visual C++ 2003
00146  *
00147  * Revision 1.89  2003/09/17 09:00:59  csoutheren
00148  * Moved PSmartPointer and PNotifier into seperate files
00149  * Added detection for system regex libraries on all platforms
00150  *
00151  * Revision 1.88  2003/09/17 05:41:58  csoutheren
00152  * Removed recursive includes
00153  *
00154  * Revision 1.87  2003/09/17 01:18:02  csoutheren
00155  * Removed recursive include file system and removed all references
00156  * to deprecated coooperative threading support
00157  *
00158  * Revision 1.86  2002/10/14 21:42:37  rogerh
00159  * Only use malloc.h on Windows
00160  *
00161  * Revision 1.85  2002/10/10 04:43:43  robertj
00162  * VxWorks port, thanks Martijn Roest
00163  *
00164  * Revision 1.84  2002/10/08 12:41:51  robertj
00165  * Changed for IPv6 support, thanks Sébastien Josset.
00166  *
00167  * Revision 1.83  2002/09/16 01:08:59  robertj
00168  * Added #define so can select if #pragma interface/implementation is used on
00169  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00170  *
00171  * Revision 1.82  2002/08/06 02:27:58  robertj
00172  * GNU C++ v3 compatibility.
00173  *
00174  * Revision 1.81  2002/06/25 02:22:47  robertj
00175  * Improved assertion system to allow C++ class name to be displayed if
00176  *   desired, especially relevant to container classes.
00177  *
00178  * Revision 1.80  2002/06/14 10:29:43  rogerh
00179  * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de>
00180  *
00181  * Revision 1.79  2002/06/13 08:34:05  rogerh
00182  * gcc 3.1 needs iostream instead of iostream.h
00183  *
00184  * Revision 1.78  2002/05/22 00:23:31  craigs
00185  * Added GMTTime flag to tracing options
00186  *
00187  * Revision 1.77  2002/04/19 00:20:51  craigs
00188  * Added option to append to log file rather than create anew each time
00189  *
00190  * Revision 1.76  2002/01/26 23:55:55  craigs
00191  * Changed for GCC 3.0 compatibility, thanks to manty@manty.net
00192  *
00193  * Revision 1.75  2001/10/18 19:56:26  yurik
00194  * Fixed WinCE x86 compilation problems with memory check off
00195  *
00196  * Revision 1.74  2001/08/12 11:26:07  robertj
00197  * Put back PMEMORY_CHECK taken out by the Carbon port.
00198  *
00199  * Revision 1.73  2001/08/11 07:57:30  rogerh
00200  * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
00201  *
00202  * Revision 1.72  2001/05/03 06:27:29  robertj
00203  * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state.
00204  *
00205  * Revision 1.71  2001/03/24 01:11:10  robertj
00206  * Added missing PTRACE_IF define in non PTRACING mode.
00207  *
00208  * Revision 1.70  2001/03/23 05:34:09  robertj
00209  * Added PTRACE_IF to output trace if a conditional is TRUE.
00210  *
00211  * Revision 1.69  2001/03/01 02:15:16  robertj
00212  * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise.
00213  *
00214  * Revision 1.68  2001/02/22 08:16:41  robertj
00215  * Added standard trace file setup subroutine.
00216  *
00217  * Revision 1.67  2001/02/13 03:27:24  robertj
00218  * Added function to do heap validation.
00219  *
00220  * Revision 1.66  2001/02/09 04:41:27  robertj
00221  * Removed added non memrycheck implementations of new/delete when using GNU C++.
00222  *
00223  * Revision 1.65  2001/02/07 04:47:49  robertj
00224  * Added changes for possible random crashes in multi DLL environment
00225  *   due to memory allocation wierdness, thanks Milan Dimitrijevic.
00226  *
00227  * Revision 1.64  2001/01/24 06:15:44  yurik
00228  * Windows CE port-related declarations
00229  *
00230  * Revision 1.63  2000/07/28 05:13:47  robertj
00231  * Fixed silly mistake in runtime_malloc() function, should return a pointer!
00232  *
00233  * Revision 1.62  2000/07/20 05:46:34  robertj
00234  * Added runtime_malloc() function for cases where memory check code must be bypassed.
00235  *
00236  * Revision 1.61  2000/07/13 15:45:35  robertj
00237  * Removed #define std that causes everyone so much grief!
00238  *
00239  * Revision 1.60  2000/06/26 11:17:19  robertj
00240  * Nucleus++ port (incomplete).
00241  *
00242  * Revision 1.59  2000/02/29 12:26:14  robertj
00243  * Added named threads to tracing, thanks to Dave Harvey
00244  *
00245  * Revision 1.58  2000/01/07 12:31:12  robertj
00246  * Fixed 8 byte alignment on memory heap checking.
00247  *
00248  * Revision 1.57  2000/01/05 00:29:12  robertj
00249  * Fixed alignment problems in memory checking debug functions.
00250  *
00251  * Revision 1.56  1999/11/30 00:22:54  robertj
00252  * Updated documentation for doc++
00253  *
00254  * Revision 1.55  1999/11/01 00:10:27  robertj
00255  * Added override of new functions for MSVC memory check code.
00256  *
00257  * Revision 1.54  1999/10/19 09:21:30  robertj
00258  * Added functions to get current trace options and level.
00259  *
00260  * Revision 1.53  1999/09/13 13:15:06  robertj
00261  * Changed PTRACE so will output to system log in PServiceProcess applications.
00262  *
00263  * Revision 1.52  1999/08/24 08:15:23  robertj
00264  * Added missing operator on smart pointer to return the pointer!
00265  *
00266  * Revision 1.51  1999/08/24 06:54:36  robertj
00267  * Cleaned up the smart pointer code (macros).
00268  *
00269  * Revision 1.50  1999/08/22 13:38:39  robertj
00270  * Fixed termination hang up problem with memory check code under unix pthreads.
00271  *
00272  * Revision 1.49  1999/08/17 03:46:40  robertj
00273  * Fixed usage of inlines in optimised version.
00274  *
00275  * Revision 1.48  1999/08/10 10:45:09  robertj
00276  * Added mutex in memory check detection code.
00277  *
00278  * Revision 1.47  1999/07/18 15:08:24  robertj
00279  * Fixed 64 bit compatibility
00280  *
00281  * Revision 1.46  1999/06/14 07:59:37  robertj
00282  * Enhanced tracing again to add options to trace output (timestamps etc).
00283  *
00284  * Revision 1.45  1999/05/01 11:29:19  robertj
00285  * Alpha linux port changes.
00286  *
00287  * Revision 1.44  1999/04/18 12:58:39  robertj
00288  * MSVC 5 backward compatibility
00289  *
00290  * Revision 1.43  1999/03/09 10:30:17  robertj
00291  * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions.
00292  *
00293  * Revision 1.42  1999/03/09 02:59:50  robertj
00294  * Changed comments to doc++ compatible documentation.
00295  *
00296  * Revision 1.41  1999/02/23 07:11:26  robertj
00297  * Improved trace facility adding trace levels and #define to remove all trace code.
00298  *
00299  * Revision 1.40  1999/02/22 10:48:14  robertj
00300  * Fixed delete operator prototypes for MSVC6 and GNU compatibility.
00301  *
00302  * Revision 1.39  1999/02/19 11:33:02  robertj
00303  * Fixed compatibility problems with GNU/MSVC6
00304  *
00305  * Revision 1.38  1999/02/16 08:12:22  robertj
00306  * MSVC 6.0 compatibility changes.
00307  *
00308  * Revision 1.37  1999/01/07 03:35:35  robertj
00309  * Added default for PCHAR8 to ANSI, removes need for compiler option.
00310  *
00311  * Revision 1.36  1998/12/15 09:00:29  robertj
00312  * Fixed 8 byte alignment problem in memory leak check code for sparc.
00313  *
00314  * Revision 1.35  1998/11/03 00:57:19  robertj
00315  * Added allocation breakpoint variable.
00316  *
00317  * Revision 1.34  1998/10/26 11:05:26  robertj
00318  * Added raw free for things allocated within the runtime library.
00319  *
00320  * Revision 1.33  1998/10/18 14:26:55  robertj
00321  * Improved tracing functions.
00322  *
00323  * Revision 1.32  1998/10/15 07:47:21  robertj
00324  * Added ability to ignore G++lib memory leaks.
00325  *
00326  * Revision 1.31  1998/10/15 01:53:58  robertj
00327  * GNU compatibility.
00328  *
00329  * Revision 1.30  1998/10/13 14:23:29  robertj
00330  * Complete rewrite of memory leak detection.
00331  *
00332  * Revision 1.29  1998/09/23 06:20:57  robertj
00333  * Added open source copyright license.
00334  *
00335  * Revision 1.28  1998/09/14 12:29:11  robertj
00336  * Fixed memory leak dump under windows to not include static globals.
00337  * Fixed problem with notifier declaration not allowing implementation inline after macro.
00338  *
00339  * Revision 1.27  1997/07/08 13:13:45  robertj
00340  * DLL support.
00341  *
00342  * Revision 1.26  1997/04/27 05:50:11  robertj
00343  * DLL support.
00344  *
00345  * Revision 1.25  1997/02/05 11:54:10  robertj
00346  * Fixed problems with memory check and leak detection.
00347  *
00348  * Revision 1.24  1996/09/16 12:57:23  robertj
00349  * DLL support
00350  *
00351  * Revision 1.23  1996/08/17 10:00:23  robertj
00352  * Changes for Windows DLL support.
00353  *
00354  * Revision 1.22  1996/07/15 10:27:51  robertj
00355  * Changed endian classes to be memory mapped.
00356  *
00357  * Revision 1.21  1996/05/09 12:14:48  robertj
00358  * Fixed up 64 bit integer class for Mac platform.
00359  *
00360  * Revision 1.20  1996/02/24 14:19:29  robertj
00361  * Fixed bug in endian independent integer code for memory transfers.
00362  *
00363  * Revision 1.19  1996/01/28 02:46:43  robertj
00364  * Removal of MemoryPointer classes as usage didn't work for GNU.
00365  * Added missing bit shift operators to 64 bit integer class.
00366  *
00367  * Revision 1.18  1996/01/23 13:14:32  robertj
00368  * Added const version of PMemoryPointer.
00369  * Added constructor to endian classes for the base type.
00370  *
00371  * Revision 1.17  1996/01/02 11:54:11  robertj
00372  * Mac OS compatibility changes.
00373  *
00374  * Revision 1.16  1995/11/09 12:17:10  robertj
00375  * Added platform independent base type access classes.
00376  *
00377  * Revision 1.15  1995/06/17 11:12:47  robertj
00378  * Documentation update.
00379  *
00380  * Revision 1.14  1995/06/04 12:34:19  robertj
00381  * Added trace functions.
00382  *
00383  * Revision 1.13  1995/04/25 12:04:35  robertj
00384  * Fixed borland compatibility.
00385  * Fixed function hiding ancestor virtuals.
00386  *
00387  * Revision 1.12  1995/03/14 12:41:54  robertj
00388  * Updated documentation to use HTML codes.
00389  *
00390  * Revision 1.11  1995/03/12  04:40:55  robertj
00391  * Changed standard error code for not open from file to channel.
00392  *
00393  * Revision 1.10  1995/02/19  04:19:14  robertj
00394  * Added dynamically linked command processing.
00395  *
00396  * Revision 1.9  1995/02/05  00:48:07  robertj
00397  * Fixed template version.
00398  *
00399  * Revision 1.8  1995/01/15  04:51:31  robertj
00400  * Mac compatibility.
00401  * Added levels of memory checking.
00402  *
00403  * Revision 1.7  1995/01/09  12:38:31  robertj
00404  * Changed variable names around during documentation run.
00405  * Fixed smart pointer comparison.
00406  * Fixed serialisation stuff.
00407  * Documentation.
00408  *
00409  * Revision 1.6  1995/01/03  09:39:06  robertj
00410  * Put standard malloc style memory allocation etc into memory check system.
00411  *
00412  * Revision 1.5  1994/12/12  10:08:30  robertj
00413  * Renamed PWrapper to PSmartPointer..
00414  *
00415  * Revision 1.4  1994/12/05  11:23:28  robertj
00416  * Fixed PWrapper macros.
00417  *
00418  * Revision 1.3  1994/11/19  00:22:55  robertj
00419  * Changed PInteger to be INT, ie standard type like BOOL/WORD etc.
00420  * Moved null object check in notifier to construction rather than use.
00421  * Added virtual to the callback function in notifier destination class.
00422  *
00423  * Revision 1.2  1994/11/03  09:25:30  robertj
00424  * Made notifier destination object not to be descendent of PObject.
00425  *
00426  * Revision 1.1  1994/10/30  12:01:37  robertj
00427  * Initial revision
00428  *
00429  */
00430 
00431 #ifndef _POBJECT_H
00432 #define _POBJECT_H
00433 
00434 #ifdef P_USE_PRAGMA
00435 #pragma interface
00436 #endif
00437 
00438 #ifdef _WIN32
00439 #include "msos/ptlib/contain.h"
00440 #else
00441 #include "unix/ptlib/contain.h"
00442 #endif
00443 
00444 #if defined(P_VXWORKS)
00445 #include <private/stdiop.h>
00446 #endif
00447 
00448 #include <stdio.h>
00449 #include <stdarg.h>
00450 #include <stdlib.h>
00451 
00452 #ifdef _WIN32
00453   #include <malloc.h>
00454 #endif
00455 
00456 #include <string.h>
00457 
00458 #ifdef __USE_STL__
00459   #include <string>
00460   #include <iomanip>
00461   #include <iostream>
00462   #if (__GNUC__ >= 3)
00463     #include <sstream>
00464     typedef std::ostringstream ostrstream;
00465   #else
00466     #include <strstream>
00467   #endif
00468   //using namespace std;
00469   #ifdef _STLP_IOS_BASE_H
00470   typedef std::ios_base::fmtflags _Ios_Fmtflags;
00471   #endif
00472 #else
00473   #if (__GNUC__ >= 3)
00474     #include <iostream>
00475     #ifndef __MWERKS__
00476       #include <iomanip>
00477     #endif
00478   #else
00479     #include <iostream.h>
00480     #ifdef __GNUC__
00481       #include <strstream.h>
00482     #else
00483       #include <strstrea.h>
00484     #endif
00485     #ifndef __MWERKS__
00486       #include <iomanip.h>
00487     #endif
00488   #endif
00489 #endif
00490 
00491 #ifdef _WIN32_WCE
00492   #include <stdlibx.h>
00493 #endif
00494 
00495 #if (__GNUC__ < 3) && !defined(_STLP_IOS_BASE_H)
00496 typedef long _Ios_Fmtflags;
00497 #endif
00498 
00499 #if _MSC_VER<1300
00500 #define _BADOFF -1
00501 #endif
00502 
00504 // Disable inlines when debugging for faster compiles (the compiler doesn't
00505 // actually inline the function with debug on any way).
00506 
00507 #ifndef P_USE_INLINES
00508 #ifdef _DEBUG
00509 #define P_USE_INLINES 0
00510 #else
00511 #define P_USE_INLINES 0
00512 #endif
00513 #endif
00514 
00515 #if P_USE_INLINES
00516 #define PINLINE inline
00517 #else
00518 #define PINLINE
00519 #endif
00520 
00521 
00523 // Declare the debugging support
00524 
00525 #ifndef P_USE_ASSERTS
00526 #define P_USE_ASSERTS 1
00527 #endif
00528 
00529 #if !P_USE_ASSERTS
00530 
00531 #define PAssert(b, m) (b)
00532 #define PAssert2(b, c, m) (b)
00533 #define PAssertOS(b) (b)
00534 #define PAssertNULL(p) (p)
00535 #define PAssertAlways(m)
00536 #define PAssertAlways2(c, m)
00537 
00538 #else // P_USE_ASSERTS
00539 
00541 enum PStandardAssertMessage {
00542   PLogicError,              // A logic error occurred.
00543   POutOfMemory,             // A new or malloc failed.
00544   PNullPointerReference,    // A reference was made through a NULL pointer.
00545   PInvalidCast,             // An invalid cast to descendant is required.
00546   PInvalidArrayIndex,       // An index into an array was negative.
00547   PInvalidArrayElement,     // A NULL array element object was accessed.
00548   PStackEmpty,              // A Pop() was made of a stack with no elements.
00549   PUnimplementedFunction,   // Funtion is not implemented.
00550   PInvalidParameter,        // Invalid parameter was passed to a function.
00551   POperatingSystemError,    // Error was returned by Operating System.
00552   PChannelNotOpen,          // Operation attempted when channel not open.
00553   PUnsupportedFeature,      // Feature is not supported.
00554   PInvalidWindow,           // Access through invalid window.
00555   PMaxStandardAssertMessage
00556 };
00557 
00558 #define __CLASS__ NULL
00559 
00560 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00561 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00562 void PAssertFunc(const char * full_msg);
00563 
00564 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00565 {
00566   if (!b) 
00567     PAssertFunc(file, line, className, msg);
00568   return b;
00569 }
00570 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00571 {
00572   if (!b) 
00573     PAssertFunc(file, line, className, msg);
00574   return b;
00575 }
00576 
00583 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00584 
00592 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00593 
00600 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00601 
00611 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p): \
00612                      (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00613 
00620 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00621 
00628 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00629 
00630 #endif // P_USE_ASSERTS
00631 
00632 
00637 ostream & PGetErrorStream();
00638 
00642 void PSetErrorStream(ostream * strm  );
00643 
00658 #define PError (PGetErrorStream())
00659 
00660 
00661 
00663 // Debug and tracing
00664 
00665 #ifndef PTRACING
00666 #ifndef _DEBUG
00667 #define PTRACING 0
00668 #else
00669 #define PTRACING 1
00670 #endif
00671 #endif
00672 
00677 class PTrace
00678 {
00679 public:
00681   enum Options {
00687     Blocks = 1,
00689     DateAndTime = 2,
00691     Timestamp = 4,
00693     Thread = 8,
00695     TraceLevel = 16,
00697     FileAndLine = 32,
00699     ThreadAddress = 64,
00701     AppendToFile = 128,
00704     GMTTime = 256,
00707     RotateDaily = 512,
00711     SystemLogStream = 32768
00712   };
00713 
00721   static void Initialise(
00722     unsigned level,
00723     const char * filename = NULL,
00724     unsigned options = Timestamp | Thread | Blocks
00725   );
00726 
00737   static void Initialise(
00738     unsigned level,
00739     const char * filename,
00740     const char * rolloverPattern,
00741     unsigned options = Timestamp | Thread | Blocks
00742   );
00743 
00750   static void SetOptions(unsigned options  );
00751 
00759   static void ClearOptions(unsigned options  );
00760 
00765   static unsigned GetOptions();
00766 
00772   static void SetLevel(unsigned level  );
00773 
00779   static unsigned GetLevel();
00780 
00785   static BOOL CanTrace(unsigned level );
00786 
00791   static void SetStream(ostream * out  );
00792 
00808   static ostream & Begin(
00809     unsigned level,         
00810     const char * fileName,  
00811     int lineNum             
00812   );
00813 
00830   static ostream & End(ostream & strm );
00831 
00832 
00838   class Block {
00839     public:
00841       Block(
00842         const char * fileName, 
00843         int lineNum,           
00844         const char * traceName
00846        );
00847       Block(const Block & obj)
00848         : file(obj.file), line(obj.line), name(obj.name) { }
00850       ~Block();
00851     private:
00852       Block & operator=(const Block &)
00853       { return *this; }
00854       const char * file;
00855       int          line;
00856       const char * name;
00857   };
00858 };
00859 
00860 #if !PTRACING
00861 
00862 #define PTRACE_PARAM(param)
00863 #define PTRACE_BLOCK(n)
00864 #define PTRACE_LINE()
00865 #define PTRACE(level, arg)
00866 #define PTRACE_IF(level, cond, args)
00867 
00868 #else
00869 
00870 /* Macro to conditionally declare a parameter to a function to avoid compiler
00871    warning due that parameter only being used in a PTRACE */
00872 #define PTRACE_PARAM(param) param
00873 
00880 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00881 
00885 #define PTRACE_LINE() \
00886     if (!PTrace::CanTrace(1)) ; else \
00887       PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00888 
00894 #define PTRACE(level, args) \
00895     if (!PTrace::CanTrace(level)) ; else \
00896       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00897 
00905 #define PTRACE_IF(level, cond, args) \
00906     if (!(PTrace::CanTrace(level)  && (cond))) ; else \
00907       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00908 
00909 #endif
00910 
00911 #if PMEMORY_CHECK
00912 
00919 class PMemoryHeap {
00920   protected:
00922     PMemoryHeap();
00923 
00924   public:
00925     // Clear up the memory checking subsystem, dumping memory leaks.
00926     ~PMemoryHeap();
00927 
00934     static void * Allocate(
00935       size_t nSize,           
00936       const char * file,      
00937       int line,               
00938       const char * className  
00939     );
00946     static void * Allocate(
00947       size_t count,       
00948       size_t iSize,       
00949       const char * file,  
00950       int line            
00951     );
00952 
00960     static void * Reallocate(
00961       void * ptr,         
00962       size_t nSize,       
00963       const char * file,  
00964       int line            
00965     );
00966 
00972     static void Deallocate(
00973       void * ptr,             
00974       const char * className  
00975     );
00976 
00979     enum Validation {
00980       Ok, Bad, Trashed
00981     };
00989     static Validation Validate(
00990       void * ptr,             
00991       const char * className, 
00992       ostream * error         
00993     );
00994 
00999     static BOOL ValidateHeap(
01000       ostream * error = NULL  
01001     );
01002 
01008     static BOOL SetIgnoreAllocations(
01009       BOOL ignore  
01010     );
01011 
01015     static void DumpStatistics();
01019     static void DumpStatistics(ostream & strm );
01020 
01021     /* Get number of allocation.
01022       Each allocation is counted and if desired the next allocation request
01023       number may be obtained via this function.
01024       @return Allocation request number.
01025      */
01026     static DWORD GetAllocationRequest();
01027 
01035     static void DumpObjectsSince(
01036       DWORD objectNumber    
01037     );
01038 
01044     static void DumpObjectsSince(
01045       DWORD objectNumber,   
01046       ostream & strm        
01047     );
01048 
01054     static void SetAllocationBreakpoint(
01055       DWORD point   
01056     );
01057 
01058   protected:
01059     void * InternalAllocate(
01060       size_t nSize,           // Number of bytes to allocate.
01061       const char * file,      // Source file name for allocating function.
01062       int line,               // Source file line for allocating function.
01063       const char * className  // Class name for allocating function.
01064     );
01065     Validation InternalValidate(
01066       void * ptr,             // Pointer to memory block to check
01067       const char * className, // Class name it should be.
01068       ostream * error         // Stream to receive error message (may be NULL)
01069     );
01070     void InternalDumpStatistics(ostream & strm);
01071     void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01072 
01073     class Wrapper {
01074       public:
01075         Wrapper();
01076         ~Wrapper();
01077         PMemoryHeap * operator->() const { return instance; }
01078       private:
01079         PMemoryHeap * instance;
01080     };
01081     friend class Wrapper;
01082 
01083     enum Flags {
01084       NoLeakPrint = 1
01085     };
01086 
01087 #pragma pack(1)
01088     struct Header {
01089       enum {
01090         // Assure that the Header struct is aligned to 8 byte boundary
01091         NumGuardBytes = 16 - (sizeof(Header *) +
01092                               sizeof(Header *) +
01093                               sizeof(const char *) +
01094                               sizeof(const char *) +
01095                               sizeof(size_t) +
01096                               sizeof(DWORD) +
01097                               sizeof(WORD) +
01098                               sizeof(BYTE))%8
01099       };
01100 
01101       Header     * prev;
01102       Header     * next;
01103       const char * className;
01104       const char * fileName;
01105       size_t       size;
01106       DWORD        request;
01107       WORD         line;
01108       BYTE         flags;
01109       char         guard[NumGuardBytes];
01110 
01111       static char GuardBytes[NumGuardBytes];
01112     };
01113 #pragma pack()
01114 
01115     BOOL isDestroyed;
01116 
01117     Header * listHead;
01118     Header * listTail;
01119 
01120     static DWORD allocationBreakpoint;
01121     DWORD allocationRequest;
01122     DWORD firstRealObject;
01123     BYTE  flags;
01124 
01125     char  allocFillChar;
01126     char  freeFillChar;
01127 
01128     DWORD currentMemoryUsage;
01129     DWORD peakMemoryUsage;
01130     DWORD currentObjects;
01131     DWORD peakObjects;
01132     DWORD totalObjects;
01133 
01134     ostream * leakDumpStream;
01135 
01136 #if defined(_WIN32)
01137     CRITICAL_SECTION mutex;
01138 #elif defined(P_PTHREADS)
01139     pthread_mutex_t mutex;
01140 #elif defined(P_VXWORKS)
01141     void * mutex;
01142 #endif
01143 };
01144 
01145 
01150 inline void * runtime_malloc(size_t bytes  ) { return malloc(bytes); }
01151 
01156 inline void runtime_free(void * ptr  ) { free(ptr); }
01157 
01158 
01165 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01166 
01173 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01174 
01181 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01182 
01183 
01190 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01191 
01192 
01199 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01200 
01201 
01216 #define PNEW  new (__FILE__, __LINE__)
01217 
01218 #if !defined(_MSC_VER) || _MSC_VER<1200
01219 #define PSPECIAL_DELETE_FUNCTION
01220 #else
01221 #define PSPECIAL_DELETE_FUNCTION \
01222     void operator delete(void * ptr, const char *, int) \
01223       { PMemoryHeap::Deallocate(ptr, Class()); } \
01224     void operator delete[](void * ptr, const char *, int) \
01225       { PMemoryHeap::Deallocate(ptr, Class()); }
01226 #endif
01227 
01228 #define PNEW_AND_DELETE_FUNCTIONS \
01229     void * operator new(size_t nSize, const char * file, int line) \
01230       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01231     void * operator new(size_t nSize) \
01232       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01233     void operator delete(void * ptr) \
01234       { PMemoryHeap::Deallocate(ptr, Class()); } \
01235     void * operator new[](size_t nSize, const char * file, int line) \
01236       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01237     void * operator new[](size_t nSize) \
01238       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01239     void operator delete[](void * ptr) \
01240       { PMemoryHeap::Deallocate(ptr, Class()); } \
01241     PSPECIAL_DELETE_FUNCTION
01242 
01243 
01244 inline void * operator new(size_t nSize, const char * file, int line)
01245   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01246 
01247 inline void * operator new[](size_t nSize, const char * file, int line)
01248   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01249 
01250 #ifndef __GNUC__
01251 void * operator new(size_t nSize);
01252 void * operator new[](size_t nSize);
01253 
01254 void operator delete(void * ptr);
01255 void operator delete[](void * ptr);
01256 
01257 #if defined(_MSC_VER) && _MSC_VER>=1200
01258 inline void operator delete(void * ptr, const char *, int)
01259   { PMemoryHeap::Deallocate(ptr, NULL); }
01260 
01261 inline void operator delete[](void * ptr, const char *, int)
01262   { PMemoryHeap::Deallocate(ptr, NULL); }
01263 #endif
01264 #endif
01265 
01266 
01267 #else // PMEMORY_CHECK
01268 
01269 #define PNEW new
01270 
01271 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01272 
01273 #define PNEW_AND_DELETE_FUNCTIONS
01274 
01275 #else
01276 
01277 #define PNEW_AND_DELETE_FUNCTIONS \
01278     void * operator new(size_t nSize) \
01279       { return malloc(nSize); } \
01280     void operator delete(void * ptr) \
01281       { free(ptr); } \
01282     void * operator new[](size_t nSize) \
01283       { return malloc(nSize); } \
01284     void operator delete[](void * ptr) \
01285       { free(ptr); }
01286 
01287 void * operator new(size_t nSize);
01288 void * operator new[](size_t nSize);
01289 
01290 void operator delete(void * ptr);
01291 void operator delete[](void * ptr);
01292 
01293 #endif
01294 
01295 #define runtime_malloc(s) malloc(s)
01296 #define runtime_free(p) free(p)
01297 
01298 #endif // PMEMORY_CHECK
01299 
01300 
01311 /*
01312 
01313   ORIGINAL
01314 
01315 #define PCLASSINFO(cls, par) \
01316   public: \
01317     static const char * Class() \
01318       { return #cls; } \
01319     virtual const char * GetClass(unsigned ancestor = 0) const \
01320       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01321     virtual BOOL IsClass(const char * clsName) const \
01322       { return strcmp(clsName, cls::Class()) == 0; } \
01323     virtual BOOL IsDescendant(const char * clsName) const \
01324       { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \
01325     virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01326       { return (Comparison)memcmp(this, &obj, sizeof(cls)); } 
01327 */
01328 
01329 
01330 #if P_HAS_TYPEINFO
01331 
01332 #define PIsDescendant(ptr, cls)    (dynamic_cast<const cls *>(ptr) != NULL) 
01333 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 
01334 
01335 #define PRemoveConst(cls, ptr)  (const_cast<cls*>(ptr))
01336 
01337 #if P_USE_ASSERTS
01338 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line) 
01339   { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01340 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01341 #else
01342 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01343 #endif
01344 
01345 #include <typeinfo>
01346 
01347 #define   PCLASSNAME(cls) (#cls)
01348 
01349 #define PBASECLASSINFO(cls, par) \
01350   public: \
01351     static inline const char * Class() \
01352       { return PCLASSNAME(cls); } \
01353     virtual BOOL InternalIsDescendant(const char * clsName) const \
01354       { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01355 
01356 #else // P_HAS_TYPEINFO
01357 
01358 #define PIsDescendant(ptr, cls)    ((ptr)->InternalIsDescendant(cls::Class()))
01359 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01360 
01361 #define PRemoveConst(cls, ptr)  ((cls*)(ptr))
01362 
01363 #if P_USE_ASSERTS
01364 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line) 
01365   { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01366 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01367 #else
01368 #define PDownCast(cls, ptr) ((cls*)(ptr))
01369 #endif
01370 
01371 #define PBASECLASSINFO(cls, par) \
01372   public: \
01373     static const char * Class() \
01374       { return #cls; } \
01375     virtual BOOL InternalIsDescendant(const char * clsName) const \
01376       { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01377 
01378 #endif // P_HAS_TYPEINFO
01379 
01380 
01381 #define PCLASSINFO(cls, par) \
01382     PBASECLASSINFO(cls, par) \
01383     virtual const char * GetClass(unsigned ancestor = 0) const \
01384       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01385     virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01386       { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01387 
01388 
01396 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01397 #ifdef DOC_PLUS_PLUS
01398 } Match previous opening brace in doc++
01399 #endif
01400 
01402 // The root of all evil ... umm classes
01403 
01408 class PObject {
01409 
01410   protected:
01414     PObject() { }
01415 
01416   public:
01417     /* Destructor required to get the "virtual". A PObject really has nothing
01418        to destroy.
01419      */
01420     virtual ~PObject() { }
01421 
01434     static inline const char * Class()    { return PCLASSNAME(PObject); }
01435 
01448     virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); }
01449 
01450     BOOL IsClass(const char * cls) const 
01451     { return strcmp(cls, GetClass()) == 0; }
01452 
01462     virtual BOOL InternalIsDescendant(
01463       const char * clsName    // Ancestor class name to compare against.
01464     ) const
01465     { return IsClass(clsName); }
01466 
01468 
01474     enum Comparison {
01475       LessThan = -1,
01476       EqualTo = 0,
01477       GreaterThan = 1
01478     };
01479 
01491     virtual Comparison Compare(
01492       const PObject & obj   // Object to compare against.
01493     ) const;
01494     
01506     virtual Comparison CompareObjectMemoryDirect(
01507       const PObject & obj   // Object to compare against.
01508     ) const;
01509 
01515     bool operator==(
01516       const PObject & obj   // Object to compare against.
01517     ) const { return Compare(obj) == EqualTo; }
01518 
01524     bool operator!=(
01525       const PObject & obj   // Object to compare against.
01526     ) const { return Compare(obj) != EqualTo; }
01527 
01533     bool operator<(
01534       const PObject & obj   // Object to compare against.
01535     ) const { return Compare(obj) == LessThan; }
01536 
01542     bool operator>(
01543       const PObject & obj   // Object to compare against.
01544     ) const { return Compare(obj) == GreaterThan; }
01545 
01551     bool operator<=(
01552       const PObject & obj   // Object to compare against.
01553     ) const { return Compare(obj) != GreaterThan; }
01554 
01560     bool operator>=(
01561       const PObject & obj   // Object to compare against.
01562     ) const { return Compare(obj) != LessThan; }
01564 
01573     virtual void PrintOn(
01574       ostream &strm   // Stream to print the object into.
01575     ) const;
01576 
01583     virtual void ReadFrom(
01584       istream &strm   // Stream to read the objects contents from.
01585     );
01586 
01587 
01593     inline friend ostream & operator<<(
01594       ostream &strm,       // Stream to print the object into.
01595       const PObject & obj  // Object to print to the stream.
01596     ) { obj.PrintOn(strm); return strm; }
01597 
01603     inline friend istream & operator>>(
01604       istream &strm,   // Stream to read the objects contents from.
01605       PObject & obj    // Object to read inormation into.
01606     ) { obj.ReadFrom(strm); return strm; }
01607 
01608 
01623     virtual PObject * Clone() const;
01624 
01636     virtual PINDEX HashFunction() const;
01638 };
01639 
01641 // Platform independent types
01642 
01643 // All these classes encapsulate primitive types such that they may be
01644 // transfered in a platform independent manner. In particular it is used to
01645 // do byte swapping for little endien and big endien processor architectures
01646 // as well as accommodating structure packing rules for memory structures.
01647 
01648 #define PANSI_CHAR 1
01649 #define PLITTLE_ENDIAN 2
01650 #define PBIG_ENDIAN 3
01651 
01652 
01653 #if 0
01654 class PStandardType
01655 /* Encapsulate a standard 8 bit character into a portable format. This would
01656    rarely need to do translation, only if the target platform uses EBCDIC
01657    would it do anything.
01658 
01659    The platform independent form here is always 8 bit ANSI.
01660  */
01661 {
01662   public:
01663     PStandardType(
01664       type newVal   // Value to initialise data in platform dependent form.
01665     ) { data = newVal; }
01666     /* Create a new instance of the platform independent type using platform
01667        dependent data, or platform independent streams.
01668      */
01669 
01670     operator type() { return data; }
01671     /* Get the platform dependent value for the type.
01672 
01673        @return
01674        data for instance.
01675      */
01676 
01677     friend ostream & operator<<(ostream & strm, const PStandardType & val)
01678       { return strm << (type)val; }
01679     /* Output the platform dependent value for the type to the stream.
01680 
01681        @return
01682        the stream output was made to.
01683      */
01684 
01685     friend istream & operator>>(istream & strm, PStandardType & val)
01686       { type data; strm >> data; val = PStandardType(data); return strm; }
01687     /* Input the platform dependent value for the type from the stream.
01688 
01689        @return
01690        the stream input was made from.
01691      */
01692 
01693 
01694   private:
01695     type data;
01696 };
01697 #endif
01698 
01699 
01700 #define PI_SAME(name, type) \
01701   struct name { \
01702     name() : data(0) { } \
01703     name(type value) : data(value) { } \
01704     name(const name & value) : data(value.data) { } \
01705     name & operator =(type value) { data = value; return *this; } \
01706     name & operator =(const name & value) { data = value.data; return *this; } \
01707     operator type() const { return data; } \
01708     friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01709     friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01710     private: type data; \
01711   }
01712 
01713 #define PI_LOOP(src, dst) \
01714     BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01715     while (s != (BYTE *)&src) *d++ = *--s;
01716 
01717 #define PI_DIFF(name, type) \
01718   struct name { \
01719     name() : data(0) { } \
01720     name(type value) : data(0) { operator=(value); } \
01721     name(const name & value) : data(value.data) { } \
01722     name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01723     name & operator =(const name & value) { data = value.data; return *this; } \
01724     operator type() const { type value; PI_LOOP(data, value); return value; } \
01725     friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01726     friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01727     private: type data; \
01728   }
01729 
01730 #ifndef PCHAR8
01731 #define PCHAR8 PANSI_CHAR
01732 #endif
01733 
01734 #if PCHAR8==PANSI_CHAR
01735 PI_SAME(PChar8, char);
01736 #endif
01737 
01738 PI_SAME(PInt8, signed char);
01739 
01740 PI_SAME(PUInt8, unsigned char);
01741 
01742 #if PBYTE_ORDER==PLITTLE_ENDIAN
01743 PI_SAME(PInt16l, PInt16);
01744 #elif PBYTE_ORDER==PBIG_ENDIAN
01745 PI_DIFF(PInt16l, PInt16);
01746 #endif
01747 
01748 #if PBYTE_ORDER==PLITTLE_ENDIAN
01749 PI_DIFF(PInt16b, PInt16);
01750 #elif PBYTE_ORDER==PBIG_ENDIAN
01751 PI_SAME(PInt16b, PInt16);
01752 #endif
01753 
01754 #if PBYTE_ORDER==PLITTLE_ENDIAN
01755 PI_SAME(PUInt16l, WORD);
01756 #elif PBYTE_ORDER==PBIG_ENDIAN
01757 PI_DIFF(PUInt16l, WORD);
01758 #endif
01759 
01760 #if PBYTE_ORDER==PLITTLE_ENDIAN
01761 PI_DIFF(PUInt16b, WORD);
01762 #elif PBYTE_ORDER==PBIG_ENDIAN
01763 PI_SAME(PUInt16b, WORD);
01764 #endif
01765 
01766 #if PBYTE_ORDER==PLITTLE_ENDIAN
01767 PI_SAME(PInt32l, PInt32);
01768 #elif PBYTE_ORDER==PBIG_ENDIAN
01769 PI_DIFF(PInt32l, PInt32);
01770 #endif
01771 
01772 #if PBYTE_ORDER==PLITTLE_ENDIAN
01773 PI_DIFF(PInt32b, PInt32);
01774 #elif PBYTE_ORDER==PBIG_ENDIAN
01775 PI_SAME(PInt32b, PInt32);
01776 #endif
01777 
01778 #if PBYTE_ORDER==PLITTLE_ENDIAN
01779 PI_SAME(PUInt32l, DWORD);
01780 #elif PBYTE_ORDER==PBIG_ENDIAN
01781 PI_DIFF(PUInt32l, DWORD);
01782 #endif
01783 
01784 #if PBYTE_ORDER==PLITTLE_ENDIAN
01785 PI_DIFF(PUInt32b, DWORD);
01786 #elif PBYTE_ORDER==PBIG_ENDIAN
01787 PI_SAME(PUInt32b, DWORD);
01788 #endif
01789 
01790 #if PBYTE_ORDER==PLITTLE_ENDIAN
01791 PI_SAME(PInt64l, PInt64);
01792 #elif PBYTE_ORDER==PBIG_ENDIAN
01793 PI_DIFF(PInt64l, PInt64);
01794 #endif
01795 
01796 #if PBYTE_ORDER==PLITTLE_ENDIAN
01797 PI_DIFF(PInt64b, PInt64);
01798 #elif PBYTE_ORDER==PBIG_ENDIAN
01799 PI_SAME(PInt64b, PInt64);
01800 #endif
01801 
01802 #if PBYTE_ORDER==PLITTLE_ENDIAN
01803 PI_SAME(PUInt64l, PUInt64);
01804 #elif PBYTE_ORDER==PBIG_ENDIAN
01805 PI_DIFF(PUInt64l, PUInt64);
01806 #endif
01807 
01808 #if PBYTE_ORDER==PLITTLE_ENDIAN
01809 PI_DIFF(PUInt64b, PUInt64);
01810 #elif PBYTE_ORDER==PBIG_ENDIAN
01811 PI_SAME(PUInt64b, PUInt64);
01812 #endif
01813 
01814 #if PBYTE_ORDER==PLITTLE_ENDIAN
01815 PI_SAME(PFloat32l, float);
01816 #elif PBYTE_ORDER==PBIG_ENDIAN
01817 PI_DIFF(PFloat32l, float);
01818 #endif
01819 
01820 #if PBYTE_ORDER==PLITTLE_ENDIAN
01821 PI_DIFF(PFloat32b, float);
01822 #elif PBYTE_ORDER==PBIG_ENDIAN
01823 PI_SAME(PFloat32b, float);
01824 #endif
01825 
01826 #if PBYTE_ORDER==PLITTLE_ENDIAN
01827 PI_SAME(PFloat64l, double);
01828 #elif PBYTE_ORDER==PBIG_ENDIAN
01829 PI_DIFF(PFloat64l, double);
01830 #endif
01831 
01832 #if PBYTE_ORDER==PLITTLE_ENDIAN
01833 PI_DIFF(PFloat64b, double);
01834 #elif PBYTE_ORDER==PBIG_ENDIAN
01835 PI_SAME(PFloat64b, double);
01836 #endif
01837 
01838 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01839 #if PBYTE_ORDER==PLITTLE_ENDIAN
01840 PI_SAME(PFloat80l, long double);
01841 #elif PBYTE_ORDER==PBIG_ENDIAN
01842 PI_DIFF(PFloat80l, long double);
01843 #endif
01844 
01845 #if PBYTE_ORDER==PLITTLE_ENDIAN
01846 PI_DIFF(PFloat80b, long double);
01847 #elif PBYTE_ORDER==PBIG_ENDIAN
01848 PI_SAME(PFloat80b, long double);
01849 #endif
01850 #endif
01851 
01852 #undef PI_LOOP
01853 #undef PI_SAME
01854 #undef PI_DIFF
01855 
01856 
01858 // Miscellaneous
01859 
01860 /*$MACRO PARRAYSIZE(array)
01861    This macro is used to calculate the number of array elements in a static
01862    array.
01863  */
01864 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01865 
01866 /*$MACRO PMIN(v1, v2)
01867    This macro is used to calculate the minimum of two values. As this is a
01868    macro the expression in #v1# or #v2# is executed
01869    twice so extreme care should be made in its use.
01870  */
01871 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01872 
01873 /*$MACRO PMAX(v1, v2)
01874    This macro is used to calculate the maximum of two values. As this is a
01875    macro the expression in #v1# or #v2# is executed
01876    twice so extreme care should be made in its use.
01877  */
01878 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01879 
01880 /*$MACRO PABS(val)
01881    This macro is used to calculate an absolute value. As this is a macro the
01882    expression in #val# is executed twice so extreme care should be
01883    made in its use.
01884  */
01885 #define PABS(v) ((v) < 0 ? -(v) : (v))
01886 
01887 #endif // _POBJECT_H
01888 
01889 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Feb 29 13:37:09 2008 for PWLib by  doxygen 1.5.5