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