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