OpenVDB  12.0.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 /// 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  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN \
215  _Pragma("GCC diagnostic push") \
216  _Pragma("GCC diagnostic ignored \"-Wconversion\"") \
217  _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"")
218  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END \
219  _Pragma("GCC diagnostic pop")
220 #else
221  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
222  #define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
223 #endif
224 
225 /// Helper macros for defining library symbol visibility
226 #ifdef OPENVDB_EXPORT
227 #undef OPENVDB_EXPORT
228 #endif
229 #ifdef OPENVDB_IMPORT
230 #undef OPENVDB_IMPORT
231 #endif
232 #ifdef _WIN32
233  #ifdef OPENVDB_DLL
234  #define OPENVDB_EXPORT __declspec(dllexport)
235  #define OPENVDB_IMPORT __declspec(dllimport)
236  #else
237  #define OPENVDB_EXPORT
238  #define OPENVDB_IMPORT
239  #endif
240 #elif defined(__GNUC__)
241  #define OPENVDB_EXPORT __attribute__((visibility("default")))
242  #define OPENVDB_IMPORT __attribute__((visibility("default")))
243 #endif
244 
245 /// Helper macros for explicit template instantiation
246 #if defined(_WIN32) && defined(OPENVDB_DLL)
247  #ifdef OPENVDB_PRIVATE
248  #define OPENVDB_TEMPLATE_EXPORT OPENVDB_EXPORT
249  #define OPENVDB_TEMPLATE_IMPORT
250  #else
251  #define OPENVDB_TEMPLATE_EXPORT
252  #define OPENVDB_TEMPLATE_IMPORT OPENVDB_IMPORT
253  #endif
254 #else
255  #define OPENVDB_TEMPLATE_IMPORT
256  #define OPENVDB_TEMPLATE_EXPORT
257 #endif
258 
259 /// All classes and public free standing functions must be explicitly marked
260 /// as <lib>_API to be exported. The <lib>_PRIVATE macros are defined when
261 /// building that particular library.
262 #ifdef OPENVDB_API
263 #undef OPENVDB_API
264 #endif
265 #ifdef OPENVDB_PRIVATE
266  #define OPENVDB_API OPENVDB_EXPORT
267 #else
268  #define OPENVDB_API OPENVDB_IMPORT
269 #endif
270 #ifdef OPENVDB_HOUDINI_API
271 #undef OPENVDB_HOUDINI_API
272 #endif
273 #ifdef OPENVDB_HOUDINI_PRIVATE
274  #define OPENVDB_HOUDINI_API OPENVDB_EXPORT
275 #else
276  #define OPENVDB_HOUDINI_API OPENVDB_IMPORT
277 #endif
278 
279 #ifdef OPENVDB_AX_DLL
280 #ifdef OPENVDB_AX_API
281 #undef OPENVDB_AX_API
282 #endif
283 #ifdef OPENVDB_AX_PRIVATE
284  #define OPENVDB_AX_API OPENVDB_EXPORT
285 #else
286  #define OPENVDB_AX_API OPENVDB_IMPORT
287 #endif
288 #else
289 #define OPENVDB_AX_API
290 #endif // OPENVDB_AX_DLL
291 
292 #if defined(__ICC)
293 
294 // Use these defines to bracket a region of code that has safe static accesses.
295 // Keep the region as small as possible.
296 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
297 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
298 #define OPENVDB_START_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
299 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
300 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
301 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
302 
303 // Use these defines to bracket a region of code that has unsafe static accesses.
304 // Keep the region as small as possible.
305 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(disable:1710))
306 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE __pragma(warning(default:1710))
307 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE __pragma(warning(disable:1711))
308 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE __pragma(warning(default:1711))
309 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(disable:1712))
310 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS __pragma(warning(default:1712))
311 
312 // Simpler version for one-line cases
313 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) \
314  __pragma(warning(disable:1710)); CODE; __pragma(warning(default:1710))
315 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) \
316  __pragma(warning(disable:1711)); CODE; __pragma(warning(default:1711))
317 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) \
318  __pragma(warning(disable:1712)); CODE; __pragma(warning(default:1712))
319 
320 #else // GCC does not support these compiler warnings
321 
322 #define OPENVDB_START_THREADSAFE_STATIC_REFERENCE
323 #define OPENVDB_FINISH_THREADSAFE_STATIC_REFERENCE
324 #define OPENVDB_START_THREADSAFE_STATIC_WRITE
325 #define OPENVDB_FINISH_THREADSAFE_STATIC_WRITE
326 #define OPENVDB_START_THREADSAFE_STATIC_ADDRESS
327 #define OPENVDB_FINISH_THREADSAFE_STATIC_ADDRESS
328 
329 #define OPENVDB_START_NON_THREADSAFE_STATIC_REFERENCE
330 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_REFERENCE
331 #define OPENVDB_START_NON_THREADSAFE_STATIC_WRITE
332 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_WRITE
333 #define OPENVDB_START_NON_THREADSAFE_STATIC_ADDRESS
334 #define OPENVDB_FINISH_NON_THREADSAFE_STATIC_ADDRESS
335 
336 #define OPENVDB_THREADSAFE_STATIC_REFERENCE(CODE) CODE
337 #define OPENVDB_THREADSAFE_STATIC_WRITE(CODE) CODE
338 #define OPENVDB_THREADSAFE_STATIC_ADDRESS(CODE) CODE
339 
340 #endif // defined(__ICC)
341 
342 #endif // OPENVDB_PLATFORM_HAS_BEEN_INCLUDED