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

Generated on Mon Jan 22 14:51:36 2007 for PWLib by  doxygen 1.5.1