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>
67 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
72 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
74 #define P_DEPRECATED __declspec(deprecated)
75 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
77 #define P_DEPRECATED __declspec(deprecated)
78 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
80 #elif defined(__GNUC__)
83 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
85 #define P_DEPRECATED __attribute__((deprecated))
86 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
90 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
93 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
94 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
101 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
104 # define PFalse FALSE
108 # define PFalse false
116 #ifndef P_USE_INLINES
118 #define P_USE_INLINES 0
120 #define P_USE_INLINES 0
125 #define PINLINE inline
134 #ifndef P_USE_ASSERTS
135 #define P_USE_ASSERTS 1
140 #define PAssert(b, m) (b)
141 #define PAssert2(b, c, m) (b)
142 #define PAssertOS(b) (b)
143 #define PAssertNULL(p) (p)
144 #define PAssertAlways(m) {}
145 #define PAssertAlways2(c, m) {}
147 #else // P_USE_ASSERTS
167 #define __CLASS__ NULL
170 void PAssertFunc(
const char * file,
int line,
const char * className,
const char * msg);
179 inline bool PAssertFuncInline(
bool b,
const char * file,
int line,
const char * className,
const char * msg)
192 #define PAssert(b, msg) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(msg))
201 #define PAssert2(b, cls, msg) PAssertFuncInline((b), __FILE__,__LINE__,(cls),(msg))
209 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
220 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
221 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
229 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
237 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
239 #endif // P_USE_ASSERTS
267 #define PError (PGetErrorStream())
349 const char * filename = NULL,
365 const char * filename,
366 const char * rolloverPattern,
446 static ostream &
Begin(
448 const char * fileName,
469 static ostream &
End(
487 const char * fileName,
489 const char * traceName
493 : file(obj.file), line(obj.line), name(obj.name) { }
507 #define PTRACE_PARAM(param) param
515 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
520 #define PTRACE_LINE() \
521 if (PTrace::CanTrace(1)) \
522 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
530 #define PTRACE(level, args) \
531 if (PTrace::CanTrace(level)) \
532 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
542 #define PTRACE_IF(level, cond, args) \
543 if ((PTrace::CanTrace(level) && (cond))) \
544 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
549 #define PTRACE_PARAM(param)
550 #define PTRACE_BLOCK(n)
551 #define PTRACE_LINE()
552 #define PTRACE(level, arg)
553 #define PTRACE_IF(level, cond, args)
559 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
561 #define PMEMORY_HEAP 1
587 const char * className
623 const char * className
640 const char * className,
649 ostream * error = NULL
675 typedef _CrtMemState
State;
723 const char * className
727 const char * className,
753 sizeof(
const char *) +
754 sizeof(
const char *) +
804 CRITICAL_SECTION mutex;
805 #elif defined(P_PTHREADS)
806 pthread_mutex_t mutex;
807 #elif defined(P_VXWORKS)
813 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
814 _CrtMemState initialState;
816 #endif // PMEMORY_CHECK
839 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
847 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
855 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
864 #define free(p) PMemoryHeap::Deallocate(p, NULL)
873 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
890 #define PNEW new (__FILE__, __LINE__)
892 #if !defined(_MSC_VER) || _MSC_VER<1200
893 #define PSPECIAL_DELETE_FUNCTION
895 #define PSPECIAL_DELETE_FUNCTION \
896 void operator delete(void * ptr, const char *, int) \
897 { PMemoryHeap::Deallocate(ptr, Class()); } \
898 void operator delete[](void * ptr, const char *, int) \
899 { PMemoryHeap::Deallocate(ptr, Class()); }
902 #define PNEW_AND_DELETE_FUNCTIONS \
903 void * operator new(size_t nSize, const char * file, int line) \
904 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
905 void * operator new(size_t nSize) \
906 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
907 void operator delete(void * ptr) \
908 { PMemoryHeap::Deallocate(ptr, Class()); } \
909 void * operator new(size_t, void * placement) \
910 { return placement; } \
911 void operator delete(void *, void *) \
913 void * operator new[](size_t nSize, const char * file, int line) \
914 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
915 void * operator new[](size_t nSize) \
916 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
917 void operator delete[](void * ptr) \
918 { PMemoryHeap::Deallocate(ptr, Class()); } \
919 PSPECIAL_DELETE_FUNCTION
922 inline void *
operator new(
size_t nSize,
const char * file,
int line)
925 inline void *
operator new[](
size_t nSize,
const char * file,
int line)
929 void *
operator new(
size_t nSize);
930 void *
operator new[](
size_t nSize);
932 void operator delete(
void * ptr);
933 void operator delete[](
void * ptr);
935 #if defined(_MSC_VER) && _MSC_VER>=1200
936 inline void operator delete(
void * ptr,
const char *, int)
939 inline void operator delete[](
void * ptr,
const char *, int)
953 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
963 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
966 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
968 #define PMEMORY_HEAP 0
972 #define PNEW_AND_DELETE_FUNCTIONS
974 #define runtime_malloc(s) malloc(s)
975 #define runtime_free(p) free(p)
977 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
978 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
980 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
988 template <
class GnuAllocator,
class Type>
993 return GetAllocator().allocate(v);
998 GetAllocator().deallocate(p, v);
1002 static GnuAllocator & GetAllocator()
1004 static GnuAllocator instance;
1009 #define GCC_VERSION (__GNUC__ * 10000 \
1010 + __GNUC_MINOR__ * 100 \
1011 + __GNUC_PATCHLEVEL__)
1014 #if defined(__GNUC__) && (GCC_VERSION > 40000) && !defined(P_MINGW) && !defined(P_MACOSX)
1015 #include <ext/mt_allocator.h>
1025 #define PDECLARE_POOL_ALLOCATOR() \
1026 void * operator new(size_t nSize); \
1027 void * operator new(size_t nSize, const char * file, int line); \
1028 void operator delete(void * ptr); \
1029 void operator delete(void * ptr, const char *, int)
1031 #define PDEFINE_POOL_ALLOCATOR(cls) \
1032 static PFixedPoolAllocator<cls> cls##_allocator; \
1033 void * cls::operator new(size_t) { return cls##_allocator.allocate(1); } \
1034 void * cls::operator new(size_t, const char *, int) { return cls##_allocator.allocate(1); } \
1035 void cls::operator delete(void * ptr) { cls##_allocator.deallocate((cls *)ptr, 1); } \
1036 void cls::operator delete(void * ptr, const char *, int) { cls##_allocator.deallocate((cls *)ptr, 1); }
1049 #define PCLASSINFO(cls, par) \
1051 typedef cls P_thisClass; \
1052 static inline const char * Class() \
1054 virtual PBoolean InternalIsDescendant(const char * clsName) const \
1055 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
1056 virtual const char * GetClass(unsigned ancestor = 0) const \
1057 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
1058 virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1059 { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1060 PNEW_AND_DELETE_FUNCTIONS
1065 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
1066 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1068 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
1071 template<
class BaseClass>
inline BaseClass *
PAssertCast(BaseClass * obj,
const char * file,
int line)
1073 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1075 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1080 #else // P_HAS_TYPEINFO
1082 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
1083 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1085 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
1088 template<
class BaseClass>
inline BaseClass *
PAssertCast(
PObject * obj,
const char * file,
int line)
1090 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
1092 #define PDownCast(cls, ptr) ((cls*)(ptr))
1095 #endif // P_HAS_TYPEINFO
1106 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1107 #ifdef DOC_PLUS_PLUS
1108 } Match previous opening brace in doc++
1144 static inline const char *
Class() {
return "PObject"; }
1158 virtual const char *
GetClass(
unsigned ancestor = 0)
const {
return ancestor > 0 ?
"" :
Class(); }
1161 {
return strcmp(cls,
GetClass()) == 0; }
1173 const char * clsName
1313 ) { obj.
PrintOn(strm);
return strm; }
1323 ) { obj.
ReadFrom(strm);
return strm; }
1365 #define PANSI_CHAR 1
1366 #define PLITTLE_ENDIAN 2
1367 #define PBIG_ENDIAN 3
1370 template <
typename type>
1377 __inline
operator type()
const {
return data; }
1386 template <
typename type>
1393 __inline
operator type()
const { type value; ReverseBytes(data, value);
return value; }
1400 static __inline
void ReverseBytes(
const type & src, type & dst)
1402 size_t s =
sizeof(type)-1;
1403 for (
size_t d = 0; d <
sizeof(type); ++d,--s)
1404 ((BYTE *)&dst)[d] = ((
const BYTE *)&src)[s];
1409 #define PCHAR8 PANSI_CHAR
1412 #if PCHAR8==PANSI_CHAR
1420 #if PBYTE_ORDER==PLITTLE_ENDIAN
1422 #elif PBYTE_ORDER==PBIG_ENDIAN
1426 #if PBYTE_ORDER==PLITTLE_ENDIAN
1428 #elif PBYTE_ORDER==PBIG_ENDIAN
1432 #if PBYTE_ORDER==PLITTLE_ENDIAN
1434 #elif PBYTE_ORDER==PBIG_ENDIAN
1438 #if PBYTE_ORDER==PLITTLE_ENDIAN
1440 #elif PBYTE_ORDER==PBIG_ENDIAN
1444 #if PBYTE_ORDER==PLITTLE_ENDIAN
1446 #elif PBYTE_ORDER==PBIG_ENDIAN
1450 #if PBYTE_ORDER==PLITTLE_ENDIAN
1452 #elif PBYTE_ORDER==PBIG_ENDIAN
1456 #if PBYTE_ORDER==PLITTLE_ENDIAN
1458 #elif PBYTE_ORDER==PBIG_ENDIAN
1462 #if PBYTE_ORDER==PLITTLE_ENDIAN
1464 #elif PBYTE_ORDER==PBIG_ENDIAN
1468 #if PBYTE_ORDER==PLITTLE_ENDIAN
1470 #elif PBYTE_ORDER==PBIG_ENDIAN
1474 #if PBYTE_ORDER==PLITTLE_ENDIAN
1476 #elif PBYTE_ORDER==PBIG_ENDIAN
1480 #if PBYTE_ORDER==PLITTLE_ENDIAN
1482 #elif PBYTE_ORDER==PBIG_ENDIAN
1486 #if PBYTE_ORDER==PLITTLE_ENDIAN
1488 #elif PBYTE_ORDER==PBIG_ENDIAN
1492 #if PBYTE_ORDER==PLITTLE_ENDIAN
1494 #elif PBYTE_ORDER==PBIG_ENDIAN
1498 #if PBYTE_ORDER==PLITTLE_ENDIAN
1500 #elif PBYTE_ORDER==PBIG_ENDIAN
1504 #if PBYTE_ORDER==PLITTLE_ENDIAN
1506 #elif PBYTE_ORDER==PBIG_ENDIAN
1510 #if PBYTE_ORDER==PLITTLE_ENDIAN
1512 #elif PBYTE_ORDER==PBIG_ENDIAN
1516 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1517 #if PBYTE_ORDER==PLITTLE_ENDIAN
1519 #elif PBYTE_ORDER==PBIG_ENDIAN
1523 #if PBYTE_ORDER==PLITTLE_ENDIAN
1525 #elif PBYTE_ORDER==PBIG_ENDIAN
1538 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1545 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1552 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1559 #define PABS(v) ((v) < 0 ? -(v) : (v))
1562 #endif // PTLIB_OBJECT_H