Made some subtle changes to the way the static variables are instantiated in
[pwlib.git] / include / ptlib / object.h
blob8cf469ba09d5e38df92f136c3ebe22d328c0c24b
1 /*
2 * object.h
4 * Mother of all ancestor classes.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
29 * $Log$
30 * Revision 1.104 2004/05/12 04:36:17 csoutheren
31 * Fixed problems with using sem_wait and friends on systems that do not
32 * support atomic integers
34 * Revision 1.103 2004/04/18 04:33:36 rjongbloed
35 * Changed all operators that return BOOL to return standard type bool. This is primarily
36 * for improved compatibility with std STL usage removing many warnings.
38 * Revision 1.102 2004/04/11 13:26:25 csoutheren
39 * Removed namespace problems and removed warnings for Windows <string>
41 * Revision 1.101 2004/04/11 03:20:41 csoutheren
42 * Added Unix implementation of PCriticalSection
44 * Revision 1.100 2004/04/11 02:55:17 csoutheren
45 * Added PCriticalSection for Windows
46 * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
48 * Revision 1.99 2004/04/09 11:54:46 csoutheren
49 * Added configure.in check for STL streams, and tested with gcc 2.95.3,
50 * gcc 3.3.1, and gcc 3.3.3
52 * Revision 1.98 2004/04/09 07:53:51 rjongbloed
53 * Fixed backward compatibility after STL streams change
55 * Revision 1.97 2004/04/09 00:56:35 csoutheren
56 * Fixed problem with new class name code
58 * Revision 1.96 2004/04/09 00:42:58 csoutheren
59 * Changed Unix build to use slightly different method for
60 * keep class names, as GCC does not use actual class names for typeinfo
62 * Revision 1.95 2004/04/04 13:24:18 rjongbloed
63 * Changes to support native C++ Run Time Type Information
65 * Revision 1.94 2004/04/03 08:57:31 csoutheren
66 * Replaced pseudo-RTTI with real RTTI
68 * Revision 1.93 2004/04/03 08:22:20 csoutheren
69 * Remove pseudo-RTTI and replaced with real RTTI
71 * Revision 1.92 2004/04/03 07:41:00 csoutheren
72 * Fixed compile problem with ostringstream/ostrstream
74 * Revision 1.91 2004/04/03 07:16:05 rjongbloed
75 * Fixed backward compatibility with MSVC 6
77 * Revision 1.90 2004/04/03 06:54:22 rjongbloed
78 * Many and various changes to support new Visual C++ 2003
80 * Revision 1.89 2003/09/17 09:00:59 csoutheren
81 * Moved PSmartPointer and PNotifier into seperate files
82 * Added detection for system regex libraries on all platforms
84 * Revision 1.88 2003/09/17 05:41:58 csoutheren
85 * Removed recursive includes
87 * Revision 1.87 2003/09/17 01:18:02 csoutheren
88 * Removed recursive include file system and removed all references
89 * to deprecated coooperative threading support
91 * Revision 1.86 2002/10/14 21:42:37 rogerh
92 * Only use malloc.h on Windows
94 * Revision 1.85 2002/10/10 04:43:43 robertj
95 * VxWorks port, thanks Martijn Roest
97 * Revision 1.84 2002/10/08 12:41:51 robertj
98 * Changed for IPv6 support, thanks Sébastien Josset.
100 * Revision 1.83 2002/09/16 01:08:59 robertj
101 * Added #define so can select if #pragma interface/implementation is used on
102 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
104 * Revision 1.82 2002/08/06 02:27:58 robertj
105 * GNU C++ v3 compatibility.
107 * Revision 1.81 2002/06/25 02:22:47 robertj
108 * Improved assertion system to allow C++ class name to be displayed if
109 * desired, especially relevant to container classes.
111 * Revision 1.80 2002/06/14 10:29:43 rogerh
112 * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de>
114 * Revision 1.79 2002/06/13 08:34:05 rogerh
115 * gcc 3.1 needs iostream instead of iostream.h
117 * Revision 1.78 2002/05/22 00:23:31 craigs
118 * Added GMTTime flag to tracing options
120 * Revision 1.77 2002/04/19 00:20:51 craigs
121 * Added option to append to log file rather than create anew each time
123 * Revision 1.76 2002/01/26 23:55:55 craigs
124 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net
126 * Revision 1.75 2001/10/18 19:56:26 yurik
127 * Fixed WinCE x86 compilation problems with memory check off
129 * Revision 1.74 2001/08/12 11:26:07 robertj
130 * Put back PMEMORY_CHECK taken out by the Carbon port.
132 * Revision 1.73 2001/08/11 07:57:30 rogerh
133 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
135 * Revision 1.72 2001/05/03 06:27:29 robertj
136 * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state.
138 * Revision 1.71 2001/03/24 01:11:10 robertj
139 * Added missing PTRACE_IF define in non PTRACING mode.
141 * Revision 1.70 2001/03/23 05:34:09 robertj
142 * Added PTRACE_IF to output trace if a conditional is TRUE.
144 * Revision 1.69 2001/03/01 02:15:16 robertj
145 * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise.
147 * Revision 1.68 2001/02/22 08:16:41 robertj
148 * Added standard trace file setup subroutine.
150 * Revision 1.67 2001/02/13 03:27:24 robertj
151 * Added function to do heap validation.
153 * Revision 1.66 2001/02/09 04:41:27 robertj
154 * Removed added non memrycheck implementations of new/delete when using GNU C++.
156 * Revision 1.65 2001/02/07 04:47:49 robertj
157 * Added changes for possible random crashes in multi DLL environment
158 * due to memory allocation wierdness, thanks Milan Dimitrijevic.
160 * Revision 1.64 2001/01/24 06:15:44 yurik
161 * Windows CE port-related declarations
163 * Revision 1.63 2000/07/28 05:13:47 robertj
164 * Fixed silly mistake in runtime_malloc() function, should return a pointer!
166 * Revision 1.62 2000/07/20 05:46:34 robertj
167 * Added runtime_malloc() function for cases where memory check code must be bypassed.
169 * Revision 1.61 2000/07/13 15:45:35 robertj
170 * Removed #define std that causes everyone so much grief!
172 * Revision 1.60 2000/06/26 11:17:19 robertj
173 * Nucleus++ port (incomplete).
175 * Revision 1.59 2000/02/29 12:26:14 robertj
176 * Added named threads to tracing, thanks to Dave Harvey
178 * Revision 1.58 2000/01/07 12:31:12 robertj
179 * Fixed 8 byte alignment on memory heap checking.
181 * Revision 1.57 2000/01/05 00:29:12 robertj
182 * Fixed alignment problems in memory checking debug functions.
184 * Revision 1.56 1999/11/30 00:22:54 robertj
185 * Updated documentation for doc++
187 * Revision 1.55 1999/11/01 00:10:27 robertj
188 * Added override of new functions for MSVC memory check code.
190 * Revision 1.54 1999/10/19 09:21:30 robertj
191 * Added functions to get current trace options and level.
193 * Revision 1.53 1999/09/13 13:15:06 robertj
194 * Changed PTRACE so will output to system log in PServiceProcess applications.
196 * Revision 1.52 1999/08/24 08:15:23 robertj
197 * Added missing operator on smart pointer to return the pointer!
199 * Revision 1.51 1999/08/24 06:54:36 robertj
200 * Cleaned up the smart pointer code (macros).
202 * Revision 1.50 1999/08/22 13:38:39 robertj
203 * Fixed termination hang up problem with memory check code under unix pthreads.
205 * Revision 1.49 1999/08/17 03:46:40 robertj
206 * Fixed usage of inlines in optimised version.
208 * Revision 1.48 1999/08/10 10:45:09 robertj
209 * Added mutex in memory check detection code.
211 * Revision 1.47 1999/07/18 15:08:24 robertj
212 * Fixed 64 bit compatibility
214 * Revision 1.46 1999/06/14 07:59:37 robertj
215 * Enhanced tracing again to add options to trace output (timestamps etc).
217 * Revision 1.45 1999/05/01 11:29:19 robertj
218 * Alpha linux port changes.
220 * Revision 1.44 1999/04/18 12:58:39 robertj
221 * MSVC 5 backward compatibility
223 * Revision 1.43 1999/03/09 10:30:17 robertj
224 * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions.
226 * Revision 1.42 1999/03/09 02:59:50 robertj
227 * Changed comments to doc++ compatible documentation.
229 * Revision 1.41 1999/02/23 07:11:26 robertj
230 * Improved trace facility adding trace levels and #define to remove all trace code.
232 * Revision 1.40 1999/02/22 10:48:14 robertj
233 * Fixed delete operator prototypes for MSVC6 and GNU compatibility.
235 * Revision 1.39 1999/02/19 11:33:02 robertj
236 * Fixed compatibility problems with GNU/MSVC6
238 * Revision 1.38 1999/02/16 08:12:22 robertj
239 * MSVC 6.0 compatibility changes.
241 * Revision 1.37 1999/01/07 03:35:35 robertj
242 * Added default for PCHAR8 to ANSI, removes need for compiler option.
244 * Revision 1.36 1998/12/15 09:00:29 robertj
245 * Fixed 8 byte alignment problem in memory leak check code for sparc.
247 * Revision 1.35 1998/11/03 00:57:19 robertj
248 * Added allocation breakpoint variable.
250 * Revision 1.34 1998/10/26 11:05:26 robertj
251 * Added raw free for things allocated within the runtime library.
253 * Revision 1.33 1998/10/18 14:26:55 robertj
254 * Improved tracing functions.
256 * Revision 1.32 1998/10/15 07:47:21 robertj
257 * Added ability to ignore G++lib memory leaks.
259 * Revision 1.31 1998/10/15 01:53:58 robertj
260 * GNU compatibility.
262 * Revision 1.30 1998/10/13 14:23:29 robertj
263 * Complete rewrite of memory leak detection.
265 * Revision 1.29 1998/09/23 06:20:57 robertj
266 * Added open source copyright license.
268 * Revision 1.28 1998/09/14 12:29:11 robertj
269 * Fixed memory leak dump under windows to not include static globals.
270 * Fixed problem with notifier declaration not allowing implementation inline after macro.
272 * Revision 1.27 1997/07/08 13:13:45 robertj
273 * DLL support.
275 * Revision 1.26 1997/04/27 05:50:11 robertj
276 * DLL support.
278 * Revision 1.25 1997/02/05 11:54:10 robertj
279 * Fixed problems with memory check and leak detection.
281 * Revision 1.24 1996/09/16 12:57:23 robertj
282 * DLL support
284 * Revision 1.23 1996/08/17 10:00:23 robertj
285 * Changes for Windows DLL support.
287 * Revision 1.22 1996/07/15 10:27:51 robertj
288 * Changed endian classes to be memory mapped.
290 * Revision 1.21 1996/05/09 12:14:48 robertj
291 * Fixed up 64 bit integer class for Mac platform.
293 * Revision 1.20 1996/02/24 14:19:29 robertj
294 * Fixed bug in endian independent integer code for memory transfers.
296 * Revision 1.19 1996/01/28 02:46:43 robertj
297 * Removal of MemoryPointer classes as usage didn't work for GNU.
298 * Added missing bit shift operators to 64 bit integer class.
300 * Revision 1.18 1996/01/23 13:14:32 robertj
301 * Added const version of PMemoryPointer.
302 * Added constructor to endian classes for the base type.
304 * Revision 1.17 1996/01/02 11:54:11 robertj
305 * Mac OS compatibility changes.
307 * Revision 1.16 1995/11/09 12:17:10 robertj
308 * Added platform independent base type access classes.
310 * Revision 1.15 1995/06/17 11:12:47 robertj
311 * Documentation update.
313 * Revision 1.14 1995/06/04 12:34:19 robertj
314 * Added trace functions.
316 * Revision 1.13 1995/04/25 12:04:35 robertj
317 * Fixed borland compatibility.
318 * Fixed function hiding ancestor virtuals.
320 * Revision 1.12 1995/03/14 12:41:54 robertj
321 * Updated documentation to use HTML codes.
323 * Revision 1.11 1995/03/12 04:40:55 robertj
324 * Changed standard error code for not open from file to channel.
326 * Revision 1.10 1995/02/19 04:19:14 robertj
327 * Added dynamically linked command processing.
329 * Revision 1.9 1995/02/05 00:48:07 robertj
330 * Fixed template version.
332 * Revision 1.8 1995/01/15 04:51:31 robertj
333 * Mac compatibility.
334 * Added levels of memory checking.
336 * Revision 1.7 1995/01/09 12:38:31 robertj
337 * Changed variable names around during documentation run.
338 * Fixed smart pointer comparison.
339 * Fixed serialisation stuff.
340 * Documentation.
342 * Revision 1.6 1995/01/03 09:39:06 robertj
343 * Put standard malloc style memory allocation etc into memory check system.
345 * Revision 1.5 1994/12/12 10:08:30 robertj
346 * Renamed PWrapper to PSmartPointer..
348 * Revision 1.4 1994/12/05 11:23:28 robertj
349 * Fixed PWrapper macros.
351 * Revision 1.3 1994/11/19 00:22:55 robertj
352 * Changed PInteger to be INT, ie standard type like BOOL/WORD etc.
353 * Moved null object check in notifier to construction rather than use.
354 * Added virtual to the callback function in notifier destination class.
356 * Revision 1.2 1994/11/03 09:25:30 robertj
357 * Made notifier destination object not to be descendent of PObject.
359 * Revision 1.1 1994/10/30 12:01:37 robertj
360 * Initial revision
364 #ifndef _POBJECT_H
365 #define _POBJECT_H
367 #ifdef P_USE_PRAGMA
368 #pragma interface
369 #endif
371 #ifdef _WIN32
372 #include "msos/ptlib/contain.h"
373 #else
374 #include "unix/ptlib/contain.h"
375 #endif
377 #if defined(P_VXWORKS)
378 #include <private/stdiop.h>
379 #endif
381 #include <stdio.h>
382 #include <stdarg.h>
383 #include <stdlib.h>
385 #ifdef _WIN32
386 #include <malloc.h>
387 #endif
389 #include <string.h>
391 #ifdef __USE_STL__
392 #include <string>
393 #include <iomanip>
394 #include <iostream>
395 #if (__GNUC__ >= 3)
396 #include <sstream>
397 //typedef std::ostringstream ostrstream;
398 #else
399 #include <strstream>
400 #endif
401 //using namespace std;
402 #else
403 #if (__GNUC__ >= 3)
404 #include <iostream>
405 #ifndef __MWERKS__
406 #include <iomanip>
407 #endif
408 #else
409 #include <iostream.h>
410 #ifdef __GNUC__
411 #include <strstream.h>
412 #else
413 #include <strstrea.h>
414 #endif
415 #ifndef __MWERKS__
416 #include <iomanip.h>
417 #endif
418 #endif
419 #endif
421 #ifdef _WIN32_WCE
422 #include <stdlibx.h>
423 #endif
425 #if (__GNUC__ < 3)
426 typedef long _Ios_Fmtflags;
427 #endif
429 #if _MSC_VER<1300
430 #define _BADOFF -1
431 #endif
433 ///////////////////////////////////////////////////////////////////////////////
434 // Disable inlines when debugging for faster compiles (the compiler doesn't
435 // actually inline the function with debug on any way).
437 #ifndef P_USE_INLINES
438 #ifdef _DEBUG
439 #define P_USE_INLINES 0
440 #else
441 #define P_USE_INLINES 0
442 #endif
443 #endif
445 #if P_USE_INLINES
446 #define PINLINE inline
447 #else
448 #define PINLINE
449 #endif
452 ///////////////////////////////////////////////////////////////////////////////
453 // Declare the debugging support
455 /// Standard assert messages for the PAssert macro.
456 enum PStandardAssertMessage {
457 PLogicError, // A logic error occurred.
458 POutOfMemory, // A new or malloc failed.
459 PNullPointerReference, // A reference was made through a NULL pointer.
460 PInvalidCast, // An invalid cast to descendant is required.
461 PInvalidArrayIndex, // An index into an array was negative.
462 PInvalidArrayElement, // A NULL array element object was accessed.
463 PStackEmpty, // A Pop() was made of a stack with no elements.
464 PUnimplementedFunction, // Funtion is not implemented.
465 PInvalidParameter, // Invalid parameter was passed to a function.
466 POperatingSystemError, // Error was returned by Operating System.
467 PChannelNotOpen, // Operation attempted when channel not open.
468 PUnsupportedFeature, // Feature is not supported.
469 PInvalidWindow, // Access through invalid window.
470 PMaxStandardAssertMessage
473 #define __CLASS__ NULL
475 /** This macro is used to assert that a condition must be TRUE.
476 If the condition is FALSE then an assert function is called with the source
477 file and line number the macro was instantiated on, plus the message described
478 by the #msg# parameter. This parameter may be either a standard value
479 from the #PStandardAssertMessage# enum or a literal string.
481 #define PAssert(b, m) if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, (m))
483 /** This macro is used to assert that a condition must be TRUE.
484 If the condition is FALSE then an assert function is called with the source
485 file and line number the macro was instantiated on, plus the message described
486 by the #msg# parameter. This parameter may be either a standard value
487 from the #PStandardAssertMessage# enum or a literal string.
488 The #c# parameter specifies the class name that the error occurred in
490 #define PAssert2(b, c, m) if(b);else PAssertFunc(__FILE__, __LINE__, (c), (m))
492 /** This macro is used to assert that an operating system call succeeds.
493 If the condition is FALSE then an assert function is called with the source
494 file and line number the macro was instantiated on, plus the message
495 described by the #POperatingSystemError# value in the #PStandardAssertMessage#
496 enum.
498 #define PAssertOS(b) \
499 if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, POperatingSystemError)
501 /** This macro is used to assert that a pointer must be non-null.
502 If the pointer is NULL then an assert function is called with the source file
503 and line number the macro was instantiated on, plus the message described by
504 the PNullPointerReference value in the #PStandardAssertMessage# enum.
506 Note that this evaluates the expression defined by #ptr# twice. To
507 prevent incorrect behaviour with this, the macro will assume that the
508 #ptr# parameter is an L-Value.
510 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p):(PAssertFunc(__FILE__, \
511 __LINE__, __CLASS__, PNullPointerReference), (p)))
513 /** This macro is used to assert immediately.
514 The assert function is called with the source file and line number the macro
515 was instantiated on, plus the message described by the #msg# parameter. This
516 parameter may be either a standard value from the #PStandardAssertMessage#
517 enum or a literal string.
519 #define PAssertAlways(m) PAssertFunc(__FILE__, __LINE__, __CLASS__, (m))
521 /** This macro is used to assert immediately.
522 The assert function is called with the source file and line number the macro
523 was instantiated on, plus the message described by the #msg# parameter. This
524 parameter may be either a standard value from the #PStandardAssertMessage#
525 enum or a literal string.
527 #define PAssertAlways2(c, m) PAssertFunc(__FILE__, __LINE__, (c), (m))
530 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
531 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
532 void PAssertFunc(const char * full_msg);
535 /** Get the stream being used for error output.
536 This stream is used for all trace output using the various trace functions
537 and macros.
539 ostream & PGetErrorStream();
541 /** Set the stream to be used for error output.
542 This stream is used for all error output using the #PError# macro.
544 void PSetErrorStream(ostream * strm /** New stream for error output */ );
546 /** This macro is used to access the platform specific error output stream.
547 This is to be used in preference to assuming #cerr# is always available. On
548 Unix platforms this {\bfis} #cerr# but for MS-Windows this is another stream
549 that uses the OutputDebugString() Windows API function. Note that a MS-DOS or
550 Windows NT console application would still use #cerr#.
552 The #PError# stream would normally only be used for debugging information as
553 a suitable display is not always available in windowed environments.
555 The macro is a wrapper for a global variable #PErrorStream# which is a pointer
556 to an #ostream#. The variable is initialised to #cerr# for all but MS-Windows
557 and NT GUI applications. An application could change this pointer to a
558 #ofstream# variable of #PError# output is wished to be redirected to a file.
560 #define PError (PGetErrorStream())
564 ///////////////////////////////////////////////////////////////////////////////
565 // Debug and tracing
567 #ifndef PTRACING
568 #ifndef _DEBUG
569 #define PTRACING 0
570 #else
571 #define PTRACING 1
572 #endif
573 #endif
575 /**Class to encapsulate tracing functions.
576 This class does not require any instances and is only being used as a
577 method of grouping functions together in a name space.
579 class PTrace
581 public:
582 /// Options for trace output.
583 enum Options {
584 /**Include PTrace::Block constructs in output
585 If this is bit is clear, all PTrace::Block output is inhibited
586 regardless of the trace level. If set, the PTrace::Block may occur
587 provided the trace level is greater than zero.
589 Blocks = 1,
590 /// Include date and time in all output
591 DateAndTime = 2,
592 /// Include (millisecond) timestamp in all output
593 Timestamp = 4,
594 /// Include identifier for thread trace is made from in all output
595 Thread = 8,
596 /// Include trace level in all output
597 TraceLevel = 16,
598 /// Include the file and line for the trace call in all output
599 FileAndLine = 32,
600 /// Include thread object pointer address in all trace output
601 ThreadAddress = 64,
602 /// Append to log file rather than resetting every time
603 AppendToFile = 128,
604 /** SystemLog flag for tracing within a PServiceProcess application. Must
605 be set in conjection with SetStream(new PSystemLog).
607 GMTTime = 256,
608 /** Output timestamps in GMT time rather than local time
610 SystemLogStream = 32768
613 /**Set the most common trace options.
614 If filename is not NULL then a PTextFile is created and attached the
615 trace output stream. This object is never closed or deleted until the
616 termination of the program.
618 A trace output of the program name version and OS is written as well.
620 static void Initialise(
621 unsigned level,
622 const char * filename = NULL,
623 unsigned options = Timestamp | Thread | Blocks
626 /** Set the trace options.
627 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
628 may contain assorted values. These are defined by the Options enum.
630 Note this function OR's the bits included in the options parameter.
632 static void SetOptions(unsigned options /** New level for trace */ );
634 /** Clear the trace options.
635 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
636 may contain assorted values. These are defined by the Options enum.
638 Note this function AND's the complement of the bits included in the options
639 parameter.
641 static void ClearOptions(unsigned options /** New level for trace */ );
643 /** Get the current trace options.
644 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
645 may contain assorted values. These are defined by the Options enum.
647 static unsigned GetOptions();
649 /** Set the trace level.
650 The PTRACE() macro checks to see if its level is equal to or lower then the
651 level set by this function. If so then the trace text is output to the trace
652 stream.
654 static void SetLevel(unsigned level /** New level for trace */ );
656 /** Get the trace level.
657 The PTRACE() macro checks to see if its level is equal to or lower then the
658 level set by this function. If so then the trace text is output to the trace
659 stream.
661 static unsigned GetLevel();
663 /** Determine if the level may cause trace output.
664 This checks against the current global trace level set by #PSetTraceLevel#
665 for if the trace output may be emitted. This is used by the PTRACE macro.
667 static BOOL CanTrace(unsigned level /** Trace level to check */);
669 /** Set the stream to be used for trace output.
670 This stream is used for all trace output using the various trace functions
671 and macros.
673 static void SetStream(ostream * out /** New output stream from trace. */ );
675 /** Begin a trace output.
676 If the trace stream output is used outside of the provided macros, it
677 should be noted that a mutex is obtained on the call to #PBeginTrace# which
678 will prevent any other threads from using the trace stream until the
679 #PEndTrace# function is called.
681 So a typical usage would be:
682 \begin{verbatim}
683 ostream & s = PTrace::Begin(3, __FILE__, __LINE__);
684 s << "hello";
685 if (want_there)
686 s << " there";
687 s << '!' << PTrace::End();
688 \end{verbatim}
690 static ostream & Begin(
691 unsigned level, /// Log level for output
692 const char * fileName, /// Filename of source file being traced
693 int lineNum /// Line number of source file being traced.
696 /** End a trace output.
697 If the trace stream output is used outside of the provided macros, the
698 #PEndTrace# function must be used at the end of the section of trace
699 output. A mutex is obtained on the call to #PBeginTrace# which will prevent
700 any other threads from using the trace stream until the PEndTrace. The
701 #PEndTrace# is used in a similar manner to #::endl# or #::flush#.
703 So a typical usage would be:
704 \begin{verbatim}
705 ostream & s = PTrace::Begin();
706 s << "hello";
707 if (want_there)
708 s << " there";
709 s << '!' << PTrace::End();
710 \end{verbatim}
712 static ostream & End(ostream & strm /** Trace output stream being completed */);
715 /** Class to trace Execution blocks.
716 This class is used for tracing the entry and exit of program blocks. Upon
717 construction it outputs an entry trace message and on destruction outputs an
718 exit trace message. This is normally only used from in the PTRACE_BLOCK macro.
720 class Block {
721 public:
722 /** Output entry trace message. */
723 Block(
724 const char * fileName, /// Filename of source file being traced
725 int lineNum, /// Line number of source file being traced.
726 const char * traceName
727 /// String to be output with trace, typically it is the function name.
729 /// Output exit trace message.
730 ~Block();
731 private:
732 const char * file;
733 int line;
734 const char * name;
738 #if !PTRACING
740 #define PTRACE_BLOCK(n)
741 #define PTRACE_LINE()
742 #define PTRACE(level, arg)
743 #define PTRACE_IF(level, cond, args)
745 #else
747 /** Trace an execution block.
748 This macro creates a trace variable for tracking the entry and exit of program
749 blocks. It creates an instance of the PTraceBlock class that will output a
750 trace message at the line PTRACE_BLOCK is called and then on exit from the
751 scope it is defined in.
753 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
755 /** Trace the execution of a line.
756 This macro outputs a trace of a source file line execution.
758 #define PTRACE_LINE() \
759 if (!PTrace::CanTrace(1)) ; else \
760 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
762 /** Output trace.
763 This macro outputs a trace of any information needed, using standard stream
764 output operators. The output is only made if the trace level set by the
765 #PSetTraceLevel# function is greater than or equal to the #level# argument.
767 #define PTRACE(level, args) \
768 if (!PTrace::CanTrace(level)) ; else \
769 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
771 /** Output trace on condition.
772 This macro outputs a trace of any information needed, using standard stream
773 output operators. The output is only made if the trace level set by the
774 #PSetTraceLevel# function is greater than or equal to the #level# argument
775 and the conditional is TRUE. Note the conditional is only evaluated if the
776 trace level is sufficient.
778 #define PTRACE_IF(level, cond, args) \
779 if (!(PTrace::CanTrace(level) && (cond))) ; else \
780 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
782 #endif
784 // the following macros exist purely for backwards compatibility
786 #define PNEW new
787 #define runtime_malloc(s) malloc(s)
788 #define runtime_free(p) free(p)
790 /** Declare all the standard PWlib class information.
791 This macro is used to provide the basic run-time typing capability needed
792 by the library. All descendent classes from the #PObject# class require
793 these functions for correct operation. Either use this macro or the
794 #PDECLARE_CLASS# macro.
796 The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
797 of compatibility with documentation systems.
802 ORIGINAL
804 #define PCLASSINFO(cls, par) \
805 public: \
806 static const char * Class() \
807 { return #cls; } \
808 virtual const char * GetClass(unsigned ancestor = 0) const \
809 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
810 virtual BOOL IsClass(const char * clsName) const \
811 { return strcmp(clsName, cls::Class()) == 0; } \
812 virtual BOOL IsDescendant(const char * clsName) const \
813 { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \
814 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
815 { return (Comparison)memcmp(this, &obj, sizeof(cls)); }
819 #if P_HAS_TYPEINFO
821 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
822 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
824 #include <typeinfo>
826 #ifndef PCLASSNAME
827 #error "Must define PCLASSNAME"
828 #endif
830 #define PBASECLASSINFO(cls, par) \
831 public: \
832 static inline const char * Class() \
833 { return PCLASSNAME(cls); } \
834 virtual BOOL InternalIsDescendant(const char * clsName) const \
835 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
837 #else // P_HAS_TYPEINFO
839 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
840 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
842 #define PBASECLASSINFO(cls, par) \
843 public: \
844 static const char * Class() \
845 { return #cls; } \
846 virtual BOOL InternalIsDescendant(const char * clsName) const \
847 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
849 #endif // P_HAS_TYPEINFO
852 #define PCLASSINFO(cls, par) \
853 PBASECLASSINFO(cls, par) \
854 virtual const char * GetClass(unsigned ancestor = 0) const \
855 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
856 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
857 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
859 /** Declare a class with PWLib class information.
860 This macro is used to declare a new class with a single public ancestor. It
861 starts the class declaration and then uses the #PCLASSINFO# macro to
862 get all the run-time type functions.
864 The use of this macro is no longer recommended for reasons of compatibility
865 with documentation systems.
867 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
868 #ifdef DOC_PLUS_PLUS
869 } Match previous opening brace in doc++
870 #endif
872 ///////////////////////////////////////////////////////////////////////////////
873 // The root of all evil ... umm classes
875 /** Ultimate parent class for all objects in the class library.
876 This provides functionality provided to all classes, eg run-time types,
877 default comparison operations, simple stream I/O and serialisation support.
879 class PObject {
881 protected:
882 /** Constructor for PObject, make protected so cannot ever create one on
883 its own.
885 PObject() { }
887 public:
888 /* Destructor required to get the "virtual". A PObject really has nothing
889 to destroy.
891 virtual ~PObject() { }
893 /**@name Run Time Type functions */
894 //@{
895 /** Get the name of the class as a C string. This is a static function which
896 returns the type of a specific class.
898 When comparing class names, always use the #strcmp()#
899 function rather than comparing pointers. The pointers are not
900 necessarily the same over compilation units depending on the compiler,
901 platform etc.
903 @return pointer to C string literal.
905 static inline const char * Class() { return PCLASSNAME(PObject); }
907 /** Get the current dynamic type of the object instance.
909 When comparing class names, always use the #strcmp()#
910 function rather than comparing pointers. The pointers are not
911 necessarily the same over compilation units depending on the compiler,
912 platform etc.
914 The #PCLASSINFO# macro declares an override of this function for
915 the particular class. The user need not implement it.
917 @return pointer to C string literal.
919 virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); }
921 BOOL IsClass(const char * cls) const
922 { return strcmp(cls, GetClass()) == 0; }
924 /** Determine if the dynamic type of the current instance is a descendent of
925 the specified class. The class name is usually provided by the
926 #Class()# static function of the desired class.
928 The #PCLASSINFO# macro declares an override of this function for
929 the particular class. The user need not implement it.
931 @return TRUE if object is descended from the class.
933 virtual BOOL InternalIsDescendant(
934 const char * clsName // Ancestor class name to compare against.
935 ) const
936 { return IsClass(clsName); }
938 //@}
940 /**@name Comparison functions */
941 //@{
942 /** Result of the comparison operation performed by the #Compare()#
943 function.
945 enum Comparison {
946 LessThan = -1,
947 EqualTo = 0,
948 GreaterThan = 1
951 /** Compare the two objects and return their relative rank. This function is
952 usually overridden by descendent classes to yield the ranking according
953 to the semantics of the object.
955 The default function is to use the #CompareObjectMemoryDirect()#
956 function to do a byte wise memory comparison of the two objects.
958 @return
959 #LessThan#, #EqualTo# or #GreaterThan#
960 according to the relative rank of the objects.
962 virtual Comparison Compare(
963 const PObject & obj // Object to compare against.
964 ) const;
966 /** Determine the byte wise comparison of two objects. This is the default
967 comparison operation for objects that do not explicitly override the
968 #Compare()# function.
970 The #PCLASSINFO# macro declares an override of this function for
971 the particular class. The user need not implement it.
973 @return
974 #LessThan#, #EqualTo# or #GreaterThan#
975 according to the result #memcpy()# function.
977 virtual Comparison CompareObjectMemoryDirect(
978 const PObject & obj // Object to compare against.
979 ) const;
981 /** Compare the two objects.
983 @return
984 TRUE if objects are equal.
986 bool operator==(
987 const PObject & obj // Object to compare against.
988 ) const { return Compare(obj) == EqualTo; }
990 /** Compare the two objects.
992 @return
993 TRUE if objects are not equal.
995 bool operator!=(
996 const PObject & obj // Object to compare against.
997 ) const { return Compare(obj) != EqualTo; }
999 /** Compare the two objects.
1001 @return
1002 TRUE if objects are less than.
1004 bool operator<(
1005 const PObject & obj // Object to compare against.
1006 ) const { return Compare(obj) == LessThan; }
1008 /** Compare the two objects.
1010 @return
1011 TRUE if objects are greater than.
1013 bool operator>(
1014 const PObject & obj // Object to compare against.
1015 ) const { return Compare(obj) == GreaterThan; }
1017 /** Compare the two objects.
1019 @return
1020 TRUE if objects are less than or equal.
1022 bool operator<=(
1023 const PObject & obj // Object to compare against.
1024 ) const { return Compare(obj) != GreaterThan; }
1026 /** Compare the two objects.
1028 @return
1029 TRUE if objects are greater than or equal.
1031 bool operator>=(
1032 const PObject & obj // Object to compare against.
1033 ) const { return Compare(obj) != LessThan; }
1034 //@}
1036 /**@name I/O functions */
1037 //@{
1038 /** Output the contents of the object to the stream. The exact output is
1039 dependent on the exact semantics of the descendent class. This is
1040 primarily used by the standard #operator<<# function.
1042 The default behaviour is to print the class name.
1044 virtual void PrintOn(
1045 ostream &strm // Stream to print the object into.
1046 ) const;
1048 /** Input the contents of the object from the stream. The exact input is
1049 dependent on the exact semantics of the descendent class. This is
1050 primarily used by the standard #operator>># function.
1052 The default behaviour is to do nothing.
1054 virtual void ReadFrom(
1055 istream &strm // Stream to read the objects contents from.
1059 /** Global function for using the standard << operator on objects descended
1060 from PObject. This simply calls the objects #PrintOn()# function.
1062 @return the #strm# parameter.
1064 inline friend ostream & operator<<(
1065 ostream &strm, // Stream to print the object into.
1066 const PObject & obj // Object to print to the stream.
1067 ) { obj.PrintOn(strm); return strm; }
1069 /** Global function for using the standard >> operator on objects descended
1070 from PObject. This simply calls the objects #ReadFrom()# function.
1072 @return the #strm# parameter.
1074 inline friend istream & operator>>(
1075 istream &strm, // Stream to read the objects contents from.
1076 PObject & obj // Object to read inormation into.
1077 ) { obj.ReadFrom(strm); return strm; }
1080 /**@name Miscellaneous functions */
1081 //@{
1082 /** Create a copy of the class on the heap. The exact semantics of the
1083 descendent class determine what is required to make a duplicate of the
1084 instance. Not all classes can even {\bf do} a clone operation.
1086 The main user of the clone function is the #PDictionary# class as
1087 it requires copies of the dictionary keys.
1089 The default behaviour is for this function to assert.
1091 @return
1092 pointer to new copy of the class instance.
1094 virtual PObject * Clone() const;
1096 /** This function yields a hash value required by the #PDictionary#
1097 class. A descendent class that is required to be the key of a dictionary
1098 should override this function. The precise values returned is dependent
1099 on the semantics of the class. For example, the #PString# class
1100 overrides it to provide a hash function for distinguishing text strings.
1102 The default behaviour is to return the value zero.
1104 @return
1105 hash function value for class instance.
1107 virtual PINDEX HashFunction() const;
1108 //@}
1111 ///////////////////////////////////////////////////////////////////////////////
1112 // Platform independent types
1114 // All these classes encapsulate primitive types such that they may be
1115 // transfered in a platform independent manner. In particular it is used to
1116 // do byte swapping for little endien and big endien processor architectures
1117 // as well as accommodating structure packing rules for memory structures.
1119 #define PANSI_CHAR 1
1120 #define PLITTLE_ENDIAN 2
1121 #define PBIG_ENDIAN 3
1124 #if 0
1125 class PStandardType
1126 /* Encapsulate a standard 8 bit character into a portable format. This would
1127 rarely need to do translation, only if the target platform uses EBCDIC
1128 would it do anything.
1130 The platform independent form here is always 8 bit ANSI.
1133 public:
1134 PStandardType(
1135 type newVal // Value to initialise data in platform dependent form.
1136 ) { data = newVal; }
1137 /* Create a new instance of the platform independent type using platform
1138 dependent data, or platform independent streams.
1141 operator type() { return data; }
1142 /* Get the platform dependent value for the type.
1144 @return
1145 data for instance.
1148 friend ostream & operator<<(ostream & strm, const PStandardType & val)
1149 { return strm << (type)val; }
1150 /* Output the platform dependent value for the type to the stream.
1152 @return
1153 the stream output was made to.
1156 friend istream & operator>>(istream & strm, PStandardType & val)
1157 { type data; strm >> data; val = PStandardType(data); return strm; }
1158 /* Input the platform dependent value for the type from the stream.
1160 @return
1161 the stream input was made from.
1165 private:
1166 type data;
1168 #endif
1171 #define PI_SAME(name, type) \
1172 struct name { \
1173 name() { } \
1174 name(type value) { data = value; } \
1175 name(const name & value) { data = value.data; } \
1176 name & operator =(type value) { data = value; return *this; } \
1177 name & operator =(const name & value) { data = value.data; return *this; } \
1178 operator type() const { return data; } \
1179 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
1180 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
1181 private: type data; \
1184 #define PI_LOOP(src, dst) \
1185 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
1186 while (s != (BYTE *)&src) *d++ = *--s;
1188 #define PI_DIFF(name, type) \
1189 struct name { \
1190 name() { } \
1191 name(type value) { operator=(value); } \
1192 name(const name & value) { data = value.data; } \
1193 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
1194 name & operator =(const name & value) { data = value.data; return *this; } \
1195 operator type() const { type value; PI_LOOP(data, value); return value; } \
1196 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
1197 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
1198 private: type data; \
1201 #ifndef PCHAR8
1202 #define PCHAR8 PANSI_CHAR
1203 #endif
1205 #if PCHAR8==PANSI_CHAR
1206 PI_SAME(PChar8, char);
1207 #endif
1209 PI_SAME(PInt8, signed char);
1211 PI_SAME(PUInt8, unsigned char);
1213 #if PBYTE_ORDER==PLITTLE_ENDIAN
1214 PI_SAME(PInt16l, PInt16);
1215 #elif PBYTE_ORDER==PBIG_ENDIAN
1216 PI_DIFF(PInt16l, PInt16);
1217 #endif
1219 #if PBYTE_ORDER==PLITTLE_ENDIAN
1220 PI_DIFF(PInt16b, PInt16);
1221 #elif PBYTE_ORDER==PBIG_ENDIAN
1222 PI_SAME(PInt16b, PInt16);
1223 #endif
1225 #if PBYTE_ORDER==PLITTLE_ENDIAN
1226 PI_SAME(PUInt16l, WORD);
1227 #elif PBYTE_ORDER==PBIG_ENDIAN
1228 PI_DIFF(PUInt16l, WORD);
1229 #endif
1231 #if PBYTE_ORDER==PLITTLE_ENDIAN
1232 PI_DIFF(PUInt16b, WORD);
1233 #elif PBYTE_ORDER==PBIG_ENDIAN
1234 PI_SAME(PUInt16b, WORD);
1235 #endif
1237 #if PBYTE_ORDER==PLITTLE_ENDIAN
1238 PI_SAME(PInt32l, PInt32);
1239 #elif PBYTE_ORDER==PBIG_ENDIAN
1240 PI_DIFF(PInt32l, PInt32);
1241 #endif
1243 #if PBYTE_ORDER==PLITTLE_ENDIAN
1244 PI_DIFF(PInt32b, PInt32);
1245 #elif PBYTE_ORDER==PBIG_ENDIAN
1246 PI_SAME(PInt32b, PInt32);
1247 #endif
1249 #if PBYTE_ORDER==PLITTLE_ENDIAN
1250 PI_SAME(PUInt32l, DWORD);
1251 #elif PBYTE_ORDER==PBIG_ENDIAN
1252 PI_DIFF(PUInt32l, DWORD);
1253 #endif
1255 #if PBYTE_ORDER==PLITTLE_ENDIAN
1256 PI_DIFF(PUInt32b, DWORD);
1257 #elif PBYTE_ORDER==PBIG_ENDIAN
1258 PI_SAME(PUInt32b, DWORD);
1259 #endif
1261 #if PBYTE_ORDER==PLITTLE_ENDIAN
1262 PI_SAME(PInt64l, PInt64);
1263 #elif PBYTE_ORDER==PBIG_ENDIAN
1264 PI_DIFF(PInt64l, PInt64);
1265 #endif
1267 #if PBYTE_ORDER==PLITTLE_ENDIAN
1268 PI_DIFF(PInt64b, PInt64);
1269 #elif PBYTE_ORDER==PBIG_ENDIAN
1270 PI_SAME(PInt64b, PInt64);
1271 #endif
1273 #if PBYTE_ORDER==PLITTLE_ENDIAN
1274 PI_SAME(PUInt64l, PUInt64);
1275 #elif PBYTE_ORDER==PBIG_ENDIAN
1276 PI_DIFF(PUInt64l, PUInt64);
1277 #endif
1279 #if PBYTE_ORDER==PLITTLE_ENDIAN
1280 PI_DIFF(PUInt64b, PUInt64);
1281 #elif PBYTE_ORDER==PBIG_ENDIAN
1282 PI_SAME(PUInt64b, PUInt64);
1283 #endif
1285 #if PBYTE_ORDER==PLITTLE_ENDIAN
1286 PI_SAME(PFloat32l, float);
1287 #elif PBYTE_ORDER==PBIG_ENDIAN
1288 PI_DIFF(PFloat32l, float);
1289 #endif
1291 #if PBYTE_ORDER==PLITTLE_ENDIAN
1292 PI_DIFF(PFloat32b, float);
1293 #elif PBYTE_ORDER==PBIG_ENDIAN
1294 PI_SAME(PFloat32b, float);
1295 #endif
1297 #if PBYTE_ORDER==PLITTLE_ENDIAN
1298 PI_SAME(PFloat64l, double);
1299 #elif PBYTE_ORDER==PBIG_ENDIAN
1300 PI_DIFF(PFloat64l, double);
1301 #endif
1303 #if PBYTE_ORDER==PLITTLE_ENDIAN
1304 PI_DIFF(PFloat64b, double);
1305 #elif PBYTE_ORDER==PBIG_ENDIAN
1306 PI_SAME(PFloat64b, double);
1307 #endif
1309 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1310 #if PBYTE_ORDER==PLITTLE_ENDIAN
1311 PI_SAME(PFloat80l, long double);
1312 #elif PBYTE_ORDER==PBIG_ENDIAN
1313 PI_DIFF(PFloat80l, long double);
1314 #endif
1316 #if PBYTE_ORDER==PLITTLE_ENDIAN
1317 PI_DIFF(PFloat80b, long double);
1318 #elif PBYTE_ORDER==PBIG_ENDIAN
1319 PI_SAME(PFloat80b, long double);
1320 #endif
1321 #endif
1323 #undef PI_LOOP
1324 #undef PI_SAME
1325 #undef PI_DIFF
1328 ///////////////////////////////////////////////////////////////////////////////
1329 // Miscellaneous
1331 /*$MACRO PARRAYSIZE(array)
1332 This macro is used to calculate the number of array elements in a static
1333 array.
1335 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1337 /*$MACRO PMIN(v1, v2)
1338 This macro is used to calculate the minimum of two values. As this is a
1339 macro the expression in #v1# or #v2# is executed
1340 twice so extreme care should be made in its use.
1342 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1344 /*$MACRO PMAX(v1, v2)
1345 This macro is used to calculate the maximum of two values. As this is a
1346 macro the expression in #v1# or #v2# is executed
1347 twice so extreme care should be made in its use.
1349 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1351 /*$MACRO PABS(val)
1352 This macro is used to calculate an absolute value. As this is a macro the
1353 expression in #val# is executed twice so extreme care should be
1354 made in its use.
1356 #define PABS(v) ((v) < 0 ? -(v) : (v))
1358 #endif // _POBJECT_H
1360 // End Of File ///////////////////////////////////////////////////////////////