HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Platform.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 ///
4 /// @file Platform.h
5 
6 #ifndef OPENVDB_PLATFORM_HAS_BEEN_INCLUDED
7 #define OPENVDB_PLATFORM_HAS_BEEN_INCLUDED
8 
9 #define PRAGMA(x) _Pragma(#x)
10 
11 /// @name Utilities
12 /// @{
13 /// @cond OPENVDB_DOCS_INTERNAL
14 #define OPENVDB_PREPROC_STRINGIFY_(x) #x
15 /// @endcond
16 /// @brief Return @a x as a string literal. If @a x is a macro,
17 /// return its value as a string literal.
18 /// @hideinitializer
19 #define OPENVDB_PREPROC_STRINGIFY(x) OPENVDB_PREPROC_STRINGIFY_(x)
20 
21 /// @cond OPENVDB_DOCS_INTERNAL
22 #define OPENVDB_PREPROC_CONCAT_(x, y) x ## y
23 /// @endcond
24 /// @brief Form a new token by concatenating two existing tokens.
25 /// If either token is a macro, concatenate its value.
26 /// @hideinitializer
27 #define OPENVDB_PREPROC_CONCAT(x, y) OPENVDB_PREPROC_CONCAT_(x, y)
28 /// @}
29 
30 /// Macro for determining if GCC version is >= than X.Y
31 #if defined(__GNUC__)
32  #define OPENVDB_CHECK_GCC(MAJOR, MINOR) \
33  (__GNUC__ > MAJOR || (__GNUC__ == MAJOR && __GNUC_MINOR__ >= MINOR))
34 #else
35  #define OPENVDB_CHECK_GCC(MAJOR, MINOR) 0
36 #endif
37 
38 /// OpenVDB now requires C++17
39 #define OPENVDB_HAS_CXX11 1 // kept for backward compatibility
40 
41 #if __cplusplus >= 202002L
42  #define OPENVDB_HAS_CXX20
43 #endif
44 
45 /// SIMD Intrinsic Headers
46 #if defined(OPENVDB_USE_SSE42) || defined(OPENVDB_USE_AVX)
47  #if defined(_WIN32)
48  #include <intrin.h>
49  #elif defined(__GNUC__)
50  #if defined(__x86_64__) || defined(__i386__)
51  #include <x86intrin.h>
52  #elif defined(__ARM_NEON__)
53  #include <arm_neon.h>
54  #endif
55  #endif
56 #endif
57 
58 /// Windows defines
59 #ifdef _WIN32
60  ///Disable the non-portable Windows definitions of min() and max() macros
61  #ifndef NOMINMAX
62  #define NOMINMAX
63  #endif
64 
65  // By default, assume we're building OpenVDB as a DLL if we're dynamically
66  // linking in the CRT, unless OPENVDB_STATICLIB is defined.
67  #if defined(_DLL) && !defined(OPENVDB_STATICLIB) && !defined(OPENVDB_DLL)
68  #define OPENVDB_DLL
69  #endif
70 
71  // By default, assume that we're dynamically linking OpenEXR, unless
72  // OPENVDB_OPENEXR_STATICLIB is defined.
73  #if !defined(OPENVDB_OPENEXR_STATICLIB) && !defined(OPENEXR_DLL)
74  #define OPENEXR_DLL
75  #endif
76 #endif
77 
78 /// Macros to suppress undefined behaviour sanitizer warnings. Should be used
79 /// sparingly, primarily to suppress issues in upstream dependencies.
80 #if defined(__clang__)
81 #define OPENVDB_UBSAN_SUPPRESS(X) __attribute__((no_sanitize(X)))
82 #else
83 #define OPENVDB_UBSAN_SUPPRESS(X)
84 #endif
85 
86 /// Macros to alias to compiler builtins which hint at critical edge selection
87 /// during conditional statements.
88 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
89 #ifdef __cplusplus
90 #define OPENVDB_LIKELY(x) (__builtin_expect(static_cast<bool>(x), true))
91 #define OPENVDB_UNLIKELY(x) (__builtin_expect(static_cast<bool>(x), false))
92 #else
93 #define OPENVDB_LIKELY(x) (__builtin_expect((x), 1))
94 #define OPENVDB_UNLIKELY(x) (__builtin_expect((x), 0))
95 #endif
96 #else
97 #define OPENVDB_LIKELY(x) (x)
98 #define OPENVDB_UNLIKELY(x) (x)
99 #endif
100 
101 /// Force inline function macros. These macros do not necessary guarantee that
102 /// the decorated function will be inlined, but provide the strongest vendor
103 /// annotations to that end.
104 #if defined(__GNUC__)
105 #define OPENVDB_FORCE_INLINE __attribute__((always_inline)) inline
106 #elif defined(_MSC_VER)
107 #define OPENVDB_FORCE_INLINE __forceinline
108 #else
109 #define OPENVDB_FORCE_INLINE inline
110 #endif
111 
112 /// Bracket code with OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN/_END,
113 /// as in the following example, to inhibit ICC remarks about unreachable code:
114 /// @code
115 /// template<typename NodeType>
116 /// void processNode(NodeType& node)
117 /// {
118 /// OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
119 /// if (NodeType::LEVEL == 0) return; // ignore leaf nodes
120 /// int i = 0;
121 /// ...
122 /// OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
123 /// }
124 /// @endcode
125 /// In the above, <tt>NodeType::LEVEL == 0</tt> is a compile-time constant expression,
126 /// so for some template instantiations, the line below it is unreachable.
127 #if defined(__INTEL_COMPILER)
128  // Disable ICC remarks 111 ("statement is unreachable"), 128 ("loop is not reachable"),
129  // 185 ("dynamic initialization in unreachable code"), and 280 ("selector expression
130  // is constant").
131  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN \
132  _Pragma("warning (push)") \
133  _Pragma("warning (disable:111)") \
134  _Pragma("warning (disable:128)") \
135  _Pragma("warning (disable:185)") \
136  _Pragma("warning (disable:280)")
137  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END \
138  _Pragma("warning (pop)")
139 #elif defined(__clang__)
140  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN \
141  PRAGMA(clang diagnostic push) \
142  PRAGMA(clang diagnostic ignored "-Wunreachable-code")
143  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END \
144  PRAGMA(clang diagnostic pop)
145 #else
146  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
147  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
148 #endif
149 
150 /// Deprecation macros. Define OPENVDB_NO_DEPRECATION_WARNINGS to disable all
151 /// deprecation warnings in OpenVDB.
152 #ifndef OPENVDB_NO_DEPRECATION_WARNINGS
153 #define OPENVDB_DEPRECATED [[deprecated]]
154 #define OPENVDB_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]
155 #else
156 #define OPENVDB_DEPRECATED
157 #define OPENVDB_DEPRECATED_MESSAGE(msg)
158 #endif
159 
160 /// @brief Bracket code with OPENVDB_NO_DEPRECATION_WARNING_BEGIN/_END,
161 /// to inhibit warnings about deprecated code.
162 /// @note Only intended to be used internally whilst parent code is being
163 /// deprecated
164 /// @details Example:
165 /// @code
166 /// OPENVDB_DEPRECATED void myDeprecatedFunction() {}
167 ///
168 /// {
169 /// OPENVDB_NO_DEPRECATION_WARNING_BEGIN
170 /// myDeprecatedFunction();
171 /// OPENVDB_NO_DEPRECATION_WARNING_END
172 /// }
173 /// @endcode
174 #if defined __INTEL_COMPILER
175  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
176  _Pragma("warning (push)") \
177  _Pragma("warning (disable:1478)")
178  #define OPENVDB_NO_DEPRECATION_WARNING_END \
179  _Pragma("warning (pop)")
180 #elif defined __clang__
181  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
182  _Pragma("clang diagnostic push") \
183  _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
184  // note: no #pragma message, since Clang treats them as warnings
185  #define OPENVDB_NO_DEPRECATION_WARNING_END \
186  _Pragma("clang diagnostic pop")
187 #elif defined __GNUC__
188  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
189  _Pragma("GCC diagnostic push") \
190  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
191  #define OPENVDB_NO_DEPRECATION_WARNING_END \
192  _Pragma("GCC diagnostic pop")
193 #elif defined _MSC_VER
194  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
195  __pragma(warning(push)) \
196  __pragma(warning(disable : 4996))
197  #define OPENVDB_NO_DEPRECATION_WARNING_END \
198  __pragma(warning(pop))
199 #else
200  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN
201  #define OPENVDB_NO_DEPRECATION_WARNING_END
202 #endif
203 
204 
205 /// @brief Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END,
206 /// to inhibit warnings about type conversion.
207 /// @note Use this sparingly. Use static casts and explicit type conversion if at all possible.
208 /// @details Example:
209 /// @code
210 /// float value = 0.1f;
211 /// OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
212 /// int valueAsInt = value;
213 /// OPENVDB_NO_TYPE_CONVERSION_WARNING_END
214 /// @endcode
215 #if defined __INTEL_COMPILER
216  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
217  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
218 #elif defined __GNUC__
219  // -Wfloat-conversion was only introduced in GCC 4.9
220  #if OPENVDB_CHECK_GCC(4, 9)
221  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \
222  _Pragma("GCC diagnostic push") \
223  _Pragma("GCC diagnostic ignored \"-Wconversion\"") \
224  _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"")
225  #else
226  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \
227  _Pragma("GCC diagnostic push") \
228  _Pragma("GCC diagnostic ignored \"-Wconversion\"")
229  #endif
230  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END \
231  _Pragma("GCC diagnostic pop")
232 #else
233  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
234  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
235 #endif
236 
237 /// Helper macros for defining library symbol visibility
238 #ifdef OPENVDB_EXPORT
239 #undef OPENVDB_EXPORT
240 #endif
241 #ifdef OPENVDB_IMPORT
242 #undef OPENVDB_IMPORT
243 #endif
244 #ifdef _WIN32
245  #ifdef OPENVDB_DLL
246  #define OPENVDB_EXPORT __declspec(dllexport)
247  #define OPENVDB_IMPORT __declspec(dllimport)
248  #else
249  #define OPENVDB_EXPORT
250  #define OPENVDB_IMPORT
251  #endif
252 #elif defined(__GNUC__)
253  #define OPENVDB_EXPORT __attribute__((visibility("default")))
254  #define OPENVDB_IMPORT __attribute__((visibility("default")))
255 #endif
256 
257 /// Helper macros for explicit template instantiation
258 #if defined(_WIN32) && defined(OPENVDB_DLL)
259  #ifdef OPENVDB_PRIVATE
260  #define OPENVDB_TEMPLATE_EXPORT OPENVDB_EXPORT
261  #define OPENVDB_TEMPLATE_IMPORT
262  #else
263  #define OPENVDB_TEMPLATE_EXPORT
264  #define OPENVDB_TEMPLATE_IMPORT OPENVDB_IMPORT
265  #endif
266 #else
267  #define OPENVDB_TEMPLATE_IMPORT
268  #define OPENVDB_TEMPLATE_EXPORT
269 #endif
270 
271 /// All classes and public free standing functions must be explicitly marked
272 /// as <lib>_API to be exported. The <lib>_PRIVATE macros are defined when
273 /// building that particular library.
274 #ifdef OPENVDB_API
275 #undef OPENVDB_API
276 #endif
277 #ifdef OPENVDB_PRIVATE
278  #define OPENVDB_API OPENVDB_EXPORT
279 #else
280  #define OPENVDB_API OPENVDB_IMPORT
281 #endif
282 #ifdef OPENVDB_HOUDINI_API
283 #undef OPENVDB_HOUDINI_API
284 #endif
285 #ifdef OPENVDB_HOUDINI_PRIVATE
286  #define OPENVDB_HOUDINI_API OPENVDB_EXPORT
287 #else
288  #define OPENVDB_HOUDINI_API OPENVDB_IMPORT
289 #endif
290 
291 #ifdef OPENVDB_AX_DLL
292 #ifdef OPENVDB_AX_API
293 #undef OPENVDB_AX_API
294 #endif
295 #ifdef OPENVDB_AX_PRIVATE
296  #define OPENVDB_AX_API OPENVDB_EXPORT
297 #else
298  #define OPENVDB_AX_API OPENVDB_IMPORT
299 #endif
300 #else
301 #define OPENVDB_AX_API
302 #endif // OPENVDB_AX_DLL
303 
304 #if defined(__ICC)
305 
306 // Use these defines to bracket a region of code that has safe static accesses.
307 // Keep the region as small as possible.
308 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
309 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
310 #define OPENVDB_START_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
311 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
312 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
313 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
314 
315 // Use these defines to bracket a region of code that has unsafe static accesses.
316 // Keep the region as small as possible.
317 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
318 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
319 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
320 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
321 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
322 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
323 
324 // Simpler version for one-line cases
325 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) \
326  __pragma(warning(disable:1710)); CODE; __pragma(warning(default:1710))
327 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) \
328  __pragma(warning(disable:1711)); CODE; __pragma(warning(default:1711))
329 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) \
330  __pragma(warning(disable:1712)); CODE; __pragma(warning(default:1712))
331 
332 #else // GCC does not support these compiler warnings
333 
334 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE
335 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE
336 #define OPENVDB_START_THREADSAFE_STATIC_WRITE
337 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE
338 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS
339 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS
340 
341 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE
342 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE
343 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE
344 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE
345 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS
346 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS
347 
348 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) CODE
349 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) CODE
350 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) CODE
351 
352 #endif // defined(__ICC)
353 
354 #endif // OPENVDB_PLATFORM_HAS_BEEN_INCLUDED