132 lines
3.3 KiB
C
132 lines
3.3 KiB
C
#pragma once
|
|
|
|
#define STRINGIFY(str) #str
|
|
#define PASTE(a, b) a##b
|
|
#define XPASTE(a, b) PASTE(a, b)
|
|
#define STRLEN(str) (sizeof("" str "") - 1)
|
|
#define DO_PRAGMA(x) _Pragma(#x)
|
|
#define COUNT_OF(x) ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x])))))
|
|
|
|
#ifdef __has_attribute
|
|
#define HAS_ATTRIBUTE(x) __has_attribute(x)
|
|
#else
|
|
#define HAS_ATTRIBUTE(x) 0
|
|
#endif
|
|
|
|
#ifdef __has_builtin
|
|
#define HAS_BUILTIN(x) __has_builtin(x)
|
|
#else
|
|
#define HAS_BUILTIN(x) 0
|
|
#endif
|
|
|
|
#ifdef __has_include
|
|
#define HAS_INCLUDE(x) __has_include(x)
|
|
#else
|
|
#define HAS_INCLUDE(x) 0
|
|
#endif
|
|
|
|
#ifdef __has_feature
|
|
#define HAS_FEATURE(x) __has_feature(x)
|
|
#else
|
|
#define HAS_FEATURE(x) 0
|
|
#endif
|
|
|
|
// __has_extension() is a Clang macro used to determine if a feature is
|
|
// available even if not standardized in the current "-std" mode.
|
|
#ifdef __has_extension
|
|
#define HAS_EXTENSION(x) __has_extension(x)
|
|
#else
|
|
// Clang versions prior to 3.0 only supported __has_feature()
|
|
#define HAS_EXTENSION(x) HAS_FEATURE(x)
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(cold)
|
|
#define _COLD __attribute__((__cold__))
|
|
#else
|
|
#define _COLD
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(hot)
|
|
#define _HOT __attribute__((hot))
|
|
#else
|
|
#define _HOT
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(unused)
|
|
#define _UNUSED __attribute__((__unused__))
|
|
#else
|
|
#define _UNUSED
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(pure)
|
|
#define _PURE __attribute__((__pure__))
|
|
#else
|
|
#define _PURE
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(const)
|
|
#define _CONST __attribute__((__const__))
|
|
#else
|
|
#define _CONST
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(malloc)
|
|
#define _MALLOC __attribute__((__malloc__))
|
|
#else
|
|
#define _MALLOC
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(constructor)
|
|
#define _CONSTRUCTOR __attribute__((__constructor__))
|
|
#define HAVE_ATTR_CONSTRUCTOR 1
|
|
#else
|
|
#define _CONST_CONSTRUCTOR
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(destructor)
|
|
#define _DESTRUCTOR __attribute__((__destructor__))
|
|
#else
|
|
#define _DEST_DESTRUCTOR
|
|
#endif
|
|
|
|
#if HAS_ATTRIBUTE(format)
|
|
#define PRINTF(x) __attribute__((__format__(__printf__, (x), (x + 1))))
|
|
#define VPRINTF(x) __attribute__((__format__(__printf__, (x), 0)))
|
|
#else
|
|
#define PRINTF(x)
|
|
#define VPRINTF(x)
|
|
#endif
|
|
|
|
#if HAS_BUILTIN(__builtin_expect)
|
|
#define likely(x) __builtin_expect(!!(x), 1)
|
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
#else
|
|
#define likely(x) (x)
|
|
#define unlikely(x) (x)
|
|
#endif
|
|
|
|
#if defined(__clang__)
|
|
#define UNROLL(n) DO_PRAGMA(clang loop unroll_count(n))
|
|
#elif defined(__GNUC__)
|
|
#define UNROLL(n) DO_PRAGMA(GCC unroll(n))
|
|
#else
|
|
#define UNROLL(n)
|
|
#endif
|
|
|
|
#ifdef __clang__
|
|
#define PUSH_IGNORE(flag) \
|
|
DO_PRAGMA(clang diagnostic push) \
|
|
DO_PRAGMA(clang diagnostic ignored "-Wunknown-pragmas") \
|
|
DO_PRAGMA(clang diagnostic ignored "-Wunknown-warning-option") \
|
|
DO_PRAGMA(clang diagnostic ignored flag)
|
|
#define POP_IGNORE DO_PRAGMA(clang diagnostic pop)
|
|
#elifdef __GNUC__
|
|
#define PUSH_IGNORE(flag) \
|
|
DO_PRAGMA(GCC diagnostic push) \
|
|
DO_PRAGMA(GCC diagnostic ignored "-Wpragmas") \
|
|
DO_PRAGMA(GCC diagnostic ignored flag)
|
|
#define POP_IGNORE DO_PRAGMA(GCC diagnostic pop)
|
|
#else
|
|
#define PUSH_IGNORE(flag)
|
|
#define POP_IGNORE
|
|
#endif
|