Panda3D
 All Classes Functions Variables Enumerations
dtoolbase.h
1 /* Filename: dtoolbase.h
2  * Created by: drose (12Sep00)
3  *
4  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5  *
6  * PANDA 3D SOFTWARE
7  * Copyright (c) Carnegie Mellon University. All rights reserved.
8  *
9  * All use of this software is subject to the terms of the revised BSD
10  * license. You should have received a copy of this license along
11  * with this source code in a file named "LICENSE."
12  *
13  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
14 
15 /* This file is included at the beginning of every header file and/or
16  C or C++ file. It must be compilable for C as well as C++ files,
17  so no C++-specific code or syntax can be put here. See
18  dtoolbase_cc.h for C++-specific stuff. */
19 
20 #ifndef DTOOLBASE_H
21 #define DTOOLBASE_H
22 
23 #include "dtool_config.h"
24 
25 /* Make sure WIN32 and WIN32_VC are defined when using MSVC */
26 #if defined(_WIN32) || defined(_WIN64)
27 #ifndef WIN32
28 #define WIN32
29 #endif
30 #ifdef _MSC_VER
31 #ifndef WIN32_VC
32 #define WIN32_VC
33 #endif
34 #endif
35 #endif
36 
37 #ifdef WIN32_VC
38 /* These warning pragmas must appear before anything else for VC++ to
39  respect them. Sheesh. */
40 
41 /* C4231: extern before template instantiation */
42 /* For some reason, this particular warning won't disable. */
43 #pragma warning (disable : 4231)
44 /* C4786: 255 char debug symbols */
45 #pragma warning (disable : 4786)
46 /* C4251: needs dll interface */
47 #pragma warning (disable : 4251)
48 /* C4503: decorated name length exceeded */
49 #pragma warning (disable : 4503)
50 /* C4305: truncation from 'const double' to 'float' */
51 #pragma warning (disable : 4305)
52 /* C4250: 'myclass' : inherits 'baseclass::member' via dominance */
53 #pragma warning (disable : 4250)
54 /* C4355: 'this' : used in base member initializer list */
55 #pragma warning (disable : 4355)
56 /* C4244: 'initializing' : conversion from 'double' to 'float', possible loss of data */
57 #pragma warning (disable : 4244)
58 /* C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data */
59 #pragma warning (disable : 4267)
60 
61 #if _MSC_VER >= 1300
62  #if _MSC_VER >= 1310
63  #define USING_MSVC7_1
64 //#pragma message("VC 7.1")
65  #else
66 //#pragma message("VC 7.0")
67  #endif
68 #define USING_MSVC7
69 #else
70 // #pragma message("VC 6.0")
71 #endif
72 
73 // Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go to the final untested case
74 // after it has failed all the other cases (i.e. 'assume at least one of the cases is always true')
75 #ifdef _DEBUG
76 # define NODEFAULT default: assert(0);
77 #else
78 # define NODEFAULT default: __assume(0); // special VC keyword
79 #endif
80 
81 #else /* if !WIN32_VC */
82 #ifdef _DEBUG
83 # define NODEFAULT default: assert(0);
84 #else
85 # define NODEFAULT
86 #endif
87 #endif /* WIN32_VC */
88 
89 /*
90  include win32 defns for everything up to WinServer2003, and assume
91  I'm smart enough to use GetProcAddress for backward compat on
92  w95/w98 for newer fns
93 */
94 #ifdef _WIN32_WINNT
95 #undef _WIN32_WINNT
96 #endif
97 #define _WIN32_WINNT 0x0502
98 
99 #ifdef __cplusplus
100 #ifndef __STDC_LIMIT_MACROS
101 #define __STDC_LIMIT_MACROS
102 #endif
103 #ifndef __STDC_CONSTANT_MACROS
104 #define __STDC_CONSTANT_MACROS
105 #endif
106 #endif
107 
108 // This is a workaround for a glibc bug that is triggered by
109 // clang when compiling with -ffast-math.
110 #ifdef __clang__
111 #include <sys/cdefs.h>
112 #ifndef __extern_always_inline
113 #define __extern_always_inline extern __always_inline
114 #endif
115 #endif
116 
117 #ifdef HAVE_PYTHON
118 #undef _POSIX_C_SOURCE
119 #undef _XOPEN_SOURCE
120 #include "pyconfig.h"
121 #endif
122 
123 #ifndef HAVE_EIGEN
124 // If we don't have the Eigen library, don't define LINMATH_ALIGN.
125 #undef LINMATH_ALIGN
126 #endif
127 
128 #include "dtoolsymbols.h"
129 
130 // always include assert.h until drose unbreaks it for opt4
131 #include <assert.h>
132 
133 #ifdef __GNUC__
134 // Large file >2GB support
135 // this needs be be before systypes.h and other C headers
136 #define _FILE_OFFSET_BITS 64
137 #define _LARGEFILE_SOURCE 1
138 #endif
139 
140 #ifdef PHAVE_TYPES_H
141 #include <types.h>
142 #endif
143 
144 #ifdef PHAVE_SYS_TYPES_H
145 #include <sys/types.h>
146 #endif
147 
148 #ifdef PHAVE_MALLOC_H
149 #include <malloc.h>
150 #endif
151 
152 #ifdef PHAVE_SYS_MALLOC_H
153 #include <sys/malloc.h>
154 #endif
155 
156 #ifdef PHAVE_ALLOCA_H
157 #include <alloca.h>
158 #endif
159 
160 #ifdef PHAVE_UNISTD_H
161 #include <unistd.h>
162 #endif
163 
164 #ifdef PHAVE_IO_H
165 #include <io.h>
166 #endif
167 
168 #ifdef PHAVE_LOCALE_H
169 #include <locale.h>
170 #endif
171 
172 #ifdef PHAVE_STRING_H
173 #include <string.h>
174 #endif
175 
176 #ifdef PHAVE_STDLIB_H
177 #include <stdlib.h>
178 #endif
179 
180 #ifdef PHAVE_LIMITS_H
181 #include <limits.h>
182 #endif
183 
184 #ifdef PHAVE_MINMAX_H
185 #include <minmax.h>
186 #endif
187 
188 #ifdef PHAVE_SYS_TIME_H
189 #include <sys/time.h>
190 #endif
191 
192 #ifdef PHAVE_STDINT_H
193 #include <stdint.h>
194 #endif
195 
196 #ifdef CPPPARSER
197 #include <stdtypedefs.h>
198 
199 // Also pick up the forward declaration of PyObject.
200 #include <Python.h>
201 #endif
202 
203 #ifdef USE_TAU
204 /* If we're building with the Tau instrumentor, include the
205  appropriate header file to pick up the TAU macros. */
206 #include <TAU.h>
207 #include <Profile/Profiler.h>
208 #else
209 /* Otherwise, if we're not building with the Tau instrumentor, turn
210  off all the TAU macros. We could include the Tau header file to do
211  this, but it's better not to assume that Tau is installed. */
212 #define TAU_TYPE_STRING(profileString, str)
213 #define TAU_PROFILE(name, type, group)
214 #define TAU_PROFILE_TIMER(var, name, type, group)
215 #define TAU_PROFILE_START(var)
216 #define TAU_PROFILE_STOP(var)
217 #define TAU_PROFILE_STMT(stmt)
218 #define TAU_PROFILE_EXIT(msg)
219 #define TAU_PROFILE_INIT(argc, argv)
220 #define TAU_PROFILE_SET_NODE(node)
221 #define TAU_PROFILE_SET_CONTEXT(context)
222 #define TAU_PROFILE_SET_GROUP_NAME(newname)
223 #define TAU_PROFILE_TIMER_SET_GROUP_NAME(t, newname)
224 #define TAU_PROFILE_CALLSTACK()
225 #define TAU_DB_DUMP()
226 #define TAU_DB_PURGE()
227 
228 #define TAU_REGISTER_CONTEXT_EVENT(event, name)
229 #define TAU_CONTEXT_EVENT(event, data)
230 #define TAU_DISABLE_CONTEXT_EVENT(event)
231 #define TAU_ENABLE_CONTEXT_EVENT(event)
232 
233 #define TAU_REGISTER_EVENT(event, name)
234 #define TAU_EVENT(event, data)
235 #define TAU_EVENT_DISABLE_MIN(event)
236 #define TAU_EVENT_DISABLE_MAX(event)
237 #define TAU_EVENT_DISABLE_MEAN(event)
238 #define TAU_EVENT_DISABLE_STDDEV(event)
239 #define TAU_REPORT_STATISTICS()
240 #define TAU_REPORT_THREAD_STATISTICS()
241 #define TAU_REGISTER_THREAD()
242 #define TAU_REGISTER_FORK(id, op)
243 #define TAU_ENABLE_INSTRUMENTATION()
244 #define TAU_DISABLE_INSTRUMENTATION()
245 #define TAU_ENABLE_GROUP(group)
246 #define TAU_DISABLE_GROUP(group)
247 #define TAU_ENABLE_GROUP_NAME(group)
248 #define TAU_DISABLE_GROUP_NAME(group)
249 #define TAU_ENABLE_ALL_GROUPS()
250 #define TAU_DISABLE_ALL_GROUPS()
251 #define TAU_TRACK_MEMORY()
252 #define TAU_TRACK_MEMORY_HERE()
253 #define TAU_ENABLE_TRACKING_MEMORY()
254 #define TAU_DISABLE_TRACKING_MEMORY()
255 #define TAU_TRACK_MEMORY()
256 #define TAU_TRACK_MEMORY_HERE()
257 #define TAU_ENABLE_TRACKING_MUSE_EVENTS()
258 #define TAU_DISABLE_TRACKING_MUSE_EVENTS()
259 #define TAU_TRACK_MUSE_EVENTS()
260 #define TAU_SET_INTERRUPT_INTERVAL(value)
261 
262 #define TAU_TRACE_SENDMSG(type, destination, length)
263 #define TAU_TRACE_RECVMSG(type, source, length)
264 
265 #define TAU_MAPPING(stmt, group) stmt
266 #define TAU_MAPPING_OBJECT(FuncInfoVar)
267 #define TAU_MAPPING_LINK(FuncInfoVar, Group)
268 #define TAU_MAPPING_PROFILE(FuncInfoVar)
269 #define TAU_MAPPING_CREATE(name, type, key, groupname, tid)
270 #define TAU_MAPPING_PROFILE_TIMER(Timer, FuncInfoVar, tid)
271 #define TAU_MAPPING_TIMER_CREATE(t, name, type, gr, group_name)
272 #define TAU_MAPPING_PROFILE_START(Timer, tid)
273 #define TAU_MAPPING_PROFILE_STOP(tid)
274 #define TAU_MAPPING_PROFILE_EXIT(msg, tid)
275 #define TAU_MAPPING_DB_DUMP(tid)
276 #define TAU_MAPPING_DB_PURGE(tid)
277 #define TAU_MAPPING_PROFILE_SET_NODE(node, tid)
278 #define TAU_MAPPING_PROFILE_SET_GROUP_NAME(timer, name)
279 #define TAU_PROFILE_TIMER_SET_NAME(t, newname)
280 #define TAU_PROFILE_TIMER_SET_TYPE(t, newname)
281 #define TAU_PROFILE_TIMER_SET_GROUP(t, id)
282 #define TAU_MAPPING_PROFILE_SET_NAME(timer, name)
283 #define TAU_MAPPING_PROFILE_SET_TYPE(timer, name)
284 #define TAU_MAPPING_PROFILE_SET_GROUP(timer, id)
285 #define TAU_MAPPING_PROFILE_GET_GROUP_NAME(timer)
286 #define TAU_MAPPING_PROFILE_GET_GROUP(timer)
287 #define TAU_MAPPING_PROFILE_GET_NAME(timer)
288 #define TAU_MAPPING_PROFILE_GET_TYPE(timer)
289 
290 #define TAU_PHASE(name, type, group)
291 #define TAU_PHASE_CREATE_STATIC(var, name, type, group)
292 #define TAU_PHASE_CREATE_DYNAMIC(var, name, type, group)
293 #define TAU_PHASE_START(var)
294 #define TAU_PHASE_STOP(var)
295 #define TAU_GLOBAL_PHASE(timer, name, type, group)
296 #define TAU_GLOBAL_PHASE_START(timer)
297 #define TAU_GLOBAL_PHASE_STOP(timer)
298 #define TAU_GLOBAL_PHASE_EXTERNAL(timer)
299 #define TAU_GLOBAL_TIMER(timer, name, type, group)
300 #define TAU_GLOBAL_TIMER_EXTERNAL(timer)
301 #define TAU_GLOBAL_TIMER_START(timer)
302 #define TAU_GLOBAL_TIMER_STOP()
303 
304 #endif /* USE_TAU */
305 
306 /* Try to infer the endianness of the host based on compiler
307  predefined macros. For systems on which the compiler does not
308  define these macros, we rely on ppremake to define WORDS_BIGENDIAN
309  correctly. For systems on which the compiler *does* define these
310  macros, we ignore what ppremake said and define WORDS_BIGENDIAN
311  correctly here. (This is essential on OSX, which requires
312  compiling each file twice in different modes, for universal binary
313  support.) */
314 
315 #if defined(__LITTLE_ENDIAN__) || defined(__i386__)
316 #undef WORDS_BIGENDIAN
317 
318 #elif defined(__BIG_ENDIAN__) || defined(__ppc__)
319 #undef WORDS_BIGENDIAN
320 #define WORDS_BIGENDIAN 1
321 
322 #endif
323 
324 /* Try to determine if we're compiling in a 64-bit mode. */
325 
326 #ifdef __WORDSIZE
327 #define NATIVE_WORDSIZE __WORDSIZE
328 #elif defined(_LP64)
329 #define NATIVE_WORDSIZE 64
330 #else
331 #define NATIVE_WORDSIZE 32
332 #endif
333 
334 /* Some byte-alignment macros. */
335 #ifdef CPPPARSER
336 #define ALIGN_4BYTE
337 #define ALIGN_8BYTE
338 #define ALIGN_16BYTE
339 #define ALIGN_64BYTE
340 #elif defined(_MSC_VER)
341 #define ALIGN_4BYTE __declspec(align(4))
342 #define ALIGN_8BYTE __declspec(align(8))
343 #define ALIGN_16BYTE __declspec(align(16))
344 #define ALIGN_64BYTE __declspec(align(64))
345 #elif defined(__GNUC__)
346 #define ALIGN_4BYTE __attribute__ ((aligned (4)))
347 #define ALIGN_8BYTE __attribute__ ((aligned (8)))
348 #define ALIGN_16BYTE __attribute__ ((aligned (16)))
349 #define ALIGN_64BYTE __attribute__ ((aligned (64)))
350 #else
351 #define ALIGN_4BYTE
352 #define ALIGN_8BYTE
353 #define ALIGN_16BYTE
354 #endif
355 
356 // Do we need to implement memory-alignment enforcement within the
357 // MemoryHook class, or will the underlying malloc implementation
358 // provide it automatically?
359 #if !defined(LINMATH_ALIGN)
360 // We don't actually require any special memory-alignment beyond what
361 // the underlying implementation is likely to provide anyway.
362 #undef MEMORY_HOOK_DO_ALIGN
363 
364 #elif defined(USE_MEMORY_DLMALLOC)
365 // This specialized malloc implementation can perform the required
366 // alignment.
367 #undef MEMORY_HOOK_DO_ALIGN
368 
369 #elif defined(USE_MEMORY_PTMALLOC2)
370 // But not this one. For some reason it crashes when we try to build
371 // it with alignment 16. So if we're using ptmalloc2, we need to
372 // enforce alignment externally.
373 #define MEMORY_HOOK_DO_ALIGN 1
374 
375 #elif defined(IS_OSX) || defined(_WIN64)
376 // The OS-provided malloc implementation will do the required
377 // alignment.
378 #undef MEMORY_HOOK_DO_ALIGN
379 
380 #elif defined(MEMORY_HOOK_DO_ALIGN)
381 // We need memory alignment, and we're willing to provide it ourselves.
382 
383 #else
384 // We need memory alignment, and we haven't specified whether it
385 // should be provided on top of the existing malloc library, or
386 // otherwise. Let's rely on dlmalloc to provide it, it seems to be
387 // the most memory-efficient option.
388 #define USE_MEMORY_DLMALLOC 1
389 
390 #endif
391 
392 /* Determine our memory-allocation requirements. */
393 #if defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN)
394 /* In this case we have some custom memory management requirements. */
395 #else
396 /* Otherwise, if we have no custom memory management needs at all, we
397  might as well turn it all off and go straight to the OS-level
398  calls. */
399 #define USE_MEMORY_NOWRAPPERS 1
400 #endif
401 
402 /* We must always use the STL allocator nowadays, because we have
403  redefined the constructors for pvector, pmap, etc. */
404 #define USE_STL_ALLOCATOR 1
405 
406 /*
407  We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
408  functions and global variable definitions that are to be published
409  via interrogate to scripting languages. Also, the macro BLOCKING is
410  used to flag any function or method that might perform I/O blocking
411  and thus needs to release Python threads for its duration.
412  */
413 #ifdef CPPPARSER
414 #define BEGIN_PUBLISH __begin_publish
415 #define END_PUBLISH __end_publish
416 #define BLOCKING __blocking
417 #define MAKE_PROPERTY(property_name, ...) __make_property(property_name, __VA_ARGS__)
418 #define MAKE_SEQ(seq_name, num_name, element_name) __make_seq(seq_name, num_name, element_name)
419 #undef USE_STL_ALLOCATOR /* Don't try to parse these template classes in interrogate. */
420 #define EXTENSION(x) __extension x
421 #define EXTEND __extension
422 #else
423 #define BEGIN_PUBLISH
424 #define END_PUBLISH
425 #define BLOCKING
426 #define MAKE_PROPERTY(property_name, ...)
427 #define MAKE_SEQ(seq_name, num_name, element_name)
428 #define EXTENSION(x)
429 #define EXTEND
430 #endif
431 
432 /* These symbols are used in dtoolsymbols.h and pandasymbols.h. */
433 #if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
434 #define EXPORT_CLASS __declspec(dllexport)
435 #define IMPORT_CLASS __declspec(dllimport)
436 #else
437 #define EXPORT_CLASS
438 #define IMPORT_CLASS
439 #endif
440 /* "extern template" is now part of the C++11 standard. */
441 #if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
442 #define EXPORT_TEMPL
443 #define IMPORT_TEMPL extern
444 #else
445 #define EXPORT_TEMPL
446 #define IMPORT_TEMPL
447 #endif
448 
449 #ifdef __cplusplus
450 #include "dtoolbase_cc.h"
451 #endif
452 
453 #endif