OpenVDB  12.1.0
Platform.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: Apache-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 #endif
71 
72 /// Macros to suppress undefined behaviour sanitizer warnings. Should be used
73 /// sparingly, primarily to suppress issues in upstream dependencies.
74 #if defined(__clang__)
75 #define OPENVDB_UBSAN_SUPPRESS(X) __attribute__((no_sanitize(X)))
76 #else
77 #define OPENVDB_UBSAN_SUPPRESS(X)
78 #endif
79 
80 /// Macros to alias to compiler builtins which hint at critical edge selection
81 /// during conditional statements.
82 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
83 #ifdef __cplusplus
84 #define OPENVDB_LIKELY(x) (__builtin_expect(static_cast<bool>(x), true))
85 #define OPENVDB_UNLIKELY(x) (__builtin_expect(static_cast<bool>(x), false))
86 #else
87 #define OPENVDB_LIKELY(x) (__builtin_expect((x), 1))
88 #define OPENVDB_UNLIKELY(x) (__builtin_expect((x), 0))
89 #endif
90 #else
91 #define OPENVDB_LIKELY(x) (x)
92 #define OPENVDB_UNLIKELY(x) (x)
93 #endif
94 
95 /// Macros for assume builtins. Note that we currently don't simply apply these
96 /// in place of asserts (when asserts are disabled) - they should be only be
97 /// applied with an assert once profiled
98 #ifdef __has_cpp_attribute
99  #if __has_cpp_attribute(assume) >= 202207L
100  #define OPENVDB_ASSUME(...) [[assume(__VA_ARGS__)]]
101  #endif
102 #endif
103 #ifndef OPENVDB_ASSUME
104  #if defined(__clang__)
105  #define OPENVDB_ASSUME(...) __builtin_assume(__VA_ARGS__);
106  #elif defined(_MSC_VER)
107  #define OPENVDB_ASSUME(...) __assume(__VA_ARGS__);
108  #elif defined(__GNUC__)
109  #if __GNUC__ >= 13
110  #define OPENVDB_ASSUME(...) __attribute__((__assume__(__VA_ARGS__)))
111  #endif
112  #endif
113 #endif
114 #ifndef OPENVDB_ASSUME
115  #define OPENVDB_ASSUME(...)
116 #endif
117 
118 /// Force inline function macros. These macros do not necessary guarantee that
119 /// the decorated function will be inlined, but provide the strongest vendor
120 /// annotations to that end.
121 #if defined(__GNUC__)
122 #define OPENVDB_FORCE_INLINE __attribute__((always_inline)) inline
123 #elif defined(_MSC_VER)
124 #define OPENVDB_FORCE_INLINE __forceinline
125 #else
126 #define OPENVDB_FORCE_INLINE inline
127 #endif
128 
129 /// Bracket code with OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN/_END,
130 /// as in the following example, to inhibit ICC remarks about unreachable code:
131 /// @code
132 /// template<typename NodeType>
133 /// void processNode(NodeType& node)
134 /// {
135 /// OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
136 /// if (NodeType::LEVEL == 0) return; // ignore leaf nodes
137 /// int i = 0;
138 /// ...
139 /// OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
140 /// }
141 /// @endcode
142 /// In the above, <tt>NodeType::LEVEL == 0</tt> is a compile-time constant expression,
143 /// so for some template instantiations, the line below it is unreachable.
144 #if defined(__INTEL_COMPILER)
145  // Disable ICC remarks 111 ("statement is unreachable"), 128 ("loop is not reachable"),
146  // 185 ("dynamic initialization in unreachable code"), and 280 ("selector expression
147  // is constant").
148  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN \
149  _Pragma("warning (push)") \
150  _Pragma("warning (disable:111)") \
151  _Pragma("warning (disable:128)") \
152  _Pragma("warning (disable:185)") \
153  _Pragma("warning (disable:280)")
154  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END \
155  _Pragma("warning (pop)")
156 #elif defined(__clang__)
157  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN \
158  PRAGMA(clang diagnostic push) \
159  PRAGMA(clang diagnostic ignored "-Wunreachable-code")
160  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END \
161  PRAGMA(clang diagnostic pop)
162 #else
163  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
164  #define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
165 #endif
166 
167 /// Deprecation macros. Define OPENVDB_NO_DEPRECATION_WARNINGS to disable all
168 /// deprecation warnings in OpenVDB.
169 #ifndef OPENVDB_NO_DEPRECATION_WARNINGS
170 #define OPENVDB_DEPRECATED [[deprecated]]
171 #define OPENVDB_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]
172 #else
173 #define OPENVDB_DEPRECATED
174 #define OPENVDB_DEPRECATED_MESSAGE(msg)
175 #endif
176 
177 /// @brief Bracket code with OPENVDB_NO_DEPRECATION_WARNING_BEGIN/_END,
178 /// to inhibit warnings about deprecated code.
179 /// @note Only intended to be used internally whilst parent code is being
180 /// deprecated
181 /// @details Example:
182 /// @code
183 /// OPENVDB_DEPRECATED void myDeprecatedFunction() {}
184 ///
185 /// {
186 /// OPENVDB_NO_DEPRECATION_WARNING_BEGIN
187 /// myDeprecatedFunction();
188 /// OPENVDB_NO_DEPRECATION_WARNING_END
189 /// }
190 /// @endcode
191 #if defined __INTEL_COMPILER
192  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
193  _Pragma("warning (push)") \
194  _Pragma("warning (disable:1478)")
195  #define OPENVDB_NO_DEPRECATION_WARNING_END \
196  _Pragma("warning (pop)")
197 #elif defined __clang__
198  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
199  _Pragma("clang diagnostic push") \
200  _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
201  // note: no #pragma message, since Clang treats them as warnings
202  #define OPENVDB_NO_DEPRECATION_WARNING_END \
203  _Pragma("clang diagnostic pop")
204 #elif defined __GNUC__
205  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
206  _Pragma("GCC diagnostic push") \
207  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
208  #define OPENVDB_NO_DEPRECATION_WARNING_END \
209  _Pragma("GCC diagnostic pop")
210 #elif defined _MSC_VER
211  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN \
212  __pragma(warning(push)) \
213  __pragma(warning(disable : 4996))
214  #define OPENVDB_NO_DEPRECATION_WARNING_END \
215  __pragma(warning(pop))
216 #else
217  #define OPENVDB_NO_DEPRECATION_WARNING_BEGIN
218  #define OPENVDB_NO_DEPRECATION_WARNING_END
219 #endif
220 
221 
222 /// @brief Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END,
223 /// to inhibit warnings about type conversion.
224 /// @note Use this sparingly. Use static casts and explicit type conversion if at all possible.
225 /// @details Example:
226 /// @code
227 /// float value = 0.1f;
228 /// OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
229 /// int valueAsInt = value;
230 /// OPENVDB_NO_TYPE_CONVERSION_WARNING_END
231 /// @endcode
232 #if defined __INTEL_COMPILER
233  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
234  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
235 #elif defined __GNUC__
236  // -Wfloat-conversion was only introduced in GCC 4.9
237  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \
238  _Pragma("GCC diagnostic push") \
239  _Pragma("GCC diagnostic ignored \"-Wconversion\"") \
240  _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"")
241  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END \
242  _Pragma("GCC diagnostic pop")
243 #else
244  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
245  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
246 #endif
247 
248 /// Helper macros for defining library symbol visibility
249 #ifdef OPENVDB_EXPORT
250 #undef OPENVDB_EXPORT
251 #endif
252 #ifdef OPENVDB_IMPORT
253 #undef OPENVDB_IMPORT
254 #endif
255 #ifdef _WIN32
256  #ifdef OPENVDB_DLL
257  #define OPENVDB_EXPORT __declspec(dllexport)
258  #define OPENVDB_IMPORT __declspec(dllimport)
259  #else
260  #define OPENVDB_EXPORT
261  #define OPENVDB_IMPORT
262  #endif
263 #elif defined(__GNUC__)
264  #define OPENVDB_EXPORT __attribute__((visibility("default")))
265  #define OPENVDB_IMPORT __attribute__((visibility("default")))
266 #endif
267 
268 /// Helper macros for explicit template instantiation
269 #if defined(_WIN32) && defined(OPENVDB_DLL)
270  #ifdef OPENVDB_PRIVATE
271  #define OPENVDB_TEMPLATE_EXPORT OPENVDB_EXPORT
272  #define OPENVDB_TEMPLATE_IMPORT
273  #else
274  #define OPENVDB_TEMPLATE_EXPORT
275  #define OPENVDB_TEMPLATE_IMPORT OPENVDB_IMPORT
276  #endif
277 #else
278  #define OPENVDB_TEMPLATE_IMPORT
279  #define OPENVDB_TEMPLATE_EXPORT
280 #endif
281 
282 /// All classes and public free standing functions must be explicitly marked
283 /// as <lib>_API to be exported. The <lib>_PRIVATE macros are defined when
284 /// building that particular library.
285 #ifdef OPENVDB_API
286 #undef OPENVDB_API
287 #endif
288 #ifdef OPENVDB_PRIVATE
289  #define OPENVDB_API OPENVDB_EXPORT
290 #else
291  #define OPENVDB_API OPENVDB_IMPORT
292 #endif
293 #ifdef OPENVDB_HOUDINI_API
294 #undef OPENVDB_HOUDINI_API
295 #endif
296 #ifdef OPENVDB_HOUDINI_PRIVATE
297  #define OPENVDB_HOUDINI_API OPENVDB_EXPORT
298 #else
299  #define OPENVDB_HOUDINI_API OPENVDB_IMPORT
300 #endif
301 
302 #ifdef OPENVDB_AX_DLL
303 #ifdef OPENVDB_AX_API
304 #undef OPENVDB_AX_API
305 #endif
306 #ifdef OPENVDB_AX_PRIVATE
307  #define OPENVDB_AX_API OPENVDB_EXPORT
308 #else
309  #define OPENVDB_AX_API OPENVDB_IMPORT
310 #endif
311 #else
312 #define OPENVDB_AX_API
313 #endif // OPENVDB_AX_DLL
314 
315 #if defined(__ICC)
316 
317 // Use these defines to bracket a region of code that has safe static accesses.
318 // Keep the region as small as possible.
319 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
320 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
321 #define OPENVDB_START_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
322 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
323 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
324 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
325 
326 // Use these defines to bracket a region of code that has unsafe static accesses.
327 // Keep the region as small as possible.
328 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
329 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
330 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
331 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
332 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
333 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
334 
335 // Simpler version for one-line cases
336 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) \
337  __pragma(warning(disable:1710)); CODE; __pragma(warning(default:1710))
338 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) \
339  __pragma(warning(disable:1711)); CODE; __pragma(warning(default:1711))
340 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) \
341  __pragma(warning(disable:1712)); CODE; __pragma(warning(default:1712))
342 
343 #else // GCC does not support these compiler warnings
344 
345 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE
346 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE
347 #define OPENVDB_START_THREADSAFE_STATIC_WRITE
348 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE
349 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS
350 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS
351 
352 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE
353 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE
354 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE
355 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE
356 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS
357 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS
358 
359 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) CODE
360 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) CODE
361 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) CODE
362 
363 #endif // defined(__ICC)
364 
365 #endif // OPENVDB_PLATFORM_HAS_BEEN_INCLUDED