/* * libnogg: a decoder library for Ogg Vorbis streams * Copyright (c) 2014-2026 Andrew Church * * This software may be copied and redistributed under certain conditions; * see the file "COPYING" in the source code distribution for details. * NO WARRANTY is provided with this software. */ /* Note that this header is shared with tool sources and should not * include any library-specific declarations. */ #ifndef NOGG_SRC_BASE_H #define NOGG_SRC_BASE_H /*************************************************************************/ /***************************** Helper macros *****************************/ /*************************************************************************/ /* * Convenience macros for testing compiler versions. major and minor must * be literal integers. The #ifdef mess is required because C99 doesn't * allow defined() to be generated by a macro (6.10.1.2). * * Note that these macros will evaluate to true for any compiler which * claims via the relevant preprocessor symbols to be compatible with the * named compiler. This is particularly common with GCC; for example, most * versions of Clang also satisfy IS_GCC(4,2). */ #ifdef __clang__ #define IS_CLANG(major,minor) \ (__clang_major__ > major \ || (__clang_major__ == major && __clang_minor__ >= minor)) #else #define IS_CLANG(major,minor) 0 #endif #ifdef __GNUC__ #define IS_GCC(major,minor) \ (__GNUC__ > major || (__GNUC__ == major && __GNUC_MINOR__ >= minor)) #else #define IS_GCC(major,minor) 0 #endif /*-----------------------------------------------------------------------*/ /* Suppress version-dependent spurious diagnostics. */ #if IS_GCC(15,0) || IS_CLANG(21,0) # pragma GCC diagnostic ignored "-Wunterminated-string-initialization" #endif /*-----------------------------------------------------------------------*/ /** * ALIGN: Attribute indicating that the object to which it is attached * should be aligned to a multiple of the given number of bytes, which * must be a power of two. */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L # define ALIGN(alignment) _Alignas(alignment) #elif IS_GCC(2,95) || IS_CLANG(1,0) # define ALIGN(alignment) __attribute__((aligned(alignment))) #else # define ALIGN(alignment) /*nothing*/ #endif /** * ASSERT: Verify that the given condition is true, and abort the program * if it is not. If ENABLE_ASSERT is not defined, the expression is * evaluated and its result is discarded; if supported by the compiler, a * hint is provided that the expression is always true. */ #ifdef ENABLE_ASSERT # include # define ASSERT assert #else # define ASSERT(expr) do {if (UNLIKELY(!(expr))) {UNREACHABLE;}} while (0) #endif /** * COLD_FUNCTION: Function attribute indicating that the given function * is not expected to be called often. */ #if IS_GCC(4,3) || IS_CLANG(3,2) # define COLD_FUNCTION __attribute__((cold)) #else # define COLD_FUNCTION /*nothing*/ #endif /** * CONST_FUNCTION: Function attribute indicating that the function's * behavior depends only on its arguments and the function has no side * effects. */ #if IS_GCC(2,95) || IS_CLANG(1,0) # define CONST_FUNCTION __attribute__((const)) #else # define CONST_FUNCTION /*nothing*/ #endif /** * PURE_FUNCTION: Function attribute indicating that the function's * behavior depends only on its arguments and global state, and the * function has no side effects. */ #if IS_GCC(3,0) || IS_CLANG(1,0) # define PURE_FUNCTION __attribute__((pure)) #else # define PURE_FUNCTION /*nothing*/ #endif /** * LIKELY, UNLIKELY: Construct which indicates to the compiler that the * given expression is likely or unlikely to evaluate to true. */ #if IS_GCC(3,0) || IS_CLANG(1,0) # define LIKELY(expr) (__builtin_expect(!!(expr), 1)) # define UNLIKELY(expr) (__builtin_expect(!!(expr), 0)) #else # define LIKELY(expr) (expr) # define UNLIKELY(expr) (expr) #endif /** * NOINLINE: Function attribute indicating that the function should not * be inlined. */ #if IS_GCC(3,1) || IS_CLANG(1,0) # define NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) # define NOINLINE __declspec(noinline) #else # define NOINLINE /*nothing*/ #endif /** * UNREACHABLE: Compiler intrinsic indicating that the current code * location can never be reached. */ #if IS_GCC(4,5) || IS_CLANG(2,7) # define UNREACHABLE __builtin_unreachable() #else # define UNREACHABLE /*nothing*/ #endif /** * UNUSED: Attribute indicating that a definition is intentionally unused. */ #if IS_GCC(2,95) || IS_CLANG(1,0) # define UNUSED __attribute__((unused)) #else # define UNUSED /*nothing*/ #endif /** * min, max: Return the minimum or maximum of two values. The returned * value will be evaluated twice. */ #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) /** * lenof: Return the length of (number of elements in) the given array. */ #define lenof(array) ((int)(sizeof((array)) / sizeof(*(array)))) /*************************************************************************/ /*************************************************************************/ #endif // NOGG_SRC_BASE_H