34 #ifndef PTLIB_OBJECT_H
35 #define PTLIB_OBJECT_H
41 #if defined(_WIN32) || defined(_WIN32_WCE)
42 #include "msos/ptlib/contain.h"
44 #include "unix/ptlib/contain.h"
47 #if defined(P_VXWORKS)
48 #include <private/stdiop.h>
63 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
68 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
70 #define P_DEPRECATED __declspec(deprecated)
71 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
73 #define P_DEPRECATED __declspec(deprecated)
74 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
76 #elif defined(__GNUC__)
79 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
81 #define P_DEPRECATED __attribute__((deprecated))
82 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
86 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
89 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
90 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
97 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
100 # define PFalse FALSE
104 # define PFalse false
112 #ifndef P_USE_INLINES
114 #define P_USE_INLINES 0
116 #define P_USE_INLINES 0
121 #define PINLINE inline
130 #ifndef P_USE_ASSERTS
131 #define P_USE_ASSERTS 1
136 #define PAssert(b, m) (b)
137 #define PAssert2(b, c, m) (b)
138 #define PAssertOS(b) (b)
139 #define PAssertNULL(p) (p)
140 #define PAssertAlways(m) {}
141 #define PAssertAlways2(c, m) {}
143 #else // P_USE_ASSERTS
163 #define __CLASS__ NULL
166 void PAssertFunc(
const char * file,
int line,
const char * className,
const char * msg);
175 inline bool PAssertFuncInline(
bool b,
const char * file,
int line,
const char * className,
const char * msg)
188 #define PAssert(b, msg) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(msg))
197 #define PAssert2(b, cls, msg) PAssertFuncInline((b), __FILE__,__LINE__,(cls),(msg))
205 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
216 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
217 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
225 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
233 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
235 #endif // P_USE_ASSERTS
263 #define PError (PGetErrorStream())
345 const char * filename = NULL,
361 const char * filename,
362 const char * rolloverPattern,
442 static ostream &
Begin(
444 const char * fileName,
465 static ostream &
End(
483 const char * fileName,
485 const char * traceName
489 : file(obj.file), line(obj.line), name(obj.name) { }
503 #define PTRACE_PARAM(param) param
511 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
516 #define PTRACE_LINE() \
517 if (PTrace::CanTrace(1)) \
518 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
526 #define PTRACE(level, args) \
527 if (PTrace::CanTrace(level)) \
528 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
538 #define PTRACE_IF(level, cond, args) \
539 if ((PTrace::CanTrace(level) && (cond))) \
540 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
545 #define PTRACE_PARAM(param)
546 #define PTRACE_BLOCK(n)
547 #define PTRACE_LINE()
548 #define PTRACE(level, arg)
549 #define PTRACE_IF(level, cond, args)
555 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
557 #define PMEMORY_HEAP 1
583 const char * className
619 const char * className
636 const char * className,
645 ostream * error = NULL
671 typedef _CrtMemState
State;
719 const char * className
723 const char * className,
749 sizeof(
const char *) +
750 sizeof(
const char *) +
800 CRITICAL_SECTION mutex;
801 #elif defined(P_PTHREADS)
802 pthread_mutex_t mutex;
803 #elif defined(P_VXWORKS)
809 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
810 _CrtMemState initialState;
812 #endif // PMEMORY_CHECK
835 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
843 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
851 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
860 #define free(p) PMemoryHeap::Deallocate(p, NULL)
869 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
886 #define PNEW new (__FILE__, __LINE__)
888 #if !defined(_MSC_VER) || _MSC_VER<1200
889 #define PSPECIAL_DELETE_FUNCTION
891 #define PSPECIAL_DELETE_FUNCTION \
892 void operator delete(void * ptr, const char *, int) \
893 { PMemoryHeap::Deallocate(ptr, Class()); } \
894 void operator delete[](void * ptr, const char *, int) \
895 { PMemoryHeap::Deallocate(ptr, Class()); }
898 #define PNEW_AND_DELETE_FUNCTIONS \
899 void * operator new(size_t nSize, const char * file, int line) \
900 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
901 void * operator new(size_t nSize) \
902 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
903 void operator delete(void * ptr) \
904 { PMemoryHeap::Deallocate(ptr, Class()); } \
905 void * operator new(size_t, void * placement) \
906 { return placement; } \
907 void operator delete(void *, void *) \
909 void * operator new[](size_t nSize, const char * file, int line) \
910 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
911 void * operator new[](size_t nSize) \
912 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
913 void operator delete[](void * ptr) \
914 { PMemoryHeap::Deallocate(ptr, Class()); } \
915 PSPECIAL_DELETE_FUNCTION
918 inline void *
operator new(
size_t nSize,
const char * file,
int line)
921 inline void *
operator new[](
size_t nSize,
const char * file,
int line)
925 void *
operator new(
size_t nSize);
926 void *
operator new[](
size_t nSize);
928 void operator delete(
void * ptr);
929 void operator delete[](
void * ptr);
931 #if defined(_MSC_VER) && _MSC_VER>=1200
932 inline void operator delete(
void * ptr,
const char *, int)
935 inline void operator delete[](
void * ptr,
const char *, int)
949 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
959 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
962 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
964 #define PMEMORY_HEAP 0
968 #define PNEW_AND_DELETE_FUNCTIONS
970 #define runtime_malloc(s) malloc(s)
971 #define runtime_free(p) free(p)
973 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
974 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
976 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
984 template <
class GnuAllocator,
class Type>
989 return GetAllocator().allocate(v);
994 GetAllocator().deallocate(p, v);
998 static GnuAllocator & GetAllocator()
1000 static GnuAllocator instance;
1005 #define GCC_VERSION (__GNUC__ * 10000 \
1006 + __GNUC_MINOR__ * 100 \
1007 + __GNUC_PATCHLEVEL__)
1010 #if defined(__GNUC__) && (GCC_VERSION > 40000) && !defined(P_MINGW) && !defined(P_MACOSX)
1011 #include <ext/mt_allocator.h>
1021 #define PDECLARE_POOL_ALLOCATOR() \
1022 void * operator new(size_t nSize); \
1023 void * operator new(size_t nSize, const char * file, int line); \
1024 void operator delete(void * ptr); \
1025 void operator delete(void * ptr, const char *, int)
1027 #define PDEFINE_POOL_ALLOCATOR(cls) \
1028 static PFixedPoolAllocator<cls> cls##_allocator; \
1029 void * cls::operator new(size_t) { return cls##_allocator.allocate(1); } \
1030 void * cls::operator new(size_t, const char *, int) { return cls##_allocator.allocate(1); } \
1031 void cls::operator delete(void * ptr) { cls##_allocator.deallocate((cls *)ptr, 1); } \
1032 void cls::operator delete(void * ptr, const char *, int) { cls##_allocator.deallocate((cls *)ptr, 1); }
1045 #define PCLASSINFO(cls, par) \
1047 typedef cls P_thisClass; \
1048 static inline const char * Class() \
1050 virtual PBoolean InternalIsDescendant(const char * clsName) const \
1051 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
1052 virtual const char * GetClass(unsigned ancestor = 0) const \
1053 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
1054 virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1055 { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1056 PNEW_AND_DELETE_FUNCTIONS
1061 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
1062 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1064 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
1067 template<
class BaseClass>
inline BaseClass *
PAssertCast(BaseClass * obj,
const char * file,
int line)
1069 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1071 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1076 #else // P_HAS_TYPEINFO
1078 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
1079 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1081 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
1084 template<
class BaseClass>
inline BaseClass *
PAssertCast(
PObject * obj,
const char * file,
int line)
1086 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
1088 #define PDownCast(cls, ptr) ((cls*)(ptr))
1091 #endif // P_HAS_TYPEINFO
1102 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1103 #ifdef DOC_PLUS_PLUS
1104 } Match previous opening brace in doc++
1140 static inline const char *
Class() {
return "PObject"; }
1154 virtual const char *
GetClass(
unsigned ancestor = 0)
const {
return ancestor > 0 ?
"" :
Class(); }
1157 {
return strcmp(cls,
GetClass()) == 0; }
1169 const char * clsName
1309 ) { obj.
PrintOn(strm);
return strm; }
1319 ) { obj.
ReadFrom(strm);
return strm; }
1361 #define PANSI_CHAR 1
1362 #define PLITTLE_ENDIAN 2
1363 #define PBIG_ENDIAN 3
1366 template <
typename type>
1373 __inline
operator type()
const {
return data; }
1382 template <
typename type>
1389 __inline
operator type()
const { type value; ReverseBytes(data, value);
return value; }
1396 static __inline
void ReverseBytes(
const type & src, type & dst)
1398 size_t s =
sizeof(type)-1;
1399 for (
size_t d = 0; d <
sizeof(type); ++d,--s)
1400 ((BYTE *)&dst)[d] = ((
const BYTE *)&src)[s];
1405 #define PCHAR8 PANSI_CHAR
1408 #if PCHAR8==PANSI_CHAR
1416 #if PBYTE_ORDER==PLITTLE_ENDIAN
1418 #elif PBYTE_ORDER==PBIG_ENDIAN
1422 #if PBYTE_ORDER==PLITTLE_ENDIAN
1424 #elif PBYTE_ORDER==PBIG_ENDIAN
1428 #if PBYTE_ORDER==PLITTLE_ENDIAN
1430 #elif PBYTE_ORDER==PBIG_ENDIAN
1434 #if PBYTE_ORDER==PLITTLE_ENDIAN
1436 #elif PBYTE_ORDER==PBIG_ENDIAN
1440 #if PBYTE_ORDER==PLITTLE_ENDIAN
1442 #elif PBYTE_ORDER==PBIG_ENDIAN
1446 #if PBYTE_ORDER==PLITTLE_ENDIAN
1448 #elif PBYTE_ORDER==PBIG_ENDIAN
1452 #if PBYTE_ORDER==PLITTLE_ENDIAN
1454 #elif PBYTE_ORDER==PBIG_ENDIAN
1458 #if PBYTE_ORDER==PLITTLE_ENDIAN
1460 #elif PBYTE_ORDER==PBIG_ENDIAN
1464 #if PBYTE_ORDER==PLITTLE_ENDIAN
1466 #elif PBYTE_ORDER==PBIG_ENDIAN
1470 #if PBYTE_ORDER==PLITTLE_ENDIAN
1472 #elif PBYTE_ORDER==PBIG_ENDIAN
1476 #if PBYTE_ORDER==PLITTLE_ENDIAN
1478 #elif PBYTE_ORDER==PBIG_ENDIAN
1482 #if PBYTE_ORDER==PLITTLE_ENDIAN
1484 #elif PBYTE_ORDER==PBIG_ENDIAN
1488 #if PBYTE_ORDER==PLITTLE_ENDIAN
1490 #elif PBYTE_ORDER==PBIG_ENDIAN
1494 #if PBYTE_ORDER==PLITTLE_ENDIAN
1496 #elif PBYTE_ORDER==PBIG_ENDIAN
1500 #if PBYTE_ORDER==PLITTLE_ENDIAN
1502 #elif PBYTE_ORDER==PBIG_ENDIAN
1506 #if PBYTE_ORDER==PLITTLE_ENDIAN
1508 #elif PBYTE_ORDER==PBIG_ENDIAN
1512 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1513 #if PBYTE_ORDER==PLITTLE_ENDIAN
1515 #elif PBYTE_ORDER==PBIG_ENDIAN
1519 #if PBYTE_ORDER==PLITTLE_ENDIAN
1521 #elif PBYTE_ORDER==PBIG_ENDIAN
1534 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1541 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1548 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1555 #define PABS(v) ((v) < 0 ? -(v) : (v))
1558 #endif // PTLIB_OBJECT_H