├── README.md └── cxx_detect.h /README.md: -------------------------------------------------------------------------------- 1 | cxx_detect.h 2 | ------------ 3 | 4 | C++ compiler and features detection: 5 | 6 | * C/C++ compiler vendor and version. 7 | * C/C++ compiler features. 8 | * Target architecture. 9 | * Target operating system. 10 | 11 | Compiler-neutral macros: 12 | 13 | * API visibility control (visibility, import, export). 14 | * C/C++ calling convention. 15 | * Likely / unlikely. 16 | * Assumptions about code and alignment. 17 | * Function decorators (inline, no-inline, no-return). 18 | * C/C++ language features like fallthrough. 19 | * C/C++ support for typical concepts like length of a static array[], offset-of, etc. 20 | 21 | This project is dual licensed under **PUBLIC DOMAIN** and **ZLIB** licenses. ZLIB is provided for those that cannot use PUBLIC DOMAIN. Contributing to this project means that you agree with the licensing and that you make the contribution available under BOTH licenses mentioned. 22 | 23 | Disclaimer 24 | ---------- 25 | 26 | The project just started and still forms itself, however, it reached a certain stability already. Let us know if you think some macros should be renamed or added. 27 | 28 | Design 29 | ------ 30 | 31 | * If you never needed something like this you are lucky! However, if you found yourself having broken builds on CI because of wrongly written auto-detection, try `cxx_detect.h` or take it as an inspiration for your own solution. 32 | * It shouldn't be used as a dependency, distribute `cxx_detect.h` with your project / product and update it from time to time to ensure compatibility with new compilers and C++ features. 33 | * The whole functionality is implemented in a single header `cxx_detect.h` and all macros provided start with **CXX_** prefix. The intention is that multiple projects can use the same macros instead of defining their own like `SOMEPROJECT_HAS_RVALUE_REFERENCES` or `SOMEPROJECT_INLINE`. 34 | * The header is versioned and will automatically update all macros if older `cxx_detect.h` was included previously, allowing coexistence of multiple projects having various versions of the header embedded with them. Each inclusion of `cxx_detect.h` performs a version check and updates itself when necessary. 35 | 36 | The header defines a set of preprocessor macros that can be divided into the following categories: 37 | 38 | * Values - in most cases used to store a boolean value that contains 0 (feature not-present) or 1 (feature present). Alternatively, non-boolean values can contain arbitrary constant clarifying some feature or compiler version. 39 | * Macros - used to implement common concepts in a compiler agnostic way like **CXX_LIKELY**, **CXX_EXPORT**, etc... which would expand to a vendor-specific code. 40 | 41 | The library mostly targets C++ projects that require extensible detection of C++ features, but it does no harm to C - it just defines macros, nothing else, so it's perfectly safe for any kind of C/C++/ObjC project. 42 | 43 | Motivation 44 | ---------- 45 | 46 | This header started as an experiment to unify needs of various projects. When a project starts it's usually small and clean and everybody wants to keep it that way, but when it gets features, when it's ported to other architectures and supposed to be compiled by more C/C++ compilers, the amount of compiler-specific stuff grows and sometimes it gets challenging to get it right from the beginning. For example there isn't a way to 'force-inline' function without knowing vendor-specific keywords, there is no cross-platform API (export / import) concept, and there is in general no easy C++ features detection outside of clang. 47 | 48 | It's not just about the C++ standardized features. Today's compilers support a lot of extensions that make our lives easier - sanitizers, code deprecation, annotatations to get rid of diagnostic warnings, etc... In general most projects try to solve this problem either locally or by relying on other library/framework that solves that problem for them, like boost or Qt. Projects that solve this locally have to provide and maintain a lot of `#ifdef`ed code that grows and that is sometimes hard to follow and understand as it tries to be as small as possible. 49 | 50 | The first phase of this project was to write a tool that generates all of this with `SOMEPROJECT_` prefix to solve the compiler detection and features locally, making all of the macros available per-project basis. That works well but clutters the project with project-specific macros which no other project(s) should use (they are usually not documented, they are not part of the API). Based on past experience the `cxx_detect.h` header was written to address such issues and to document what each macro means and how it should be used. 51 | 52 | Contributing 53 | ------------ 54 | 55 | If you like `cxx_detect.h` and would like to contribute please open an issue, and/or provide an implementation of your problem/solution. Pull requests are welcome if they solve a general problem (C/C++ features detection, C/C++ language support, etc...). 56 | 57 | The most appreciated contributions: 58 | 59 | * Supporting other C/C++ compilers (not outdated ones). 60 | * Supporting more C/C++ language features not currently provided. 61 | * Fixing wrongly detected features and macro names (if not too late). 62 | * Fixing and improving documentation (fixing terms and incorrectness, possibly providing links to each feature specification, etc). 63 | 64 | C/C++ Compiler Vendor and Version 65 | --------------------------------- 66 | 67 | Each compiler-vendor constant contains either 0, which means the compiler was not detected, or non-zero value, which represents a normalized compiler version. 68 | 69 | * `CXX_CLANG` - Clang C/C++ compiler. 70 | * `CXX_GNU` - GNU C/C++ compiler. 71 | * `CXX_INTEL` - Intel C/C++ compiler (ICC). 72 | * `CXX_MSC` - Microsoft C/C++ compiler (MSC). 73 | 74 | Additionally the following constants are provided: 75 | 76 | * `CXX_GNU_COMPAT` - GNU compatibility mode, contains GNU version the compiler pretents to be (or is, in case of GNU compiler). Please note that the version is not reliable, for example Clang 4.0.1 with C++11 enabled pretends to be GCC 4.2.1, which doesn't even officially support C++11. 77 | * `CXX_MINGW` - 0 if not MINGW, 32 if `__MINGW32__` is defined, or 64 if `__MINGW64__` is defined 78 | 79 | The compilers are checked the following way: 80 | 81 | ```c++ 82 | #if CXX_MSC 83 | // Microsoft compiler 84 | #elif CXX_GNU || CXX_CLANG 85 | // GNU or Clang 86 | #else 87 | // other 88 | #endif 89 | ``` 90 | 91 | If you need a compiler version you can use arithmetic operators and `CXX_MAKE_VER(MAJOR, MINOR, PATCH)` macro: 92 | 93 | ```c++ 94 | #if CXX_GNU >= CXX_MAKE_VER(4, 8, 2) 95 | // GNU compiler >= 4.8.2 96 | #elif CXX_MSC >= CXX_MAKE_VER(19, 0, 0) 97 | // MSC compiler >= 19.0.0 98 | #elif CXX_INTEL >= CXX_MAKE_VER(14, 1, 0) 99 | // Intel compiler >= 14.1.0 100 | #else 101 | // Other compiler 102 | #endif 103 | ``` 104 | 105 | Some compilers pretend to be GNU, you can check for `CXX_GNU_COMPAT` if you rely on GNU/Clang `__attribute__` or anything else: 106 | 107 | ```c++ 108 | // You can also use `CXX_GNU_COMPAT >= CXX_MAKE_VER(X, Y, Z)`, but it isn't reliable. 109 | #if CXX_GNU_COMPAT 110 | // Use GNU-compiler specifics. 111 | #endif 112 | ``` 113 | 114 | Please note that if the compiler is not GNU the `CXX_GNU` will always be 0 even if the compiler defines `__GNUC__`. So checking `__GNUC__` is not the same as checking `CXX_GNU`. Use `CXX_GNU_COMPAT` in such case, which will be set always accordingly to the GNU compatibilty level (or the same as `CXX_GNU` if the compiler actually is GNU). 115 | 116 | C/C++ Language Version 117 | ---------------------- 118 | 119 | * **CXX_CPLUSPLUS** - C++ version, 0 if not C++ (C mode only), or a number that mostly corresponds to `__cplusplus` if set properly (otherwise it's changed to contain either **199711L** or **201103L** depending on the compiler features available). 120 | 121 | C/C++ Compiler Features 122 | ----------------------- 123 | 124 | All macro names that describe a language feature should correspond to the name of the feature as used insinde clang's `__has_feature()` and `__has_extension` macros. 125 | 126 | Vendor Specific (all prefixed by `_X` to avoid collission with possible C++ ``[[attributes]]`): 127 | 128 | * `CXX_HAS_X_ASSUME` - `__assume` keyword. 129 | * `CXX_HAS_X_ASSUME_ALIGNED` - `__assume_aligned` keyword. 130 | * `CXX_HAS_X_ATTRIBUTE` - `__attribute__` in general. 131 | * `CXX_HAS_X_ATTRIBUTE_ALIGNED` - `__attribute__(__aligned__)`. 132 | * `CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE` - `__attribute__(__always_inline__)`. 133 | * `CXX_HAS_X_ATTRIBUTE_DEPRECATED` - `__attribute__(__deprecated__)`. 134 | * `CXX_HAS_X_ATTRIBUTE_NOINLINE` - `__attribute__(__noinline__)`. 135 | * `CXX_HAS_X_ATTRIBUTE_NORETURN` - `__attribute__(__noreturn__)`. 136 | * `CXX_HAS_X_ATTRIBUTE_OPTIMIZE` - `__attribute__(__optimize__)`. 137 | * `CXX_HAS_X_BUILTIN_ASSUME` - `__builtin_assume()`. 138 | * `CXX_HAS_X_BUILTIN_ASSUME_ALIGNED` - `__builtin_assume_aligned()`. 139 | * `CXX_HAS_X_BUILTIN_EXPECT` - `__builtin_expect()`. 140 | * `CXX_HAS_X_BUILTIN_UNREACHABLE` - `__builtin_unreachable()`. 141 | * `CXX_HAS_X_DECLSPEC_ALIGN` - `__declspec(align)`. 142 | * `CXX_HAS_X_DECLSPEC_DEPRECATED` - `__declspec(deprecated)` and __declspec(deprecated("msg")). 143 | * `CXX_HAS_X_DECLSPEC_NOINLINE` - `__declspec(noinline)`. 144 | * `CXX_HAS_X_DECLSPEC_NORETURN` - `__declspec(noreturn)`. 145 | * `CXX_HAS_X_FORCEINLINE` - `__forceinline` keyword. 146 | 147 | Standardized (C++11): 148 | 149 | * `CXX_HAS_ALIAS_TEMPLATES` - Alias templates. 150 | * `CXX_HAS_ALIGNAS` - `alignas` keyword. 151 | * `CXX_HAS_ALIGNOF` - `alignof` keyword. 152 | * `CXX_HAS_ATTRIBUTES` - `[[attributes]]` support. 153 | * `CXX_HAS_AUTO_TYPE` - `auto` type. 154 | * `CXX_HAS_CONSTEXPR` - `constexpr` keyword. 155 | * `CXX_HAS_DECLTYPE` - `decltype` keyword. 156 | * `CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS` - Default template arguments in function templates. 157 | * `CXX_HAS_DEFAULTED_FUNCTIONS` - Defaulted functions. 158 | * `CXX_HAS_DELEGATING_CONSTRUCTORS` - Delegating constructors. 159 | * `CXX_HAS_DELETED_FUNCTIONS` - Deleted functions. 160 | * `CXX_HAS_EXPLICIT_CONVERSIONS` - Explicit conversions. 161 | * `CXX_HAS_FINAL` - `final` keyword. 162 | * `CXX_HAS_INHERITING_CONSTRUCTORS` - Inheriting constructors. 163 | * `CXX_HAS_INITIALIZER_LISTS` - Initializer lists. 164 | * `CXX_HAS_INLINE_NAMESPACES` - Inline namespaces. 165 | * `CXX_HAS_LAMBDAS` - Lambda functions. 166 | * `CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS` - Local and unnamed types as template arguments. 167 | * `CXX_HAS_NOEXCEPT` - `noexcept` keyword. 168 | * `CXX_HAS_NONSTATIC_MEMBER_INIT` - In-class non-static data member initialization. 169 | * `CXX_HAS_NULLPTR` - `nullptr` keyword. 170 | * `CXX_HAS_OVERRIDE` - `override` keyword. 171 | * `CXX_HAS_RANGE_FOR` - Range-based for-loop. 172 | * `CXX_HAS_RAW_STRING_LITERALS` - Raw string literals `R"..."`. 173 | * `CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS` - Reference-qualified functions. 174 | * `CXX_HAS_RVALUE_REFERENCES` - RValue references & move semantics. 175 | * `CXX_HAS_STATIC_ASSERT` - `static_assert` keyword. 176 | * `CXX_HAS_STRONG_ENUMS` - Strongly typed enums. 177 | * `CXX_HAS_THREAD_LOCAL` - `thread_local` keyword. 178 | * `CXX_HAS_UNICODE_LITERALS` - Unicode literals. 179 | * `CXX_HAS_UNRESTRICTED_UNIONS` - Unrestricted unions. 180 | * `CXX_HAS_VARIADIC_TEMPLATES` - Variadic templates. 181 | 182 | Standardized (C++14): 183 | 184 | * `CXX_HAS_AGGREGATE_NSDMI` - Default initializers for aggregates (NSDMI). 185 | * `CXX_HAS_BINARY_LITERALS` - Binary literals. 186 | * `CXX_HAS_CONTEXTUAL_CONVERSIONS` - Contextual conversions. 187 | * `CXX_HAS_DECLTYPE_AUTO` - `decltype(auto)` support. 188 | * `CXX_HAS_GENERIC_LAMBDAS` - Generic lambdas. 189 | * `CXX_HAS_INIT_CAPTURES` - Generalized lambda capture (init-capture). 190 | * `CXX_HAS_RELAXED_CONSTEXPR` - Relaxed `constexpr`. 191 | * `CXX_HAS_VARIABLE_TEMPLATES` - Variable templates. 192 | 193 | Standardized (C++17): 194 | 195 | * (TODO) 196 | 197 | Type System: 198 | 199 | * `CXX_HAS_NATIVE_CHAR` - Native `char` type. 200 | * `CXX_HAS_NATIVE_CHAR16_T` - Native `char16_t` type (C++11), always matches `CXX_HAS_UNICODE_LITERALS`. 201 | * `CXX_HAS_NATIVE_CHAR32_T` - Native `char32_t` type (C++11), always matches `CXX_HAS_UNICODE_LITERALS`. 202 | * `CXX_HAS_NATIVE_WCHAR_T` - Native `wchar_t` type. 203 | 204 | Since all macros are always defined features can be checked by the following way: 205 | 206 | ```c++ 207 | #if !CXX_HAS_STRONG_ENUMS || \ 208 | !CXX_HAS_VARIADIC_TEMPLATES || \ 209 | !CXX_HAS_CONSTEXPR 210 | #error "Project X cannot be compiled as your compiler doesn't support some C++ features it requires" 211 | #endif 212 | ``` 213 | 214 | Another example: 215 | 216 | ```c++ 217 | class SomeClass { 218 | public: 219 | SomeClass() {} 220 | 221 | // Provide move semantics only if supported. 222 | #if CXX_HAS_RVALUE_REFERENCES 223 | SomeClass(SomeClass&& other) { ... } 224 | #endif 225 | } 226 | ``` 227 | 228 | Target Architecture 229 | ------------------- 230 | 231 | * `CXX_ARCH_X86` - Target architecture is 32-bit x86 (X86|IA32). 232 | * `CXX_ARCH_X86_64` - Target architecture is 64-bit x86 (X64|X86_64|AMD64). 233 | * `CXX_ARCH_ARM32` - Target architecture is 32-bit ARM or AArch32. 234 | * `CXX_ARCH_ARM64` - Target architecture is 64-bit AArch64. 235 | 236 | Additionally the following constants are provided: 237 | 238 | * `CXX_ARCH_BITS` - 32 or 64 depending on the architecture. 239 | * `CXX_ARCH_LE` - 1 if the target architecture is LITTLE ENDIAN, otherwise 0. 240 | * `CXX_ARCH_BE` - 1 if the target architecture is BIG ENDIAN, otherwise 0. 241 | 242 | Architectures can be checked the following way: 243 | 244 | ```c++ 245 | #if CXX_ARCH_X86 || CXX_ARCH_X86_64 246 | // X86 32-bit or 64-bit code path. 247 | #endif 248 | 249 | #if CXX_ARCH_BITS == 32 250 | // 32-bit arch code-path. 251 | #else 252 | // 64-bit arch code-path. 253 | #endif 254 | ``` 255 | 256 | Target Operating System 257 | ----------------------- 258 | 259 | * `CXX_OS_BSD` - BSD, including MacOS, OpenBSD, FreeBSD, etc. 260 | * `CXX_OS_MAC` - MacOS. 261 | * `CXX_OS_LINUX` - Linux, including Android. 262 | * `CXX_OS_WINDOWS` - Windows. 263 | 264 | Additionally the following constants are provided: 265 | 266 | * `CXX_OS_IOS` - iOS. 267 | * `CXX_OS_ANDROID` - Android. 268 | * `CXX_OS_NETBSD` - NetBSD. 269 | * `CXX_OS_FREEBSD` - FreeBSD. 270 | * `CXX_OS_OPENBSD` - OpenBSD. 271 | * `CXX_OS_DRAGONFLYBSD` - DragonFlyBSD. 272 | * `CXX_OS_QNX` - QNX. 273 | * `CXX_OS_SOLARIS` - Solaris. 274 | * `CXX_OS_CYGWIN` - Cygwin. 275 | 276 | Export & Import 277 | --------------- 278 | 279 | * `CXX_EXPORT` - Mark API to be exported. 280 | * `CXX_IMPORT` - Mark API to be imported. 281 | 282 | Example: 283 | 284 | ```c++ 285 | #if SOMELIB_EXPORTS 286 | # define SOMELIB_API CXX_EXPORT 287 | #else 288 | # define SOMELIB_API CXX_IMPORT 289 | #endif 290 | 291 | SOMELIB_API void SomeFunction(int x, int y); 292 | 293 | class SomeClass { 294 | public: 295 | SOMELIB_API SomeClass(); 296 | SOMELIB_API ~SomeClass(); 297 | 298 | // etc... 299 | } 300 | ``` 301 | 302 | Function Attributes & Calling Conventions 303 | ----------------------------------------- 304 | 305 | Calling Conventions: 306 | 307 | * `CXX_CDECL` - CDECL calling convention. 308 | * `CXX_STDCALL` - STDCALL calling convention (32-bit X86). 309 | * `CXX_FASTCALL` - FASTCALL calling convention (32-bit X86). 310 | * `CXX_REGPARM(N)` - REGPARM(N) calling convention (GNU and Clang). 311 | 312 | Function Attributes: 313 | 314 | * `CXX_FORCEINLINE` - Function should be always inlined. 315 | * `CXX_NOINLINE` - Function should be never inlined. 316 | * `CXX_NORETURN` - Function doesn't return (abort, etc). 317 | 318 | Example: 319 | 320 | ```c++ 321 | // Will always use CDECL calling convention, even if the compiler defaults to a different one. 322 | typedef void (CXX_CDECL* SomeFunc)(int, int); 323 | 324 | void CXX_CDECL SomeFuncImpl(int x, int y) {} 325 | 326 | // Will use __attribute__((regparm(3))) if available, nothing otherwise. 327 | int CXX_REGPARM(3) ExplicitRegParm3Func(int x, int y, int z) { return x + y + z; } 328 | 329 | // Enforced to be always inlined. 330 | CXX_FORCEINLINE uint32_t PerformanceCriticalFunction(uint32_t x, uint32_t y) {} 331 | 332 | // Enforced to be never inlined. 333 | CXX_NOINLINE uint32_t FunctionThatShouldNeverBeInlined(uint32_t x, uint32_t y) {} 334 | 335 | // Never returns. 336 | CXX_NORETURN void Terminate() { ::abort(); } 337 | 338 | uint32_t SomeFunc(void *p) { 339 | if (p) { 340 | // Expected code-path. 341 | return 0; 342 | } 343 | else { 344 | // Runtime error. Since Terminate() has CXX_NORETURN attribute 345 | // the compiler will not emit a warning about a missing return. 346 | Terminate(); 347 | } 348 | } 349 | ``` 350 | 351 | Likely / Unlikely 352 | ----------------- 353 | 354 | * `CXX_LIKELY` - Expression is likely to be true. 355 | * `CXX_UNLIKELY` - Expression is unlikely to be true. 356 | 357 | Used to tell compiler which code-paths are likely, improves error-handling performance: 358 | 359 | ```c++ 360 | void SomeFunc(uint8_t* array, size_t size) { 361 | if (CXX_UNLIKELY(!array)) 362 | return; 363 | 364 | if (CXX_LIKELY(size < 16)) { 365 | // Likely code-path. 366 | } 367 | else { 368 | // Unlikely code-path. 369 | } 370 | } 371 | ``` 372 | 373 | Assumptions 374 | ----------- 375 | 376 | * `CXX_ASSUME(EXP)` - Assume certain expression must always be true. 377 | * `CXX_ASSUME_ALIGNED(PTR, N)` - Assume the `PTR` is aligned to at least `N` bytes. NOTE that `N` must be equal or greater than the natural alignment of `PTR`. 378 | 379 | Example: 380 | 381 | ```c++ 382 | uint32_t SomeFunc(uint8_t* array, size_t size) { 383 | CXX_ASSUME(size > 0); 384 | 385 | // Compiler should omit the first `i < size` check 386 | // as it assumes size is always greater than zero. 387 | uint32_t result = 0; 388 | for (size_t i = 0; i < size; i++) 389 | result += array[i]; 390 | return result; 391 | } 392 | 393 | uint32_t SomeFunc(const uint8_t* array, size_t size) { 394 | // Autovectorizer knows this array is aligned to 16 bytes. 395 | CXX_ASSUME_ALIGNED(array, 16); 396 | 397 | uint32_t result = 0; 398 | for (size_t i = 0; i < size; i++) 399 | result += array[i]; 400 | return result; 401 | } 402 | ``` 403 | 404 | Annotations 405 | ----------- 406 | 407 | * `CXX_UNUSED(X)` - Mark a variable or function argument as possibly unused. 408 | * `CXX_FALLTHROUGH` - Tell the compiler that it's a fallthrough from one switch case to another. Required by new compilers otherwise they would warn about it. 409 | 410 | Example: 411 | 412 | ```c++ 413 | uint32_t FuncWithUnusedArgument(uint32_t x, uint32_t y) { 414 | CXX_UNUSED(x); 415 | return y; 416 | } 417 | 418 | void FuncWithExplicitFallThrough(uint32_t x) { 419 | switch (x) { 420 | case 0: 421 | DoSomething(); 422 | // Modern compiler would warn you without explicit `CXX_FALLTHROUGH`. 423 | CXX_FALLTHROUGH; 424 | case 1: 425 | DoSomethingElse(); 426 | break; 427 | } 428 | } 429 | ``` 430 | 431 | Other General Purpose Macros 432 | ---------------------------- 433 | 434 | * `CXX_ARRAY_SIZE(X)` - Get number of elements of an array at a compile time. 435 | * `CXX_OFFSET_OF(STRUCT, MEMBER)` - Get an offset of `MEMBER` in `STRUCT`. 436 | 437 | Example: 438 | 439 | ```c++ 440 | struct Point { 441 | double x, y; 442 | }; 443 | 444 | void FuncThatUsesOffsetOf() { 445 | printf("Offset of 'Point.x' %u\n", unsigned(CXX_OFFSET_OF(Point, x))); 446 | printf("Offset of 'Point.y' %u\n", unsigned(CXX_OFFSET_OF(Point, y))); 447 | } 448 | 449 | void FuncThatUsesArraySize() { 450 | uint32_t array[32]; 451 | for (size_t i = 0; i < CXX_ARRAY_SIZE(array); i++) 452 | array[i] = uint32_t(i); 453 | } 454 | ``` 455 | 456 | TODOs & Unsable Macros 457 | ---------------------- 458 | 459 | These macros will most probably change their names in the future and are thus unstable: 460 | 461 | * `CXX_ARCH_ARM32` - Not sure about the name. 462 | * `CXX_ARCH_ARM64` - Not sure about the name. 463 | * `CXX_ALIGN_TYPE` - Allows to align type, addition to C++ `alignas` (used in situations not allowed by `alignas`). 464 | * `CXX_ALIGN_DECL` - Allows to align variable, addition to C++ `alignas` (used in situations not allowed by `alignas`). 465 | -------------------------------------------------------------------------------- /cxx_detect.h: -------------------------------------------------------------------------------- 1 | // CXX_DETECT - C++ Compiler and Features Detection 2 | // ================================================ 3 | // 4 | // Dual licensed under PUBLIC DOMAIN (UNLICENSE) and ZLIB. 5 | // (choose the one that you prefer and is valid in your country) 6 | // 7 | // PUBLIC DOMAIN (UNLICENSE) 8 | // ========================= 9 | // 10 | // This is free and unencumbered software released into the public domain. 11 | // 12 | // Anyone is free to copy, modify, publish, use, compile, sell, or 13 | // distribute this software, either in source code form or as a compiled 14 | // binary, for any purpose, commercial or non-commercial, and by any 15 | // means. 16 | // 17 | // In jurisdictions that recognize copyright laws, the author or authors 18 | // of this software dedicate any and all copyright interest in the 19 | // software to the public domain. We make this dedication for the benefit 20 | // of the public at large and to the detriment of our heirs and 21 | // successors. We intend this dedication to be an overt act of 22 | // relinquishment in perpetuity of all present and future rights to this 23 | // software under copyright law. 24 | // 25 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 29 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 30 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 31 | // OTHER DEALINGS IN THE SOFTWARE. 32 | // 33 | // For more information, please refer to 34 | // 35 | // ZLIB LICENSE 36 | // ============ 37 | // 38 | // This software is provided 'as-is', without any express or implied 39 | // warranty. In no event will the authors be held liable for any damages 40 | // arising from the use of this software. 41 | // 42 | // Permission is granted to anyone to use this software for any purpose, 43 | // including commercial applications, and to alter it and redistribute it 44 | // freely, subject to the following restrictions: 45 | // 46 | // 1. The origin of this software must not be misrepresented; you must not 47 | // claim that you wrote the original software. If you use this software 48 | // in a product, an acknowledgment in the product documentation would be 49 | // appreciated but is not required. 50 | // 2. Altered source versions must be plainly marked as such, and must not be 51 | // misrepresented as being the original software. 52 | // 3. This notice may not be removed or altered from any source distribution. 53 | 54 | // ============================================================================ 55 | // [Guard] 56 | // ============================================================================ 57 | 58 | #if !defined(CXX_DETECT_H) || CXX_DETECT_H < 20171018 59 | 60 | #if defined(CXX_DETECT_H) 61 | # undef CXX_DETECT_H 62 | # define CXX_DETECT_H_CLEANUP 63 | #endif 64 | #define CXX_DETECT_H 20171018 65 | 66 | // ============================================================================ 67 | // [Cleanup] 68 | // ============================================================================ 69 | 70 | #if defined(CXX_DETECT_H_CLEANUP) 71 | # undef CXX_DETECT_H_CLEANUP 72 | 73 | // C/C++ Compiler vendor and vendor details 74 | # undef CXX_CLANG 75 | # undef CXX_GNU 76 | # undef CXX_GNU_COMPAT 77 | # undef CXX_INTEL 78 | # undef CXX_MSC 79 | # undef CXX_MINGW 80 | # undef CXX_MAKE_VER 81 | 82 | // C++ standard version. 83 | # undef CXX_CPLUSPLUS 84 | 85 | // C++ features (X == vendor-specific). 86 | # undef CXX_HAS_X_ASSUME 87 | # undef CXX_HAS_X_ASSUME_ALIGNED 88 | # undef CXX_HAS_X_ATTRIBUTE 89 | # undef CXX_HAS_X_ATTRIBUTE_ALIGNED 90 | # undef CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE 91 | # undef CXX_HAS_X_ATTRIBUTE_NOINLINE 92 | # undef CXX_HAS_X_ATTRIBUTE_DEPRECATED 93 | # undef CXX_HAS_X_ATTRIBUTE_NORETURN 94 | # undef CXX_HAS_X_ATTRIBUTE_NOSANITIZE 95 | # undef CXX_HAS_X_ATTRIBUTE_OPTIMIZE 96 | # undef CXX_HAS_X_BUILTIN_ASSUME 97 | # undef CXX_HAS_X_BUILTIN_ASSUME_ALIGNED 98 | # undef CXX_HAS_X_BUILTIN_EXPECT 99 | # undef CXX_HAS_X_BUILTIN_UNREACHABLE 100 | # undef CXX_HAS_X_DECLSPEC_ALIGN 101 | # undef CXX_HAS_X_DECLSPEC_DEPRECATED 102 | # undef CXX_HAS_X_DECLSPEC_NOINLINE 103 | # undef CXX_HAS_X_DECLSPEC_NORETURN 104 | # undef CXX_HAS_X_FORCEINLINE 105 | 106 | // C++ features (C++11). 107 | # undef CXX_HAS_ALIAS_TEMPLATES 108 | # undef CXX_HAS_ALIGNAS 109 | # undef CXX_HAS_ALIGNOF 110 | # undef CXX_HAS_ATTRIBUTES 111 | # undef CXX_HAS_AUTO_TYPE 112 | # undef CXX_HAS_CONSTEXPR 113 | # undef CXX_HAS_DECLTYPE 114 | # undef CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS 115 | # undef CXX_HAS_DEFAULTED_FUNCTIONS 116 | # undef CXX_HAS_DELEGATING_CONSTRUCTORS 117 | # undef CXX_HAS_DELETED_FUNCTIONS 118 | # undef CXX_HAS_EXPLICIT_CONVERSIONS 119 | # undef CXX_HAS_FINAL 120 | # undef CXX_HAS_INHERITING_CONSTRUCTORS 121 | # undef CXX_HAS_INITIALIZER_LISTS 122 | # undef CXX_HAS_INLINE_NAMESPACES 123 | # undef CXX_HAS_LAMBDAS 124 | # undef CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS 125 | # undef CXX_HAS_NOEXCEPT 126 | # undef CXX_HAS_NONSTATIC_MEMBER_INIT 127 | # undef CXX_HAS_NULLPTR 128 | # undef CXX_HAS_OVERRIDE 129 | # undef CXX_HAS_RANGE_FOR 130 | # undef CXX_HAS_RAW_STRING_LITERALS 131 | # undef CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS 132 | # undef CXX_HAS_RVALUE_REFERENCES 133 | # undef CXX_HAS_STATIC_ASSERT 134 | # undef CXX_HAS_STRONG_ENUMS 135 | # undef CXX_HAS_THREAD_LOCAL 136 | # undef CXX_HAS_UNICODE_LITERALS 137 | # undef CXX_HAS_UNRESTRICTED_UNIONS 138 | # undef CXX_HAS_VARIADIC_TEMPLATES 139 | 140 | // C++ features (C++14). 141 | # undef CXX_HAS_AGGREGATE_NSDMI 142 | # undef CXX_HAS_BINARY_LITERALS 143 | # undef CXX_HAS_CONTEXTUAL_CONVERSIONS 144 | # undef CXX_HAS_DECLTYPE_AUTO 145 | # undef CXX_HAS_GENERIC_LAMBDAS 146 | # undef CXX_HAS_INIT_CAPTURES 147 | # undef CXX_HAS_RELAXED_CONSTEXPR 148 | # undef CXX_HAS_VARIABLE_TEMPLATES 149 | 150 | // C++ features (C++17). 151 | 152 | // C++ native types. 153 | # undef CXX_HAS_NATIVE_CHAR 154 | # undef CXX_HAS_NATIVE_CHAR16_T 155 | # undef CXX_HAS_NATIVE_CHAR32_T 156 | # undef CXX_HAS_NATIVE_WCHAR_T 157 | 158 | // Target architecture. 159 | # undef CXX_ARCH_X86 160 | # undef CXX_ARCH_X86_64 161 | # undef CXX_ARCH_ARM32 162 | # undef CXX_ARCH_ARM64 163 | # undef CXX_ARCH_BITS 164 | # undef CXX_ARCH_LE 165 | # undef CXX_ARCH_BE 166 | 167 | // Target operating system. 168 | # undef CXX_OS_WINDOWS 169 | # undef CXX_OS_MAC 170 | # undef CXX_OS_IOS 171 | # undef CXX_OS_ANDROID 172 | # undef CXX_OS_LINUX 173 | # undef CXX_OS_NETBSD 174 | # undef CXX_OS_FREEBSD 175 | # undef CXX_OS_OPENBSD 176 | # undef CXX_OS_DRAGONFLYBSD 177 | # undef CXX_OS_QNX 178 | # undef CXX_OS_SOLARIS 179 | # undef CXX_OS_CYGWIN 180 | # undef CXX_OS_BSD 181 | 182 | // Visibility. 183 | # undef CXX_EXPORT 184 | # undef CXX_IMPORT 185 | 186 | // Function Attributes. 187 | # undef CXX_CDECL 188 | # undef CXX_STDCALL 189 | # undef CXX_FASTCALL 190 | # undef CXX_REGPARM 191 | # undef CXX_FORCEINLINE 192 | # undef CXX_NOINLINE 193 | # undef CXX_NORETURN 194 | 195 | // Likely / Unlikely. 196 | # undef CXX_LIKELY 197 | # undef CXX_UNLIKELY 198 | 199 | // Assumptions. 200 | # undef CXX_ASSUME 201 | # undef CXX_ASSUME_ALIGNED 202 | 203 | // Annotations. 204 | # undef CXX_UNUSED 205 | # undef CXX_FALLTHROUGH 206 | 207 | // Other macros. 208 | # undef CXX_ALIGN_DECL 209 | # undef CXX_ALIGN_TYPE 210 | 211 | # undef CXX_ARRAY_SIZE 212 | # undef CXX_OFFSET_OF 213 | 214 | #endif 215 | 216 | // ============================================================================ 217 | // [C++ Compiler Vendor] 218 | // ============================================================================ 219 | 220 | #define CXX_CLANG 0 221 | #define CXX_GNU 0 222 | #define CXX_INTEL 0 223 | #define CXX_MSC 0 224 | 225 | #define CXX_MAKE_VER(MAJOR, MINOR, PATCH) ((MAJOR) * 10000000 + (MINOR) * 100000 + (PATCH)) 226 | 227 | // Intel pretends to be GNU/MSC, so check it first. 228 | #if defined(__INTEL_COMPILER) 229 | # undef CXX_INTEL 230 | # define CXX_INTEL CXX_MAKE_VER(__INTEL_COMPILER / 100, (__INTEL_COMPILER / 10) % 10, __INTEL_COMPILER % 10) 231 | #elif defined(_MSC_VER) && defined(_MSC_FULL_VER) 232 | # undef CXX_MSC 233 | # if _MSC_VER == _MSC_FULL_VER / 10000 234 | # define CXX_MSC CXX_MAKE_VER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000) 235 | # else 236 | # define CXX_MSC CXX_MAKE_VER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000) 237 | # endif 238 | #elif defined(__clang__) && defined(__clang_minor__) 239 | # undef CXX_CLANG 240 | # define CXX_CLANG CXX_MAKE_VER(__clang_major__, __clang_minor__, __clang_patchlevel__) 241 | #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 242 | # undef CXX_GNU 243 | # define CXX_GNU CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 244 | #else 245 | # error "[ccx_detect.h] Unable to detect C/C++ compiler." 246 | #endif 247 | 248 | // CXX_MINGW - MINGW - 0 (no MINGW), 32 (MINGW32), 64 (MINGW64). 249 | #if defined(__MINGW64__) 250 | # define CXX_MINGW 64 251 | #elif defined(__MINGW32__) 252 | # define CXX_MINGW 32 253 | #else 254 | # define CXX_MINGW 0 255 | #endif 256 | 257 | // CXX_GNU_COMPAT - C++ compiler is GNU or pretends to be (clang/ICC). 258 | #if defined(__GNUC__) && !defined(__GNUC_MINOR__) 259 | # define CXX_GNU_COMPAT CXX_MAKE_VER(__GNUC__, 0, 0) 260 | #elif defined(__GNUC__) && !defined(__GNUC_PATCHLEVEL__) 261 | # define CXX_GNU_COMPAT CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__, 0) 262 | #elif defined(__GNUC__) 263 | # define CXX_GNU_COMPAT CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 264 | #else 265 | # define CXX_GNU_COMPAT 0 266 | #endif 267 | 268 | // ============================================================================ 269 | // [C++ Version] 270 | // ============================================================================ 271 | 272 | // 199711L - C++98 273 | // 201103L - C++11 274 | // 201402L - C++14 275 | // 201703L - C++17 276 | #if defined(__cplusplus) 277 | # if __cplusplus >= 201103L 278 | # define CXX_CPLUSPLUS __cplusplus 279 | # elif defined(__GXX_EXPERIMENTAL_CXX0X__) || CXX_MSC >= CXX_MAKE_VER(18, 0, 0) || CXX_INTEL >= CXX_MAKE_VER(14, 0, 0) 280 | # define CXX_CPLUSPLUS 201103L 281 | # else 282 | # define CXX_CPLUSPLUS 199711L 283 | # endif 284 | #endif 285 | 286 | #if !defined(CXX_CPLUSPLUS) 287 | # define CXX_CPLUSPLUS 0 288 | #endif 289 | 290 | // ============================================================================ 291 | // [C++ Compiler Features] 292 | // ============================================================================ 293 | 294 | // Feature Comparison: 295 | // http://en.cppreference.com/w/cpp/compiler_support 296 | 297 | // Clang Compiler: 298 | // https://releases.llvm.org/5.0.0/tools/clang/docs/LanguageExtensions.html 299 | #if CXX_CLANG 300 | # define CXX_HAS_X_ASSUME (0) 301 | # define CXX_HAS_X_ASSUME_ALIGNED (0) 302 | # define CXX_HAS_X_ATTRIBUTE (1) 303 | # define CXX_HAS_X_ATTRIBUTE_ALIGNED (__has_attribute(__aligned__)) 304 | # define CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(__always_inline__)) 305 | # define CXX_HAS_X_ATTRIBUTE_DEPRECATED (__has_attribute(__deprecated__) && __has_extension(__attribute_deprecated_with_message__)) 306 | # define CXX_HAS_X_ATTRIBUTE_NOINLINE (__has_attribute(__noinline__)) 307 | # define CXX_HAS_X_ATTRIBUTE_NORETURN (__has_attribute(__noreturn__)) 308 | # define CXX_HAS_X_ATTRIBUTE_NOSANITIZE (__has_attribute(__nosanitize__)) 309 | # define CXX_HAS_X_ATTRIBUTE_OPTIMIZE (__has_attribute(__optimize__)) 310 | # define CXX_HAS_X_BUILTIN_ASSUME (__has_builtin(__builtin_assume)) 311 | # define CXX_HAS_X_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) 312 | # define CXX_HAS_X_BUILTIN_EXPECT (__has_builtin(__builtin_expect)) 313 | # define CXX_HAS_X_BUILTIN_UNREACHABLE (__has_builtin(__builtin_unreachable)) 314 | # define CXX_HAS_X_DECLSPEC_ALIGN (0) 315 | # define CXX_HAS_X_DECLSPEC_DEPRECATED (0) 316 | # define CXX_HAS_X_DECLSPEC_NOINLINE (0) 317 | # define CXX_HAS_X_DECLSPEC_NORETURN (0) 318 | # define CXX_HAS_X_FORCEINLINE (0) 319 | 320 | # define CXX_HAS_ALIAS_TEMPLATES (__has_extension(__cxx_alias_templates__)) 321 | # define CXX_HAS_ALIGNAS (__has_extension(__cxx_alignas__)) 322 | # define CXX_HAS_ALIGNOF (__has_extension(__cxx_alignof__)) 323 | # define CXX_HAS_ATTRIBUTES (__has_extension(__cxx_attributes__)) 324 | # define CXX_HAS_AUTO_TYPE (__has_extension(__cxx_auto_type__)) 325 | # define CXX_HAS_CONSTEXPR (__has_extension(__cxx_constexpr__)) 326 | # define CXX_HAS_DECLTYPE (__has_extension(__cxx_decltype__)) 327 | # define CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS (__has_extension(__cxx_default_function_template_args__)) 328 | # define CXX_HAS_DEFAULTED_FUNCTIONS (__has_extension(__cxx_defaulted_functions__)) 329 | # define CXX_HAS_DELEGATING_CONSTRUCTORS (__has_extension(__cxx_delegating_constructors__)) 330 | # define CXX_HAS_DELETED_FUNCTIONS (__has_extension(__cxx_deleted_functions__)) 331 | # define CXX_HAS_EXPLICIT_CONVERSIONS (__has_feature(__cxx_explicit_conversions__)) 332 | # define CXX_HAS_FINAL (__has_extension(__cxx_override_control__)) 333 | # define CXX_HAS_INHERITING_CONSTRUCTORS (__has_feature(__cxx_inheriting_constructors__)) 334 | # define CXX_HAS_INITIALIZER_LISTS (__has_extension(__cxx_generalized_initializers__)) 335 | # define CXX_HAS_INLINE_NAMESPACES (__has_extension(__cxx_inline_namespaces__)) 336 | # define CXX_HAS_LAMBDAS (__has_extension(__cxx_lambdas__)) 337 | # define CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS (__has_extension(__cxx_local_type_template_args__)) 338 | # define CXX_HAS_NOEXCEPT (__has_extension(__cxx_noexcept__)) 339 | # define CXX_HAS_NONSTATIC_MEMBER_INIT (__has_feature(__cxx_nonstatic_member_init__)) 340 | # define CXX_HAS_NULLPTR (__has_extension(__cxx_nullptr__)) 341 | # define CXX_HAS_OVERRIDE (__has_extension(__cxx_override_control__)) 342 | # define CXX_HAS_RANGE_FOR (__has_extension(__cxx_range_for__)) 343 | # define CXX_HAS_RAW_STRING_LITERALS (__has_feature(__cxx_raw_string_literals__)) 344 | # define CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS (__has_extension(__cxx_reference_qualified_functions__)) 345 | # define CXX_HAS_RVALUE_REFERENCES (__has_extension(__cxx_rvalue_references__)) 346 | # define CXX_HAS_STATIC_ASSERT (__has_extension(__cxx_static_assert__)) 347 | # define CXX_HAS_STRONG_ENUMS (__has_extension(__cxx_strong_enums__)) 348 | # define CXX_HAS_THREAD_LOCAL (__has_feature(__cxx_thread_local__)) 349 | # define CXX_HAS_UNICODE_LITERALS (__has_extension(__cxx_unicode_literals__)) 350 | # define CXX_HAS_UNRESTRICTED_UNIONS (__has_feature(__cxx_unrestricted_unions__)) 351 | # define CXX_HAS_VARIADIC_TEMPLATES (__has_extension(__cxx_variadic_templates__)) 352 | 353 | # define CXX_HAS_AGGREGATE_NSDMI (__has_extension(__cxx_aggregate_nsdmi__)) 354 | # define CXX_HAS_BINARY_LITERALS (__has_extension(__cxx_binary_literals__)) 355 | # define CXX_HAS_CONTEXTUAL_CONVERSIONS (__has_extension(__cxx_contextual_conversions__)) 356 | # define CXX_HAS_DECLTYPE_AUTO (__has_extension(__cxx_decltype_auto__)) 357 | # define CXX_HAS_GENERIC_LAMBDAS (__has_extension(__cxx_generic_lambdas__)) 358 | # define CXX_HAS_INIT_CAPTURES (__has_extension(__cxx_init_captures__)) 359 | # define CXX_HAS_RELAXED_CONSTEXPR (__has_extension(__cxx_relaxed_constexpr__)) 360 | # define CXX_HAS_VARIABLE_TEMPLATES (__has_extension(__cxx_variable_templates__)) 361 | 362 | # define CXX_HAS_NATIVE_CHAR (1) 363 | # define CXX_HAS_NATIVE_CHAR16_T (CXX_HAS_UNICODE_LITERALS) 364 | # define CXX_HAS_NATIVE_CHAR32_T (CXX_HAS_UNICODE_LITERALS) 365 | # define CXX_HAS_NATIVE_WCHAR_T (1) 366 | #endif 367 | 368 | // GNU Compiler: 369 | // https://gcc.gnu.org/projects/cxx-status.html 370 | #if CXX_GNU 371 | # define CXX_HAS_X_ASSUME (0) 372 | # define CXX_HAS_X_ASSUME_ALIGNED (0) 373 | # define CXX_HAS_X_ATTRIBUTE (1) 374 | # define CXX_HAS_X_ATTRIBUTE_ALIGNED (CXX_GNU >= CXX_MAKE_VER(2, 7, 0)) 375 | # define CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && !CXX_MINGW) 376 | # define CXX_HAS_X_ATTRIBUTE_DEPRECATED (CXX_GNU >= CXX_MAKE_VER(4, 5, 0)) 377 | # define CXX_HAS_X_ATTRIBUTE_NOINLINE (CXX_GNU >= CXX_MAKE_VER(3, 4, 0) && !CXX_MINGW) 378 | # define CXX_HAS_X_ATTRIBUTE_NORETURN (CXX_GNU >= CXX_MAKE_VER(2, 5, 0)) 379 | # define CXX_HAS_X_ATTRIBUTE_NOSANITIZE (0) 380 | # define CXX_HAS_X_ATTRIBUTE_OPTIMIZE (CXX_GNU >= CXX_MAKE_VER(4, 4, 0)) 381 | # define CXX_HAS_X_BUILTIN_ASSUME (0) 382 | # define CXX_HAS_X_BUILTIN_ASSUME_ALIGNED (CXX_GNU >= CXX_MAKE_VER(4, 7, 0)) 383 | # define CXX_HAS_X_BUILTIN_EXPECT (1) 384 | # define CXX_HAS_X_BUILTIN_UNREACHABLE (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 385 | # define CXX_HAS_X_DECLSPEC_ALIGN (0) 386 | # define CXX_HAS_X_DECLSPEC_DEPRECATED (0) 387 | # define CXX_HAS_X_DECLSPEC_NOINLINE (0) 388 | # define CXX_HAS_X_DECLSPEC_NORETURN (0) 389 | # define CXX_HAS_X_FORCEINLINE (0) 390 | 391 | # define CXX_HAS_ALIAS_TEMPLATES (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 392 | # define CXX_HAS_ALIGNAS (CXX_GNU >= CXX_MAKE_VER(4, 8, 0) && CXX_CPLUSPLUS >= 201103L) 393 | # define CXX_HAS_ALIGNOF (CXX_GNU >= CXX_MAKE_VER(4, 8, 0) && CXX_CPLUSPLUS >= 201103L) 394 | # define CXX_HAS_ATTRIBUTES (CXX_GNU >= CXX_MAKE_VER(4, 8, 0) && CXX_CPLUSPLUS >= 201103L) 395 | # define CXX_HAS_AUTO_TYPE (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 396 | # define CXX_HAS_CONSTEXPR (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 397 | # define CXX_HAS_DECLTYPE (CXX_GNU >= CXX_MAKE_VER(4, 3, 0) && CXX_CPLUSPLUS >= 201103L) 398 | # define CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 399 | # define CXX_HAS_DEFAULTED_FUNCTIONS (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 400 | # define CXX_HAS_DELEGATING_CONSTRUCTORS (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 401 | # define CXX_HAS_DELETED_FUNCTIONS (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 402 | # define CXX_HAS_EXPLICIT_CONVERSIONS (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 403 | # define CXX_HAS_FINAL (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 404 | # define CXX_HAS_INHERITING_CONSTRUCTORS (CXX_GNU >= CXX_MAKE_VER(4, 8, 0) && CXX_CPLUSPLUS >= 201103L) 405 | # define CXX_HAS_INITIALIZER_LISTS (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 406 | # define CXX_HAS_INLINE_NAMESPACES (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 407 | # define CXX_HAS_LAMBDAS (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 408 | # define CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 409 | # define CXX_HAS_NOEXCEPT (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 410 | # define CXX_HAS_NONSTATIC_MEMBER_INIT (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 411 | # define CXX_HAS_NULLPTR (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 412 | # define CXX_HAS_OVERRIDE (CXX_GNU >= CXX_MAKE_VER(4, 7, 0) && CXX_CPLUSPLUS >= 201103L) 413 | # define CXX_HAS_RANGE_FOR (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 414 | # define CXX_HAS_RAW_STRING_LITERALS (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 415 | # define CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS (CXX_GNU >= CXX_MAKE_VER(4, 8, 1) && CXX_CPLUSPLUS >= 201103L) 416 | # define CXX_HAS_RVALUE_REFERENCES (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 417 | # define CXX_HAS_STATIC_ASSERT (CXX_GNU >= CXX_MAKE_VER(4, 3, 0) && CXX_CPLUSPLUS >= 201103L) 418 | # define CXX_HAS_STRONG_ENUMS (CXX_GNU >= CXX_MAKE_VER(4, 4, 0) && CXX_CPLUSPLUS >= 201103L) 419 | # define CXX_HAS_THREAD_LOCAL (CXX_GNU >= CXX_MAKE_VER(4, 8, 0) && CXX_CPLUSPLUS >= 201103L) 420 | # define CXX_HAS_UNICODE_LITERALS (CXX_GNU >= CXX_MAKE_VER(4, 5, 0) && CXX_CPLUSPLUS >= 201103L) 421 | # define CXX_HAS_UNRESTRICTED_UNIONS (CXX_GNU >= CXX_MAKE_VER(4, 6, 0) && CXX_CPLUSPLUS >= 201103L) 422 | # define CXX_HAS_VARIADIC_TEMPLATES (CXX_GNU >= CXX_MAKE_VER(4, 3, 0) && CXX_CPLUSPLUS >= 201103L) 423 | 424 | # define CXX_HAS_AGGREGATE_NSDMI (CXX_GNU >= CXX_MAKE_VER(5, 0, 0) && CXX_CPLUSPLUS >= 201402L) 425 | # define CXX_HAS_BINARY_LITERALS (CXX_GNU >= CXX_MAKE_VER(4, 9, 0) && CXX_CPLUSPLUS >= 201402L) 426 | # define CXX_HAS_CONTEXTUAL_CONVERSIONS (CXX_GNU >= CXX_MAKE_VER(4, 9, 0) && CXX_CPLUSPLUS >= 201402L) 427 | # define CXX_HAS_DECLTYPE_AUTO (CXX_GNU >= CXX_MAKE_VER(4, 9, 0) && CXX_CPLUSPLUS >= 201402L) 428 | # define CXX_HAS_GENERIC_LAMBDAS (CXX_GNU >= CXX_MAKE_VER(4, 9, 0) && CXX_CPLUSPLUS >= 201402L) 429 | # define CXX_HAS_INIT_CAPTURES (CXX_GNU >= CXX_MAKE_VER(4, 9, 0) && CXX_CPLUSPLUS >= 201402L) 430 | # define CXX_HAS_RELAXED_CONSTEXPR (CXX_GNU >= CXX_MAKE_VER(5, 0, 0) && CXX_CPLUSPLUS >= 201402L) 431 | # define CXX_HAS_VARIABLE_TEMPLATES (CXX_GNU >= CXX_MAKE_VER(5, 0, 0) && CXX_CPLUSPLUS >= 201402L) 432 | 433 | # define CXX_HAS_NATIVE_CHAR (1) 434 | # define CXX_HAS_NATIVE_CHAR16_T (CXX_HAS_UNICODE_LITERALS) 435 | # define CXX_HAS_NATIVE_CHAR32_T (CXX_HAS_UNICODE_LITERALS) 436 | # define CXX_HAS_NATIVE_WCHAR_T (1) 437 | #endif 438 | 439 | // Intel Compiler: 440 | // https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler 441 | // https://software.intel.com/en-us/articles/c14-features-supported-by-intel-c-compiler 442 | // https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler 443 | #if CXX_INTEL 444 | # define CXX_HAS_X_ASSUME (1) 445 | # define CXX_HAS_X_ASSUME_ALIGNED (1) 446 | # define CXX_HAS_X_ATTRIBUTE (CXX_GNU_COMPAT >= 1) 447 | # define CXX_HAS_X_ATTRIBUTE_ALIGNED (CXX_GNU_COMPAT >= 1) 448 | # define CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE (CXX_GNU_COMPAT >= 1) 449 | # define CXX_HAS_X_ATTRIBUTE_DEPRECATED (CXX_GNU_COMPAT >= 1) 450 | # define CXX_HAS_X_ATTRIBUTE_NOINLINE (CXX_GNU_COMPAT >= 1) 451 | # define CXX_HAS_X_ATTRIBUTE_NORETURN (CXX_GNU_COMPAT >= 1) 452 | # define CXX_HAS_X_ATTRIBUTE_NOSANITIZE (0) 453 | # define CXX_HAS_X_ATTRIBUTE_OPTIMIZE (CXX_GNU_COMPAT >= 1) 454 | # define CXX_HAS_X_BUILTIN_ASSUME (0) 455 | # define CXX_HAS_X_BUILTIN_ASSUME_ALIGNED (0) 456 | # define CXX_HAS_X_BUILTIN_EXPECT (CXX_GNU_COMPAT >= 1) 457 | # define CXX_HAS_X_BUILTIN_UNREACHABLE (0) 458 | # define CXX_HAS_X_DECLSPEC_ALIGN (CXX_GNU_COMPAT == 0) 459 | # define CXX_HAS_X_DECLSPEC_DEPRECATED (CXX_GNU_COMPAT == 0) 460 | # define CXX_HAS_X_DECLSPEC_NOINLINE (CXX_GNU_COMPAT == 0) 461 | # define CXX_HAS_X_DECLSPEC_NORETURN (CXX_GNU_COMPAT == 0) 462 | # define CXX_HAS_X_FORCEINLINE (CXX_GNU_COMPAT == 0) 463 | 464 | # define CXX_HAS_ALIAS_TEMPLATES (CXX_INTEL >= CXX_MAKE_VER(12, 1, 0)) 465 | # define CXX_HAS_ALIGNAS (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 466 | # define CXX_HAS_ALIGNOF (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 467 | # define CXX_HAS_ATTRIBUTES (CXX_INTEL >= CXX_MAKE_VER(12, 1, 0)) 468 | # define CXX_HAS_AUTO_TYPE (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 469 | # define CXX_HAS_CONSTEXPR (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 470 | # define CXX_HAS_DECLTYPE (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 471 | # define CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS (CXX_INTEL >= CXX_MAKE_VER(13, 0, 0)) 472 | # define CXX_HAS_DEFAULTED_FUNCTIONS (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 473 | # define CXX_HAS_DELEGATING_CONSTRUCTORS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 474 | # define CXX_HAS_DELETED_FUNCTIONS (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 475 | # define CXX_HAS_EXPLICIT_CONVERSIONS (CXX_INTEL >= CXX_MAKE_VER(13, 0, 0)) 476 | # define CXX_HAS_FINAL (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 477 | # define CXX_HAS_INHERITING_CONSTRUCTORS (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 478 | # define CXX_HAS_INITIALIZER_LISTS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 479 | # define CXX_HAS_INLINE_NAMESPACES (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 480 | # define CXX_HAS_LAMBDAS (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 481 | # define CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS (CXX_INTEL >= CXX_MAKE_VER(12, 0, 0)) 482 | # define CXX_HAS_NOEXCEPT (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 483 | # define CXX_HAS_NONSTATIC_MEMBER_INIT (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 484 | # define CXX_HAS_NULLPTR (CXX_INTEL >= CXX_MAKE_VER(12, 6, 0)) 485 | # define CXX_HAS_OVERRIDE (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 486 | # define CXX_HAS_RANGE_FOR (CXX_INTEL >= CXX_MAKE_VER(13, 0, 0)) 487 | # define CXX_HAS_RAW_STRING_LITERALS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 488 | # define CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0)) 489 | # define CXX_HAS_RVALUE_REFERENCES (CXX_INTEL >= CXX_MAKE_VER(11, 1, 0)) 490 | # define CXX_HAS_STATIC_ASSERT (CXX_INTEL >= CXX_MAKE_VER(11, 1, 0)) 491 | # define CXX_HAS_STRONG_ENUMS (CXX_INTEL >= CXX_MAKE_VER(13, 0, 0)) 492 | # define CXX_HAS_THREAD_LOCAL (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 493 | # define CXX_HAS_UNICODE_LITERALS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0) || (CXX_GNU_COMPAT > 0 && CXX_INTEL >= CXX_MAKE_VER(12, 6, 0))) 494 | # define CXX_HAS_UNRESTRICTED_UNIONS (CXX_INTEL >= CXX_MAKE_VER(14, 0, 0) && CXX_GNU_COMPAT) 495 | # define CXX_HAS_VARIADIC_TEMPLATES (CXX_INTEL >= CXX_MAKE_VER(12, 6, 0)) 496 | 497 | # define CXX_HAS_AGGREGATE_NSDMI (CXX_INTEL >= CXX_MAKE_VER(16, 0, 0)) 498 | # define CXX_HAS_BINARY_LITERALS (CXX_INTEL >= CXX_MAKE_VER(11, 0, 0)) 499 | # define CXX_HAS_CONTEXTUAL_CONVERSIONS (CXX_INTEL >= CXX_MAKE_VER(16, 0, 0)) 500 | # define CXX_HAS_DECLTYPE_AUTO (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 501 | # define CXX_HAS_GENERIC_LAMBDAS (CXX_INTEL >= CXX_MAKE_VER(16, 0, 0)) 502 | # define CXX_HAS_INIT_CAPTURES (CXX_INTEL >= CXX_MAKE_VER(15, 0, 0)) 503 | # define CXX_HAS_RELAXED_CONSTEXPR (CXX_INTEL >= CXX_MAKE_VER(17, 0, 0)) 504 | # define CXX_HAS_VARIABLE_TEMPLATES (CXX_INTEL >= CXX_MAKE_VER(17, 0, 0)) 505 | 506 | # define CXX_HAS_NATIVE_CHAR (1) 507 | # define CXX_HAS_NATIVE_CHAR16_T (CXX_HAS_UNICODE_LITERALS) 508 | # define CXX_HAS_NATIVE_CHAR32_T (CXX_HAS_UNICODE_LITERALS) 509 | # define CXX_HAS_NATIVE_WCHAR_T (1) 510 | #endif 511 | 512 | // MSC Compiler: 513 | // https://msdn.microsoft.com/en-us/library/hh567368.aspx 514 | // 515 | // Version List: 516 | // 16.00.0 == VS2010 517 | // 17.00.0 == VS2012 518 | // 18.00.0 == VS2013 519 | // 19.00.0 == VS2015 520 | // 19.10.0 == VS2017 521 | #if CXX_MSC 522 | # define CXX_HAS_X_ASSUME (1) 523 | # define CXX_HAS_X_ASSUME_ALIGNED (0) 524 | # define CXX_HAS_X_ATTRIBUTE (0) 525 | # define CXX_HAS_X_ATTRIBUTE_ALIGNED (0) 526 | # define CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE (0) 527 | # define CXX_HAS_X_ATTRIBUTE_DEPRECATED (0) 528 | # define CXX_HAS_X_ATTRIBUTE_NOINLINE (0) 529 | # define CXX_HAS_X_ATTRIBUTE_NORETURN (0) 530 | # define CXX_HAS_X_ATTRIBUTE_NOSANITIZE (0) 531 | # define CXX_HAS_X_ATTRIBUTE_OPTIMIZE (0) 532 | # define CXX_HAS_X_BUILTIN_ASSUME (0) 533 | # define CXX_HAS_X_BUILTIN_ASSUME_ALIGNED (0) 534 | # define CXX_HAS_X_BUILTIN_EXPECT (0) 535 | # define CXX_HAS_X_BUILTIN_UNREACHABLE (0) 536 | # define CXX_HAS_X_DECLSPEC_ALIGN (1) 537 | # define CXX_HAS_X_DECLSPEC_DEPRECATED (1) 538 | # define CXX_HAS_X_DECLSPEC_NOINLINE (1) 539 | # define CXX_HAS_X_DECLSPEC_NORETURN (1) 540 | # define CXX_HAS_X_FORCEINLINE (1) 541 | 542 | # define CXX_HAS_ALIAS_TEMPLATES (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 543 | # define CXX_HAS_ALIGNAS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 544 | # define CXX_HAS_ALIGNOF (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 545 | # define CXX_HAS_ATTRIBUTES (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 546 | # define CXX_HAS_AUTO_TYPE (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 547 | # define CXX_HAS_CONSTEXPR (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 548 | # define CXX_HAS_DECLTYPE (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 549 | # define CXX_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 550 | # define CXX_HAS_DEFAULTED_FUNCTIONS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 551 | # define CXX_HAS_DELEGATING_CONSTRUCTORS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 552 | # define CXX_HAS_DELETED_FUNCTIONS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 553 | # define CXX_HAS_EXPLICIT_CONVERSIONS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 554 | # define CXX_HAS_FINAL (CXX_MSC >= CXX_MAKE_VER(14, 0 , 0)) 555 | # define CXX_HAS_INHERITING_CONSTRUCTORS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 556 | # define CXX_HAS_INITIALIZER_LISTS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 557 | # define CXX_HAS_INLINE_NAMESPACES (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 558 | # define CXX_HAS_LAMBDAS (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 559 | # define CXX_HAS_LOCAL_TYPE_TEMPLATE_ARGS (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 560 | # define CXX_HAS_NOEXCEPT (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 561 | # define CXX_HAS_NONSTATIC_MEMBER_INIT (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 562 | # define CXX_HAS_NULLPTR (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 563 | # define CXX_HAS_OVERRIDE (CXX_MSC >= CXX_MAKE_VER(14, 0 , 0)) 564 | # define CXX_HAS_RANGE_FOR (CXX_MSC >= CXX_MAKE_VER(17, 0 , 0)) 565 | # define CXX_HAS_RAW_STRING_LITERALS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 566 | # define CXX_HAS_REFERENCE_QUALIFIED_FUNCTIONS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 567 | # define CXX_HAS_RVALUE_REFERENCES (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 568 | # define CXX_HAS_STATIC_ASSERT (CXX_MSC >= CXX_MAKE_VER(16, 0 , 0)) 569 | # define CXX_HAS_STRONG_ENUMS (CXX_MSC >= CXX_MAKE_VER(14, 0 , 0)) 570 | # define CXX_HAS_THREAD_LOCAL (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 571 | # define CXX_HAS_UNICODE_LITERALS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 572 | # define CXX_HAS_UNRESTRICTED_UNIONS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 573 | # define CXX_HAS_VARIADIC_TEMPLATES (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 574 | 575 | # define CXX_HAS_AGGREGATE_NSDMI (CXX_MSC >= CXX_MAKE_VER(19, 10, 0)) 576 | # define CXX_HAS_BINARY_LITERALS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 577 | # define CXX_HAS_CONTEXTUAL_CONVERSIONS (CXX_MSC >= CXX_MAKE_VER(18, 0 , 0)) 578 | # define CXX_HAS_DECLTYPE_AUTO (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 579 | # define CXX_HAS_GENERIC_LAMBDAS (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 580 | # define CXX_HAS_INIT_CAPTURES (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 581 | # define CXX_HAS_RELAXED_CONSTEXPR (CXX_MSC >= CXX_MAKE_VER(19, 10, 0)) 582 | # define CXX_HAS_VARIABLE_TEMPLATES (CXX_MSC >= CXX_MAKE_VER(19, 0 , 0)) 583 | 584 | # define CXX_HAS_NATIVE_CHAR (1) 585 | # define CXX_HAS_NATIVE_CHAR16_T (CXX_HAS_UNICODE_LITERALS) 586 | # define CXX_HAS_NATIVE_CHAR32_T (CXX_HAS_UNICODE_LITERALS) 587 | # if defined(_NATIVE_WCHAR_T_DEFINED) 588 | # define CXX_HAS_NATIVE_WCHAR_T (1) 589 | # else 590 | # define CXX_HAS_NATIVE_WCHAR_T (0) 591 | # endif 592 | #endif 593 | 594 | // ============================================================================ 595 | // [Target Architecture] 596 | // ============================================================================ 597 | 598 | #if (defined(_M_X64 ) || defined(__x86_64) || defined(__x86_64__) || \ 599 | defined(_M_AMD64) || defined(__amd64 ) || defined(__amd64__ )) 600 | # define CXX_ARCH_X86_64 (1) 601 | #else 602 | # define CXX_ARCH_X86_64 (0) 603 | #endif 604 | 605 | #if (defined(_M_IX86 ) || defined(__X86__ ) || defined(__i386 ) || \ 606 | defined(__IA32__) || defined(__I86__ ) || defined(__i386__) || \ 607 | defined(__i486__) || defined(__i586__) || defined(__i686__)) 608 | # define CXX_ARCH_X86 (!CXX_ARCH_X86_64) 609 | #else 610 | # define CXX_ARCH_X86 (0) 611 | #endif 612 | 613 | #if defined(__aarch64__) 614 | # define CXX_ARCH_ARM64 (1) 615 | #else 616 | # define CXX_ARCH_ARM64 (0) 617 | #endif 618 | 619 | #if (defined(_M_ARM ) || defined(__arm ) || defined(__thumb__ ) || \ 620 | defined(_M_ARMT ) || defined(__arm__ ) || defined(__thumb2__)) 621 | # define CXX_ARCH_ARM32 (!CXX_ARCH_ARM64) 622 | #else 623 | # define CXX_ARCH_ARM32 (0) 624 | #endif 625 | 626 | #if CXX_ARCH_X86_64 || CXX_ARCH_ARM64 627 | # define CXX_ARCH_BITS (64) 628 | #else 629 | # define CXX_ARCH_BITS (32) 630 | #endif 631 | 632 | #define CXX_ARCH_LE (CXX_ARCH_X86 || CXX_ARCH_X86_64 || CXX_ARCH_ARM32 || CXX_ARCH_ARM64) 633 | #define CXX_ARCH_BE (!(CXX_ARCH_LE)) 634 | 635 | // ============================================================================ 636 | // [Target OS] 637 | // ============================================================================ 638 | 639 | #if defined(_WIN32) || defined(_WINDOWS) 640 | # define CXX_OS_WINDOWS (1) 641 | #else 642 | # define CXX_OS_WINDOWS (0) 643 | #endif 644 | 645 | #if defined(__APPLE__) 646 | # include 647 | # define CXX_OS_MAC (TARGET_OS_MAC) 648 | # define CXX_OS_IOS (TARGET_OS_IPHONE) 649 | #else 650 | # define CXX_OS_MAC (0) 651 | # define CXX_OS_IOS (0) 652 | #endif 653 | 654 | #if defined(__ANDROID__) 655 | # define CXX_OS_ANDROID (1) 656 | #else 657 | # define CXX_OS_ANDROID (0) 658 | #endif 659 | 660 | #if defined(__linux__) || defined(__ANDROID__) 661 | # define CXX_OS_LINUX (1) 662 | #else 663 | # define CXX_OS_LINUX (0) 664 | #endif 665 | 666 | #if defined(__NetBSD__) 667 | # define CXX_OS_NETBSD (1) 668 | #else 669 | # define CXX_OS_NETBSD (0) 670 | #endif 671 | 672 | #if defined(__FreeBSD__) 673 | # define CXX_OS_FREEBSD (1) 674 | #else 675 | # define CXX_OS_FREEBSD (0) 676 | #endif 677 | 678 | #if defined(__OpenBSD__) 679 | # define CXX_OS_OPENBSD (1) 680 | #else 681 | # define CXX_OS_OPENBSD (0) 682 | #endif 683 | 684 | #if defined(__DragonFly__) 685 | # define CXX_OS_DRAGONFLYBSD (1) 686 | #else 687 | # define CXX_OS_DRAGONFLYBSD (0) 688 | #endif 689 | 690 | #if defined(__QNXNTO__) 691 | # define CXX_OS_QNX (1) 692 | #else 693 | # define CXX_OS_QNX (0) 694 | #endif 695 | 696 | #if defined(__sun) 697 | # define CXX_OS_SOLARIS (1) 698 | #else 699 | # define CXX_OS_SOLARIS (0) 700 | #endif 701 | 702 | #if defined(__CYGWIN__) 703 | # define CXX_OS_CYGWIN (1) 704 | #else 705 | # define CXX_OS_CYGWIN (0) 706 | #endif 707 | 708 | #define CXX_OS_BSD (CXX_OS_FREEBSD || CXX_OS_DRAGONFLYBSD || CXX_OS_NETBSD || CXX_OS_OPENBSD || CXX_OS_MAC) 709 | 710 | // ============================================================================ 711 | // [Export|Import] 712 | // ============================================================================ 713 | 714 | #if CXX_OS_WINDOWS 715 | # if (CXX_GNU || CXX_CLANG) && !CXX_MINGW 716 | # define CXX_EXPORT __attribute__((__dllexport__)) 717 | # define CXX_IMPORT __attribute__((__dllimport__)) 718 | # else 719 | # define CXX_EXPORT __declspec(dllexport) 720 | # define CXX_IMPORT __declspec(dllimport) 721 | # endif 722 | #else 723 | # if CXX_CLANG || CXX_GNU >= CXX_MAKE_VER(4, 0, 0) || CXX_GNU_COMPAT 724 | # define CXX_EXPORT __attribute__((__visibility__("default"))) 725 | # define CXX_IMPORT 726 | # else 727 | # define CXX_EXPORT 728 | # define CXX_IMPORT 729 | # endif 730 | #endif 731 | 732 | // ============================================================================ 733 | // [Function Attributes] 734 | // ============================================================================ 735 | 736 | #if CXX_ARCH_X86 737 | # if CXX_HAS_X_ATTRIBUTE 738 | # define CXX_CDECL __attribute__((__cdecl__)) 739 | # define CXX_STDCALL __attribute__((__stdcall__)) 740 | # define CXX_FASTCALL __attribute__((__fastcall__)) 741 | # define CXX_REGPARM(N) __attribute__((__regparm__(N))) 742 | # else 743 | # define CXX_CDECL __cdecl 744 | # define CXX_STDCALL __stdcall 745 | # define CXX_FASTCALL __fastcall 746 | # define CXX_REGPARM(N) 747 | # endif 748 | #else 749 | # define CXX_CDECL 750 | # define CXX_STDCALL 751 | # define CXX_FASTCALL 752 | # define CXX_REGPARM(N) 753 | #endif 754 | 755 | #if CXX_HAS_X_ATTRIBUTE_ALWAYS_INLINE 756 | # define CXX_FORCEINLINE inline __attribute__((__always_inline__)) 757 | #elif CXX_HAS_X_FORCEINLINE 758 | # define CXX_FORCEINLINE __forceinline 759 | #else 760 | # define CXX_FORCEINLINE inline 761 | #endif 762 | 763 | #if CXX_HAS_X_ATTRIBUTE_NOINLINE 764 | # define CXX_NOINLINE __attribute__((__noinline__)) 765 | #elif CXX_HAS_X_DECLSPEC_NOINLINE 766 | # define CXX_NOINLINE __declspec(noinline) 767 | #else 768 | # define CXX_NOINLINE 769 | #endif 770 | 771 | #if CXX_HAS_X_ATTRIBUTE_NORETURN 772 | # define CXX_NORETURN __attribute__((__noreturn__)) 773 | #elif CXX_HAS_X_DECLSPEC_NORETURN 774 | # define CXX_NORETURN __declspec(noreturn) 775 | #else 776 | # define CXX_NORETURN 777 | #endif 778 | 779 | 780 | // ============================================================================ 781 | // [Likely / Unlikely] 782 | // ============================================================================ 783 | 784 | #if CXX_HAS_X_BUILTIN_EXPECT 785 | # define CXX_LIKELY(EXP) __builtin_expect(!!(EXP), 1) 786 | # define CXX_UNLIKELY(EXP) __builtin_expect(!!(EXP), 0) 787 | #else 788 | # define CXX_LIKELY(EXP) (EXP) 789 | # define CXX_UNLIKELY(EXP) (EXP) 790 | #endif 791 | 792 | // ============================================================================ 793 | // [CXX_ALIGN] 794 | // ============================================================================ 795 | 796 | #if CXX_HAS_X_DECLSPEC_ALIGN 797 | # define CXX_ALIGN_TYPE(TYPE, N_ALIGN) __declspec(align(N_ALIGN)) TYPE 798 | # define CXX_ALIGN_DECL(TYPE, VARIABLE, N_ALIGN) __declspec(align(N_ALIGN)) TYPE VARIABLE 799 | #elif CXX_HAS_X_ATTRIBUTE_ALIGNED 800 | # define CXX_ALIGN_TYPE(TYPE, N_ALIGN) __attribute__((__aligned__(N_ALIGN))) TYPE 801 | # define CXX_ALIGN_DECL(TYPE, VARIABLE, N_ALIGN) TYPE __attribute__((__aligned__(N_ALIGN))) VARIABLE 802 | #else 803 | # define CXX_ALIGN_TYPE(TYPE, N_ALIGN) TYPE 804 | # define CXX_ALIGN_DECL(TYPE, VARIABLE, N_ALIGN) TYPE VARIABLE 805 | #endif 806 | 807 | // ============================================================================ 808 | // [Assumptions] 809 | // ============================================================================ 810 | 811 | #if CXX_HAS_X_ASSUME 812 | # define CXX_ASSUME(EXP) __assume(EXP) 813 | #elif CXX_HAS_X_BUILTIN_ASSUME 814 | # define CXX_ASSUME(EXP) __builtin_assume(EXP) 815 | #elif CXX_HAS_X_BUILTIN_UNREACHABLE 816 | # define CXX_ASSUME(EXP) do { if (!(EXP)) __builtin_unreachable(); } while (0) 817 | #else 818 | # define CXX_ASSUME(EXP) ((void)0) 819 | #endif 820 | 821 | #if CXX_HAS_X_ASSUME_ALIGNED 822 | # define CXX_ASSUME_ALIGNED(PTR, N_ALIGN) __assume_aligned(PTR, N_ALIGN) 823 | #elif CXX_HAS_X_BUILTIN_ASSUME_ALIGNED 824 | # define CXX_ASSUME_ALIGNED(PTR, N_ALIGN) PTR = __builtin_assume_aligned(PTR, N_ALIGN) 825 | #else 826 | # define CXX_ASSUME_ALIGNED(PTR, N_ALIGN) ((void)0) 827 | #endif 828 | 829 | // ============================================================================ 830 | // [Annotations] 831 | // ============================================================================ 832 | 833 | #define CXX_UNUSED(X) (void)(X) 834 | 835 | #if CXX_CLANG && CXX_CPLUSPLUS >= 201103L 836 | # define CXX_FALLTHROUGH [[clang::fallthrough]] 837 | #elif CXX_GNU >= CXX_MAKE_VER(7, 0, 0) 838 | # define CXX_FALLTHROUGH __attribute__((__fallthrough__)) 839 | #else 840 | # define CXX_FALLTHROUGH (void)0 /* fallthrough */ 841 | #endif 842 | 843 | // ============================================================================ 844 | // [Other General Purpose Macros] 845 | // ============================================================================ 846 | 847 | #define CXX_ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 848 | #define CXX_OFFSET_OF(STRUCT, MEMBER) ((size_t)((const char*)&((const (STRUCT)*)0x1)->MEMBER) - 1) 849 | 850 | // ============================================================================ 851 | // [Guard] 852 | // ============================================================================ 853 | 854 | #endif 855 | --------------------------------------------------------------------------------