carb/Defines.h
File members: carb/Defines.h
// Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "detail/PushBadMacros.h"
#include <cassert>
#include <cinttypes>
#include <climits>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <csignal>
#ifndef CARB_NO_MALLOC_FREE
# include <cstring>
#else
# include <cstddef> // for size_t
#endif
#include <new>
#include <exception> // for std::terminate
#include <type_traits>
#include <mutex>
#include "detail/PopBadMacros.h"
#define CARB_UNSUPPORTED_PLATFORM() static_assert(false, "Unsupported platform!")
#define CARB_UNSUPPORTED_ARCHITECTURE() static_assert(false, "Unsupported architecture!")
#ifndef CARB_DEBUG
# if defined(NDEBUG) || defined(DOXYGEN_BUILD)
# define CARB_DEBUG 0
# else
# define CARB_DEBUG 1
# endif
#endif
#define CARB_VIZ
#ifdef DOXYGEN_BUILD
# define CARB_PLATFORM_WINDOWS 0
# define CARB_PLATFORM_LINUX 1
# define CARB_PLATFORM_MACOS 0
# define CARB_PLATFORM_NAME
#elif defined(CARB_PLATFORM_WINDOWS) && defined(CARB_PLATFORM_LINUX) && defined(CARB_PLATFORM_MACOS)
# if (!!CARB_PLATFORM_WINDOWS) + (!!CARB_PLATFORM_LINUX) + (!!CARB_PLATFORM_MACOS) != 1
# define CARB_PLATFORM_WINDOWS // show previous definition
# define CARB_PLATFORM_LINUX // show previous definition
# define CARB_PLATFORM_MACOS // show previous definition
# error Exactly one of CARB_PLATFORM_WINDOWS, CARB_PLATFORM_LINUX or CARB_PLATFORM_MACOS must be non-zero.
# endif
#elif !defined(CARB_PLATFORM_WINDOWS) && !defined(CARB_PLATFORM_LINUX)
# ifdef _WIN32
# define CARB_PLATFORM_WINDOWS 1
# define CARB_PLATFORM_LINUX 0
# define CARB_PLATFORM_MACOS 0
# define CARB_PLATFORM_NAME "windows"
# elif defined(__linux__)
# define CARB_PLATFORM_WINDOWS 0
# define CARB_PLATFORM_LINUX 1
# define CARB_PLATFORM_MACOS 0
# define CARB_PLATFORM_NAME "linux"
# elif defined(__APPLE__)
# define CARB_PLATFORM_WINDOWS 0
# define CARB_PLATFORM_LINUX 0
# define CARB_PLATFORM_MACOS 1
# define CARB_PLATFORM_NAME "macos"
# else
CARB_UNSUPPORTED_PLATFORM();
# endif
#else
# error "Must define all of CARB_PLATFORM_WINDOWS, CARB_PLATFORM_LINUX and CARB_PLATFORM_MACOS or none."
#endif
#if CARB_PLATFORM_LINUX || CARB_PLATFORM_MACOS || defined(DOXYGEN_BUILD)
# include <unistd.h> // _POSIX_VERSION comes from unistd.h
# define CARB_POSIX _POSIX_VERSION
#else
# define CARB_POSIX 0
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
# if CARB_PLATFORM_WINDOWS
# ifndef CARB_NO_MALLOC_FREE
# include "malloc.h"
# endif
# include <intrin.h>
# elif CARB_PLATFORM_LINUX
# include <alloca.h>
# include <signal.h>
# define _alloca alloca
# endif
#endif
// Architecture defines
#ifdef DOXYGEN_BUILD
# define CARB_AARCH64 0
# define CARB_X86_64 1
# define CARB_ARCH_NAME
#elif defined(__aarch64__)
# define CARB_AARCH64 1
# define CARB_X86_64 0
#elif defined(__x86_64__) /*GCC*/ || defined(_M_X64) /*MSVC*/
# define CARB_X86_64 1
# define CARB_AARCH64 0
#endif
#if CARB_PLATFORM_MACOS
# define CARB_ARCH_NAME "universal"
#else
# if CARB_X86_64
# define CARB_ARCH_NAME "x86_64"
# elif CARB_AARCH64
# define CARB_ARCH_NAME "aarch64"
# endif
#endif
#ifndef CARB_PROFILING
# define CARB_PROFILING 1
#endif
#ifdef DOXYGEN_BUILD
# define CARB_TEGRA 0
#elif !defined(CARB_TEGRA)
# if defined(__aarch64__) && defined(__LINARO_RELEASE__)
# define CARB_TEGRA 1
# else
# define CARB_TEGRA 0
# endif
#endif
#ifdef DOXYGEN_BUILD
# define CARB_COMPILER_MSC 0
# define CARB_COMPILER_GNUC 1
#elif defined(CARB_COMPILER_MSC) && defined(CARB_COMPILER_GNUC)
# if (!!CARB_COMPILER_MSC) + (!!CARB_COMPILER_GNUC) != 1
# define CARB_COMPILER_MSC // Show previous definition
# define CARB_COMPILER_GNUC // Show previous definition
# error Exactly one of CARB_COMPILER_MSC or CARB_COMPILER_GNUC must be non-zero.
# endif
#elif !defined(CARB_COMPILER_MSC) && !defined(CARB_COMPILER_GNUC)
# ifndef CARB_COMPILER_MSC
# if defined(_MSC_VER)
# define CARB_COMPILER_MSC 1
# define CARB_COMPILER_GNUC 0
# elif defined(__GNUC__)
# define CARB_COMPILER_MSC 0
# define CARB_COMPILER_GNUC 1
# else
# error "Unsupported compiler."
# endif
# endif
#else
# error "Must define CARB_COMPILER_MSC and CARB_COMPILER_GNUC or neither."
#endif
#ifdef DOXYGEN_BUILD
# define CARB_TOOLCHAIN_CLANG 0
#elif !defined(CARB_TOOLCHAIN_CLANG)
# if defined(__clang__)
# define CARB_TOOLCHAIN_CLANG 1
# else
# define CARB_TOOLCHAIN_CLANG 0
# endif
#endif
#ifdef DOXYGEN_BUILD
# define CARB_ASAN_ENABLED 0
#elif !defined(CARB_ASAN_ENABLED)
# ifdef __SANITIZE_ADDRESS__
# define CARB_ASAN_ENABLED __SANITIZE_ADDRESS__
# else
# define CARB_ASAN_ENABLED 0
# endif
#endif
#ifdef DOXYGEN_BUILD
# define CARB_TSAN_ENABLED 0
#elif !defined(CARB_TSAN_ENABLED)
# ifdef __SANITIZE_THREAD__
# define CARB_TSAN_ENABLED __SANITIZE_THREAD__
# else
# define CARB_TSAN_ENABLED 0
# endif
#endif
#define CARB_DEPAREN(pack_) CARB_IDENTITY pack_
#define CARB_IDENTITY(...) __VA_ARGS__
// Compiler specific defines. Exist for all supported compilers but may be a no-op for certain compilers.
#ifdef DOXYGEN_BUILD
# define CARB_PRETTY_FUNCTION "<function signature here>"
# define CARB_ATTRIBUTE(...)
# define CARB_DECLSPEC(...)
# define CARB_MSC_ONLY(...)
# define CARB_NOT_MSC(...)
# define CARB_GNUC_ONLY(...)
# define CARB_NOT_GNUC(...)
# define CARB_PRAGMA(...)
# define CARB_PRAGMA_MSC(...)
# define CARB_PRAGMA_GNUC(...)
# define CARB_DOC_CONSTEXPR const
# define CARB_EXCEPTIONS_ENABLED 1
# define CARB_DOC_ONLY(...) __VA_ARGS__
# define CARB_NO_DOC(...)
#else
# define CARB_DOC_CONSTEXPR constexpr
# define CARB_DOC_ONLY(...)
# define CARB_NO_DOC(...) __VA_ARGS__
# if CARB_COMPILER_MSC
# define CARB_PRETTY_FUNCTION __FUNCSIG__
# define CARB_ATTRIBUTE(...)
# define CARB_MSC_ONLY(...) __VA_ARGS__
# define CARB_NOT_MSC(...)
# define CARB_GNUC_ONLY(...)
# define CARB_NOT_GNUC(...) __VA_ARGS__
# define CARB_PRAGMA(...) __pragma(__VA_ARGS__)
# define CARB_DECLSPEC(...) __declspec(__VA_ARGS__)
# define CARB_PRAGMA_MSC(...) CARB_PRAGMA(__VA_ARGS__)
# define CARB_PRAGMA_GNUC(...)
# ifdef __cpp_exceptions
# define CARB_EXCEPTIONS_ENABLED 1
# else
# define CARB_EXCEPTIONS_ENABLED 0
# endif
// Other MSC-specific definitions that must exist outside of the carb namespace
extern "C" void _mm_prefetch(char const* _A, int _Sel); // From winnt.h/intrin.h
# if defined(__INTELLISENSE__) && _MSC_VER < 1920
// See: https://stackoverflow.com/questions/61485127/including-windows-h-causes-unknown-attributeno-init-all-error
# define no_init_all deprecated
# endif
# elif CARB_COMPILER_GNUC
# define CARB_PRETTY_FUNCTION __PRETTY_FUNCTION__
# define CARB_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
# define CARB_DECLSPEC(...)
# define CARB_MSC_ONLY(...)
# define CARB_NOT_MSC(...) __VA_ARGS__
# define CARB_GNUC_ONLY(...) __VA_ARGS__
# define CARB_NOT_GNUC(...)
# define CARB_PRAGMA(...) _Pragma(__VA_ARGS__)
# define CARB_PRAGMA_MSC(...)
# define CARB_PRAGMA_GNUC(...) CARB_PRAGMA(__VA_ARGS__)
# ifdef __EXCEPTIONS
# define CARB_EXCEPTIONS_ENABLED 1
# else
# define CARB_EXCEPTIONS_ENABLED 0
# endif
# else
# error Unsupported compiler
# endif
#endif
#if defined(DOXYGEN_BUILD) || defined(OMNI_BIND)
# define CARB_OPTIMIZE_OFF_MSC()
# define CARB_OPTIMIZE_ON_MSC()
# define CARB_NO_OPTIMIZE_GNUC_CLANG()
#else
# if CARB_COMPILER_MSC
# define CARB_OPTIMIZE_OFF_MSC() CARB_PRAGMA_MSC(optimize("", off))
# define CARB_OPTIMIZE_ON_MSC() CARB_PRAGMA_MSC(optimize("", on))
# define CARB_NO_OPTIMIZE_GNUC_CLANG()
# elif CARB_TOOLCHAIN_CLANG
# define CARB_NO_OPTIMIZE_GNUC_CLANG() CARB_ATTRIBUTE(optnone)
# define CARB_OPTIMIZE_OFF_MSC()
# define CARB_OPTIMIZE_ON_MSC()
# elif CARB_COMPILER_GNUC
# define CARB_NO_OPTIMIZE_GNUC_CLANG() CARB_ATTRIBUTE(optimize("-O0"))
# define CARB_OPTIMIZE_OFF_MSC()
# define CARB_OPTIMIZE_ON_MSC()
# else
# error Unsupported compiler
# endif
#endif
// MSC-specific warning macros are defined only for MSC
// CARB_IGNOREWARNING_MSC_PUSH: MSVC only; pushes the warning state
// CARB_IGNOREWARNING_MSC_POP: MSVC only; pops the warning state
// CARB_IGNOREWARNING_MSC(w): MSVC only; disables the given warning number (ex: CARB_IGNOREWARNING_MSC(4505))
// CARB_IGNOREWARNING_MSC_WITH_PUSH(w): MSVC only; combines CARB_IGNOREWARNING_MSC_PUSH and CARB_IGNOREWARNING_MSC()
#if !defined(DOXYGEN_BUILD) && CARB_COMPILER_MSC
# define CARB_IGNOREWARNING_MSC_PUSH __pragma(warning(push))
# define CARB_IGNOREWARNING_MSC_POP __pragma(warning(pop))
# define CARB_IGNOREWARNING_MSC(w) __pragma(warning(disable : w))
# define CARB_IGNOREWARNING_MSC_WITH_PUSH(w) \
CARB_IGNOREWARNING_MSC_PUSH \
CARB_IGNOREWARNING_MSC(w)
#else
# define CARB_IGNOREWARNING_MSC_PUSH
# define CARB_IGNOREWARNING_MSC_POP
# define CARB_IGNOREWARNING_MSC(w)
# define CARB_IGNOREWARNING_MSC_WITH_PUSH(w)
#endif
// GNUC-specific helper macros are defined for GCC and Clang-infrastructure
// CARB_IGNOREWARNING_GNUC_PUSH: GCC only; pushes the warning state
// CARB_IGNOREWARNING_GNUC_POP: GCC only; pops the warning state
// CARB_IGNOREWARNING_CLANG_PUSH: Clang only; pushes the warning state
// CARB_IGNOREWARNING_CLANG_POP: Clang only; pops the warning state
// CARB_IGNOREWARNING_GNUC(w): GCC only; disables the given warning (ex: CARB_IGNOREWARNING_GNUC("-Wattributes"))
// CARB_IGNOREWARNING_GNUC_WITH_PUSH(w): GCC only; combines CARB_IGNOREWARNING_GNUC_PUSH and CARB_IGNOREWARNING_GNUC()
// CARB_IGNOREWARNING_CLANG(w): Clang only; disables the given warning (ex: CARB_IGNOREWARNING_CLANG("-Wattributes"))
// CARB_IGNOREWARNING_CLANG_WITH_PUSH(w): Clang only; combines CARB_IGNOREWARNING_CLANG_PUSH and
// CARB_IGNOREWARNING_CLANG()
#if !defined(DOXYGEN_BUILD) && (CARB_COMPILER_GNUC || CARB_TOOLCHAIN_CLANG)
# define CARB_IGNOREWARNING_GNUC_PUSH _Pragma("GCC diagnostic push")
# define CARB_IGNOREWARNING_GNUC_POP _Pragma("GCC diagnostic pop")
# define INTERNAL_CARB_IGNOREWARNING_GNUC(str) _Pragma(# str)
# define CARB_IGNOREWARNING_GNUC(w) INTERNAL_CARB_IGNOREWARNING_GNUC(GCC diagnostic ignored w)
# define CARB_IGNOREWARNING_GNUC_WITH_PUSH(w) CARB_IGNOREWARNING_GNUC_PUSH CARB_IGNOREWARNING_GNUC(w)
# if CARB_TOOLCHAIN_CLANG
# define CARB_IGNOREWARNING_CLANG_PUSH _Pragma("GCC diagnostic push")
# define CARB_IGNOREWARNING_CLANG_POP _Pragma("GCC diagnostic pop")
# define INTERNAL_CARB_IGNOREWARNING_CLANG(str) _Pragma(# str)
# define CARB_IGNOREWARNING_CLANG(w) INTERNAL_CARB_IGNOREWARNING_CLANG(GCC diagnostic ignored w)
# define CARB_IGNOREWARNING_CLANG_WITH_PUSH(w) CARB_IGNOREWARNING_CLANG_PUSH CARB_IGNOREWARNING_CLANG(w)
# else
# define CARB_IGNOREWARNING_CLANG_PUSH
# define CARB_IGNOREWARNING_CLANG_POP
# define CARB_IGNOREWARNING_CLANG(w)
# define CARB_IGNOREWARNING_CLANG_WITH_PUSH(w)
# endif
#else
# define CARB_IGNOREWARNING_GNUC_PUSH
# define CARB_IGNOREWARNING_GNUC_POP
# define CARB_IGNOREWARNING_CLANG_PUSH
# define CARB_IGNOREWARNING_CLANG_POP
# define CARB_IGNOREWARNING_GNUC(w)
# define CARB_IGNOREWARNING_GNUC_WITH_PUSH(w)
# define CARB_IGNOREWARNING_CLANG(w)
# define CARB_IGNOREWARNING_CLANG_WITH_PUSH(w)
#endif
#if defined(__cplusplus) || defined(DOXYGEN_BUILD)
# define CARB_EXTERN_C extern "C"
#else
# define CARB_EXTERN_C
#endif
#define CARB_EXPORT CARB_EXTERN_C CARB_DECLSPEC(dllexport) CARB_ATTRIBUTE(visibility("default"))
#define CARB_IMPORT CARB_EXTERN_C
// For documentation only
#ifdef DOXYGEN_BUILD
# define CARB_EXPORTS
#endif
#if defined(CARB_EXPORTS) || defined(DOXYGEN_BUILD)
# define CARB_DYNAMICLINK CARB_EXPORT
#else
# define CARB_DYNAMICLINK CARB_IMPORT
#endif
#if CARB_PLATFORM_WINDOWS || defined(DOXYGEN_BUILD)
# define CARB_ABI __cdecl
#else
# define CARB_ABI
#endif
#if (defined(__cplusplus) && __cplusplus >= 201400L) || defined(DOXYGEN_BUILD)
# define CARB_HAS_CPP14 1
#else
# define CARB_HAS_CPP14 0
#endif
#if (defined(__cplusplus) && __cplusplus >= 201700L) || defined(DOXYGEN_BUILD)
# define CARB_HAS_CPP17 1
#else
# define CARB_HAS_CPP17 0
#endif
#if CARB_HAS_CPP17 && !defined(DOXYGEN_BUILD)
# define CARB_CPP17_CONSTEXPR constexpr
#else
# define CARB_CPP17_CONSTEXPR
#endif
#if (defined(__cplusplus) && __cplusplus >= 202000L) || defined(DOXYGEN_BUILD)
# define CARB_HAS_CPP20 1
#else
# define CARB_HAS_CPP20 0
#endif
#if defined(__has_cpp_attribute) // C++20
# define CARBLOCAL_HAS_NODISCARD (__has_cpp_attribute(nodiscard) >= 201603L)
# define CARBLOCAL_HAS_NODISCARD_MSG (__has_cpp_attribute(nodiscard) >= 201907L)
# define CARBLOCAL_HAS_FALLTHROUGH (__has_cpp_attribute(fallthrough) >= 201603L)
# define CARBLOCAL_HAS_MAYBE_UNUSED (__has_cpp_attribute(maybe_unused) >= 201603L)
# define CARBLOCAL_HAS_LIKELY (__has_cpp_attribute(likely) >= 201803L)
# define CARBLOCAL_HAS_UNLIKELY (__has_cpp_attribute(unlikely) >= 201803L)
# define CARBLOCAL_HAS_NO_UNIQUE_ADDRESS (__has_cpp_attribute(no_unique_address) >= 201803L)
#else
# define CARBLOCAL_HAS_NODISCARD CARB_HAS_CPP17
# define CARBLOCAL_HAS_NODISCARD_MSG 0
# define CARBLOCAL_HAS_FALLTHROUGH CARB_HAS_CPP17
# define CARBLOCAL_HAS_MAYBE_UNUSED CARB_HAS_CPP17
# define CARBLOCAL_HAS_LIKELY 0
# define CARBLOCAL_HAS_UNLIKELY 0
# define CARBLOCAL_HAS_NO_UNIQUE_ADDRESS 0
#endif
// [[nodiscard]]
#if (CARB_HAS_CPP17 && CARBLOCAL_HAS_NODISCARD) || defined(DOXYGEN_BUILD)
# define CARB_NODISCARD [[nodiscard]]
# define CARB_NODISCARD_TYPE [[nodiscard]]
#elif CARB_COMPILER_GNUC
# define CARB_NODISCARD __attribute__((warn_unused_result))
# define CARB_NODISCARD_TYPE
#else // not supported
# define CARB_NODISCARD
# define CARB_NODISCARD_TYPE
#endif
// [[nodiscard(msg)]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_NODISCARD_MSG) || defined(DOXYGEN_BUILD)
# define CARB_NODISCARD_MSG(msg) [[nodiscard(msg)]]
# define CARB_NODISCARD_TYPE_MSG(msg) [[nodiscard(msg)]]
#else
# define CARB_NODISCARD_MSG(msg) CARB_NODISCARD
# define CARB_NODISCARD_TYPE_MSG(msg) CARB_NODISCARD_TYPE
#endif
// [[fallthrough]]
#if (CARB_HAS_CPP17 && CARBLOCAL_HAS_FALLTHROUGH) || defined(DOXYGEN_BUILD)
# define CARB_FALLTHROUGH [[fallthrough]]
#elif CARB_COMPILER_GNUC
# if __GNUC__ >= 7
# define CARB_FALLTHROUGH __attribute__((fallthrough))
# else
// Marker comment
# define CARB_FALLTHROUGH /* fall through */
# endif
#else // not supported
# define CARB_FALLTHROUGH
#endif
// [[maybe_unused]]
#if (CARB_HAS_CPP17 && CARBLOCAL_HAS_MAYBE_UNUSED) || defined(DOXYGEN_BUILD)
# define CARB_MAYBE_UNUSED [[maybe_unused]]
#elif CARB_COMPILER_GNUC
# define CARB_MAYBE_UNUSED __attribute__((unused))
#else // not supported
# define CARB_MAYBE_UNUSED
#endif
// [[likely]] / [[unlikely]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_LIKELY) || defined(DOXYGEN_BUILD)
# define CARB_CPP20_LIKELY [[likely]]
#else
# define CARB_CPP20_LIKELY
#endif
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_UNLIKELY) || defined(DOXYGEN_BUILD)
# define CARB_CPP20_UNLIKELY [[unlikely]]
#else
# define CARB_CPP20_UNLIKELY
#endif
#if CARB_COMPILER_GNUC || defined(DOXYGEN_BUILD)
# define CARB_LIKELY(expr) __builtin_expect(!!(expr), 1)
# define CARB_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
#else // not supported
# define CARB_LIKELY(expr) (!!(expr))
# define CARB_UNLIKELY(expr) (!!(expr))
#endif
#define CARB_LIKELY_IF(...) \
if (CARB_LIKELY(__VA_ARGS__)) \
CARB_CPP20_LIKELY
#define CARB_UNLIKELY_IF(...) \
if (CARB_UNLIKELY(__VA_ARGS__)) \
CARB_CPP20_UNLIKELY
// [[no_unique_address]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_NO_UNIQUE_ADDRESS) || defined(DOXYGEN_BUILD)
# define CARB_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else // not supported
# define CARB_NO_UNIQUE_ADDRESS
#endif
#define CARB_HIDDEN CARB_ATTRIBUTE(visibility("hidden"))
#define CARB_WEAKLINK CARB_DECLSPEC(selectany) CARB_ATTRIBUTE(weak)
// constexpr in CPP20, but not before
#if (CARB_HAS_CPP20 && __cpp_constexpr >= 201907L) || defined(DOXYGEN_BUILD)
# define CARB_CPP20_CONSTEXPR constexpr
#else
# define CARB_CPP20_CONSTEXPR
#endif
// include the IAssert interface here. Note that this cannot be included any earlier because
// it requires symbols such as "CARB_ABI". Also note that it cannot be put into the CARB_DEBUG
// section below because the mirroring tool picks it up and generates type information for it.
// If it is not unconditionally included here, that leads to build errors in release builds.
#include "assert/IAssert.h"
#ifdef DOXYGEN_BUILD
# define CARB_BREAK_POINT()
#elif CARB_POSIX
# define CARB_BREAK_POINT() ::raise(SIGTRAP)
#elif CARB_PLATFORM_WINDOWS
# define CARB_BREAK_POINT() ::__debugbreak()
#else
CARB_UNSUPPORTED_PLATFORM();
#endif
namespace carb
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace detail
{
// clang-format off
#define C(a) (unsigned char)(0x##a)
constexpr unsigned char lowerTable[256] = {
C(00), C(01), C(02), C(03), C(04), C(05), C(06), C(07), C(08), C(09), C(0A), C(0B), C(0C), C(0D), C(0E), C(0F),
C(10), C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18), C(19), C(1A), C(1B), C(1C), C(1D), C(1E), C(1F),
C(20), C(21), C(22), C(23), C(24), C(25), C(26), C(27), C(28), C(29), C(2A), C(2B), C(2C), C(2D), C(2E), C(2F),
C(30), C(31), C(32), C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(3A), C(3B), C(3C), C(3D), C(3E), C(3F),
C(40),
// [0x41, 0x5A] -> [0x61, 0x7A]
C(61), C(62), C(63), C(64), C(65), C(66), C(67), C(68), C(69), C(6A), C(6B), C(6C), C(6D), C(6E), C(6F),
C(70), C(71), C(72), C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(7A),
C(5B), C(5C), C(5D), C(5E), C(5F),
C(60), C(61), C(62), C(63), C(64), C(65), C(66), C(67), C(68), C(69), C(6A), C(6B), C(6C), C(6D), C(6E), C(6F),
C(70), C(71), C(72), C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(7A), C(7B), C(7C), C(7D), C(7E), C(7F),
C(80), C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88), C(89), C(8A), C(8B), C(8C), C(8D), C(8E), C(8F),
C(90), C(91), C(92), C(93), C(94), C(95), C(96), C(97), C(98), C(99), C(9A), C(9B), C(9C), C(9D), C(9E), C(9F),
C(A0), C(A1), C(A2), C(A3), C(A4), C(A5), C(A6), C(A7), C(A8), C(A9), C(AA), C(AB), C(AC), C(AD), C(AE), C(AF),
C(B0), C(B1), C(B2), C(B3), C(B4), C(B5), C(B6), C(B7), C(B8), C(B9), C(BA), C(BB), C(BC), C(BD), C(BE), C(BF),
C(C0), C(C1), C(C2), C(C3), C(C4), C(C5), C(C6), C(C7), C(C8), C(C9), C(CA), C(CB), C(CC), C(CD), C(CE), C(CF),
C(D0), C(D1), C(D2), C(D3), C(D4), C(D5), C(D6), C(D7), C(D8), C(D9), C(DA), C(DB), C(DC), C(DD), C(DE), C(DF),
C(E0), C(E1), C(E2), C(E3), C(E4), C(E5), C(E6), C(E7), C(E8), C(E9), C(EA), C(EB), C(EC), C(ED), C(EE), C(EF),
C(F0), C(F1), C(F2), C(F3), C(F4), C(F5), C(F6), C(F7), C(F8), C(F9), C(FA), C(FB), C(FC), C(FD), C(FE), C(FF),
};
constexpr unsigned char upperTable[256] = {
C(00), C(01), C(02), C(03), C(04), C(05), C(06), C(07), C(08), C(09), C(0A), C(0B), C(0C), C(0D), C(0E), C(0F),
C(10), C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18), C(19), C(1A), C(1B), C(1C), C(1D), C(1E), C(1F),
C(20), C(21), C(22), C(23), C(24), C(25), C(26), C(27), C(28), C(29), C(2A), C(2B), C(2C), C(2D), C(2E), C(2F),
C(30), C(31), C(32), C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(3A), C(3B), C(3C), C(3D), C(3E), C(3F),
C(40), C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48), C(49), C(4A), C(4B), C(4C), C(4D), C(4E), C(4F),
C(50), C(51), C(52), C(53), C(54), C(55), C(56), C(57), C(58), C(59), C(5A), C(5B), C(5C), C(5D), C(5E), C(5F),
C(60),
// [0x61, 0x7A] -> [0x41, 0x5A]
C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48), C(49), C(4A), C(4B), C(4C), C(4D), C(4E), C(4F),
C(50), C(51), C(52), C(53), C(54), C(55), C(56), C(57), C(58), C(59), C(5A),
C(7B), C(7C), C(7D), C(7E), C(7F),
C(80), C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88), C(89), C(8A), C(8B), C(8C), C(8D), C(8E), C(8F),
C(90), C(91), C(92), C(93), C(94), C(95), C(96), C(97), C(98), C(99), C(9A), C(9B), C(9C), C(9D), C(9E), C(9F),
C(A0), C(A1), C(A2), C(A3), C(A4), C(A5), C(A6), C(A7), C(A8), C(A9), C(AA), C(AB), C(AC), C(AD), C(AE), C(AF),
C(B0), C(B1), C(B2), C(B3), C(B4), C(B5), C(B6), C(B7), C(B8), C(B9), C(BA), C(BB), C(BC), C(BD), C(BE), C(BF),
C(C0), C(C1), C(C2), C(C3), C(C4), C(C5), C(C6), C(C7), C(C8), C(C9), C(CA), C(CB), C(CC), C(CD), C(CE), C(CF),
C(D0), C(D1), C(D2), C(D3), C(D4), C(D5), C(D6), C(D7), C(D8), C(D9), C(DA), C(DB), C(DC), C(DD), C(DE), C(DF),
C(E0), C(E1), C(E2), C(E3), C(E4), C(E5), C(E6), C(E7), C(E8), C(E9), C(EA), C(EB), C(EC), C(ED), C(EE), C(EF),
C(F0), C(F1), C(F2), C(F3), C(F4), C(F5), C(F6), C(F7), C(F8), C(F9), C(FA), C(FB), C(FC), C(FD), C(FE), C(FF),
};
#undef C
// clang-format on
} // namespace detail
#endif
inline bool assertHandlerFallback(
const char* condition, const char* file, const char* func, int32_t line, const char* fmt = nullptr, ...)
{
static std::mutex m;
std::lock_guard<std::mutex> g(m);
if (fmt != nullptr)
{
fprintf(stderr, "%s:%s():%" PRId32 ": Assertion (%s) failed: ", file, func, line, condition);
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fputc('\n', stderr);
}
else
fprintf(stderr, "%s:%" PRId32 ":%s(): Assertion (%s) failed.\n", file, line, func, condition);
return true;
}
} // namespace carb
#ifdef DOXYGEN_BUILD
# define CARB_ASSERT_ENABLED 0
# define CARB_CHECK_ENABLED 0
# define CARB_ASSERT(cond, ...) ((void)0)
# define CARB_CHECK(cond, ...) ((void)0)
# define CARB_FATAL_UNLESS(cond, fmt, ...) (!(cond) ? (std::terminate(), false) : true)
#else
/* main assertion test entry point. This is implemented as a single conditional statement to
* ensure that the assertion failure breakpoint occurs on the same line of code as the assertion
* test itself. CARB_CHECK() exists in release and debug, and CARB_ASSERT() is debug-only.
*/
// example-begin CARB_IMPL_ASSERT
# define CARB_IMPL_ASSERT(cond, ...) \
(CARB_LIKELY(cond) || \
![&](const char* funcname__, ...) CARB_NOINLINE { \
return g_carbAssert ? \
g_carbAssert->reportFailedAssertion(#cond, __FILE__, funcname__, __LINE__, ##__VA_ARGS__) : \
::carb::assertHandlerFallback(#cond, __FILE__, funcname__, __LINE__, ##__VA_ARGS__); \
}(CARB_PRETTY_FUNCTION) || \
(CARB_BREAK_POINT(), false))
// example-end CARB_IMPL_ASSERT
# ifndef CARB_CHECK
# ifndef CARB_CHECK_ENABLED
# define CARB_CHECK_ENABLED 1
# endif
# if CARB_CHECK_ENABLED
# define CARB_CHECK(cond, ...) CARB_IMPL_ASSERT(cond, ##__VA_ARGS__)
# else
# define CARB_CHECK(cond, ...) ((void)0)
# endif
# else
// CARB_CHECK was already defined
# ifndef CARB_CHECK_ENABLED
# define CARB_CHECK /* cause an error showing where it was already defined */
# error CARB_CHECK_ENABLED must also be defined if CARB_CHECK is pre-defined!
# endif
# endif
# ifndef CARB_FATAL_UNLESS
// example-begin CARB_FATAL_UNLESS
# define CARB_FATAL_UNLESS(cond, fmt, ...) \
(CARB_LIKELY(cond) || \
([&](const char* funcname__, ...) CARB_NOINLINE { \
if (false) \
::printf(fmt, ##__VA_ARGS__); \
g_carbAssert ? g_carbAssert->reportFailedAssertion(#cond, __FILE__, funcname__, __LINE__, fmt, ##__VA_ARGS__) : \
::carb::assertHandlerFallback(#cond, __FILE__, funcname__, __LINE__, fmt, ##__VA_ARGS__); \
}(CARB_PRETTY_FUNCTION), std::terminate(), false))
// example-end CARB_FATAL_UNLESS
# endif
# ifndef CARB_ASSERT
# ifndef CARB_ASSERT_ENABLED
# if CARB_DEBUG
# define CARB_ASSERT_ENABLED 1
# else
# define CARB_ASSERT_ENABLED 0
# endif
# endif
# if CARB_ASSERT_ENABLED
# define CARB_ASSERT(cond, ...) CARB_IMPL_ASSERT(cond, ##__VA_ARGS__)
# else
# define CARB_ASSERT(cond, ...) ((void)0)
# endif
# else
// CARB_ASSERT was already defined
# ifndef CARB_ASSERT_ENABLED
# define CARB_ASSERT /* cause an error showing where it was already defined */
# error CARB_ASSERT_ENABLED must also be defined if CARB_ASSERT is pre-defined!
# endif
# endif
#endif
#define CARB_ASSERT_STRUCTS_MATCH(A, B) \
static_assert( \
sizeof(A) == sizeof(B) && alignof(A) == alignof(B), "Size or alignment mismatch between " #A " and " #B ".")
#define CARB_ASSERT_MEMBERS_MATCH(A, a, B, b) \
static_assert(offsetof(A, a) == offsetof(B, b) && sizeof(A::a) == sizeof(B::b), \
"Offset or size mismatch between members " #a " of " #A " and " #b " of " #B ".")
#define CARB_UINT16_MAX UINT16_MAX
#define CARB_UINT32_MAX UINT32_MAX
#define CARB_UINT64_MAX UINT64_MAX
#define CARB_ULLONG_MAX ULLONG_MAX
#define CARB_USHRT_MAX USHRT_MAX
#define CARB_FLOAT_MAX 3.402823466e+38F
#define CARB_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define CARB_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CARB_CLAMP(x, lo, hi) (((x) < (lo)) ? (lo) : (((x) > (hi)) ? (hi) : (x)))
#define CARB_ROUNDUP(value, to) ((((value) + (to)-1) / (to)) * (to))
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// CARB_JOIN will join together `a` and `b` and also work properly if either parameter is another macro like __LINE__.
// This requires two macros since the preprocessor will only recurse macro expansion if # and ## are not present.
# define __CARB_JOIN(a, b) a##b
#endif
#define CARB_JOIN(a, b) __CARB_JOIN(a, b)
#define CARB_PREVENT_COPY(classname) \
classname(const classname&) = delete; \
classname& operator=(const classname&) = delete
#define CARB_PREVENT_MOVE(classname) \
classname(classname&&) = delete; \
classname& operator=(classname&&) = delete
#define CARB_PREVENT_COPY_AND_MOVE(classname) \
CARB_PREVENT_COPY(classname); \
CARB_PREVENT_MOVE(classname)
#if defined(__COUNTER__) || defined(DOXYGEN_BUILD)
# define CARB_ANONYMOUS_VAR(str) CARB_JOIN(str, __COUNTER__)
#else
# define CARB_ANONYMOUS_VAR(str) CARB_JOIN(str, __LINE__)
#endif
namespace carb
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T, size_t N>
constexpr size_t countOf(T const (&)[N])
{
return N;
}
#endif
#define CARB_COUNTOF(a) carb::countOf(a)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T, uint32_t N>
constexpr uint32_t countOf32(T const (&)[N])
{
return N;
}
#endif
#define CARB_COUNTOF32(a) carb::countOf32(a)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T, typename U>
constexpr uint32_t offsetOf(U T::*member)
{
CARB_IGNOREWARNING_GNUC_PUSH
# if CARB_TOOLCHAIN_CLANG && __clang_major__ >= 13 // this error is issued on clang 13
CARB_IGNOREWARNING_GNUC_WITH_PUSH("-Wnull-pointer-subtraction")
# endif
return (uint32_t)((char*)&((T*)nullptr->*member) - (char*)nullptr);
CARB_IGNOREWARNING_GNUC_POP
}
#endif
#define CARB_OFFSETOF(a) carb::offsetOf(&a)
#if CARB_COMPILER_MSC || defined(DOXYGEN_BUILD)
# define CARB_ALIGN_OF(T) __alignof(T)
#elif CARB_COMPILER_GNUC
# define CARB_ALIGN_OF(T) __alignof__(T)
#else
# error "Align of cannot be determined - compiler not known"
#endif
// Implement CARB_HARDWARE_PAUSE; a way of idling the pipelines and reducing the penalty
// from memory order violations. See
// https://software.intel.com/en-us/articles/long-duration-spin-wait-loops-on-hyper-threading-technology-enabled-intel-processors
#ifdef DOXYGEN_BUILD
# define CARB_HARDWARE_PAUSE()
#elif CARB_X86_64
// avoid including immintrin.h
# if CARB_COMPILER_MSC
# pragma intrinsic(_mm_pause)
# define CARB_HARDWARE_PAUSE() _mm_pause()
# else
# define CARB_HARDWARE_PAUSE() __builtin_ia32_pause()
# endif
#elif defined(__aarch64__)
# define CARB_HARDWARE_PAUSE() __asm__ __volatile__("yield" ::: "memory")
#else
CARB_UNSUPPORTED_PLATFORM();
#endif
#if CARB_COMPILER_MSC || defined(DOXYGEN_BUILD)
# pragma intrinsic(_mm_prefetch)
# define CARB_ALWAYS_INLINE __forceinline
# define CARB_PREFETCH(addr, write, level) _mm_prefetch(reinterpret_cast<char*>(addr), int(level))
enum class PrefetchLevel
{
kHintNonTemporal = 0,
kHintL1 = 1,
kHintL2 = 2,
kHintL3 = 3,
};
#elif CARB_COMPILER_GNUC
# define CARB_ALWAYS_INLINE CARB_ATTRIBUTE(always_inline)
# define CARB_PREFETCH(addr, write, level) __builtin_prefetch((addr), (write), int(level))
enum class PrefetchLevel
{
kHintNonTemporal = 0,
kHintL1 = 3,
kHintL2 = 2,
kHintL3 = 1,
};
#else
CARB_UNSUPPORTED_PLATFORM();
#endif
#define CARB_NOINLINE CARB_ATTRIBUTE(noinline) CARB_DECLSPEC(noinline)
#ifdef DOXYGEN_BUILD
# define CARB_DEPRECATED(msg)
# define CARB_FILE_DEPRECATED
# define CARB_NOEXCEPT throw()
# define DOXYGEN_EMPTY_CLASS \
{ \
}
#else
# define CARB_DEPRECATED(msg) CARB_ATTRIBUTE(deprecated(msg)) CARB_DECLSPEC(deprecated(msg))
# ifdef CARB_IGNORE_REMOVEFILE_WARNINGS
# define CARB_FILE_DEPRECATED
# define CARB_FILE_DEPRECATED_MSG(...)
# else
# define CARB_FILE_DEPRECATED_MSG(msg) \
CARB_PRAGMA(message("\x1b[33m" __FILE__ ":" CARB_STRINGIFY( \
__LINE__) ": " msg " (#define CARB_IGNORE_REMOVEFILE_WARNINGS to ignore these warnings)\x1b[0m")) \
CARB_PRAGMA(warning_see_message)
# define CARB_FILE_DEPRECATED CARB_FILE_DEPRECATED_MSG("This file is no longer needed and will be removed soon")
# endif
# define CARB_NOEXCEPT noexcept
# define DOXYGEN_EMPTY_CLASS
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T>
constexpr T align(T x, size_t alignment)
{
return (T)(((size_t)x + alignment - 1) / alignment * alignment);
}
template <typename T>
T* align(T* x, size_t alignment)
{
return (T*)(((size_t)x + alignment - 1) / alignment * alignment);
}
#endif
#define CARB_ALIGN(x, alignment) carb::align(x, alignment)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T>
constexpr T alignedSize(const T& size, uint32_t alignment)
{
return ((size + alignment - 1) / alignment) * alignment;
}
#endif
#define CARB_ALIGNED_SIZE(size, alignment) carb::alignedSize(size, alignment)
#define CARB_ALIGN_AS(T) alignas(T)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <typename T>
constexpr T divideCeil(T size, uint32_t divisor)
{
static_assert(std::is_integral<T>::value, "Integral required.");
return (size + divisor - 1) / divisor;
}
#endif
#define CARB_DIVIDE_CEIL(size, divisor) carb::divideCeil(size, divisor)
#if (CARB_HAS_CPP17 && defined(__cpp_lib_hardware_interference_size)) || defined(DOXYGEN_BUILD)
# define CARB_CACHELINE_SIZE (std::hardware_destructive_interference_size)
#else
# define CARB_CACHELINE_SIZE (64)
#endif
#define CARB_CACHELINE_ALIGN CARB_ALIGN_AS(CARB_CACHELINE_SIZE)
#if CARB_PLATFORM_WINDOWS
# define CARB_ALLOCA(size) _alloca(size)
#elif CARB_PLATFORM_LINUX || CARB_PLATFORM_MACOS
# define CARB_ALLOCA(size) alloca(size)
#else
CARB_UNSUPPORTED_PLATFORM();
#endif
#define CARB_STACK_ALLOC(T, number) \
carb::align<T>(((number) ? (T*)CARB_ALLOCA((number) * sizeof(T) + alignof(T)) : nullptr), alignof(T))
#define CARB_MALLOC(size) std::malloc(size)
#define CARB_FREE(ptr) std::free(ptr)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
# define __CARB_STRINGIFY(x) # x
#endif
#define CARB_STRINGIFY(x) __CARB_STRINGIFY(x)
constexpr uint64_t kFnvBasis = 14695981039346656037ull;
constexpr uint64_t kFnvPrime = 1099511628211ull;
constexpr uint64_t fnv1aHash(const char* str, std::size_t n, uint64_t hash = kFnvBasis)
{
return n > 0 ? fnv1aHash(str + 1, n - 1, (hash ^ *str) * kFnvPrime) : hash;
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <std::size_t N>
constexpr uint64_t fnv1aHash(const char (&array)[N])
{
return fnv1aHash(&array[0], N - 1);
}
#endif
inline uint64_t hashString(const char* str, uint64_t hash = kFnvBasis)
{
while (*str != '\0')
{
hash ^= static_cast<unsigned char>(*(str++));
hash *= kFnvPrime;
}
return hash;
}
constexpr unsigned char tolower(unsigned char c)
{
return detail::lowerTable[c];
};
constexpr unsigned char toupper(unsigned char c)
{
return detail::upperTable[c];
}
inline uint64_t hashLowercaseString(const char* str, uint64_t hash = kFnvBasis)
{
while (*str != '\0')
{
hash ^= tolower(static_cast<unsigned char>(*(str++)));
hash *= kFnvPrime;
}
return hash;
}
inline uint64_t hashLowercaseBuffer(const void* buffer, size_t len, uint64_t hash = kFnvBasis)
{
const unsigned char* data = static_cast<const unsigned char*>(buffer);
const unsigned char* const end = data + len;
while (data != end)
{
hash ^= tolower(*(data++));
hash *= kFnvPrime;
}
return hash;
}
inline uint64_t hashUppercaseString(const char* str, uint64_t hash = kFnvBasis)
{
while (*str != '\0')
{
hash ^= toupper(static_cast<unsigned char>(*(str++)));
hash *= kFnvPrime;
}
return hash;
}
inline uint64_t hashUppercaseBuffer(const void* buffer, size_t len, uint64_t hash = kFnvBasis)
{
const unsigned char* data = static_cast<const unsigned char*>(buffer);
const unsigned char* const end = data + len;
while (data != end)
{
hash ^= toupper(*(data++));
hash *= kFnvPrime;
}
return hash;
}
inline uint64_t hashBuffer(const void* buffer, size_t length, uint64_t hash = kFnvBasis)
{
const char* ptr = static_cast<const char*>(buffer);
for (size_t i = 0; i < length; ++i)
{
hash ^= static_cast<unsigned char>(ptr[i]);
hash *= kFnvPrime;
}
return hash;
}
template <class T>
constexpr uint64_t hashScalar(const T& type, uint64_t hash = kFnvBasis)
{
static_assert(std::is_scalar<T>::value, "Unsupported type for hashing");
return hashBuffer(reinterpret_cast<const char*>(std::addressof(type)), sizeof(type), hash);
}
inline constexpr uint64_t hashCombine(uint64_t hash1, uint64_t hash2) noexcept
{
constexpr uint64_t kConstant{ 14313749767032793493ull };
constexpr int kRotate = 47;
hash2 *= kConstant;
hash2 ^= (hash2 >> kRotate);
hash2 *= kConstant;
hash1 ^= hash2;
hash1 *= kConstant;
// Add an arbitrary value to prevent 0 hashing to 0
hash1 += 0x42524143; // CARB
return hash1;
}
// The string hash macro is guaranteed to evaluate at compile time. MSVC raises a warning for this, which we disable.
#if defined(__CUDACC__) || defined(DOXYGEN_BUILD)
# define CARB_HASH_STRING(str) std::integral_constant<uint64_t, carb::fnv1aHash(str)>::value
#else
# define CARB_HASH_STRING(str) \
CARB_IGNOREWARNING_MSC_WITH_PUSH(4307) /* 'operator': integral constant overflow */ \
std::integral_constant<uint64_t, carb::fnv1aHash(str)>::value CARB_IGNOREWARNING_MSC_POP
#endif
#define CARB_HASH_TYPE(T) CARB_HASH_STRING(CARB_STRINGIFY(T))
// printf-like functions attributes
#if CARB_COMPILER_GNUC || defined(DOXYGEN_BUILD)
# define CARB_PRINTF_FUNCTION(fmt_ordinal, args_ordinal) CARB_ATTRIBUTE(format(printf, fmt_ordinal, args_ordinal))
#elif CARB_COMPILER_MSC
// Microsoft suggest to use SAL annotations _Printf_format_string_ and _Printf_format_string_params_ for
// printf-like functions. Unfortunately it does not work properly for custom printf-like function pointers.
// So, instead of defining marker attribute for format string, we use the "fake printf" trick to force compiler
// checks and keep function attribute empty.
# define CARB_PRINTF_FUNCTION(fmt_ordinal, args_ordinal)
#else
# define CARB_PRINTF_FUNCTION(fmt_ordinal, args_ordinal)
#endif
struct ValueInitFirst
{
constexpr explicit ValueInitFirst() = default;
};
struct InitBoth
{
constexpr explicit InitBoth() = default;
};
template <class First, class Second, bool = std::is_empty<First>::value && !std::is_final<First>::value>
class EmptyMemberPair : private First
{
public:
using FirstType = First;
using SecondType = Second;
template <class... Args2>
constexpr explicit EmptyMemberPair(ValueInitFirst, Args2&&... args)
: First{}, second{ std::forward<Args2>(args)... }
{
}
template <class Arg1, class... Args2>
constexpr explicit EmptyMemberPair(InitBoth, Arg1&& arg1, Args2&&... args2)
: First(std::forward<Arg1>(arg1)), second(std::forward<Args2>(args2)...)
{
}
constexpr FirstType& first() noexcept
{
return *this;
}
constexpr const FirstType& first() const noexcept
{
return *this;
}
SecondType second;
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <class First, class Second>
class EmptyMemberPair<First, Second, false>
{
public:
using FirstType = First;
using SecondType = Second;
template <class... Args2>
constexpr explicit EmptyMemberPair(ValueInitFirst, Args2&&... args)
: m_first(), second(std::forward<Args2>(args)...)
{
}
template <class Arg1, class... Args2>
constexpr explicit EmptyMemberPair(InitBoth, Arg1&& arg1, Args2&&... args2)
: m_first(std::forward<Arg1>(arg1)), second(std::forward<Args2>(args2)...)
{
}
constexpr FirstType& first() noexcept
{
return m_first;
}
constexpr const FirstType& first() const noexcept
{
return m_first;
}
private:
FirstType m_first;
public:
SecondType second;
};
#endif
} // namespace carb
template <class T>
CARB_NODISCARD constexpr const T& carb_min(const T& left, const T& right) noexcept(noexcept(left < right))
{
return left < right ? left : right;
}
template <class T>
CARB_NODISCARD constexpr const T& carb_max(const T& left, const T& right) noexcept(noexcept(left < right))
{
return left < right ? right : left;
}
#if CARB_POSIX || defined(DOXYGEN_BUILD)
# define CARB_RETRY_EINTR(op) \
[&] { \
decltype(op) ret_; \
while ((ret_ = (op)) < 0 && errno == EINTR) \
{ \
} \
return ret_; \
}()
#else
# define CARB_RETRY_EINTR(op) (op)
#endif
template <class... Args>
void CARB_UNUSED(Args&&... CARB_DOC_ONLY(args))
{
}
#define CARB_UNIMPLEMENTED(msg, ...) \
do \
{ \
CARB_FATAL_UNLESS(false, (msg), ##__VA_ARGS__); \
std::terminate(); \
} while (0)
#define CARB_MACOS_UNIMPLEMENTED() CARB_UNIMPLEMENTED("Unimplemented on Mac OS")
#if defined(CARB_INCLUDE_PURIFY_NAME) && !defined(DOXYGEN_BUILD)
# ifdef __COUNTER__
# define CARB_INCLUDE_PURIFY_TEST(...) \
inline void CARB_JOIN(CARB_INCLUDE_PURIFY_NAME, __COUNTER__)() \
__VA_ARGS__ static_assert(true, "Semicolon required")
# else
# define CARB_INCLUDE_PURIFY_TEST(...) \
inline void CARB_JOIN(CARB_INCLUDE_PURIFY_NAME, __LINE__)() \
__VA_ARGS__ static_assert(true, "Semicolon required")
# endif
#else
# define CARB_INCLUDE_PURIFY_TEST(...)
#endif
// Undefine locals
#undef CARBLOCAL_HAS_NODISCARD
#undef CARBLOCAL_HAS_NODISCARD_MSG
#undef CARBLOCAL_HAS_FALLTHROUGH
#undef CARBLOCAL_HAS_MAYBE_UNUSED
#undef CARBLOCAL_HAS_LIKELY
#undef CARBLOCAL_HAS_UNLIKELY
#undef CARBLOCAL_HAS_NO_UNIQUE_ADDRESS