HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
platform.h
Go to the documentation of this file.
1 /*
2  Copyright 2014 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 
32 /////////////////////////////////////////////////////////////////////////
33 /// @file platform.h
34 ///
35 /// @brief Platform-related macros.
36 /////////////////////////////////////////////////////////////////////////
37 
38 // clang-format off
39 
40 #pragma once
41 
42 #include <utility> // std::forward
43 
44 // Make sure all platforms have the explicit sized integer types
45 #ifndef __STDC_LIMIT_MACROS
46 # define __STDC_LIMIT_MACROS /* needed for some defs in stdint.h */
47 #endif
48 #include <cstdint>
49 
50 #if defined(__FreeBSD__)
51 # include <sys/param.h>
52 #endif
53 
54 #ifdef __MINGW32__
55 # include <malloc.h> // for alloca
56 #endif
57 
58 #if defined(_MSC_VER) || defined(_WIN32)
59 # ifndef WIN32_LEAN_AND_MEAN
60 # define WIN32_LEAN_AND_MEAN
61 # endif
62 # ifndef VC_EXTRALEAN
63 # define VC_EXTRALEAN
64 # endif
65 # ifndef NOMINMAX
66 # define NOMINMAX
67 # endif
68 # include <windows.h>
69 #endif
70 
71 #ifdef _MSC_VER
72 # include <intrin.h>
73 #endif
74 
76 
77 // Detect which C++ standard we're using, and handy macros.
78 //
79 // OIIO_CPLUSPLUS_VERSION : which C++ standard is compiling (3, 11, 14, ...)
80 // OIIO_USING_CPP11 : (deprecated) defined and 1 if using C++11 or newer.
81 // OIIO_CONSTEXPR14 : constexpr for C++ >= 14, otherwise nothing (this is
82 // useful for things that can only be constexpr for 14)
83 // OIIO_CONSTEXPR17 : constexpr for C++ >= 17, otherwise nothing (this is
84 // useful for things that can only be constexpr for 17)
85 //
86 // Note: oiioversion.h defines OIIO_BUILD_CPP11, OIIO_BUILD_CPP14,
87 // OIIO_BUILD_CPP17, or OIIO_BUILD_CPP20 to be 1 if OIIO itself was *built*
88 // using C++11, C++14, C++17, or C++20, respectively. In contrast,
89 // OIIO_CPLUSPLUS_VERSION defined below will be set to the right number for
90 // the C++ standard being compiled RIGHT NOW. These two things may be the
91 // same when compiling OIIO, but they may not be the same if another
92 // packages is compiling against OIIO and using these headers (OIIO may be
93 // C++11 but the client package may be older, or vice versa -- use these two
94 // symbols to differentiate these cases, when important).
95 #if (__cplusplus >= 201703L)
96 # define OIIO_CPLUSPLUS_VERSION 17
97 # define OIIO_CONSTEXPR14 constexpr
98 # define OIIO_CONSTEXPR17 constexpr
99 # define OIIO_CONSTEXPR20 /* not constexpr before C++20 */
100 #elif (__cplusplus >= 201402L)
101 # define OIIO_CPLUSPLUS_VERSION 14
102 # define OIIO_CONSTEXPR14 constexpr
103 # define OIIO_CONSTEXPR17 /* not constexpr before C++17 */
104 # define OIIO_CONSTEXPR20 /* not constexpr before C++20 */
105 #elif (__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
106 # define OIIO_CPLUSPLUS_VERSION 11
107 # define OIIO_CONSTEXPR14 /* not constexpr before C++14 */
108 # define OIIO_CONSTEXPR17 /* not constexpr before C++17 */
109 # define OIIO_CONSTEXPR20 /* not constexpr before C++20 */
110 #else
111 # error "This version of OIIO is meant to work only with C++11 and above"
112 #endif
113 
114 // DEPRECATED(1.8): use C++11 constexpr
115 #define OIIO_CONSTEXPR constexpr
116 #define OIIO_CONSTEXPR_OR_CONST constexpr
117 
118 // DEPRECATED(1.8): use C++11 noexcept
119 #define OIIO_NOEXCEPT noexcept
120 
121 
122 // In C++20 (and some compilers before that), __has_cpp_attribute can
123 // test for understand of [[attr]] tests.
124 #ifndef __has_cpp_attribute
125 # define __has_cpp_attribute(x) 0
126 #endif
127 
128 // On gcc & clang, __has_attribute can test for __attribute__((attr))
129 #ifndef __has_attribute
130 # define __has_attribute(x) 0
131 #endif
132 
133 // In C++17 (and some compilers before that), __has_include("blah.h") or
134 // __has_include(<blah.h>) can test for presence of an include file.
135 #ifndef __has_include
136 # define __has_include(x) 0
137 #endif
138 
139 
140 
141 // Detect which compiler and version we're using
142 
143 // Define OIIO_GNUC_VERSION to hold an encoded gcc version (e.g. 40802 for
144 // 4.8.2), or 0 if not a GCC release. N.B.: This will be 0 for clang.
145 #if defined(__GNUC__) && !defined(__clang__)
146 # define OIIO_GNUC_VERSION (10000*__GNUC__ + 100*__GNUC_MINOR__ + __GNUC_PATCHLEVEL__)
147 #else
148 # define OIIO_GNUC_VERSION 0
149 #endif
150 
151 // Define OIIO_CLANG_VERSION to hold an encoded generic Clang version (e.g.
152 // 30402 for clang 3.4.2), or 0 if not a generic Clang release.
153 // N.B. This will be 0 for the clang Apple distributes (which has different
154 // version numbers entirely).
155 #if defined(__clang__) && !defined(__apple_build_version__)
156 # define OIIO_CLANG_VERSION (10000*__clang_major__ + 100*__clang_minor__ + __clang_patchlevel__)
157 #else
158 # define OIIO_CLANG_VERSION 0
159 #endif
160 
161 // Define OIIO_APPLE_CLANG_VERSION to hold an encoded Apple Clang version
162 // (e.g. 70002 for clang 7.0.2), or 0 if not an Apple Clang release.
163 #if defined(__clang__) && defined(__apple_build_version__)
164 # define OIIO_APPLE_CLANG_VERSION (10000*__clang_major__ + 100*__clang_minor__ + __clang_patchlevel__)
165 #else
166 # define OIIO_APPLE_CLANG_VERSION 0
167 #endif
168 
169 // Tests for MSVS versions, always 0 if not MSVS at all.
170 #if defined(_MSC_VER)
171 # if _MSC_VER < 1900
172 # error "This version of OIIO is meant to work only with Visual Studio 2015 or later"
173 # endif
174 # define OIIO_MSVS_AT_LEAST_2013 (_MSC_VER >= 1800)
175 # define OIIO_MSVS_BEFORE_2013 (_MSC_VER < 1800)
176 # define OIIO_MSVS_AT_LEAST_2015 (_MSC_VER >= 1900)
177 # define OIIO_MSVS_BEFORE_2015 (_MSC_VER < 1900)
178 # define OIIO_MSVS_AT_LEAST_2017 (_MSC_VER >= 1910)
179 # define OIIO_MSVS_BEFORE_2017 (_MSC_VER < 1910)
180 #else
181 # define OIIO_MSVS_AT_LEAST_2013 0
182 # define OIIO_MSVS_BEFORE_2013 0
183 # define OIIO_MSVS_AT_LEAST_2015 0
184 # define OIIO_MSVS_BEFORE_2015 0
185 # define OIIO_MSVS_AT_LEAST_2017 0
186 # define OIIO_MSVS_BEFORE_2017 0
187 #endif
188 
189 
190 /// allocates memory, equivalent of C99 type var_name[size]
191 #define OIIO_ALLOCA(type, size) ((size) != 0 ? ((type*)alloca((size) * sizeof (type))) : nullptr)
192 
193 /// Deprecated (for namespace pollution reasons)
194 #define ALLOCA(type, size) ((size) != 0 ? ((type*)alloca((size) * sizeof (type))) : nullptr)
195 
196 
197 // Define a macro that can be used for memory alignment.
198 // This macro is mostly obsolete and C++11 alignas() should be preferred
199 // for new code.
200 #if defined(__GNUC__) || __has_attribute(aligned)
201 # define OIIO_ALIGN(size) __attribute__((aligned(size)))
202 #elif defined(_MSC_VER)
203 # define OIIO_ALIGN(size) __declspec(align(size))
204 #elif defined(__INTEL_COMPILER)
205 # define OIIO_ALIGN(size) __declspec(align((size)))
206 #else
207 # error "Don't know how to define OIIO_ALIGN"
208 #endif
209 
210 // Cache line size is 64 on all modern x86 CPUs. If this changes or we
211 // anticipate ports to other architectures, we'll need to change this.
212 #define OIIO_CACHE_LINE_SIZE 64
213 
214 // Align the next declaration to be on its own cache line
215 #define OIIO_CACHE_ALIGN OIIO_ALIGN(OIIO_CACHE_LINE_SIZE)
216 
217 
218 
219 // gcc defines a special intrinsic to use in conditionals that can speed
220 // up extremely performance-critical spots if the conditional usually
221 // (or rarely) is true. You use it by replacing
222 // if (x) ...
223 // with
224 // if (OIIO_LIKELY(x)) ... // if you think x will usually be true
225 // or
226 // if (OIIO_UNLIKELY(x)) ... // if you think x will rarely be true
227 // Caveat: Programmers are notoriously bad at guessing this, so it
228 // should be used only with thorough benchmarking.
229 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
230 # define OIIO_LIKELY(x) (__builtin_expect(bool(x), true))
231 # define OIIO_UNLIKELY(x) (__builtin_expect(bool(x), false))
232 #else
233 # define OIIO_LIKELY(x) (x)
234 # define OIIO_UNLIKELY(x) (x)
235 #endif
236 
237 
238 // OIIO_FORCELINE is a function attribute that attempts to make the function
239 // always inline. On many compilers regular 'inline' is only advisory. Put
240 // this attribute before the function return type, just like you would use
241 // 'inline'.
242 #if defined(__CUDACC__)
243 # define OIIO_FORCEINLINE __inline__
244 #elif defined(__GNUC__) || defined(__clang__) || __has_attribute(always_inline)
245 # define OIIO_FORCEINLINE inline __attribute__((always_inline))
246 #elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
247 # define OIIO_FORCEINLINE __forceinline
248 #else
249 # define OIIO_FORCEINLINE inline
250 #endif
251 
252 // OIIO_PURE_FUNC is a function attribute that assures the compiler that the
253 // function does not write to any non-local memory other than its return
254 // value and has no side effects. This can ebable additional compiler
255 // optimizations by knowing that calling the function cannot possibly alter
256 // any other memory. This declaration goes after the function declaration:
257 // int blah (int arg) OIIO_PURE_FUNC;
258 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) || __has_attribute(pure)
259 # define OIIO_PURE_FUNC __attribute__((pure))
260 #elif defined(_MSC_VER)
261 # define OIIO_PURE_FUNC /* seems not supported by MSVS */
262 #else
263 # define OIIO_PURE_FUNC
264 #endif
265 
266 // OIIO_CONST_FUNC is a function attribute that assures the compiler that
267 // the function does not examine (read) any values except for its arguments,
268 // does not write any non-local memory other than its return value, and has
269 // no side effects. This is even more strict than 'pure', and allows even
270 // more optimizations (such as eliminating multiple calls to the function
271 // that have the exact same argument values).
272 #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) || __has_attribute(const)
273 # define OIIO_CONST_FUNC __attribute__((const))
274 #elif defined(_MSC_VER)
275 # define OIIO_CONST_FUNC /* seems not supported by MSVS */
276 #else
277 # define OIIO_CONST_FUNC
278 #endif
279 
280 // OIIO_MAYBE_UNUSED is a function or variable attribute that assures the
281 // compiler that it's fine for the item to appear to be unused.
282 #if OIIO_CPLUSPLUS_VERSION >= 17 || __has_cpp_attribute(maybe_unused)
283 # define OIIO_MAYBE_UNUSED [[maybe_unused]]
284 #elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) || __has_attribute(unused)
285 # define OIIO_MAYBE_UNUSED __attribute__((unused))
286 #else
287 # define OIIO_MAYBE_UNUSED
288 #endif
289 
290 // DEPRECATED(1.9) name:
291 #define OIIO_UNUSED_OK OIIO_MAYBE_UNUSED
292 
293 // OIIO_RESTRICT is a parameter attribute that indicates a promise that the
294 // parameter definitely will not alias any other parameters in such a way
295 // that creates a data dependency. Use with caution!
296 #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) || defined(__INTEL_COMPILER)
297 # define OIIO_RESTRICT __restrict
298 #else
299 # define OIIO_RESTRICT
300 #endif
301 
302 
303 #if OIIO_CPLUSPLUS_VERSION >= 14 || __has_cpp_attribute(deprecated)
304 # define OIIO_DEPRECATED(msg) [[deprecated(msg)]]
305 #elif defined(__GNUC__) || defined(__clang__) || __has_attribute(deprecated)
306 # define OIIO_DEPRECATED(msg) __attribute__((deprecated(msg)))
307 #elif defined(_MSC_VER)
308 # define OIIO_DEPRECATED(msg) __declspec(deprecated(msg))
309 #else
310 # define OIIO_DEPRECATED(msg)
311 #endif
312 
313 
314 // OIIO_FALLTHROUGH documents that switch statement fallthrough case.
315 #if OIIO_CPLUSPLUS_VERSION >= 17 || __has_cpp_attribute(fallthrough)
316 # define OIIO_FALLTHROUGH [[fallthrough]]
317 #else
318 # define OIIO_FALLTHROUGH
319 #endif
320 
321 
322 // OIIO_NODISCARD documents functions whose return values should never be
323 // ignored.
324 #if OIIO_CPLUSPLUS_VERSION >= 17 || __has_cpp_attribute(nodiscard)
325 # define OIIO_NODISCARD [[nodiscard]]
326 #else
327 # define OIIO_NODISCARD
328 #endif
329 
330 
331 // OIIO_NO_SANITIZE_ADDRESS can be used to mark a function that you don't
332 // want address sanitizer to catch. Only use this if you know there are
333 // false positives that you can't easily get rid of.
334 // This should work for any clang >= 3.3 and gcc >= 4.8, which are
335 // guaranteed by our minimum requirements.
336 #if defined(__clang__) || defined(__GNUC__) || __has_attribute(no_sanitize_address)
337 # define OIIO_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
338 #else
339 # define OIIO_NO_SANITIZE_ADDRESS
340 #endif
341 
342 
343 // OIIO_HOSTDEVICE is used to supply the function decorators needed when
344 // compiling for CUDA devices.
345 #ifdef __CUDACC__
346 # define OIIO_HOSTDEVICE __host__ __device__
347 #else
348 # define OIIO_HOSTDEVICE
349 #endif
350 
351 
353 
354 /// Class for describing endianness. Test for endianness as
355 /// `if (endian::native == endian::little)` or
356 /// `if (endian::native == endian::big)`.
357 /// This uses the same semantics as C++20's std::endian.
358 enum class endian {
359 #ifdef _WIN32 /* All Windows platforms are little endian */
360  little = 0,
361  big = 1,
362  native = little
363 #else /* gcc, clang, icc all define these macros */
364  little = __ORDER_LITTLE_ENDIAN__,
365  big = __ORDER_BIG_ENDIAN__,
366  native = __BYTE_ORDER__
367 #endif
368 };
369 
370 
371 /// Return true if the architecture we are running on is little endian
372 OIIO_FORCEINLINE constexpr bool
374 {
375  return endian::native == endian::little;
376 }
377 
378 
379 /// Return true if the architecture we are running on is big endian
380 OIIO_FORCEINLINE constexpr bool
382 {
383  return endian::native == endian::big;
384 }
385 
386 
387 
388 /// Retrieve cpuid flags into 'info'.
389 inline void cpuid (int info[4], int infoType, int extra)
390 {
391  // Implementation cribbed from Halide (http://halide-lang.org), which
392  // cribbed it from ISPC (https://github.com/ispc/ispc).
393 #if (defined(_WIN32) || defined(__i386__) || defined(__x86_64__))
394 # ifdef _MSC_VER
395  __cpuidex(info, infoType, extra);
396 # elif defined(__x86_64__)
397  __asm__ __volatile__ (
398  "cpuid \n\t"
399  : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
400  : "0" (infoType), "2" (extra));
401 # else
402  __asm__ __volatile__ (
403  "mov{l}\t{%%}ebx, %1 \n\t"
404  "cpuid \n\t"
405  "xchg{l}\t{%%}ebx, %1 \n\t"
406  : "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3])
407  : "0" (infoType), "2" (extra));
408 # endif
409 #else
410  info[0] = 0; info[1] = 0; info[2] = 0; info[3] = 0;
411 #endif
412 }
413 
414 
415 inline bool cpu_has_sse2 () {int i[4]; cpuid(i,1,0); return (i[3] & (1<<26)) != 0; }
416 inline bool cpu_has_sse3 () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<0)) != 0; }
417 inline bool cpu_has_ssse3 () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<9)) != 0; }
418 inline bool cpu_has_fma () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<12)) != 0; }
419 inline bool cpu_has_sse41 () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<19)) != 0; }
420 inline bool cpu_has_sse42 () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<20)) != 0; }
421 inline bool cpu_has_popcnt() {int i[4]; cpuid(i,1,0); return (i[2] & (1<<23)) != 0; }
422 inline bool cpu_has_avx () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<28)) != 0; }
423 inline bool cpu_has_f16c () {int i[4]; cpuid(i,1,0); return (i[2] & (1<<29)) != 0; }
424 inline bool cpu_has_rdrand() {int i[4]; cpuid(i,1,0); return (i[2] & (1<<30)) != 0; }
425 inline bool cpu_has_avx2 () {int i[4]; cpuid(i,7,0); return (i[1] & (1<<5)) != 0; }
426 inline bool cpu_has_avx512f() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<16)) != 0; }
427 inline bool cpu_has_avx512dq() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<17)) != 0; }
428 inline bool cpu_has_avx512ifma() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<21)) != 0; }
429 inline bool cpu_has_avx512pf() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<26)) != 0; }
430 inline bool cpu_has_avx512er() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<27)) != 0; }
431 inline bool cpu_has_avx512cd() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<28)) != 0; }
432 inline bool cpu_has_avx512bw() {int i[4]; cpuid(i,7,0); return (i[1] & (1<<30)) != 0; }
433 inline bool cpu_has_avx512vl() {int i[4]; cpuid(i,7,0); return (i[1] & (0x80000000 /*1<<31*/)) != 0; }
434 
435 // portable aligned malloc
436 void* aligned_malloc(std::size_t size, std::size_t align);
437 void aligned_free(void* ptr);
438 
439 // basic wrappers to new/delete over-aligned types since this isn't guaranteed to be supported until C++17
440 template <typename T, class... Args>
441 inline T* aligned_new(Args&&... args) {
442  static_assert(alignof(T) > alignof(void*), "Type doesn't seem to be over-aligned, aligned_new is not required");
443  void* ptr = aligned_malloc(sizeof(T), alignof(T));
444  return ptr ? new (ptr) T(std::forward<Args>(args)...) : nullptr;
445 }
446 
447 template <typename T>
448 inline void aligned_delete(T* t) {
449  if (t) {
450  t->~T();
451  aligned_free(t);
452  }
453 }
454 
455 
bool cpu_has_sse42()
Definition: platform.h:420
bool cpu_has_avx512ifma()
Definition: platform.h:428
GLsizeiptr size
Definition: glew.h:1681
void aligned_delete(T *t)
Definition: platform.h:448
#define OIIO_FORCEINLINE
Definition: platform.h:249
bool cpu_has_avx()
Definition: platform.h:422
bool cpu_has_avx512cd()
Definition: platform.h:431
const Args & args
Definition: printf.h:628
bool cpu_has_avx2()
Definition: platform.h:425
bool cpu_has_fma()
Definition: platform.h:418
bool cpu_has_sse2()
Definition: platform.h:415
bool cpu_has_sse3()
Definition: platform.h:416
bool cpu_has_avx512pf()
Definition: platform.h:429
OIIO_FORCEINLINE constexpr bool littleendian(void)
Return true if the architecture we are running on is little endian.
Definition: platform.h:373
bool cpu_has_avx512vl()
Definition: platform.h:433
bool cpu_has_avx512bw()
Definition: platform.h:432
void cpuid(int info[4], int infoType, int extra)
Retrieve cpuid flags into 'info'.
Definition: platform.h:389
void aligned_free(void *ptr)
bool cpu_has_rdrand()
Definition: platform.h:424
const void * ptr(const T *p)
Definition: format.h:3292
bool cpu_has_f16c()
Definition: platform.h:423
endian
Definition: platform.h:358
bool cpu_has_avx512er()
Definition: platform.h:430
bool cpu_has_avx512dq()
Definition: platform.h:427
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
bool cpu_has_avx512f()
Definition: platform.h:426
OIIO_FORCEINLINE constexpr bool bigendian(void)
Return true if the architecture we are running on is big endian.
Definition: platform.h:381
bool cpu_has_popcnt()
Definition: platform.h:421
void * aligned_malloc(std::size_t size, std::size_t align)
GLdouble GLdouble t
Definition: glew.h:1398
bool cpu_has_ssse3()
Definition: platform.h:417
bool cpu_has_sse41()
Definition: platform.h:419
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:65
T * aligned_new(Args &&...args)
Definition: platform.h:441