|
solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
|
Portable utility macros for assertions, memory, math, iteration, timing, and platform compatibility. More...
#include <stddef.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>Go to the source code of this file.
Macros | |
| #define | LIKELY(x) (x) |
| #define | WARN_UNUSED_RESULT |
| #define | PRINTF_FORMAT(fmt, va) |
| #define | NORETURN |
| #define | UNUSED(x) ((void)(x)) |
| #define | STATIC_ASSERT(cond, msg) typedef char _static_assert_##__LINE__[(cond) ? 1 : -1] |
| #define | ASSERT(cond) |
| #define | ASSERT_TRUE(cond) ASSERT(cond) |
| #define | ASSERT_NULL(ptr) |
| #define | ASSERT_NOT_NULL(ptr) |
| #define | ASSERT_STR_EQ(a, b) |
| #define | ASSERT_FLOAT_EQ(a, b, epsilon) |
| #define | IS_POWER_OF_2(n) ((n) > 0 && (((n) & ((n) - 1)) == 0)) |
| #define | STATIC_CHECK_POWER_OF_2(n) STATIC_ASSERT(IS_POWER_OF_2(n), #n " must be a power of 2") |
| #define | ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
| #define | ZERO_MEMORY(ptr, size) memset((ptr), 0, (size)) |
| #define | ZERO_STRUCT(s) memset(&(s), 0, sizeof(s)) |
| #define | ZERO_ARRAY(arr) memset((arr), 0, sizeof(arr)) |
| #define | MIN(a, b) ((a) < (b) ? (a) : (b)) |
| #define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
| #define | ABS(x) ((x) < 0 ? -(x) : (x)) |
| #define | CLAMP(x, lo, hi) (MIN(MAX((x), (lo)), (hi))) |
| #define | SET_BIT(v, pos) ((v) |= (1ULL << (pos))) |
| #define | CLEAR_BIT(v, pos) ((v) &= ~(1ULL << (pos))) |
| #define | TOGGLE_BIT(v, pos) ((v) ^= (1ULL << (pos))) |
| #define | CHECK_BIT(v, pos) (((v) >> (pos)) & 1U) |
| #define | ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1)) |
| #define | ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) |
| #define | IS_ALIGNED(x, align) (((x) & ((align) - 1)) == 0) |
| #define | STREQ(a, b) (strcmp((a), (b)) == 0) |
| #define | STRNEQ(a, b, n) (strncmp((a), (b), (n)) == 0) |
| #define | STR_EMPTY(s) ((s) == NULL || (s)[0] == '\0') |
| #define | STR_NOT_EMPTY(s) ((s) != NULL && (s)[0] != '\0') |
| #define | DEBUG_PRINT(fmt, ...) printf("[DEBUG] %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) |
| #define | DEBUG_VAR(var) printf("[DEBUG] %s:%d: %s = %td\n", __FILE__, __LINE__, #var, (ptrdiff_t)(var)) |
| #define | DEBUG_STR(str) printf("[DEBUG] %s:%d: %s = \"%s\"\n", __FILE__, __LINE__, #str, (str) ? (str) : "(null)") |
| #define | LOG_ERROR(fmt, ...) fprintf(stderr, "[ERROR] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
| #define | LOG_WARN(fmt, ...) fprintf(stderr, "[WARN] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
| #define | LOG_INFO(fmt, ...) printf("[INFO] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
| #define | FOR_EACH_ARRAY(item, array) |
| #define | TIME_DIFF(start, end) ((double)((end).tv_sec - (start).tv_sec) + (double)((end).tv_nsec - (start).tv_nsec) / 1.0e9) |
| #define | TIME_DIFF_MS(start, end) ((double)((end).tv_sec - (start).tv_sec) * 1000.0 + (double)((end).tv_nsec - (start).tv_nsec) / 1.0e6) |
Portable utility macros for assertions, memory, math, iteration, timing, and platform compatibility.
Supports: GCC, Clang, MSVC (C11 / C17). All macros are safe for use in C and C++ translation units.
Portability notes:
Definition in file macros.h.
| #define ABS | ( | x | ) | ((x) < 0 ? -(x) : (x)) |
| #define ALIGN_DOWN | ( | x, | |
| align | |||
| ) | ((x) & ~((align) - 1)) |
ALIGN_DOWN(x, align) — round x down to the previous multiple of align.
| #define ALIGN_UP | ( | x, | |
| align | |||
| ) | (((x) + (align) - 1) & ~((align) - 1)) |
ALIGN_UP(x, align) — round x up to the next multiple of align.
| #define ARRAY_SIZE | ( | arr | ) | (sizeof(arr) / sizeof((arr)[0])) |
ARRAY_SIZE(arr) — number of elements in a stack-allocated array.
| #define ASSERT | ( | cond | ) |
ASSERT(cond) — abort if cond is false.
| #define ASSERT_FLOAT_EQ | ( | a, | |
| b, | |||
| epsilon | |||
| ) |
ASSERT_FLOAT_EQ(a, b, epsilon) — abort if |a - b| > epsilon. Both operands are promoted to double for the comparison.
| #define ASSERT_NOT_NULL | ( | ptr | ) |
ASSERT_NOT_NULL(ptr) — abort if ptr is NULL.
| #define ASSERT_NULL | ( | ptr | ) |
ASSERT_NULL(ptr) — abort if ptr is not NULL.
| #define ASSERT_STR_EQ | ( | a, | |
| b | |||
| ) |
ASSERT_STR_EQ(a, b) — abort if two C strings are not equal. Handles NULL on either side gracefully.
| #define ASSERT_TRUE | ( | cond | ) | ASSERT(cond) |
ASSERT_TRUE(cond) — alias for ASSERT; documents boolean intent.
| #define CHECK_BIT | ( | v, | |
| pos | |||
| ) | (((v) >> (pos)) & 1U) |
CHECK_BIT(v, pos) — evaluate to 1 if bit pos is set in v, else 0.
CLAMP(x, lo, hi) — constrain x to [lo, hi].
| #define CLEAR_BIT | ( | v, | |
| pos | |||
| ) | ((v) &= ~(1ULL << (pos))) |
CLEAR_BIT(v, pos) — clear bit at position pos in v.
| #define DEBUG_PRINT | ( | fmt, | |
| ... | |||
| ) | printf("[DEBUG] %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) |
DEBUG_PRINT(fmt, ...) — print a formatted debug message with source location.
| #define DEBUG_STR | ( | str | ) | printf("[DEBUG] %s:%d: %s = \"%s\"\n", __FILE__, __LINE__, #str, (str) ? (str) : "(null)") |
DEBUG_STR(str) — print a string variable's name and value, handling NULL.
| #define DEBUG_VAR | ( | var | ) | printf("[DEBUG] %s:%d: %s = %td\n", __FILE__, __LINE__, #var, (ptrdiff_t)(var)) |
DEBUG_VAR(var) — print a scalar variable's name and value as a signed integer.
| #define FOR_EACH_ARRAY | ( | item, | |
| array | |||
| ) |
FOR_EACH_ARRAY — MSVC fallback using size_t index. item is a void* pointing to the current element; cast before use.
Example: FOR_EACH_ARRAY(i, arr, sizeof(arr[0])) { int n = (int)item; }
Prefer the three-argument variant when element size is not obvious.
| #define IS_ALIGNED | ( | x, | |
| align | |||
| ) | (((x) & ((align) - 1)) == 0) |
IS_ALIGNED(x, align) — evaluate to 1 if x is a multiple of align.
| #define IS_POWER_OF_2 | ( | n | ) | ((n) > 0 && (((n) & ((n) - 1)) == 0)) |
IS_POWER_OF_2(n) — evaluates to 1 if n is a power of two, 0 otherwise.
| #define LIKELY | ( | x | ) | (x) |
| #define LOG_ERROR | ( | fmt, | |
| ... | |||
| ) | fprintf(stderr, "[ERROR] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
LOG_ERROR(fmt, ...) — print an error message to stderr (always active).
| #define LOG_INFO | ( | fmt, | |
| ... | |||
| ) | printf("[INFO] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
LOG_INFO(fmt, ...) — print an informational message to stdout (always active).
| #define LOG_WARN | ( | fmt, | |
| ... | |||
| ) | fprintf(stderr, "[WARN] %s:%d [%s]: " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
LOG_WARN(fmt, ...) — print a warning to stderr (always active).
| #define MAX | ( | a, | |
| b | |||
| ) | ((a) > (b) ? (a) : (b)) |
| #define MIN | ( | a, | |
| b | |||
| ) | ((a) < (b) ? (a) : (b)) |
| #define NORETURN |
| #define PRINTF_FORMAT | ( | fmt, | |
| va | |||
| ) |
PRINTF_FORMAT(fmt_idx, va_idx) — validate printf-style format strings at compile time (1-based argument indices). Example: void log(const char *fmt, ...) PRINTF_FORMAT(1, 2);
| #define SET_BIT | ( | v, | |
| pos | |||
| ) | ((v) |= (1ULL << (pos))) |
SET_BIT(v, pos) — set bit at position pos in v (0 = LSB).
| #define STATIC_ASSERT | ( | cond, | |
| msg | |||
| ) | typedef char _static_assert_##__LINE__[(cond) ? 1 : -1] |
STATIC_ASSERT(cond, msg) — compile-time assertion with a descriptive message.
| #define STATIC_CHECK_POWER_OF_2 | ( | n | ) | STATIC_ASSERT(IS_POWER_OF_2(n), #n " must be a power of 2") |
STATIC_CHECK_POWER_OF_2(n) — compile-time assertion that n is a power of two.
| #define STR_EMPTY | ( | s | ) | ((s) == NULL || (s)[0] == '\0') |
STR_EMPTY(s) — true if s is NULL or the empty string.
| #define STR_NOT_EMPTY | ( | s | ) | ((s) != NULL && (s)[0] != '\0') |
STR_NOT_EMPTY(s) — true if s is non-NULL and non-empty.
| #define STREQ | ( | a, | |
| b | |||
| ) | (strcmp((a), (b)) == 0) |
STREQ(a, b) — true if two C strings are equal.
| #define STRNEQ | ( | a, | |
| b, | |||
| n | |||
| ) | (strncmp((a), (b), (n)) == 0) |
STRNEQ(a, b, n) — true if first n bytes of two C strings are equal.
| #define TIME_DIFF | ( | start, | |
| end | |||
| ) | ((double)((end).tv_sec - (start).tv_sec) + (double)((end).tv_nsec - (start).tv_nsec) / 1.0e9) |
TIME_DIFF(start, end) — elapsed seconds between two struct timespec values.
| #define TIME_DIFF_MS | ( | start, | |
| end | |||
| ) | ((double)((end).tv_sec - (start).tv_sec) * 1000.0 + (double)((end).tv_nsec - (start).tv_nsec) / 1.0e6) |
TIME_DIFF_MS(start, end) — elapsed milliseconds between two struct timespec values.
| #define TOGGLE_BIT | ( | v, | |
| pos | |||
| ) | ((v) ^= (1ULL << (pos))) |
TOGGLE_BIT(v, pos) — flip bit at position pos in v.
| #define UNUSED | ( | x | ) | ((void)(x)) |
| #define WARN_UNUSED_RESULT |
| #define ZERO_ARRAY | ( | arr | ) | memset((arr), 0, sizeof(arr)) |
ZERO_ARRAY(arr) — zero an entire stack-allocated array.
| #define ZERO_MEMORY | ( | ptr, | |
| size | |||
| ) | memset((ptr), 0, (size)) |
ZERO_MEMORY(ptr, size) — zero size bytes starting at ptr.
| #define ZERO_STRUCT | ( | s | ) | memset(&(s), 0, sizeof(s)) |
ZERO_STRUCT(s) — zero every byte of a struct variable s.