34 #ifndef PTLIB_OBJECT_H
35 #define PTLIB_OBJECT_H
42 #include "msos/ptlib/platform.h"
44 #include "unix/ptlib/platform.h"
78 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
83 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
85 #define P_DEPRECATED __declspec(deprecated)
86 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
88 #define P_DEPRECATED __declspec(deprecated)
89 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
91 #elif defined(__GNUC__)
94 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
96 #define P_DEPRECATED __attribute__((deprecated))
97 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
101 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
104 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
105 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
109 #define P_PUSH_MSVC_WARNINGS(warnings) __pragma(warning(push)) __pragma(warning(disable:warnings))
110 #define P_POP_MSVC_WARNINGS() __pragma(warning(pop))
112 #define P_PUSH_MSVC_WARNINGS(warnings)
113 #define P_POP_MSVC_WARNINGS()
115 #define P_DISABLE_MSVC_WARNINGS(warnings, statement) P_PUSH_MSVC_WARNINGS(warnings) statement P_POP_MSVC_WARNINGS()
129 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
144 #ifndef P_USE_INLINES
146 #define P_USE_INLINES 0
148 #define P_USE_INLINES 0
153 #define PINLINE __inline
163 #define PARG_COUNT(...) PARG_COUNT_PART1(PARG_COUNT_PART2(__VA_ARGS__,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
164 #define PARG_COUNT_PART1(arg) arg
165 #define PARG_COUNT_PART2(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,N,...) N
168 #define P_STRINGISE(v) P_STRINGISE_PART2(v)
169 #define P_STRINGIZE(v) P_STRINGISE_PART2(v)
170 #define P_STRINGISE_PART2(v) #v
183 #define P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, ...) \
184 enum name { firstName = firstValue, Begin##name = firstName, __VA_ARGS__, End##name, countName = End##name-Begin##name }; \
185 friend __inline name operator++(name & e ) { PAssert(e < End##name, PInvalidParameter); return e = (name)(e+1); } \
186 friend __inline name operator++(name & e, int) { PAssert(e < End##name, PInvalidParameter); name o=e; e = (name)(e+1); return o; } \
187 friend __inline name operator--(name & e ) { PAssert(e >= Begin##name, PInvalidParameter); return e = (name)(e-1); } \
188 friend __inline name operator--(name & e, int) { PAssert(e >= Begin##name, PInvalidParameter); name o=e; e = (name)(e-1); return o; } \
189 static __inline name name##FromInt(int v) { return (name)(v < Begin##name ? Begin##name : v >= End##name ? (End##name-1) : v); }
202 #define P_DECLARE_ENUM(name, first, ...) P_DECLARE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
204 extern void PPrintEnum(std::ostream & strm,
int e,
int begin,
int end,
char const *
const * names);
205 extern int PReadEnum(std::istream & strm,
int begin,
int end,
char const *
const * names);
207 #define P_ENUM_NAMES_PART1(narg, args)P_ENUM_NAMES_PART2(narg, args)
208 #define P_ENUM_NAMES_PART2(narg, args) P_ENUM_NAMES_ARG_##narg args
209 #define P_ENUM_NAMES_ARG_1(_1 )#_1
210 #define P_ENUM_NAMES_ARG_2(_1,_2 )#_1,#_2
211 #define P_ENUM_NAMES_ARG_3(_1,_2,_3 )#_1,#_2,#_3
212 #define P_ENUM_NAMES_ARG_4(_1,_2,_3,_4 )#_1,#_2,#_3,#_4
213 #define P_ENUM_NAMES_ARG_5(_1,_2,_3,_4,_5 )#_1,#_2,#_3,#_4,#_5
214 #define P_ENUM_NAMES_ARG_6(_1,_2,_3,_4,_5,_6 )#_1,#_2,#_3,#_4,#_5,#_6
215 #define P_ENUM_NAMES_ARG_7(_1,_2,_3,_4,_5,_6,_7 )#_1,#_2,#_3,#_4,#_5,#_6,#_7
216 #define P_ENUM_NAMES_ARG_8(_1,_2,_3,_4,_5,_6,_7,_8 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8
217 #define P_ENUM_NAMES_ARG_9(_1,_2,_3,_4,_5,_6,_7,_8,_9 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9
218 #define P_ENUM_NAMES_ARG_10(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10
219 #define P_ENUM_NAMES_ARG_11(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11
220 #define P_ENUM_NAMES_ARG_12(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12
221 #define P_ENUM_NAMES_ARG_13(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13
222 #define P_ENUM_NAMES_ARG_14(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14
223 #define P_ENUM_NAMES_ARG_15(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15
224 #define P_ENUM_NAMES_ARG_16(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16
225 #define P_ENUM_NAMES_ARG_17(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17
226 #define P_ENUM_NAMES_ARG_18(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18
227 #define P_ENUM_NAMES_ARG_19(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19
228 #define P_ENUM_NAMES_ARG_20(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20
229 #define P_ENUM_NAMES_ARG_21(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21
230 #define P_ENUM_NAMES_ARG_22(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22
231 #define P_ENUM_NAMES_ARG_23(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23
232 #define P_ENUM_NAMES_ARG_24(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24
233 #define P_ENUM_NAMES_ARG_25(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25
234 #define P_ENUM_NAMES_ARG_26(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26
235 #define P_ENUM_NAMES_ARG_27(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27
236 #define P_ENUM_NAMES_ARG_28(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28
237 #define P_ENUM_NAMES_ARG_29(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29
238 #define P_ENUM_NAMES_ARG_30(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30
239 #define P_ENUM_NAMES_ARG_31(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31
240 #define P_ENUM_NAMES_ARG_32(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32
241 #define P_ENUM_NAMES_ARG_33(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33
242 #define P_ENUM_NAMES_ARG_34(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34
243 #define P_ENUM_NAMES_ARG_35(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35
244 #define P_ENUM_NAMES_ARG_36(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36
245 #define P_ENUM_NAMES_ARG_37(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37
246 #define P_ENUM_NAMES_ARG_38(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38
247 #define P_ENUM_NAMES_ARG_39(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38,#_39
248 #define P_ENUM_NAMES_ARG_40(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40)#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38,#_39,#_40
251 #define P_DECLARE_STREAMABLE_ENUM_EX(name, countName, firstName, firstValue, ...) \
252 P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, __VA_ARGS__) \
253 struct PEnumNames_##name { \
254 static char const * const * Names() { static char const * const Strings[] = \
255 { #firstName, P_ENUM_NAMES_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__)) }; return Strings; } \
257 friend __inline std::ostream & operator<<(std::ostream & strm, name e) \
258 { PPrintEnum(strm, e, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
259 friend __inline std::istream & operator>>(std::istream & strm, name & e) \
260 { e = (name)PReadEnum(strm, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
263 #define P_DECLARE_STREAMABLE_ENUM(name, first, ...) P_DECLARE_STREAMABLE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
269 #ifndef P_USE_ASSERTS
270 #define P_USE_ASSERTS 1
275 #define PAssert(b, m) (b)
276 #define PAssert2(b, c, m) (b)
277 #define PAssertOS(b) (b)
278 #define PAssertNULL(p) (p)
279 #define PAssertAlways(m) {}
280 #define PAssertAlways2(c, m) {}
282 #else // P_USE_ASSERTS
302 #define __CLASS__ NULL
305 bool PAssertFunc(
const char * file,
int line,
const char * className,
const char * msg);
315 #define PAssert(b, msg) ((b)?true:PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg)))
324 #define PAssert2(b, cls, msg) ((b)?true:PAssertFunc(__FILE__,__LINE__,(cls),(msg)))
332 #define PAssertOS(b) ((b)?true:PAssertFunc(__FILE__,__LINE__,__CLASS__,POperatingSystemError))
343 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
344 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
352 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
360 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
362 #endif // P_USE_ASSERTS
390 #define PError (PGetErrorStream())
427 DateAndTime = 0x0002,
431 FileAndLine = 0x0020,
432 ThreadAddress = 0x0040,
433 AppendToFile = 0x0080,
435 RotateDaily = 0x0200,
436 RotateHourly = 0x0400,
437 RotateMinutely = 0x0800,
438 RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
440 ObjectInstance = 0x1000,
441 ContextIdentifier = 0x2000,
442 SystemLogStream = 0x8000
448 #define PTRACE_ARGLIST_OPT_HELP \
449 "use +X or -X to add/remove option where X is one of:\r" \
450 " block PTrace::Block constructs in output\r" \
451 " time time since prgram start\r" \
452 " date date and time\r" \
453 " gmt Date/time is in UTC\r" \
454 " thread thread name and identifier\r" \
455 " level log level\r" \
456 " file source file name and line number\r" \
457 " object PObject pointer\r" \
458 " context context identifier\r" \
459 " daily rotate output file daily\r" \
460 " hour rotate output file hourly\r" \
461 " minute rotate output file every minute\r" \
462 " append append to output file, otherwise overwrites"
464 #define PTRACE_ARGLIST \
465 "t-trace. Trace enable (use multiple times for more detail)\n" \
466 "o-output: Specify filename for trace output\n" \
467 "-trace-option: Specify trace option(s),\r" PTRACE_ARGLIST_OPT_HELP "\n" \
468 "-trace-rollover: Specify trace file rollover file name pattern\n"
470 #define PTRACE_INITIALISE(...) PTrace::Initialise(__VA_ARGS__)
475 static void Initialise(
481 Timestamp | Thread | Blocks,
482 const char * traceLevel =
"trace",
483 const char * outputFile =
"output",
484 const char * traceOpts =
"trace-option",
485 const char * traceRollover =
"trace-rollover"
519 static void Initialise(
521 const char * filename = NULL,
522 unsigned options = Timestamp | Thread | Blocks,
523 const char * rolloverPattern = NULL
527 static void Initialise(
529 const char * filename,
530 const char * rolloverPattern,
531 unsigned options = Timestamp | Thread | Blocks
532 ) {
Initialise(level, filename, options, rolloverPattern); }
540 static void SetOptions(
552 static void ClearOptions(
561 static unsigned GetOptions();
568 static void SetLevel(
577 static unsigned GetLevel();
591 static void SetStream(
597 static ostream * GetStream();
614 static ostream & Begin(
616 const char * fileName,
618 const PObject * instance = NULL,
619 const char * module = NULL
622 static ostream & Begin(
624 const char * fileName,
628 const char * defModule
629 ) {
return Begin(level, fileName, lineNum, instance, module != NULL ? module : defModule); }
631 static ostream & Begin(
633 const char * fileName,
638 ) {
return Begin(level, fileName, lineNum, instance != NULL ? instance : defInstance, module); }
657 static ostream & End(
670 const char * fileName,
672 const char * traceName
676 : file(obj.file), line(obj.line), name(obj.name) { }
687 static unsigned GetNextContextIdentifier();
692 #define PTRACE_PARAM(...) __VA_ARGS__
700 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
705 #define PTRACE_LINE() \
706 if (PTrace::CanTrace(1)) \
707 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
712 #define PTRACE_INTERNAL(level, condition, args, ...) \
713 if (PTrace::CanTrace(level) condition) \
714 PTrace::Begin(level, __FILE__, __LINE__, __VA_ARGS__) << args << PTrace::End; \
717 #define PTRACE_NO_CONDITION
720 #define PTRACE_PART1(narg, args) PTRACE_PART2(narg, args)
721 #define PTRACE_PART2(narg, args) PTRACE_ARG_##narg args
723 #define PTRACE_ARG_4(level, object, module, args) \
724 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, module)
726 #define PTRACE_ARG_3(level, objectOrModule, args) \
727 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
729 #define PTRACE_ARG_2(level, args) \
730 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, PTraceObjectInstance(), PTraceModule())
733 #define PTRACE_IF_PART1(narg, args) PTRACE_IF_PART2(narg, args)
734 #define PTRACE_IF_PART2(narg, args) PTRACE_IF_ARG_##narg args
736 #define PTRACE_IF_ARG_5(level, condition, object, module, args) \
737 PTRACE_INTERNAL(level, && (condition), args, object, module)
739 #define PTRACE_IF_ARG_4(level, condition, objectOrModule, args) \
740 PTRACE_INTERNAL(level, && (condition), args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
742 #define PTRACE_IF_ARG_3(level, condition, args) \
743 PTRACE_INTERNAL(level, && (condition), args, PTraceObjectInstance(), PTraceModule())
746 #define PTRACE_BEGIN_PART1(narg, args) PTRACE_BEGIN_PART2(narg, args)
747 #define PTRACE_BEGIN_PART2(narg, args) PTRACE_BEGIN_ARG_##narg args
749 #define PTRACE_BEGIN_ARG_3(level, object, module) \
750 PTrace::Begin(level, __FILE__, __LINE__, object, module)
752 #define PTRACE_BEGIN_ARG_2(level, objectOrModule) \
753 PTrace::Begin(level, __FILE__, __LINE__, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
755 #define PTRACE_BEGIN_ARG_1(level) \
756 PTrace::Begin(level, __FILE__, __LINE__, PTraceObjectInstance(), PTraceModule())
760 #define PTRACE2(level, object, args) \
761 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, PTraceModule())
762 #define PTRACE_IF2(level, condition, object, args) \
763 PTRACE_INTERNAL(level, && (condition), args, object, PTraceModule())
790 #define PTRACE(...) PTRACE_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
804 #define PTRACE_IF(...) PTRACE_IF_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
815 #define PTRACE_BEGIN(...) PTRACE_BEGIN_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
830 #define PTRACE_CONTEXT_ID_NEW() SetTraceContextIdentifier(PTrace::GetNextContextIdentifier())
831 #define PTRACE_CONTEXT_ID_SET(to, from) (to).SetTraceContextIdentifier(from)
832 #define PTRACE_CONTEXT_ID_FROM(obj) SetTraceContextIdentifier(obj)
833 #define PTRACE_CONTEXT_ID_TO(obj) GetTraceContextIdentifier(obj)
838 class PThread * m_currentThread;
839 unsigned m_savedContextIdentifier;
846 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj) PTraceSaveContextIdentifier praceSavedContextIdentifier(obj)
848 #endif // PTRACING==2
851 #define P_DECLARE_TRACED_ENUM P_DECLARE_STREAMABLE_ENUM
852 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_STREAMABLE_ENUM_EX
856 #ifndef PTRACE_ARGLIST
857 #define PTRACE_ARGLIST
860 #ifndef PTRACE_INITIALISE
861 #define PTRACE_INITIALISE(...)
865 #define PTRACE_PARAM(...)
869 #define PTRACE_BLOCK(n)
873 #define PTRACE_LINE()
881 #define PTRACE_IF(...)
885 #define PTRACE_BEGIN(...)
889 #define PTRACE2(level, obj, arg)
893 #define PTRACE_IF2(level, cond, obj, args)
896 #ifndef PTRACE_CONTEXT_ID_NEW
897 #define PTRACE_CONTEXT_ID_NEW()
900 #ifndef PTRACE_CONTEXT_ID_SET
901 #define PTRACE_CONTEXT_ID_SET(to, from)
904 #ifndef PTRACE_CONTEXT_ID_FROM
905 #define PTRACE_CONTEXT_ID_FROM(obj)
908 #ifndef PTRACE_CONTEXT_ID_TO
909 #define PTRACE_CONTEXT_ID_TO(obj)
912 #ifndef PTRACE_CONTEXT_ID_PUSH_THREAD
913 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj)
916 #ifndef P_DECLARE_TRACED_ENUM
917 #define P_DECLARE_TRACED_ENUM P_DECLARE_ENUM
920 #ifndef P_DECLARE_TRACED_ENUM_EX
921 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_ENUM_EX
925 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
927 #define PMEMORY_HEAP 1
950 static void * Allocate(
954 const char * className
962 static void * Allocate(
976 static void * Reallocate(
988 static void Deallocate(
990 const char * className
1005 static Validation Validate(
1007 const char * className,
1016 ostream * error = NULL
1024 static PBoolean SetIgnoreAllocations(
1031 static void DumpStatistics();
1035 static void DumpStatistics(ostream & strm );
1042 typedef _CrtMemState
State;
1049 static void GetState(
1060 static void DumpObjectsSince(
1069 static void DumpObjectsSince(
1079 static void SetAllocationBreakpoint(
1086 void * InternalAllocate(
1090 const char * className
1094 const char * className,
1097 void InternalDumpStatistics(ostream & strm);
1098 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
1120 sizeof(
const char *) +
1121 sizeof(
const char *) +
1126 sizeof(PThreadIdentifier)
1139 char guard[NumGuardBytes];
1141 static char GuardBytes[NumGuardBytes];
1167 CRITICAL_SECTION mutex;
1168 #elif defined(P_PTHREADS)
1169 pthread_mutex_t mutex;
1170 #elif defined(P_VXWORKS)
1176 static void CreateInstance();
1177 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
1178 _CrtMemState initialState;
1180 #endif // PMEMORY_CHECK
1203 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
1211 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
1219 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
1228 #define free(p) PMemoryHeap::Deallocate(p, NULL)
1237 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
1254 #define PNEW new (__FILE__, __LINE__)
1256 #if !defined(_MSC_VER) || _MSC_VER<1200
1257 #define PSPECIAL_DELETE_FUNCTION
1259 #define PSPECIAL_DELETE_FUNCTION \
1260 void operator delete(void * ptr, const char *, int) \
1261 { PMemoryHeap::Deallocate(ptr, Class()); } \
1262 void operator delete[](void * ptr, const char *, int) \
1263 { PMemoryHeap::Deallocate(ptr, Class()); }
1266 #define PNEW_AND_DELETE_FUNCTIONS \
1267 void * operator new(size_t nSize, const char * file, int line) \
1268 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1269 void * operator new(size_t nSize) \
1270 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1271 void operator delete(void * ptr) \
1272 { PMemoryHeap::Deallocate(ptr, Class()); } \
1273 void * operator new(size_t, void * placement) \
1274 { return placement; } \
1275 void operator delete(void *, void *) \
1277 void * operator new[](size_t nSize, const char * file, int line) \
1278 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1279 void * operator new[](size_t nSize) \
1280 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1281 void operator delete[](void * ptr) \
1282 { PMemoryHeap::Deallocate(ptr, Class()); } \
1283 PSPECIAL_DELETE_FUNCTION
1286 inline void *
operator new(
size_t nSize,
const char * file,
int line)
1289 inline void *
operator new[](
size_t nSize,
const char * file,
int line)
1293 void *
operator new(
size_t nSize);
1294 void *
operator new[](
size_t nSize);
1296 void operator delete(
void * ptr);
1297 void operator delete[](
void * ptr);
1299 #if defined(_MSC_VER) && _MSC_VER>=1200
1300 inline void operator delete(
void * ptr,
const char *, int)
1303 inline void operator delete[](
void * ptr,
const char *, int)
1314 PBoolean previousIgnoreAllocations;
1317 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
1327 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
1330 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1332 #define PMEMORY_HEAP 0
1336 #define PNEW_AND_DELETE_FUNCTIONS
1338 #define runtime_malloc(s) malloc(s)
1339 #define runtime_free(p) free(p)
1341 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
1342 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
1344 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1360 template <
class Type,
typename GuardType =
unsigned>
1368 static Type * s_pointer;
1369 static GuardType s_guard;
1377 static Type s_instance;
1378 s_pointer = &s_instance;
1380 m_instance = s_pointer;
1384 Type & operator* ()
const {
return *m_instance; }
1393 #include <ext/mt_allocator.h>
1399 template <
bool _Thread>
1400 struct PMemoryPool :
public __gnu_cxx::__pool<_Thread>
1403 : __gnu_cxx::__pool<_Thread>()
1407 PMemoryPool(
const __gnu_cxx::__pool_base::_Tune& t)
1408 : __gnu_cxx::__pool<_Thread>(t)
1415 template <
class Type>
1416 struct PCommonPool :
public __gnu_cxx::__common_pool_policy<PMemoryPool, true>
1422 template <
class Type,
class Pool = PCommonPool<Type> >
1427 #if P_GNU_ALLOCATOR==1
1428 template <
class Type>
1433 #include <ext/bitmap_allocator.h>
1434 template <
class Type>
1442 template <
class Type,
class Pool =
void>
1447 template <
class Type>
1454 #define PDECLARE_POOL_ALLOCATOR() \
1455 void * operator new(size_t nSize); \
1456 void * operator new(size_t nSize, const char * file, int line); \
1457 void operator delete(void * ptr); \
1458 void operator delete(void * ptr, const char *, int)
1460 #define PDEFINE_POOL_ALLOCATOR(cls) \
1461 void * cls::operator new(size_t) { return PFixedPoolAllocator<cls>()->allocate(1); } \
1462 void * cls::operator new(size_t, const char *, int) { return PFixedPoolAllocator<cls>()->allocate(1); } \
1463 void cls::operator delete(void * ptr) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); } \
1464 void cls::operator delete(void * ptr, const char *, int) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); }
1478 #define PCLASSINFO(cls, par) \
1480 typedef cls P_thisClass; \
1481 static inline const char * Class() \
1483 virtual PBoolean InternalIsDescendant(const char * clsName) const \
1484 { return strcmp(clsName, this->Class()) == 0 || par::InternalIsDescendant(clsName); } \
1485 virtual const char * GetClass(unsigned ancestor = 0) const \
1486 { return ancestor > 0 ? par::GetClass(ancestor-1) : this->Class(); } \
1487 virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1488 { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1489 PNEW_AND_DELETE_FUNCTIONS
1492 #define PCLASSINFO_WITH_CLONE(cls, par) \
1493 PCLASSINFO(cls, par) \
1494 virtual PObject * Clone() const { return new cls(*this); }
1497 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
1498 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1500 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
1503 template<
class BaseClass>
inline BaseClass *
PAssertCast(BaseClass * obj,
const char * file,
int line)
1505 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1507 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1519 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1520 #ifdef DOC_PLUS_PLUS
1521 } Match previous opening brace in doc++
1544 #endif // PTRACING==2
1572 static inline const char *
Class() {
return "PObject"; }
1586 virtual const char *
GetClass(
unsigned ancestor = 0)
const {
return ancestor > 0 ?
"" : this->
Class(); }
1589 {
return strcmp(cls,
GetClass()) == 0; }
1601 const char * clsName
1744 ) { obj.
PrintOn(strm);
return strm; }
1754 ) { obj.
ReadFrom(strm);
return strm; }
1775 template <
class CLS>
1779 CLS * obj =
dynamic_cast<CLS *
>(clone);
1809 #define PANSI_CHAR 1
1810 #define PLITTLE_ENDIAN 2
1811 #define PBIG_ENDIAN 3
1814 template <
typename type>
1821 __inline
operator type()
const {
return data; }
1830 template <
typename type>
1837 __inline
operator type()
const { type value; ReverseBytes(data, value);
return value; }
1844 static __inline
void ReverseBytes(
const type & src, type & dst)
1846 size_t s =
sizeof(type)-1;
1847 for (
size_t d = 0; d <
sizeof(type); ++d,--s)
1848 ((BYTE *)&dst)[d] = ((
const BYTE *)&src)[s];
1853 #define PCHAR8 PANSI_CHAR
1856 #if PCHAR8==PANSI_CHAR
1864 #if PBYTE_ORDER==PLITTLE_ENDIAN
1866 #elif PBYTE_ORDER==PBIG_ENDIAN
1870 #if PBYTE_ORDER==PLITTLE_ENDIAN
1872 #elif PBYTE_ORDER==PBIG_ENDIAN
1876 #if PBYTE_ORDER==PLITTLE_ENDIAN
1878 #elif PBYTE_ORDER==PBIG_ENDIAN
1882 #if PBYTE_ORDER==PLITTLE_ENDIAN
1884 #elif PBYTE_ORDER==PBIG_ENDIAN
1888 #if PBYTE_ORDER==PLITTLE_ENDIAN
1890 #elif PBYTE_ORDER==PBIG_ENDIAN
1894 #if PBYTE_ORDER==PLITTLE_ENDIAN
1896 #elif PBYTE_ORDER==PBIG_ENDIAN
1900 #if PBYTE_ORDER==PLITTLE_ENDIAN
1902 #elif PBYTE_ORDER==PBIG_ENDIAN
1906 #if PBYTE_ORDER==PLITTLE_ENDIAN
1908 #elif PBYTE_ORDER==PBIG_ENDIAN
1912 #if PBYTE_ORDER==PLITTLE_ENDIAN
1914 #elif PBYTE_ORDER==PBIG_ENDIAN
1918 #if PBYTE_ORDER==PLITTLE_ENDIAN
1920 #elif PBYTE_ORDER==PBIG_ENDIAN
1924 #if PBYTE_ORDER==PLITTLE_ENDIAN
1926 #elif PBYTE_ORDER==PBIG_ENDIAN
1930 #if PBYTE_ORDER==PLITTLE_ENDIAN
1932 #elif PBYTE_ORDER==PBIG_ENDIAN
1936 #if PBYTE_ORDER==PLITTLE_ENDIAN
1938 #elif PBYTE_ORDER==PBIG_ENDIAN
1942 #if PBYTE_ORDER==PLITTLE_ENDIAN
1944 #elif PBYTE_ORDER==PBIG_ENDIAN
1948 #if PBYTE_ORDER==PLITTLE_ENDIAN
1950 #elif PBYTE_ORDER==PBIG_ENDIAN
1954 #if PBYTE_ORDER==PLITTLE_ENDIAN
1956 #elif PBYTE_ORDER==PBIG_ENDIAN
1960 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1961 #if PBYTE_ORDER==PLITTLE_ENDIAN
1963 #elif PBYTE_ORDER==PBIG_ENDIAN
1967 #if PBYTE_ORDER==PLITTLE_ENDIAN
1969 #elif PBYTE_ORDER==PBIG_ENDIAN
1976 #if defined(_MSC_VER)
1977 #define P_ALIGN_FIELD(f,a) __declspec(align(a)) f
1978 #define P_PACK_FIELD(f) __declspec(align(1)) f
1979 #elif defined(__GNUC__)
1980 #define P_ALIGN_FIELD(f,a) f __attribute__ ((aligned(a)))
1981 #define P_PACK_FIELD(f) f __attribute__ ((packed))
1993 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1999 #define PMIN(v1, v2) std::min(v1, v2)
2005 #define PMAX(v1, v2) std::max(v1, v2)
2011 #define PABS(v) std::abs(v)
2014 #if _MSC_VER >= 1700
2015 class p_iostream :
public std::iostream {
2017 p_iostream(std::streambuf * sbuf) : std::iostream(sbuf) { }
2019 virtual void __CLR_OR_THIS_CALL _Add_vtordisp1() { }
2020 virtual void __CLR_OR_THIS_CALL _Add_vtordisp2() { }
2022 #define P_IOSTREAM p_iostream
2024 #define P_IOSTREAM std::iostream
2028 #endif // PTLIB_OBJECT_H