OpenVDB: openvdb/Platform.h Source File

OpenVDB 13.0.0

Loading...
Searching...
No Matches
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