PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
object.h
Go to the documentation of this file.
1 /*
2  * object.h
3  *
4  * Mother of all ancestor classes.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
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/
14  *
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.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  */
29 
30 #ifndef PTLIB_OBJECT_H
31 #define PTLIB_OBJECT_H
32 
33 #ifdef P_USE_PRAGMA
34 #pragma interface
35 #endif
36 
37 #include <ptlib_config.h>
38 
39 #if defined(_WIN32)
40 #include "msos/ptlib/platform.h"
41 #else
42 #include "unix/ptlib/platform.h"
43 #endif
44 
45 #include <stdio.h>
46 #include <stdarg.h>
47 #include <stdlib.h>
48 #include <limits.h>
49 #include <string.h>
50 #include <ctype.h>
51 #include <errno.h>
52 
53 #include <string>
54 #include <iomanip>
55 #include <iostream>
56 #include <sstream>
57 #include <vector>
58 #include <list>
59 #include <map>
60 #include <algorithm>
61 #include <functional>
62 #include <limits>
63 #include <typeinfo>
64 #include <memory>
65 
66 #include "atomic.h"
67 
68 using namespace std; // Not a good practice (name space polution), but will take too long to fix.
69 
70 // Somewhere in C headers you get this, which blows up STL version
71 #ifdef min
72 #undef min
73 #endif
74 #ifdef max
75 #undef max
76 #endif
77 
78 
79 #if !defined __GNUC__ || __GNUC__ >= 5
80  #define P_MAX_INDEX ::std::numeric_limits<PINDEX>::max()
81 #elif P_PINDEX_IS_SIZE_T
82  const PINDEX P_MAX_INDEX = SIZE_MAX;
83 #else
84  const PINDEX P_MAX_INDEX = INT_MAX;
85 #endif
86 
87 #if PINDEX_SIGNED
88  #define PASSERTINDEX(idx) PAssert((idx) >= 0, PInvalidArrayIndex)
89 #else
90  #define PASSERTINDEX(idx)
91 #endif
92 
93 
94 
96 // Deal with different C++ versions and std::auto_ptr deprecation
97 #if __cplusplus < 201103L
98  template <typename T> class PAutoPtr : public std::auto_ptr<T>
99  {
100  public:
101  PAutoPtr() { }
102  explicit PAutoPtr(T * p) : std::auto_ptr<T>(p) { }
103  PAutoPtr(PAutoPtr & other) : std::auto_ptr<T>(other.release()) { }
104  void transfer(PAutoPtr & other) { this->reset(other.release()); }
105  };
106 #else
107  template <typename T> class PAutoPtr : public std::unique_ptr<T>
108  {
109  public:
110  PAutoPtr() = default;
111  explicit PAutoPtr(T * p) : std::unique_ptr<T>(p) { }
112  void transfer(PAutoPtr & other) { std::unique_ptr<T>::operator=(std::move(other)); }
113  };
114 #endif
115 
116 
118 
119 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
120 
121 #if defined(_MSC_VER)
122  #if _MSC_VER < 1310
123  #define P_DEPRECATED
124  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
125  #elif _MSC_VER < 1400
126  #define P_DEPRECATED __declspec(deprecated)
127  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
128  #else
129  #define P_DEPRECATED __declspec(deprecated)
130  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
131  #endif
132 #elif defined(__GNUC__)
133  #if __GNUC__ < 4
134  #define P_DEPRECATED
135  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
136  #else
137  #define P_DEPRECATED __attribute__((deprecated))
138  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
139  #endif
140 #else
141  #define P_DEPRECATED
142  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
143 #endif
144 
145 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
146 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
147 
148 
149 #ifdef _MSC_VER
150  #define P_PUSH_MSVC_WARNINGS(warnings) __pragma(warning(push)) __pragma(warning(disable:warnings))
151  #define P_POP_MSVC_WARNINGS() __pragma(warning(pop))
152 #else
153  #define P_PUSH_MSVC_WARNINGS(warnings)
154  #define P_POP_MSVC_WARNINGS()
155 #endif // _MSC_VER
156 #define P_DISABLE_MSVC_WARNINGS(warnings, statement) P_PUSH_MSVC_WARNINGS(warnings) statement P_POP_MSVC_WARNINGS()
157 
158 #ifdef _MSC_VER
159  #define PIGNORE_RETURN(t,e) (void)(e)
160 #else
161  #define PIGNORE_RETURN(t,e) do { t unused __attribute__((unused)) = (e); } while(0)
162 #endif
163 
164 // We are gradually converting over to standard C++ names, these
165 // are for backward compatibility only
166 
167 #ifndef FALSE
168 #define FALSE 0
169 #endif
170 #ifndef TRUE
171 #define TRUE 1
172 #endif
173 
174 typedef bool PBoolean;
175 #define PTrue true
176 #define PFalse false
177 
178 
180 // Disable inlines when debugging for faster compiles (the compiler doesn't
181 // actually inline the function with debug on any way).
182 
183 #ifndef P_USE_INLINES
184 #ifdef _DEBUG
185 #define P_USE_INLINES 0
186 #else
187 #define P_USE_INLINES 0
188 #endif
189 #endif
190 
191 #if P_USE_INLINES
192 #define PINLINE __inline
193 #else
194 #define PINLINE
195 #endif
196 
197 
199 // Handy macros
200 
202 #if _MSC_VER
203  #define PARG_COUNT(...) PARG_COUNT_PART2(PARG_COUNT_PART1(__VA_ARGS__))
204  #define PARG_COUNT_PART1(...) unused, __VA_ARGS__
205  #define PARG_COUNT_PART2(...) PARG_COUNT_PART3(PARG_COUNT_PART4(__VA_ARGS__,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))
206  #define PARG_COUNT_PART3(x) x
207  #define PARG_COUNT_PART4(_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
208 #else
209  #define PARG_COUNT(...) PARG_COUNT_INTERNAL(0,##__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)
210  #define PARG_COUNT_INTERNAL(_0,_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
211 #endif
212 
214 #define P_STRINGISE(v) P_STRINGISE_PART2(v)
215 #define P_STRINGIZE(v) P_STRINGISE_PART2(v)
216 #define P_STRINGISE_PART2(v) #v
217 
229 #define P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, ...) \
230  enum name { firstName = firstValue, Begin##name = firstName, __VA_ARGS__, End##name, countName = End##name-Begin##name }; \
231  friend __inline name operator++(name & e ) { PAssert(e < End##name, PInvalidParameter); return e = (name)(e+1); } \
232  friend __inline name operator++(name & e, int) { PAssert(e < End##name, PInvalidParameter); name o=e; e = (name)(e+1); return o; } \
233  friend __inline name operator--(name & e ) { PAssert(e >= Begin##name, PInvalidParameter); return e = (name)(e-1); } \
234  friend __inline name operator--(name & e, int) { PAssert(e >= Begin##name, PInvalidParameter); name o=e; e = (name)(e-1); return o; } \
235  static __inline name name##FromInt(int v) { return (name)(v < Begin##name ? Begin##name : v >= End##name ? (End##name-1) : v); }
236 
248 #define P_DECLARE_ENUM(name, first, ...) P_DECLARE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
249 
250 extern void PPrintEnum(std::ostream & strm, int e, int begin, int end, char const * const * names);
251 extern int PReadEnum(std::istream & strm, int begin, int end, char const * const * names, bool matchCase = true);
252 extern int PParseEnum(const char * str, int begin, int end, char const * const * names, bool matchCase = true);
253 
254 #define P_ENUM_NAMES_PART1(narg, args)P_ENUM_NAMES_PART2(narg, args)
255 #define P_ENUM_NAMES_PART2(narg, args) P_ENUM_NAMES_ARG_##narg args
256 #define P_ENUM_NAMES_ARG_1(_1 )#_1
257 #define P_ENUM_NAMES_ARG_2(_1,_2 )#_1,#_2
258 #define P_ENUM_NAMES_ARG_3(_1,_2,_3 )#_1,#_2,#_3
259 #define P_ENUM_NAMES_ARG_4(_1,_2,_3,_4 )#_1,#_2,#_3,#_4
260 #define P_ENUM_NAMES_ARG_5(_1,_2,_3,_4,_5 )#_1,#_2,#_3,#_4,#_5
261 #define P_ENUM_NAMES_ARG_6(_1,_2,_3,_4,_5,_6 )#_1,#_2,#_3,#_4,#_5,#_6
262 #define P_ENUM_NAMES_ARG_7(_1,_2,_3,_4,_5,_6,_7 )#_1,#_2,#_3,#_4,#_5,#_6,#_7
263 #define P_ENUM_NAMES_ARG_8(_1,_2,_3,_4,_5,_6,_7,_8 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8
264 #define P_ENUM_NAMES_ARG_9(_1,_2,_3,_4,_5,_6,_7,_8,_9 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9
265 #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
266 #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
267 #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
268 #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
269 #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
270 #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
271 #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
272 #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
273 #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
274 #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
275 #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
276 #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
277 #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
278 #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
279 #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
280 #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
281 #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
282 #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
283 #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
284 #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
285 #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
286 #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
287 #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
288 #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
289 #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
290 #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
291 #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
292 #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
293 #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
294 #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
295 #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
296 
303 #define P_DECLARE_ENUM_NAMES(name, ...) \
304  struct PEnumNames_##name { \
305  static char const * const * Names() { static char const * const Strings[] = { __VA_ARGS__ }; return Strings; } \
306  }; \
307  friend __inline std::ostream & operator<<(std::ostream & strm, name e) \
308  { PPrintEnum(strm, e, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
309  friend __inline std::istream & operator>>(std::istream & strm, name & e) \
310  { e = (name)PReadEnum(strm, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
311  static __inline const char * name##ToString(name e) { return e >= Begin##name && e < End##name ? PAssertNULL(PEnumNames_##name::Names()[e-Begin##name]) : ""; } \
312  static __inline name name##FromString(const char * str, bool matchCase = true) { return (name)PParseEnum(str, Begin##name, End##name, PEnumNames_##name::Names(), matchCase); }
313 
318 #define P_DECLARE_STREAMABLE_ENUM_EX(name, countName, firstName, firstValue, ...) \
319  P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, __VA_ARGS__) \
320  P_DECLARE_ENUM_NAMES(name, #firstName, P_ENUM_NAMES_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__)))
321 
326 #define P_DECLARE_STREAMABLE_ENUM(name, first, ...) P_DECLARE_STREAMABLE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
327 
328 
330 // Declare the debugging support
331 
334 {
335  const char * m_file;
336  unsigned m_line;
337  const char * m_extra; // Function or class name, if available
338 
339  PDebugLocation(const char * extra = NULL) // Not explicit for backward compatibility
340  : m_file(NULL), m_line(0), m_extra(extra) { }
341  PDebugLocation(const char * file, unsigned line, const char * extra = NULL)
342  : m_file(file), m_line(line), m_extra(extra) { }
343  PDebugLocation(const PDebugLocation * location);
344 
345  void PrintOn(ostream & strm, const char * prefix = NULL) const;
346 };
347 
348 __inline ostream & operator<<(ostream & strm, const PDebugLocation & location) { location.PrintOn(strm); return strm; }
349 
350 #define P_DEBUG_LOCATION PDebugLocation(__FILE__, __LINE__)
351 
352 
353 #ifndef P_USE_ASSERTS
354 #define P_USE_ASSERTS 1
355 #endif
356 
357 #if !P_USE_ASSERTS
358 
359 #define PAssert(b, m) (b)
360 #define PAssert2(b, c, m) (b)
361 #define PAssertOS(b) (b)
362 #define PAssertNULL(p) (p)
363 #define PAssertAlways(m) {}
364 #define PAssertAlways2(c, m) {}
365 
366 #else // P_USE_ASSERTS
367 
384 };
385 
386 #define __CLASS__ NULL
387 
388 extern bool PAssertWalksStack;
389 extern unsigned PAssertCount;
390 bool PAssertFunc(const PDebugLocation & location, PStandardAssertMessage msg);
391 bool PAssertFunc(const PDebugLocation & location, const char * msg);
392 
393 
400 #define PAssert(b, msg) ((b)?true:PAssertFunc(PDebugLocation(__FILE__,__LINE__,__CLASS__),(msg)))
401 
409 #define PAssert2(b, cls, msg) ((b)?true:PAssertFunc(PDebugLocation(__FILE__,__LINE__,(cls)),(msg)))
410 
417 #define PAssertOS(b) ((b)?true:PAssertFunc(PDebugLocation(__FILE__,__LINE__,__CLASS__),POperatingSystemError))
418 
428 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
429  (PAssertFunc(PDebugLocation(__FILE__,__LINE__, __CLASS__), PNullPointerReference),(ptr)))
430 
437 #define PAssertAlways(msg) PAssertFunc(PDebugLocation(__FILE__,__LINE__,__CLASS__),(msg))
438 
445 #define PAssertAlways2(cls, msg) PAssertFunc(PDebugLocation(__FILE__,__LINE__,(cls)),(msg))
446 
447 #endif // P_USE_ASSERTS
448 
449 
454 ostream & PGetErrorStream();
455 
459 void PSetErrorStream(ostream * strm );
460 
475 #define PError (PGetErrorStream())
476 
477 
479 // Debug and tracing
480 
481 #ifndef PTRACING
482 #define PTRACING 2
483 #endif
484 
485 #if PTRACING
486 
487 class PObject;
488 class PArgList;
489 
502 class PTrace
503 {
504 public:
506  enum Options {
507  Blocks = 0x0001,
512  DateAndTime = 0x0002,
513  Timestamp = 0x0004,
514  Thread = 0x0008,
515  TraceLevel = 0x0010,
516  FileAndLine = 0x0020,
517  ThreadAddress = 0x0040,
518  AppendToFile = 0x0080,
519  GMTTime = 0x0100,
520  RotateDaily = 0x0200,
521  RotateHourly = 0x0400,
522  RotateMinutely = 0x0800,
523  RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
525  ObjectInstance = 0x1000,
526  ContextIdentifier = 0x2000,
527  SingleLine = 0x4000,
528  SystemLogStream = 0x8000,
531  HasFilePermissions = 0x8000000,
532  FilePermissionMask = 0x7ff0000,
534  FilePermissionShift = 16
535  };
536 
537 
538  #define PTRACE_ARGLIST_OPT_HELP \
539  "use +X or -X to add/remove option where X is one of:\r" \
540  " block PTrace::Block constructs in output\r" \
541  " time time since program start\r" \
542  " date date and time\r" \
543  " gmt Date/time is in UTC\r" \
544  " thread thread name and identifier\r" \
545  " level log level\r" \
546  " source source file name and line number\r" \
547  " object PObject pointer\r" \
548  " context context identifier\r" \
549  " single single line output\r" \
550  " daily rotate output file daily\r" \
551  " hour rotate output file hourly\r" \
552  " minute rotate output file every minute\r" \
553  " append append to output file, otherwise overwrites\r" \
554  " <perm> file permission similar to unix chmod, but starts\r" \
555  " with +/- and only has one combination at a time,\r" \
556  " e.g. +uw is user write, +or is other read, etc"
557 
558  #define PTRACE_ARG_TRACE "trace"
559  #define PTRACE_ARG_LEVEL "trace-level"
560  #define PTRACE_ARG_OUTPUT "output"
561  #define PTRACE_ARG_ROLLOVER "trace-rollover"
562  #define PTRACE_ARG_OPTION "trace-option"
563 
564  #define PTRACE_ARGLIST_EXT(t,l,o,r,O) \
565  t "-" PTRACE_ARG_TRACE ". Trace enable (use multiple times for more detail).\n" \
566  l "-" PTRACE_ARG_LEVEL ": Specify trace detail level.\n" \
567  o "-" PTRACE_ARG_OUTPUT ": Specify filename for trace output\rMay be special value such as \"stderr\" dependent on platform.\n" \
568  r "-" PTRACE_ARG_ROLLOVER ": Specify trace file rollover file name pattern.\n" \
569  O "-" PTRACE_ARG_OPTION ": Specify trace option(s),\r" PTRACE_ARGLIST_OPT_HELP "\n"
570 
571  #define PTRACE_ARGLIST PTRACE_ARGLIST_EXT("t","","o","","")
572 
573  #define PTRACE_INITIALISE(...) PTrace::Initialise(__VA_ARGS__)
574 
578  static void Initialise(
579  const PArgList & args,
580  unsigned options =
581 #ifdef _DEBUG
582  FileAndLine |
583 #endif
584  Timestamp | Thread | Blocks,
585  const char * traceCount = PTRACE_ARG_TRACE,
586  const char * outputFile = PTRACE_ARG_OUTPUT,
587  const char * traceOpts = PTRACE_ARG_OPTION,
588  const char * traceRollover = PTRACE_ARG_ROLLOVER,
589  const char * traceLevel = PTRACE_ARG_LEVEL
590  );
591 
623  static void Initialise(
624  unsigned level,
625  const char * filename = NULL,
626  unsigned options = Timestamp | Thread | Blocks,
627  const char * rolloverPattern = NULL
628  );
629 
630  // Deprecated - for backward compatibility
631  static void Initialise(
632  unsigned level,
633  const char * filename,
634  const char * rolloverPattern,
635  unsigned options = Timestamp | Thread | Blocks
636  ) { Initialise(level, filename, options, rolloverPattern); }
637 
640  static void SetFilename(
641  const char * filename
642  );
643 
648  static const char * GetFilename();
649 
653  static void SetMaxLength(
654  PINDEX length
655  );
656 
660  static PINDEX GetMaxLength();
661 
683  static void SetOptionsByName(
684  const char * options
685  );
686 
689  static std::string GetOptionsByName();
690 
697  static void SetOptions(
698  unsigned options
699  );
700 
709  static void ClearOptions(
710  unsigned options
711  );
712 
718  static unsigned GetOptions();
719 
725  static void SetLevel(
726  unsigned level
727  );
728 
734  static unsigned GetLevel();
735 
740  static PBoolean CanTrace(
741  unsigned level
742  );
743 
748  static void SetStream(
749  ostream * out
750  );
751 
754  static ostream * GetStream();
755 
757  static int GetTimeZone();
758 
761  static ostream & PrintInfo(
762  ostream & strm,
763  bool crlf = true
764  );
765 
781  static ostream & Begin(
782  unsigned level,
783  const char * fileName,
784  int lineNum,
785  const PObject * instance = NULL,
786  const char * module = NULL
787  );
788 
789  static ostream & Begin(
790  unsigned level,
791  const char * fileName,
792  int lineNum,
793  const char * module,
794  const PObject * instance,
795  const char * defModule
796  ) { return Begin(level, fileName, lineNum, instance, module != NULL ? module : defModule); }
797 
798  static ostream & Begin(
799  unsigned level,
800  const char * fileName,
801  int lineNum,
802  const PObject * instance,
803  const PObject * defInstance,
804  const char * module
805  ) { return Begin(level, fileName, lineNum, instance != NULL ? instance : defInstance, module); }
806 
824  static ostream & End(
825  ostream & strm
826  );
827 
833  class Block {
834  public:
836  Block(
837  const char * fileName,
838  int lineNum,
839  const char * traceName
840  );
841  Block(const Block & obj);
842 
844  ~Block();
845 
846  protected:
847  Block & operator=(const Block &)
848  { return *this; }
849  const char * file;
850  int line;
851  const char * name;
852  };
853 
873  {
874  public:
875  ThrottleBase(
876  unsigned lowLevel,
877  unsigned interval = 60000,
878  unsigned highLevel = 6,
879  unsigned maxShown = 1
880  );
881  ThrottleBase(const ThrottleBase & other);
882  ThrottleBase & operator=(const ThrottleBase & other);
883 
884  bool CanTrace(int64_t now = 0);
885  operator unsigned() const { return m_currentLevel; }
886 
887  friend ostream & operator<<(ostream & strm, const ThrottleBase & throttle);
888 
889  __inline unsigned GetLowLevel() const { return m_lowLevel; }
890  __inline unsigned GetHighLevel() const { return m_highLevel; }
891  __inline unsigned GetCurrentLevel() const { return m_currentLevel; }
892  __inline unsigned GetHiddenCount() const { return m_hiddenCount; }
893 
894  protected:
895  unsigned m_interval;
896  unsigned m_lowLevel;
897  unsigned m_highLevel;
898  unsigned m_maxShown;
903  };
904 
908  template <unsigned lowLevel,
909  unsigned interval = 60000,
910  unsigned highLevel = 6,
911  unsigned maxShown = 1
913  {
914  Throttle() : ThrottleBase(lowLevel, interval, highLevel, maxShown) { }
915  };
916 
917  static bool CanTrace(const ThrottleBase & throttle) { return const_cast<ThrottleBase &>(throttle).CanTrace(); }
918 
919  static void WalkStack(
920  ostream & strm,
921  PThreadIdentifier id = PNullThreadIdentifier,
922  PUniqueThreadIdentifier uid = 0,
923  bool noSymbols = false
924  );
925 
926  static unsigned MaxStackWalk; // Default 20
927 
928 #if PTRACING==2
929  static unsigned GetNextContextIdentifier();
930 #endif
931 };
932 
933 /* Macro to conditionally declare a parameter to a function to avoid compiler
934  warning due that parameter only being used in a <code>PTRACE()</code> */
935 #define PTRACE_PARAM(...) __VA_ARGS__
936 
943 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
944 
948 #define PTRACE_LINE() \
949  (PTrace::CanTrace(1)) ? (void)(PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End) : (void)0
950 
951 
952 
953 #define PTRACE_INTERNAL(level, condition, args, ...) \
954  (PTrace::CanTrace(level) condition) ? ((PTrace::Begin(level, __FILE__, __LINE__, __VA_ARGS__) << args << PTrace::End), true) : false
955 
956 #define PTRACE_NO_CONDITION
957 
958 
959 #define PTRACE_PART1(narg, args) PTRACE_PART2(narg, args)
960 #define PTRACE_PART2(narg, args) PTRACE_ARG_##narg args
961 
962 #define PTRACE_ARG_4(level, object, module, args) \
963  PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, module)
964 
965 #define PTRACE_ARG_3(level, objectOrModule, args) \
966  PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
967 
968 #define PTRACE_ARG_2(level, args) \
969  PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, PTraceObjectInstance(), PTraceModule())
970 
971 
972 #define PTRACE_IF_PART1(narg, args) PTRACE_IF_PART2(narg, args)
973 #define PTRACE_IF_PART2(narg, args) PTRACE_IF_ARG_##narg args
974 
975 #define PTRACE_IF_ARG_5(level, condition, object, module, args) \
976  PTRACE_INTERNAL(level, && (condition), args, object, module)
977 
978 #define PTRACE_IF_ARG_4(level, condition, objectOrModule, args) \
979  PTRACE_INTERNAL(level, && (condition), args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
980 
981 #define PTRACE_IF_ARG_3(level, condition, args) \
982  PTRACE_INTERNAL(level, && (condition), args, PTraceObjectInstance(), PTraceModule())
983 
984 
985 #define PTRACE_BEGIN_PART1(narg, args) PTRACE_BEGIN_PART2(narg, args)
986 #define PTRACE_BEGIN_PART2(narg, args) PTRACE_BEGIN_ARG_##narg args
987 
988 #define PTRACE_BEGIN_ARG_3(level, object, module) \
989  PTrace::Begin(level, __FILE__, __LINE__, object, module)
990 
991 #define PTRACE_BEGIN_ARG_2(level, objectOrModule) \
992  PTrace::Begin(level, __FILE__, __LINE__, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
993 
994 #define PTRACE_BEGIN_ARG_1(level) \
995  PTrace::Begin(level, __FILE__, __LINE__, PTraceObjectInstance(), PTraceModule())
996 
997 
998 // Backward compatibility
999 #define PTRACE2(level, object, args) \
1000  PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, PTraceModule())
1001 #define PTRACE_IF2(level, condition, object, args) \
1002  PTRACE_INTERNAL(level, && (condition), args, object, PTraceModule())
1003 
1039 #define PTRACE(...) PTRACE_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
1040 
1053 #define PTRACE_IF(...) PTRACE_IF_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
1054 
1063 #define PTRACE_ONCE(level, ...) \
1064  { \
1065  static PAtomicBoolean firstTrace(true); \
1066  PTRACE_IF((level), firstTrace.TestAndSet(false), __VA_ARGS__); \
1067  }
1068 
1078 #define PTRACE_BEGIN(...) PTRACE_BEGIN_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
1079 
1080 
1081 /* Macro to create a throttle context for use in <code>PTRACE()</code> */
1082 #define PTRACE_THROTTLE(var, ...) PTrace::Throttle<__VA_ARGS__> var
1083 #define PTRACE_THROTTLE_STATIC(var, ...) static PTrace::Throttle<__VA_ARGS__> var
1084 
1085 
1086 __inline const PObject * PTraceObjectInstance() { return NULL; }
1087 __inline static const PObject * PTraceObjectInstance(const void *) { return NULL; }
1088 __inline const char * PTraceModule() { return NULL; }
1089 
1090 
1091 #if PTRACING==2
1092 
1098 #define PTRACE_CONTEXT_ID_NEW() SetTraceContextIdentifier(PTrace::GetNextContextIdentifier())
1099 #define PTRACE_CONTEXT_ID_SET(to, from) PObject::CopyTraceContextIdentifier(to, from)
1100 #define PTRACE_CONTEXT_ID_FROM(obj) SetTraceContextIdentifier(obj)
1101 #define PTRACE_CONTEXT_ID_TO(obj) CopyTraceContextIdentifier(obj)
1102 
1104 {
1105  private:
1106  class PThread * m_currentThread;
1107  unsigned m_savedContextIdentifier;
1108  public:
1109  PTraceSaveContextIdentifier(const PObject & obj);
1110  PTraceSaveContextIdentifier(const PObject * obj);
1112 };
1113 
1114 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj) PTraceSaveContextIdentifier ptraceSavedContextIdentifier(obj)
1115 
1116 #endif // PTRACING==2
1117 
1118 
1119 #define P_DECLARE_TRACED_ENUM P_DECLARE_STREAMABLE_ENUM
1120 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_STREAMABLE_ENUM_EX
1121 
1122 #endif // PTRACING
1123 
1124 #ifndef PTRACE_ARGLIST_EXT
1125 #define PTRACE_ARGLIST_EXT(...) ""
1126 #endif
1127 
1128 #ifndef PTRACE_ARGLIST
1129 #define PTRACE_ARGLIST ""
1130 #endif
1131 
1132 #ifndef PTRACE_INITIALISE
1133 #define PTRACE_INITIALISE(...)
1134 #endif
1135 
1136 #ifndef PTRACE_PARAM
1137 #define PTRACE_PARAM(...)
1138 #endif
1139 
1140 #ifndef PTRACE_BLOCK
1141 #define PTRACE_BLOCK(n)
1142 #endif
1143 
1144 #ifndef PTRACE_LINE
1145 #define PTRACE_LINE()
1146 #endif
1147 
1148 #ifndef PTRACE
1149 #define PTRACE(...)
1150 #endif
1151 
1152 #ifndef PTRACE_IF
1153 #define PTRACE_IF(...)
1154 #endif
1155 
1156 #ifndef PTRACE_BEGIN
1157 #define PTRACE_BEGIN(...)
1158 #endif
1159 
1160 #ifndef PTRACE_THROTTLE
1161 #define PTRACE_THROTTLE(...)
1162 #endif
1163 
1164 #ifndef PTRACE2
1165 #define PTRACE2(level, obj, arg)
1166 #endif
1167 
1168 #ifndef PTRACE_IF2
1169 #define PTRACE_IF2(level, cond, obj, args)
1170 #endif
1171 
1172 #ifndef PTRACE_CONTEXT_ID_NEW
1173 #define PTRACE_CONTEXT_ID_NEW()
1174 #endif
1175 
1176 #ifndef PTRACE_CONTEXT_ID_SET
1177 #define PTRACE_CONTEXT_ID_SET(to, from)
1178 #endif
1179 
1180 #ifndef PTRACE_CONTEXT_ID_FROM
1181 #define PTRACE_CONTEXT_ID_FROM(obj)
1182 #endif
1183 
1184 #ifndef PTRACE_CONTEXT_ID_TO
1185 #define PTRACE_CONTEXT_ID_TO(obj)
1186 #endif
1187 
1188 #ifndef PTRACE_CONTEXT_ID_PUSH_THREAD
1189 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj)
1190 #endif
1191 
1192 #ifndef P_DECLARE_TRACED_ENUM
1193 #define P_DECLARE_TRACED_ENUM P_DECLARE_ENUM
1194 #endif
1195 
1196 #ifndef P_DECLARE_TRACED_ENUM_EX
1197 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_ENUM_EX
1198 #endif
1199 
1200 
1202 
1205 template <typename ValueType, typename AccumType = ValueType>
1207 {
1208 protected:
1209  ValueType m_minimum;
1210  ValueType m_maximum;
1211  AccumType m_accumulator;
1212  unsigned m_count;
1213  std::string m_units;
1214 public:
1215  explicit PMinMaxAvg(const char * units = "")
1216  : m_units(units)
1217  {
1218  Reset();
1219  }
1220 
1221  void Accumulate(const ValueType & value)
1222  {
1223  if (value < m_minimum)
1224  m_minimum = value;
1225  if (value > m_maximum)
1226  m_maximum = value;
1227  m_accumulator += value;
1228  ++m_count;
1229  }
1230 
1231  void Reset()
1232  {
1233  m_minimum = numeric_limits<ValueType>::max();
1234  m_maximum = 0;
1235  m_accumulator = 0;
1236  m_count = 0;
1237  }
1238 
1239  ValueType GetMinimum() const { return m_minimum; }
1240  ValueType GetMaximum() const { return m_maximum; }
1241  ValueType GetAverage() const { return m_count > 0 ? (ValueType)(m_accumulator/m_count) : 0; }
1242  unsigned GetCount() const { return m_count; }
1243 
1244  friend ostream & operator<<(ostream & strm, const PMinMaxAvg & mma)
1245  {
1246  return strm << " min=" << mma.GetMinimum() << mma.m_units << ","
1247  " avg=" << mma.GetAverage() << mma.m_units << ","
1248  " max=" << mma.GetMaximum() << mma.m_units;
1249  }
1250 };
1251 
1252 
1254 // Profiling
1255 
1256 #if defined( __GNUC__) && !defined(__clang__)
1257  #define PPROFILE_EXCLUDE(func) func __attribute__((no_instrument_function))
1258 #else
1259  #define PPROFILE_EXCLUDE(func) func
1260  #ifdef _MSC_VER
1261  #define __PRETTY_FUNCTION__ __FUNCSIG__
1262  #else
1263  #define __PRETTY_FUNCTION__ __FUNCTION__
1264  #endif
1265 #endif
1266 
1267 class PThread;
1268 class PTimeInterval;
1269 
1270 namespace PProfiling
1271 {
1272  __inline uint64_t GetCycles()
1273  {
1274 #if defined(P_HAS_RDTSC)
1275  return __rdtsc();
1276 #elif defined(__i386__) || defined(__x86_64__)
1277  uint32_t l,h;
1278  __asm__ __volatile__ ("rdtsc" : "=a"(l), "=d"(h));
1279  return ((uint64_t)h<<32)|l;
1280 #elif defined(_WIN32)
1281  LARGE_INTEGER li;
1282  QueryPerformanceCounter(&li);
1283  return li.QuadPart;
1284 #elif defined(CLOCK_MONOTONIC)
1285  timespec ts;
1286  clock_gettime(CLOCK_MONOTONIC, &ts);
1287  return ts.tv_sec*1000000000ULL+ts.tv_nsec;
1288 #else
1289  timeval tv;
1290  gettimeofday(&tv, NULL);
1291  return tv.tv_sec*1000000ULL+tv.tv_usec;
1292 #endif
1293  }
1294 
1295  PPROFILE_EXCLUDE(int64_t CyclesToNanoseconds(uint64_t cycles));
1296  PPROFILE_EXCLUDE(float CyclesToSeconds(uint64_t cycles));
1297 
1298 
1299 #if P_PROFILING
1300 
1301  struct Function
1302  {
1303  unsigned m_count;
1304  uint64_t m_sum;
1305  uint64_t m_minimum;
1306  uint64_t m_maximum;
1307 
1308  Function()
1309  : m_count(0)
1310  , m_sum(0)
1311  , m_minimum(std::numeric_limits<uint64_t>::max())
1312  , m_maximum(0)
1313  {
1314  }
1315  };
1316  typedef std::map<std::string, Function> FunctionMap;
1317 
1318  struct Thread
1319  {
1320  std::string m_name;
1321  PThreadIdentifier m_threadId;
1322  PUniqueThreadIdentifier m_uniqueId;
1323  float m_realTime;
1324  float m_systemCPU;
1325  float m_userCPU;
1326  bool m_running;
1327  FunctionMap m_functions;
1328 
1329  Thread(
1330  PThreadIdentifier threadId = PNullThreadIdentifier,
1331  PUniqueThreadIdentifier uniqueId = 0,
1332  const char * name = "",
1333  float realTime = 0,
1334  float systemCPU = 0,
1335  float userCPU = 0
1336  ) : m_name(name)
1337  , m_threadId(threadId)
1338  , m_uniqueId(uniqueId)
1339  , m_realTime(realTime)
1340  , m_systemCPU(systemCPU)
1341  , m_userCPU(userCPU)
1342  , m_running(false)
1343  {
1344  }
1345  };
1346  typedef std::map<PUniqueThreadIdentifier, Thread> ThreadByID;
1347  typedef std::multimap<float, Thread, std::greater<double> > ThreadByUsage; // percentage
1348 
1349  struct Analysis
1350  {
1351  uint64_t m_durationCycles;
1352  unsigned m_functionCount;
1353  ThreadByID m_threadByID;
1354  ThreadByUsage m_threadByUsage;
1355 
1356  Analysis()
1357  : m_durationCycles(0)
1358  , m_functionCount(0)
1359  {
1360  }
1361 
1362  void ToText(ostream & strm) const;
1363  void ToHTML(ostream & strm) const;
1364  };
1365 
1366  void Analyse(Analysis & analysis);
1367  void Analyse(ostream & strm, bool html);
1368 
1370  void Enable(bool enab)
1371  );
1373  bool IsEnabled()
1374  );
1375 
1377  void Reset()
1378  );
1380  void Dump(ostream & strm)
1381  );
1382 
1384  void OnThreadEnded(const PThread & thread, const PTimeInterval & realTime, const PTimeInterval & systemCPU, const PTimeInterval & userCPU)
1385  );
1386 
1388  void PreSystem()
1389  );
1390 
1392  void PostSystem()
1393  );
1394 
1395  class Block
1396  {
1397  public:
1399  Block(
1400  const PDebugLocation & location
1401  )
1402  );
1404  ~Block()
1405  );
1406 
1407  protected:
1408  PDebugLocation m_location;
1409  };
1410 
1411  #define PPROFILE_BLOCK(name) ::PProfiling::Block p_profile_block_instance(PDebugLocation(__FILE,__LINE__, name))
1412  #define PPROFILE_FUNCTION() PPROFILE_BLOCK(__PRETTY_FUNCTION__)
1413 
1414  #define PPROFILE_PRE_SYSTEM() ::PProfiling::PreSystem()
1415  #define PPROFILE_POST_SYSTEM() ::PProfiling::PostSystem()
1416  #define PPROFILE_SYSTEM(...) PPROFILE_PRE_SYSTEM(); __VA_ARGS__; PPROFILE_POST_SYSTEM()
1417 #else
1418  #define PPROFILE_BLOCK(...)
1419  #define PPROFILE_FUNCTION()
1420  #define PPROFILE_PRE_SYSTEM()
1421  #define PPROFILE_POST_SYSTEM()
1422  #define PPROFILE_SYSTEM(...) __VA_ARGS__
1423 #endif
1424 
1425 #if PTRACING
1426 
1431  {
1432  protected:
1433  struct Implementation;
1434  Implementation * const m_implementation;
1435 
1436  private:
1437  void operator=(const TimeScope &) { }
1438 
1439  public:
1443  TimeScope(
1444  const PDebugLocation & location,
1445  unsigned thresholdTime,
1446  unsigned throttleTime = 10000,
1447  unsigned throttledLogLevel = 2,
1448  unsigned unthrottledLogLevel = 6,
1449  unsigned thresholdPercent = 5,
1450  unsigned maxHistory = 0
1451  );
1452  TimeScope(const TimeScope & other);
1453 
1455  ~TimeScope();
1456 
1458  void SetThrottleTime(unsigned throttleTime);
1459 
1461  void SetThrottledLogLevel(unsigned throttledLogLevel);
1462 
1464  void SetUnthrottledLogLevel(unsigned unthrottledLogLevel);
1465 
1467  void SetThresholdPercent(unsigned thresholdPercent);
1468 
1470  void SetMaxHistory(unsigned maxHistory);
1471 
1473  void EndMeasurement(
1474  const void * context,
1475  const PObject * object,
1476  const PDebugLocation * location,
1477  uint64_t startTime
1478  );
1479 
1480  // Get the last measurement duration. Must be after EndMeasurement() is called.
1481  const PTimeInterval & GetLastDuration() const;
1482 
1486  class Measure
1487  {
1488  protected:
1490  const void * const m_context;
1491  const PObject * const m_object;
1492  uint64_t const m_startCycle;
1493 
1494  public:
1495  Measure(TimeScope & scope, const PObject * object)
1496  : m_scope(scope)
1497  , m_context(object)
1498  , m_object(object)
1499  , m_startCycle(GetCycles())
1500  {
1501  }
1502 
1503  Measure(TimeScope & scope, const void * context)
1504  : m_scope(scope)
1505  , m_context(context)
1506  , m_object(NULL)
1507  , m_startCycle(GetCycles())
1508  {
1509  }
1510 
1512  {
1513  m_scope.EndMeasurement(m_context, m_object, NULL, m_startCycle);
1514  }
1515  };
1516  };
1517 
1518  #define PPROFILE_TIMESCOPE(name, context, ...) \
1519  static ::PProfiling::TimeScope p_profile_timescope_static_instance##name(PDebugLocation(__FILE__, __LINE__, #name), __VA_ARGS__); \
1520  ::PProfiling::TimeScope::Measure p_profile_timescope_instance##name(p_profile_timescope_static_instance##name, context)
1521 #else
1522  #define PPROFILE_TIMESCOPE(...)
1523 #endif // PTRACING
1524 
1526  {
1527  std::string m_name;
1530 
1531  HighWaterMarkData(const std::string & name);
1532  void NewInstance();
1533  static HighWaterMarkData & Get(const type_info & ti);
1534  static std::map<std::string, unsigned> Get();
1535  };
1536 
1537  template <class CLS> struct HighWaterMark
1538  {
1539  static HighWaterMarkData & GetHighWaterMarkData() { static HighWaterMarkData & data = HighWaterMarkData::Get(typeid(CLS)); return data; }
1540  HighWaterMark() { GetHighWaterMarkData().NewInstance(); }
1541  ~HighWaterMark() { --GetHighWaterMarkData().m_totalCount; }
1542  };
1543 };
1544 
1545 
1547 // Memory management
1548 
1549 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1550 
1551 #define PMEMORY_HEAP 1
1552 
1560  protected:
1562  PMemoryHeap();
1563 
1564  public:
1565  // Clear up the memory checking subsystem, dumping memory leaks.
1566  ~PMemoryHeap();
1567 
1574  static void * Allocate(
1575  size_t nSize,
1576  const char * file,
1577  int line,
1578  const char * className
1579  );
1580 
1587  static void * Allocate(
1588  size_t count,
1589  size_t iSize,
1590  const char * file,
1591  int line
1592  );
1593 
1601  static void * Reallocate(
1602  void * ptr,
1603  size_t nSize,
1604  const char * file,
1605  int line
1606  );
1607 
1613  static void Deallocate(
1614  void * ptr,
1615  const char * className
1616  );
1617 
1620  enum Validation {
1621  Ok, // All good.
1622  Bad, // Bad pointer, not allocated by us, double deletion or just random address.
1623  Trashed, // Heap is trashed, linked list failed.
1624  Corrupt, // Corrupted guard bytes or object.
1625  Inactive // Heap checking disabled or after final destruction.
1626  };
1634  static Validation Validate(
1635  const void * ptr,
1636  const char * className,
1637  ostream * error
1638  );
1639 
1644  static PBoolean ValidateHeap(
1645  ostream * error = NULL
1646  );
1647 
1653  static PBoolean SetIgnoreAllocations(
1654  PBoolean ignore
1655  );
1656 
1660  static void DumpStatistics();
1664  static void DumpStatistics(ostream & strm );
1665 
1666  typedef unsigned alloc_t;
1667 
1668 #if PMEMORY_CHECK
1669  struct State {
1671  };
1672 #else
1673  typedef _CrtMemState State;
1674 #endif
1675 
1676  /* Get memory state.
1677  This returns a state that may be used to determine where to start dumping
1678  objects from.
1679  */
1680  static void GetState(
1681  State & state
1682  );
1683 
1691  static void DumpObjectsSince(
1692  const State & when
1693  );
1694 
1700  static void DumpObjectsSince(
1701  const State & when,
1702  ostream & strm
1703  );
1704 
1710  static void SetAllocationBreakpoint(
1711  alloc_t point
1712  );
1713 
1714 #if PMEMORY_CHECK
1715 
1716  protected:
1717  static PMemoryHeap & GetInstance();
1718 
1719  void * InternalAllocate(
1720  size_t nSize, // Number of bytes to allocate.
1721  const char * file, // Source file name for allocating function.
1722  int line, // Source file line for allocating function.
1723  const char * className, // Class name for allocating function.
1724  bool zeroFill // FIll with zeros
1725  );
1726  void * InternalReallocate(
1727  void * ptr, // Pointer to memory block to reallocate
1728  size_t nSize, // Number of bytes to allocate.
1729  const char * file, // Source file name for allocating function.
1730  int line // Source file line for allocating function.
1731  );
1732  void InternalDeallocate(
1733  void * ptr,
1734  const char * className
1735  );
1736  Validation InternalValidate(
1737  const void * ptr, // Pointer to memory block to check
1738  const char * className, // Class name it should be.
1739  ostream * error // Stream to receive error message (may be NULL)
1740  );
1741  bool InternalValidateHeap(ostream * error);
1742  void InternalDumpStatistics(ostream & strm);
1743  void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
1744 
1745  enum Flags {
1746  NoLeakPrint = 1
1747  };
1748 
1749 #pragma pack(1)
1750  struct Header {
1751  enum {
1752  // Assure that the Header struct is aligned to 8 byte boundary
1753  NumGuardBytes = 16 - (sizeof(Header *) +
1754  sizeof(Header *) +
1755  sizeof(const char *) +
1756  sizeof(const char *) +
1757  sizeof(size_t) +
1758  sizeof(alloc_t) +
1759  sizeof(uint16_t) +
1760  sizeof(uint8_t) +
1761  sizeof(PThreadIdentifier)
1762  )%8
1763  };
1764 
1767  const char * m_className;
1768  const char * m_fileName;
1769  size_t m_size;
1771  uint16_t m_line;
1772  uint8_t m_flags;
1773  PThreadIdentifier m_threadId;
1774  char m_guard[NumGuardBytes];
1775 
1776  static char GuardBytes[NumGuardBytes];
1777  };
1778 #pragma pack()
1779 
1780  enum {
1781  e_Destroyed =-1,
1784  e_Active
1785  } m_state;
1786 
1789 
1793  uint8_t m_flags;
1794 
1797 
1803 
1804  ostream * m_leakDumpStream;
1805 
1806  void Lock();
1807  void Unlock();
1808 #if defined(_WIN32)
1809  CRITICAL_SECTION m_mutex;
1810 #elif defined(P_PTHREADS)
1811  pthread_mutex_t m_mutex;
1812 #elif defined(P_VXWORKS)
1813  void * m_mutex;
1814 #endif
1815 
1816 #else
1817 
1818  static void CreateInstance();
1819 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
1820  _CrtMemState initialState;
1821 
1822 #endif // PMEMORY_CHECK
1823 };
1824 
1825 
1830 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
1831 
1836 inline void runtime_free(void * ptr ) { free(ptr); }
1837 
1838 
1845 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
1846 
1853 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
1854 
1861 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
1862 
1863 
1870 #define free(p) PMemoryHeap::Deallocate(p, NULL)
1871 
1872 
1879 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
1880 
1881 
1896 #define PNEW new (__FILE__, __LINE__)
1897 
1898 #if !defined(_MSC_VER) || _MSC_VER<1200
1899 #define PSPECIAL_DELETE_FUNCTION
1900 #else
1901 #define PSPECIAL_DELETE_FUNCTION \
1902  void operator delete(void * ptr, const char *, int) \
1903  { PMemoryHeap::Deallocate(ptr, Class()); } \
1904  void operator delete[](void * ptr, const char *, int) \
1905  { PMemoryHeap::Deallocate(ptr, Class()); }
1906 #endif
1907 
1908 #define PNEW_AND_DELETE_FUNCTIONS(align) \
1909  void * operator new(size_t nSize, const char * file, int line) \
1910  { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1911  void * operator new(size_t nSize) \
1912  { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1913  void operator delete(void * ptr) \
1914  { PMemoryHeap::Deallocate(ptr, Class()); } \
1915  void * operator new(size_t, void * placement) \
1916  { return placement; } \
1917  void operator delete(void *, void *) \
1918  { } \
1919  void * operator new[](size_t nSize, const char * file, int line) \
1920  { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1921  void * operator new[](size_t nSize) \
1922  { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1923  void operator delete[](void * ptr) \
1924  { PMemoryHeap::Deallocate(ptr, Class()); } \
1925  PSPECIAL_DELETE_FUNCTION
1926 
1927 
1928 inline void * operator new(size_t nSize, const char * file, int line)
1929  { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
1930 
1931 inline void * operator new[](size_t nSize, const char * file, int line)
1932  { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
1933 
1934 #ifndef __GNUC__
1935 P_PUSH_MSVC_WARNINGS(28251)
1936 void * operator new(size_t nSize);
1937 void * operator new[](size_t nSize);
1939 
1940 void operator delete(void * ptr);
1941 void operator delete[](void * ptr);
1942 
1943 #if defined(_MSC_VER) && _MSC_VER>=1200
1944 inline void operator delete(void * ptr, const char *, int)
1945  { PMemoryHeap::Deallocate(ptr, NULL); }
1946 
1947 inline void operator delete[](void * ptr, const char *, int)
1948  { PMemoryHeap::Deallocate(ptr, NULL); }
1949 #endif
1950 #endif
1951 
1952 
1954 public:
1955  PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(true)) { }
1957 private:
1958  PBoolean previousIgnoreAllocations;
1959 };
1960 
1961 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
1962 
1964 public:
1966  {
1968  }
1969 };
1970 
1971 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
1972 
1973 
1974 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1975 
1976 #define PMEMORY_HEAP 0
1977 
1978 #define PNEW new
1979 
1980 #if _MSC_VER < 1800
1981  #define PNEW_AND_DELETE_FUNCTIONS(align)
1982 #else
1983  #define PNEW_AND_DELETE_FUNCTIONS_ALIGNED(align) \
1984  void * operator new(size_t nSize) \
1985  { return _aligned_malloc(nSize, align); } \
1986  void operator delete(void * ptr) \
1987  { _aligned_free(ptr); } \
1988  void * operator new(size_t, void * placement) \
1989  { return placement; } \
1990  void operator delete(void *, void *) \
1991  { } \
1992  void * operator new[](size_t nSize) \
1993  { return _aligned_malloc(nSize, align); } \
1994  void operator delete[](void * ptr) \
1995  { _aligned_free(ptr); }
1996 
1997  #define PNEW_AND_DELETE_FUNCTIONS64 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(64)
1998  #define PNEW_AND_DELETE_FUNCTIONS32 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(32)
1999  #define PNEW_AND_DELETE_FUNCTIONS16 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(16)
2000  #define PNEW_AND_DELETE_FUNCTIONS8 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(8)
2001  #define PNEW_AND_DELETE_FUNCTIONS4 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(4)
2002  #define PNEW_AND_DELETE_FUNCTIONS2 PNEW_AND_DELETE_FUNCTIONS_ALIGNED(2)
2003  #define PNEW_AND_DELETE_FUNCTIONS0
2004  #define PNEW_AND_DELETE_FUNCTIONS(align) PNEW_AND_DELETE_FUNCTIONS##align
2005 #endif
2006 
2007 #define runtime_malloc(s) malloc(s)
2008 #define runtime_free(p) free(p)
2009 
2010 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
2011 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
2012 
2013 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
2014 
2015 
2016 void PThreadYield();
2017 
2019 
2020 template<class Type> Type * PSingletonCreatorDefault()
2021 {
2022  return new Type();
2023 }
2024 
2044 template <class Type, typename GuardType = unsigned, Type * (*Creator)() = PSingletonCreatorDefault<Type> >
2046 {
2047  protected:
2048  Type * m_instance;
2049  public:
2051  {
2052  static auto_ptr<Type> s_pointer;
2053  static GuardType s_guard(0);
2054  if (s_guard++ != 0) {
2055  s_guard = 1;
2056  while ((m_instance = s_pointer.get()) == NULL)
2057  PThreadYield();
2058  }
2059  else {
2060 #if PMEMORY_HEAP
2061  // Do this to make sure debugging is initialised as early as possible
2062  PMemoryHeap::Validate(NULL, NULL, NULL);
2063 #endif
2064  s_pointer.reset(Creator());
2065  m_instance = s_pointer.get();
2066  }
2067  }
2068 
2069  Type * operator->() const { return m_instance; }
2070  Type & operator* () const { return *m_instance; }
2071 };
2072 
2073 
2074 // Template class for thread safe singleton
2075 template <class Type, Type * (*Creator)() = PSingletonCreatorDefault<Type> >
2076 class PSafeSingleton : public PSingleton<Type, atomic<unsigned>, Creator>
2077 {
2078 };
2079 
2080 
2082 // Memory pool allocators
2083 
2084 #if P_GNU_ALLOCATOR
2085 
2086  #include <ext/mt_allocator.h>
2087 
2088  /* Need this tempalte class specialisation of standard class to do the
2089  de-allocation of the pool memory. As per:
2090  http://gcc.gnu.org/viewcvs/trunk/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?view=markup
2091  */
2092  template <bool _Thread>
2093  struct PMemoryPool : public __gnu_cxx::__pool<_Thread>
2094  {
2095  PMemoryPool()
2096  : __gnu_cxx::__pool<_Thread>()
2097  {
2098  }
2099 
2100  PMemoryPool(const __gnu_cxx::__pool_base::_Tune& t)
2101  : __gnu_cxx::__pool<_Thread>(t)
2102  {
2103  }
2104  };
2105 
2106  #if P_GNU_ALLOCATOR==1
2107  /*Do this template class specialisation so each type has it's own separate
2108  memory block for the pool. */
2109  template <class Type>
2110  struct PCommonPool : public __gnu_cxx::__common_pool_policy<PMemoryPool, true>
2111  {
2112  };
2113 
2114  template <class Type>
2115  struct PFixedPoolAllocator : public PSingleton<__gnu_cxx::__mt_alloc<Type, PCommonPool<Type> > >
2116  {
2117  };
2118  #else
2119  #include <ext/bitmap_allocator.h>
2120  template <class Type>
2121  struct PFixedPoolAllocator : public PSingleton<__gnu_cxx::bitmap_allocator<Type> >
2122  {
2123  };
2124  #endif
2125 
2126  #define PDECLARE_POOL_ALLOCATOR(cls) \
2127  void * cls::operator new(size_t) { return PFixedPoolAllocator<cls>()->allocate(1); } \
2128  void * cls::operator new(size_t, const char *, int) { return PFixedPoolAllocator<cls>()->allocate(1); } \
2129  void cls::operator delete(void * ptr) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); } \
2130  void cls::operator delete(void * ptr, const char *, int) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); }
2131 
2132 #else
2133 
2134  #define PDECLARE_POOL_ALLOCATOR(cls) \
2135  virtual ~cls() { } \
2136  __inline static const char * Class() { return typeid(cls).name(); } \
2137  PNEW_AND_DELETE_FUNCTIONS(0)
2138 
2139  #define PDEFINE_POOL_ALLOCATOR(cls)
2140 
2141 #endif
2142 
2143 
2144 #define PCLASSINFO_ALIGNED(cls, par, align) \
2145  public: \
2146  typedef cls P_thisClass; \
2147  __inline static const char * Class() { return typeid(cls).name(); } \
2148  __inline bool IsClass(const char * name) const { return strcmp(name, Class()) == 0; } \
2149  virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
2150  { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
2151  PNEW_AND_DELETE_FUNCTIONS(align)
2152 
2153 
2164 #define PCLASSINFO(cls, par) PCLASSINFO_ALIGNED(cls, (par), 0)
2165 
2167 #define PCLASSINFO_WITH_CLONE(cls, par) \
2168  PCLASSINFO(cls, par) \
2169  virtual PObject * Clone() const { return new cls(*this); }
2170 
2171 
2172 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
2173 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
2174 
2175 #if P_USE_ASSERTS
2176 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
2177  { if (obj == NULL) PAssertFunc(PDebugLocation(file, line, obj->Class()), PInvalidCast); return obj; }
2178 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
2179 #else
2180 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
2181 #endif
2182 
2183 
2192 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
2193 #ifdef DOC_PLUS_PLUS
2194 } Match previous opening brace in doc++
2195 #endif
2196 
2198 // The root of all evil ... umm classes
2199 
2204 class PObject {
2205  protected:
2207 #if PTRACING==2
2208  public:
2211  __inline unsigned GetTraceContextIdentifier() const { return m_traceContextIdentifier; }
2212  __inline void SetTraceContextIdentifier(unsigned id) { m_traceContextIdentifier = id; }
2214  __inline void SetTraceContextIdentifier(const PObject * obj) { if (obj != NULL) m_traceContextIdentifier = obj->m_traceContextIdentifier; }
2216  __inline void CopyTraceContextIdentifier(PObject * obj) const { if (obj != NULL) obj->m_traceContextIdentifier = m_traceContextIdentifier; }
2217  __inline static void CopyTraceContextIdentifier(PObject & to, const PObject & from) { to.SetTraceContextIdentifier(from); }
2218  __inline static void CopyTraceContextIdentifier(PObject & to, const PObject * from) { to.SetTraceContextIdentifier(from); }
2219  __inline static void CopyTraceContextIdentifier(PObject * to, const PObject & from) { from.CopyTraceContextIdentifier(to); }
2220  __inline static void CopyTraceContextIdentifier(PObject * to, const PObject * from) { if (to != NULL) to->SetTraceContextIdentifier(from); }
2221 #endif // PTRACING==2
2222 
2223  protected:
2229  { }
2230 
2231  public:
2232  /* Destructor required to get the "virtual". A PObject really has nothing
2233  to destroy.
2234  */
2235  virtual ~PObject() { }
2236 
2237  // Backward compatibility, use RTTI from now on!
2238  __inline static const char * Class() { return typeid(PObject).name(); }
2239  __inline const char * GetClass() const { return typeid(const_cast<PObject &>(*this)).name(); }
2240  __inline bool IsClass(const char * name) const { return strcmp(name, Class()) == 0; }
2241 
2242  __inline const PObject * PTraceObjectInstance() const { return this; }
2243  __inline static const PObject * PTraceObjectInstance(const char *) { return NULL; }
2244  __inline static const PObject * PTraceObjectInstance(const PObject * obj) { return obj; }
2245 
2251  enum Comparison {
2252  LessThan = -1,
2253  EqualTo = 0,
2255  };
2256 
2258  template<typename T> static Comparison Compare2(T v1, T v2)
2259  {
2260  if (v1 < v2)
2261  return LessThan;
2262  if (v1 > v2)
2263  return GreaterThan;
2264  return EqualTo;
2265  }
2266 
2278  virtual Comparison Compare(
2279  const PObject & obj // Object to compare against.
2280  ) const;
2281 
2294  const PObject & obj // Object to compare against.
2295  ) const;
2296 
2299  const PObject * obj1,
2300  const PObject * obj2,
2301  PINDEX size
2302  );
2303 
2310  const PObject & obj // Object to compare against.
2311  ) const { return Compare(obj) == EqualTo; }
2312 
2319  const PObject & obj // Object to compare against.
2320  ) const { return Compare(obj) != EqualTo; }
2321 
2328  const PObject & obj // Object to compare against.
2329  ) const { return Compare(obj) == LessThan; }
2330 
2337  const PObject & obj // Object to compare against.
2338  ) const { return Compare(obj) == GreaterThan; }
2339 
2346  const PObject & obj // Object to compare against.
2347  ) const { return Compare(obj) != GreaterThan; }
2348 
2355  const PObject & obj // Object to compare against.
2356  ) const { return Compare(obj) != LessThan; }
2358 
2367  virtual void PrintOn(
2368  ostream &strm // Stream to print the object into.
2369  ) const;
2370 
2377  virtual void ReadFrom(
2378  istream &strm // Stream to read the objects contents from.
2379  );
2380 
2381 
2387  inline friend ostream & operator<<(
2388  ostream &strm,
2389  const PObject & obj
2390  ) { obj.PrintOn(strm); return strm; }
2391 
2397  inline friend istream & operator>>(
2398  istream &strm,
2399  PObject & obj
2400  ) { obj.ReadFrom(strm); return strm; }
2401 
2402 
2417  virtual PObject * Clone() const;
2418 
2421  template <class CLS>
2422  CLS * CloneAs() const
2423  {
2424  PObject * clone = Clone();
2425  CLS * obj = dynamic_cast<CLS *>(clone);
2426  if (obj != NULL)
2427  return obj;
2428  delete clone;
2429  return NULL;
2430  }
2431 
2443  virtual PINDEX HashFunction() const;
2445 };
2446 
2448 // Platform independent types
2449 
2450 // All these classes encapsulate primitive types such that they may be
2451 // transfered in a platform independent manner. In particular it is used to
2452 // do byte swapping for little endien and big endien processor architectures
2453 // as well as accommodating structure packing rules for memory structures.
2454 
2455 #define PANSI_CHAR 1
2456 #define PLITTLE_ENDIAN 2
2457 #define PBIG_ENDIAN 3
2458 
2459 
2460 template <typename type>
2462  __inline PIntSameOrder() : data(0) { }
2463  __inline PIntSameOrder(type value) : data(value) { }
2464  __inline PIntSameOrder(const PIntSameOrder & value) : data(value.data) { }
2465  __inline PIntSameOrder & operator=(type value) { data = value; return *this; }
2466  __inline PIntSameOrder & operator=(const PIntSameOrder & value) { data = value.data; return *this; }
2467  __inline operator type() const { return data; }
2468  __inline friend ostream & operator<<(ostream & s, const PIntSameOrder & v) { return s << v.data; }
2469  __inline friend istream & operator>>(istream & s, PIntSameOrder & v) { return s >> v.data; }
2470 
2471  private:
2472  type data;
2473 };
2474 
2475 
2476 template <typename type>
2478  __inline PIntReversedOrder() : data(0) { }
2479  __inline PIntReversedOrder(type value) : data(ReverseBytes(value)) { }
2480  __inline PIntReversedOrder(const PIntReversedOrder & value) : data(value.data) { }
2481  __inline PIntReversedOrder & operator=(type value) { data = ReverseBytes(value); return *this; }
2482  __inline PIntReversedOrder & operator=(const PIntReversedOrder & value) { data = value.data; return *this; }
2483  __inline operator type() const { return ReverseBytes(data); }
2484  __inline friend ostream & operator<<(ostream & s, const PIntReversedOrder & value) { return s << ReverseBytes(value.data); }
2485  __inline friend istream & operator>>(istream & s, PIntReversedOrder & value) { type i; s >> i; value = i; return s; }
2486 
2487  private:
2488  type data;
2489 
2490 #if _MSC_VER
2491 __inline static int8_t ReverseBytes(const int8_t src) { return src; }
2492 __inline static uint8_t ReverseBytes(const uint8_t src) { return src; }
2493 __inline static int16_t ReverseBytes(const int16_t src) { return _byteswap_ushort(src); }
2494 __inline static uint16_t ReverseBytes(const uint16_t src) { return _byteswap_ushort(src); }
2495 __inline static int32_t ReverseBytes(const int32_t src) { return _byteswap_ulong(src); }
2496 __inline static uint32_t ReverseBytes(const uint32_t src) { return _byteswap_ulong(src); }
2497 __inline static int64_t ReverseBytes(const int64_t src) { return _byteswap_uint64(src); }
2498 __inline static uint64_t ReverseBytes(const uint64_t src) { return _byteswap_uint64(src); }
2499 __inline static float ReverseBytes(const float src) { uint32_t dst = ReverseBytes(*(uint32_t *)&src); return *(float *)&dst; }
2500 __inline static double ReverseBytes(const double src) { uint64_t dst = ReverseBytes(*(uint64_t *)&src); return *(double *)&dst; }
2501 #elif __GLIBC__
2502 __inline static int8_t ReverseBytes(const int8_t src) { return src; }
2503 __inline static uint8_t ReverseBytes(const uint8_t src) { return src; }
2504 __inline static int16_t ReverseBytes(const int16_t src) { return __bswap_16(src); }
2505 __inline static uint16_t ReverseBytes(const uint16_t src) { return __bswap_16(src); }
2506 __inline static int32_t ReverseBytes(const int32_t src) { return __bswap_32(src); }
2507 __inline static uint32_t ReverseBytes(const uint32_t src) { return __bswap_32(src); }
2508 __inline static int64_t ReverseBytes(const int64_t src) { return __bswap_64(src); }
2509 __inline static uint64_t ReverseBytes(const uint64_t src) { return __bswap_64(src); }
2510 __inline static float ReverseBytes(const float src) { uint32_t dst = ReverseBytes(*(uint32_t *)&src); return *(float *)&dst; }
2511 __inline static double ReverseBytes(const double src) { uint64_t dst = ReverseBytes(*(uint64_t *)&src); return *(double *)&dst; }
2512 #else
2513  static __inline type ReverseBytes(const type & src)
2514  {
2515  type dst;
2516  size_t s = sizeof(type)-1;
2517  for (size_t d = 0; d < sizeof(type); ++d,--s)
2518  ((BYTE *)&dst)[d] = ((const BYTE *)&src)[s];
2519  return dst;
2520  }
2521 #endif
2522 };
2523 
2524 #ifndef PCHAR8
2525 #define PCHAR8 PANSI_CHAR
2526 #endif
2527 
2528 #if PCHAR8==PANSI_CHAR
2530 #endif
2531 
2533 
2535 
2536 #if PBYTE_ORDER==PLITTLE_ENDIAN
2537 typedef PIntSameOrder<int16_t> PInt16l;
2538 #elif PBYTE_ORDER==PBIG_ENDIAN
2539 typedef PIntReversedOrder<int16_t> PInt16l;
2540 #endif
2541 
2542 #if PBYTE_ORDER==PLITTLE_ENDIAN
2543 typedef PIntReversedOrder<int16_t> PInt16b;
2544 #elif PBYTE_ORDER==PBIG_ENDIAN
2545 typedef PIntSameOrder<int16_t> PInt16b;
2546 #endif
2547 
2548 #if PBYTE_ORDER==PLITTLE_ENDIAN
2549 typedef PIntSameOrder<uint16_t> PUInt16l;
2550 #elif PBYTE_ORDER==PBIG_ENDIAN
2551 typedef PIntReversedOrder<uint16_t> PUInt16l;
2552 #endif
2553 
2554 #if PBYTE_ORDER==PLITTLE_ENDIAN
2555 typedef PIntReversedOrder<uint16_t> PUInt16b;
2556 #elif PBYTE_ORDER==PBIG_ENDIAN
2557 typedef PIntSameOrder<uint16_t> PUInt16b;
2558 #endif
2559 
2560 #if PBYTE_ORDER==PLITTLE_ENDIAN
2561 typedef PIntSameOrder<int32_t> PInt32l;
2562 #elif PBYTE_ORDER==PBIG_ENDIAN
2563 typedef PIntReversedOrder<int32_t> PInt32l;
2564 #endif
2565 
2566 #if PBYTE_ORDER==PLITTLE_ENDIAN
2567 typedef PIntReversedOrder<int32_t> PInt32b;
2568 #elif PBYTE_ORDER==PBIG_ENDIAN
2569 typedef PIntSameOrder<PInt32> int32_t;
2570 #endif
2571 
2572 #if PBYTE_ORDER==PLITTLE_ENDIAN
2573 typedef PIntSameOrder<uint32_t> PUInt32l;
2574 #elif PBYTE_ORDER==PBIG_ENDIAN
2575 typedef PIntReversedOrder<uint32_t> PUInt32l;
2576 #endif
2577 
2578 #if PBYTE_ORDER==PLITTLE_ENDIAN
2579 typedef PIntReversedOrder<uint32_t> PUInt32b;
2580 #elif PBYTE_ORDER==PBIG_ENDIAN
2581 typedef PIntSameOrder<uint32_t> PUInt32b;
2582 #endif
2583 
2584 #if PBYTE_ORDER==PLITTLE_ENDIAN
2585 typedef PIntSameOrder<int64_t> PInt64l;
2586 #elif PBYTE_ORDER==PBIG_ENDIAN
2587 typedef PIntReversedOrder<int64_t> PInt64l;
2588 #endif
2589 
2590 #if PBYTE_ORDER==PLITTLE_ENDIAN
2591 typedef PIntReversedOrder<int64_t> PInt64b;
2592 #elif PBYTE_ORDER==PBIG_ENDIAN
2593 typedef PIntSameOrder<int64_t> PInt64b;
2594 #endif
2595 
2596 #if PBYTE_ORDER==PLITTLE_ENDIAN
2597 typedef PIntSameOrder<uint64_t> PUInt64l;
2598 #elif PBYTE_ORDER==PBIG_ENDIAN
2599 typedef PIntReversedOrder<uint64_t> PUInt64l;
2600 #endif
2601 
2602 #if PBYTE_ORDER==PLITTLE_ENDIAN
2603 typedef PIntReversedOrder<uint64_t> PUInt64b;
2604 #elif PBYTE_ORDER==PBIG_ENDIAN
2605 typedef PIntSameOrder<uint64_t> PUInt64b;
2606 #endif
2607 
2608 #if PBYTE_ORDER==PLITTLE_ENDIAN
2609 typedef PIntSameOrder<float> PFloat32l;
2610 #elif PBYTE_ORDER==PBIG_ENDIAN
2611 typedef PIntReversedOrder<float> PFloat32l;
2612 #endif
2613 
2614 #if PBYTE_ORDER==PLITTLE_ENDIAN
2615 typedef PIntReversedOrder<float> PFloat32b;
2616 #elif PBYTE_ORDER==PBIG_ENDIAN
2617 typedef PIntSameOrder<float> PFloat32b;
2618 #endif
2619 
2620 #if PBYTE_ORDER==PLITTLE_ENDIAN
2621 typedef PIntSameOrder<double> PFloat64l;
2622 #elif PBYTE_ORDER==PBIG_ENDIAN
2623 typedef PIntReversedOrder<double> PFloat64l;
2624 #endif
2625 
2626 #if PBYTE_ORDER==PLITTLE_ENDIAN
2627 typedef PIntReversedOrder<double> PFloat64b;
2628 #elif PBYTE_ORDER==PBIG_ENDIAN
2629 typedef PIntSameOrder<double> PFloat64b;
2630 #endif
2631 
2632 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
2633 #if PBYTE_ORDER==PLITTLE_ENDIAN
2634 typedef PIntSameOrder<long double> PFloat80l;
2635 #elif PBYTE_ORDER==PBIG_ENDIAN
2636 typedef PIntReversedOrder<long double> PFloat80l;
2637 #endif
2638 
2639 #if PBYTE_ORDER==PLITTLE_ENDIAN
2640 typedef PIntReversedOrder<long double> PFloat80b;
2641 #elif PBYTE_ORDER==PBIG_ENDIAN
2642 typedef PIntSameOrder<long double> PFloat80b;
2643 #endif
2644 #endif
2645 
2646 typedef intptr_t P_INT_PTR;
2647 
2648 #if defined(_MSC_VER)
2649 #define P_ALIGN_FIELD(fieldType,fieldName,alignment) fieldType __declspec(align(alignment)) fieldName
2650 #elif defined(__GNUC__)
2651 #define P_ALIGN_FIELD(fieldType,fieldName,alignment) fieldType fieldName __attribute__ ((aligned(alignment)))
2652 #endif
2653 
2654 typedef intptr_t P_INT_PTR;
2655 
2657 // Miscellaneous
2658 
2659 /*$MACRO PARRAYSIZE(array)
2660  This macro is used to calculate the number of array elements in a static
2661  array.
2662  */
2663 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
2664 
2665 /*$MACRO PMIN(v1, v2)
2666  This macro is used to calculate the minimum of two values.
2667  Maps to std::min and is for backward compatibility only.
2668  */
2669 #define PMIN(v1, v2) std::min(v1, v2)
2670 
2671 /*$MACRO PMAX(v1, v2)
2672  This macro is used to calculate the maximum of two values.
2673  Maps to std::max and is for backward compatibility only.
2674  */
2675 #define PMAX(v1, v2) std::max(v1, v2)
2676 
2677 /*$MACRO PABS(val)
2678  This macro is used to calculate an absolute value.
2679  Maps to std::abs and is for backward compatibility only.
2680  */
2681 #define PABS(v) std::abs(v)
2682 
2683 
2684 #endif // PTLIB_OBJECT_H
2685 
2686 
2687 // End Of File ///////////////////////////////////////////////////////////////
Options
Options for trace output.
Definition: object.h:506
Memory heap checking class.
Definition: object.h:1559
Information about a source file location.
Definition: object.h:333
__inline std::ostream & operator<<(std::ostream &strm, const PHashTableList &hash)
Definition: dict.h:180
uint64_t const m_startCycle
Definition: object.h:1492
static void Deallocate(void *ptr, const char *className)
Free a memory block.
Definition: object.h:1783
alloc_t m_firstRealObject
Definition: object.h:1792
__inline void CopyTraceContextIdentifier(PObject *obj) const
Definition: object.h:2216
AccumType m_accumulator
Definition: object.h:1211
atomic< unsigned > m_hiddenCount
Definition: object.h:902
__inline PIntReversedOrder & operator=(const PIntReversedOrder &value)
Definition: object.h:2482
Class to encapsulate tracing functions.
Definition: object.h:502
static Validation Validate(const void *ptr, const char *className, ostream *error)
Validate the memory pointer.
const char * name
Definition: object.h:851
Definition: object.h:2253
CLS * CloneAs() const
As for Clone() but converts to specified type.
Definition: object.h:2422
static __inline const PObject * PTraceObjectInstance(const PObject *obj)
Definition: object.h:2244
virtual Comparison CompareObjectMemoryDirect(const PObject &obj) const
Determine the byte wise comparison of two objects.
__inline friend ostream & operator<<(ostream &s, const PIntSameOrder &v)
Definition: object.h:2468
This class defines an arbitrary time interval to millisecond accuracy.
Definition: timeint.h:51
Throttle()
Definition: object.h:914
__inline void SetTraceContextIdentifier(unsigned id)
Definition: object.h:2212
#define PTRACE_ARG_LEVEL
Definition: object.h:559
__inline const char * GetClass() const
Definition: object.h:2239
Definition: object.h:2477
static void * Allocate(size_t nSize, const char *file, int line, const char *className)
Allocate a memory block.
Number of standard assert message.
Definition: object.h:383
char m_freeFillChar
Definition: object.h:1796
__inline PIntSameOrder & operator=(type value)
Definition: object.h:2465
Block & operator=(const Block &)
Definition: object.h:847
Header * m_listTail
Definition: object.h:1788
__inline void SetTraceContextIdentifier(const PObject &obj)
Definition: object.h:2213
Class used by PPROFILE_TIMESCOPE() macro to do the measurement of time between construction and destr...
Definition: object.h:1486
const char * m_extra
Definition: object.h:337
PIntSameOrder< int8_t > PInt8
Definition: object.h:2532
ValueType m_maximum
Definition: object.h:1210
PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:1955
__inline void CopyTraceContextIdentifier(PObject &obj) const
Definition: object.h:2215
atomic< unsigned > m_currentLevel
Definition: object.h:899
PDebugLocation(const char *extra=NULL)
Definition: object.h:339
alloc_t m_peakObjects
Definition: object.h:1801
unsigned m_interval
Definition: object.h:895
unsigned m_traceContextIdentifier
Definition: object.h:2206
void transfer(PAutoPtr &other)
Definition: object.h:104
static PBoolean SetIgnoreAllocations(PBoolean ignore)
Ignore/Monitor allocations.
Flags
Definition: object.h:1745
__inline friend ostream & operator<<(ostream &s, const PIntReversedOrder &value)
Definition: object.h:2484
__inline PIntSameOrder & operator=(const PIntSameOrder &value)
Definition: object.h:2466
__inline friend istream & operator>>(istream &s, PIntReversedOrder &value)
Definition: object.h:2485
static ostream & Begin(unsigned level, const char *fileName, int lineNum, const char *module, const PObject *instance, const char *defModule)
Definition: object.h:789
__inline unsigned GetTraceContextIdentifier() const
Get PTRACE context identifier.
Definition: object.h:2211
HighWaterMark()
Definition: object.h:1540
Comparison
Result of the comparison operation performed by the Compare() function.
Definition: object.h:2251
Type * m_instance
Definition: object.h:2048
int PParseEnum(const char *str, int begin, int end, char const *const *names, bool matchCase=true)
PStandardAssertMessage
Standard assert messages for the PAssert macro.
Definition: object.h:369
static __inline void CopyTraceContextIdentifier(PObject &to, const PObject &from)
Definition: object.h:2217
atomic< unsigned > m_repeatCount
Definition: object.h:901
A new or malloc failed.
Definition: object.h:371
__inline friend istream & operator>>(istream &s, PIntSameOrder &v)
Definition: object.h:2469
Type * operator->() const
Definition: object.h:2069
Template class for integral types (incluing PTimeInterval) for calcualting minimum, maximum and average.
Definition: object.h:1206
A Pop() was made of a stack with no elements.
Definition: object.h:376
ostream & PGetErrorStream()
Get the stream being used for error output.
Class to reduce noise level for some logging.
Definition: object.h:872
Definition: object.h:2254
ValueType GetAverage() const
Definition: object.h:1241
Template class to reduce noise level for some logging.
Definition: object.h:912
std::string m_name
Definition: object.h:1527
static HighWaterMarkData & GetHighWaterMarkData()
Definition: object.h:1539
char m_allocFillChar
Definition: object.h:1795
size_t m_peakMemoryUsage
Definition: object.h:1799
bool operator!=(const PObject &obj) const
Compare the two objects.
Definition: object.h:2318
void runtime_free(void *ptr)
Free memory allocated by run time library.
Definition: object.h:1836
atomic< unsigned > m_highWaterMark
Definition: object.h:1529
#define P_POP_MSVC_WARNINGS()
Definition: object.h:154
unsigned PAssertCount
__inline unsigned GetCurrentLevel() const
Definition: object.h:891
uint8_t m_flags
Definition: object.h:1793
unsigned alloc_t
Definition: object.h:1666
PIntSameOrder< int8_t > PChar8
Definition: object.h:2529
alloc_t allocationNumber
Definition: object.h:1670
Definition: object.h:2076
TimeScope & m_scope
Definition: object.h:1489
BaseClass * PAssertCast(BaseClass *obj, const char *file, int line)
Definition: object.h:2176
virtual void ReadFrom(istream &strm)
Input the contents of the object from the stream.
An index into an array was negative.
Definition: object.h:374
void Reset()
Definition: object.h:1231
A reference was made through a NULL pointer.
Definition: object.h:372
virtual ~PObject()
Definition: object.h:2235
__inline PIntReversedOrder()
Definition: object.h:2478
Definition: object.h:1103
PAutoPtr(T *p)
Definition: object.h:102
Operation attempted when channel not open.
Definition: object.h:380
static __inline void CopyTraceContextIdentifier(PObject &to, const PObject *from)
Definition: object.h:2218
__inline void SetTraceContextIdentifier(const PObject *obj)
Definition: object.h:2214
Definition: object.h:2461
PObject()
Constructor for PObject, made protected so cannot ever create one on its own.
Definition: object.h:2227
__inline const PObject * PTraceObjectInstance()
Definition: object.h:1086
void * runtime_malloc(size_t bytes)
Allocate memory for the run time library.
Definition: object.h:1830
Header * m_prev
Definition: object.h:1765
Definition: object.h:1621
Access through invalid window.
Definition: object.h:382
uint8_t m_flags
Definition: object.h:1772
Definition: object.h:1953
Header * m_next
Definition: object.h:1766
Definition: object.h:1963
Template class for a simple singleton object.
Definition: object.h:2045
Definition: object.h:1750
static void SetAllocationBreakpoint(alloc_t point)
Set break point allocation number.
alloc_t m_allocationRequest
Definition: object.h:1790
Definition: object.h:1623
const PObject *const m_object
Definition: object.h:1491
Definition: object.h:1624
#define PTRACE_ARG_ROLLOVER
Definition: object.h:561
#define free(p)
Override of system call for memory check system.
Definition: object.h:1870
~HighWaterMark()
Definition: object.h:1541
__inline PIntReversedOrder(const PIntReversedOrder &value)
Definition: object.h:2480
uint16_t m_line
Definition: object.h:1771
virtual PINDEX HashFunction() const
This function yields a hash value required by the PDictionary class.
Measure(TimeScope &scope, const PObject *object)
Definition: object.h:1495
ValueType GetMaximum() const
Definition: object.h:1240
int PReadEnum(std::istream &strm, int begin, int end, char const *const *names, bool matchCase=true)
friend ostream & operator<<(ostream &strm, const PObject &obj)
Global function for using the standard &lt;&lt; operator on objects descended from PObject.
Definition: object.h:2387
PAutoPtr()
Definition: object.h:101
__inline PIntSameOrder(type value)
Definition: object.h:2463
Header * m_listHead
Definition: object.h:1787
bool operator==(const PObject &obj) const
Compare the two objects.
Definition: object.h:2309
bool PBoolean
Definition: object.h:174
bool PAssertWalksStack
bool operator<(const PObject &obj) const
Compare the two objects.
Definition: object.h:2327
unsigned m_highLevel
Definition: object.h:897
#define PPROFILE_EXCLUDE(func)
Definition: object.h:1259
__inline PIntReversedOrder & operator=(type value)
Definition: object.h:2481
void PrintOn(ostream &strm, const char *prefix=NULL) const
__inline const char * PTraceModule()
Definition: object.h:1088
intptr_t P_INT_PTR
Definition: object.h:2646
#define P_MAX_INDEX
Definition: object.h:80
__inline unsigned GetLowLevel() const
Definition: object.h:889
void PPrintEnum(std::ostream &strm, int e, int begin, int end, char const *const *names)
void PThreadYield()
This class, along with the PPROFILE_TIMESCOPE() macro, allows the measurement of the time used by a s...
Definition: object.h:1430
ValueType m_minimum
Definition: object.h:1209
#define P_PUSH_MSVC_WARNINGS(warnings)
Definition: object.h:153
PDebugLocation(const char *file, unsigned line, const char *extra=NULL)
Definition: object.h:341
const char * m_fileName
Definition: object.h:1768
friend ostream & operator<<(ostream &strm, const PMinMaxAvg &mma)
Definition: object.h:1244
static unsigned MaxStackWalk
Definition: object.h:926
static __inline const char * Class()
Definition: object.h:2238
Feature is not supported.
Definition: object.h:381
This class allows the parsing of a set of program arguments.
Definition: args.h:41
const char * m_file
Definition: object.h:335
virtual Comparison Compare(const PObject &obj) const
Compare the two objects and return their relative rank.
bool operator<=(const PObject &obj) const
Compare the two objects.
Definition: object.h:2345
size_t m_currentMemoryUsage
Definition: object.h:1798
bool operator>=(const PObject &obj) const
Compare the two objects.
Definition: object.h:2354
static __inline const PObject * PTraceObjectInstance(const char *)
Definition: object.h:2243
Definition: object.h:1782
__inline const PObject * PTraceObjectInstance() const
Definition: object.h:2242
std::string m_units
Definition: object.h:1213
unsigned m_lowLevel
Definition: object.h:896
alloc_t m_request
Definition: object.h:1770
This class defines a thread of execution in the system.
Definition: thread.h:66
Measure(TimeScope &scope, const void *context)
Definition: object.h:1503
ValueType GetMinimum() const
Definition: object.h:1239
const char * file
Definition: object.h:849
unsigned m_count
Definition: object.h:1212
const char * m_className
Definition: object.h:1767
An invalid cast to descendant is required.
Definition: object.h:373
static __inline void CopyTraceContextIdentifier(PObject *to, const PObject &from)
Definition: object.h:2219
#define malloc(s)
Override of system call for memory check system.
Definition: object.h:1845
static ostream & Begin(unsigned level, const char *fileName, int lineNum, const PObject *instance, const PObject *defInstance, const char *module)
Definition: object.h:798
~Measure()
Definition: object.h:1511
Definition: object.h:98
static Comparison Compare2(T v1, T v2)
Compare two types, returning Comparison type.
Definition: object.h:2258
__inline unsigned GetHighLevel() const
Definition: object.h:890
static void Initialise(unsigned level, const char *filename, const char *rolloverPattern, unsigned options=Timestamp|Thread|Blocks)
Definition: object.h:631
friend istream & operator>>(istream &strm, PObject &obj)
Global function for using the standard &gt;&gt; operator on objects descended from PObject.
Definition: object.h:2397
alloc_t m_totalObjects
Definition: object.h:1802
Error was returned by Operating System.
Definition: object.h:379
~PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:1956
__inline PIntSameOrder(const PIntSameOrder &value)
Definition: object.h:2464
size_t m_size
Definition: object.h:1769
Invalid parameter was passed to a function.
Definition: object.h:378
Implementation *const m_implementation
Definition: object.h:1433
Funtion is not implemented.
Definition: object.h:377
bool PAssertFunc(const PDebugLocation &location, PStandardAssertMessage msg)
PThreadIdentifier m_threadId
Definition: object.h:1773
void Accumulate(const ValueType &value)
Definition: object.h:1221
#define PTRACE_ARG_TRACE
Definition: object.h:558
const void *const m_context
Definition: object.h:1490
ostream * m_leakDumpStream
Definition: object.h:1804
Type * PSingletonCreatorDefault()
Definition: object.h:2020
PIntSameOrder< uint8_t > PUInt8
Definition: object.h:2534
void PSetErrorStream(ostream *strm)
Set the stream to be used for error output.
Definition: object.h:1525
A NULL array element object was accessed.
Definition: object.h:375
__inline PIntSameOrder()
Definition: object.h:2462
virtual PObject * Clone() const
Create a copy of the class on the heap.
#define PTRACE_ARG_OPTION
Definition: object.h:562
__inline PIntReversedOrder(type value)
Definition: object.h:2479
__inline bool IsClass(const char *name) const
Definition: object.h:2240
PAutoPtr(PAutoPtr &other)
Definition: object.h:103
#define PTRACE_ARG_OUTPUT
Definition: object.h:560
Definition: object.h:1537
unsigned m_maxShown
Definition: object.h:898
Class to trace Execution blocks.
Definition: object.h:833
bool operator>(const PObject &obj) const
Compare the two objects.
Definition: object.h:2336
unsigned m_line
Definition: object.h:336
alloc_t m_allocationBreakpoint
Definition: object.h:1791
__inline uint64_t GetCycles()
Definition: object.h:1272
Definition: object.h:2252
PMemoryAllocationBreakpoint(DWORD point)
Definition: object.h:1965
static bool CanTrace(const ThrottleBase &throttle)
Definition: object.h:917
static __inline void CopyTraceContextIdentifier(PObject *to, const PObject *from)
Definition: object.h:2220
PMinMaxAvg(const char *units="")
Definition: object.h:1215
Definition: object.h:1622
atomic< int64_t > m_nextLog
Definition: object.h:900
Ultimate parent class for all objects in the class library.
Definition: object.h:2204
A logic error occurred.
Definition: object.h:370
PSingleton()
Definition: object.h:2050
__inline unsigned GetHiddenCount() const
Definition: object.h:892
unsigned GetCount() const
Definition: object.h:1242
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
alloc_t m_currentObjects
Definition: object.h:1800
Definition: object.h:1669
static Comparison InternalCompareObjectMemoryDirect(const PObject *obj1, const PObject *obj2, PINDEX size)
Internal function caled from CompareObjectMemoryDirect()
Validation
Validation result.
Definition: object.h:1620
void PrintOn(ostream &strm) const
atomic< unsigned > m_totalCount
Definition: object.h:1528
int line
Definition: object.h:850