@ -71,22 +71,7 @@ _mixin void _drain_val(void* x, ...) { IGNORE(x); }
// Function macros
# define TRACEx(X, msg, ...) (fprintf(stderr, "[" X "] " __FILE__ ":%d->%s(): " msg "\n", __LINE__, __func__, ## __VA_ARGS__))
# ifdef DEBUG
# define TRACE(msg, ...) TRACEx("trace", msg, ## __VA_ARGS__)
# elif defined(_EVAL_DEBUG_ONLY_STMTS)
# define TRACE(msg, ...) _drain(msg, ## __VA_ARGS__)
# else
# define TRACE(msg, ...) _no_op
# endif
# define INFO(msg, ...) TRACEx("info", msg, ## __VA_ARGS__)
# define WARN(msg, ...) TRACEx("warning", msg, ## __VA_ARGS__)
# define ERROR(msg, ...) TRACEx("error", msg, ## __VA_ARGS__)
# define FATAL(msg, ...) (TRACEx("FATAL", msg, ## __VA_ARGS__), abort())
// Assertion macros
// Assertions
# ifdef DEBUG
# define debug_assert(x) assert((x))
@ -108,9 +93,52 @@ _mixin void _drain_val(void* x, ...) { IGNORE(x); }
# define debug_static_assert(x, msg) _Static_assert(1, msg)
# endif
# define static_assert_eq(x,y,msg) _Static_assert((x) == (y), msg)
# define static_assert_ne(x,y,msg) _Static_assert((x) != (y), msg)
// Bitmasking
# define _BSWAP(x) __builtin_bswa x
# define BSWAP_16(x) _BSWAP(p16) (AS((x), uint16_t))
# define BSWAP_32(x) _BSWAP(p32) (AS((x), uint32_t))
# define BSWAP_64(x) _BSWAP(p64) (AS((x), uint64_t))
# define BSWAP_128(x) _BSWAP(p128)(AS((x), uint128_t))
# undef _BSWAP
# define _BSWAP(n) __builtin_bswap ## n
# define bswap(x) _Generic((x), \
uint64_t : _BSWAP ( 64 ) , int64_t : _BSWAP ( 64 ) , \
uint32_t : _BSWAP ( 32 ) , int32_t : _BSWAP ( 32 ) , \
uint16_t : _BSWAP ( 16 ) , int16_t : _BSWAP ( 16 ) , \
__uint128_t : _BSWAP ( 128 ) , __int128_t : _BSWAP ( 128 ) ) \
( ( x ) )
static_assert_eq ( bswap ( 128lu ) , 9223372036854775808lu , " bswap128 (lu) failed (1) " ) ;
static_assert_eq ( 128lu , bswap ( 9223372036854775808lu ) , " bswap128 (lu) failed (2) " ) ;
static_assert_eq ( bswap ( bswap ( 128lu ) ) , 128 , " bswap128 (lu) failed (3) " ) ;
// Trace message output
# define TRACEx(X, msg, ...) (fprintf(stderr, "[" X "] " __FILE__ ":%d->%s(): " msg "\n", __LINE__, __func__, ## __VA_ARGS__))
# ifdef DEBUG
# define TRACE(msg, ...) TRACEx("trace", msg, ## __VA_ARGS__)
# elif defined(_EVAL_DEBUG_ONLY_STMTS)
# define TRACE(msg, ...) _drain(msg, ## __VA_ARGS__)
# else
# define TRACE(msg, ...) _no_op
# endif
# define INFO(msg, ...) TRACEx("info", msg, ## __VA_ARGS__)
# define WARN(msg, ...) TRACEx("warning", msg, ## __VA_ARGS__)
# define ERROR(msg, ...) TRACEx("error", msg, ## __VA_ARGS__)
# define FATAL(msg, ...) (TRACEx("FATAL", msg, ## __VA_ARGS__), abort())
// Version macros
# define _UI(x) ((uint32_t)(x))
# define _ AS_u32 (x) ((uint32_t)(x))
# define VER_COMP_MAJ 24u
# define VER_COMP_MIN 16u
@ -118,19 +146,18 @@ _mixin void _drain_val(void* x, ...) { IGNORE(x); }
# define VER_COMP_REV 0u
/// Create a `uint32_t` from these version componants
# define VERSION(maj,min,bf,rev) _ UI( _UI(maj) << 24u | _UI(min) << 16u | _UI(bf) << 8u | _UI (rev) )
# define VERSION(maj,min,bf,rev) _ AS_u32( _AS_u32(maj) << 24u | _AS_u32(min) << 16u | _AS_u32(bf) << 8u | _AS_u32 (rev) )
/// Mask `ver` to retain only the version component specified by `mask`
///
/// # Example
/// `_Static_assert( (VERSION_COMP(VERSION(1,2,3,4), VER_COMP_MIN) >> VER_COMP_MIN) == 2u)`
# define VERSION_COMP(ver, mask) _ UI( _UI(ver) & (0xffu << _UI(mask)) /*>> _UI (mask)*/ )
# define VERSION_COMP(ver, mask) _ AS_u32( _AS_u32(ver) & (0xffu << _AS_u32(mask)) /*>> _AS_u32 (mask)*/ )
# define VERSION_MAJ(ver) _ UI (VERSION_COMP((ver), 24u) >> 24u)
# define VERSINO_MIN(ver) _ UI (VERSION_COMP((ver), 16u) >> 16u)
# define VERSINO_BF(ver) _ UI (VERSION_COMP((ver), 8u) >> 8u)
# define VERSINO_REV(ver) _ UI(_UI (ver) & 0xffu)
# define VERSION_MAJ(ver) _ AS_u32 (VERSION_COMP((ver), 24u) >> 24u)
# define VERSINO_MIN(ver) _ AS_u32 (VERSION_COMP((ver), 16u) >> 16u)
# define VERSINO_BF(ver) _ AS_u32 (VERSION_COMP((ver), 8u) >> 8u)
# define VERSINO_REV(ver) _ AS_u32(_AS_u32 (ver) & 0xffu)
_Static_assert ( ( VERSION_COMP ( VERSION ( 1 , 2 , 3 , 4 ) , VER_COMP_MIN ) > > VER_COMP_MIN ) = = 2u , " invalid native version spec " ) ;
# undef _UI
# endif /* _MACROS_H */