advent-of-code-2024/aoc/common.h

174 lines
3.7 KiB
C

#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#include <stdio.h>
#define ASSERT(cond) if (!(cond)) { fprintf(stderr, "%s:%d (%s): Assertion failed: %s\n", __FILE__, __LINE__, __func__, #cond); __builtin_trap(); }
#define NOT_IMPLEMENTED() ASSERT(0 && "Not implemented")
#define NOT_REACHABLE() ASSERT(0 && "Not reachable")
#define INCOMPLETE(cond) if (!(cond)) { fprintf(stderr, "%s:%d (%s): Incomplete: %s\n", __FILE__, __LINE__, __func__, #cond); __builtin_trap(); }
#define BP() asm("int3;nop;")
#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
#define container_of(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member))
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t i64;
typedef int32_t i32;
typedef int16_t i16;
typedef int8_t i8;
typedef size_t usize;
typedef ptrdiff_t isize;
typedef float f32;
typedef double f64;
#define log(level, fmt, ...) fprintf(stderr, "[" level "] %s:%d (%s): " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#define LOG_LEVEL_TRACE 6
#define LOG_LEVEL_DEBUG 5
#define LOG_LEVEL_VERBOSE 4
#define LOG_LEVEL_INFO 3
#define LOG_LEVEL_WARNING 2
#define LOG_LEVEL_ERROR 1
#define LOG_LEVEL_FATAL 0
#define LOG_LEVEL LOG_LEVEL_DEBUG
#if (LOG_LEVEL >= LOG_LEVEL_TRACE)
#define logt(fmt, ...) log("TRACE", fmt, ##__VA_ARGS__)
#else
#define logt(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
#define logd(fmt, ...) log("\033[1;34mDEBUG\033[0m", fmt, ##__VA_ARGS__)
#else
#define logd(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_VERBOSE)
#define logv(fmt, ...) log("\033[1;32mVERBOSE\033[0m", fmt, ##__VA_ARGS__)
#else
#define logv(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_INFO)
#define logi(fmt, ...) log("\033[1;32mINFO\033[0m", fmt, ##__VA_ARGS__)
#else
#define logi(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_WARNING)
#define logw(fmt, ...) log("\033[1;33mWARNING\033[0m", fmt, ##__VA_ARGS__)
#else
#define logw(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_ERROR)
#define loge(fmt, ...) log("\033[1;31mERROR\033[0m", fmt, ##__VA_ARGS__)
#else
#define loge(fmt, ...)
#endif
#if (LOG_LEVEL >= LOG_LEVEL_FATAL)
#define logf(fmt, ...) do { log("\033[1;31mFATAL\033[0m", fmt, ##__VA_ARGS__); __builtin_trap(); } while (0)
#else
#define logf(fmt, ...)
#endif
#define Kilobytes(x) ((u64) (x) << 10)
#define Megabytes(x) ((u64) (x) << 20)
#define Gigabytes(x) ((u64) (x) << 30)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
typedef union Vec2 {
struct { f32 x, y; };
struct { f32 u, v; };
} Vec2;
typedef union Vec2i {
struct { i32 x, y; };
struct { i32 u, v; };
} Vec2i ;
typedef struct Mat4 {
float e[4][4];
} Mat4;
static inline Vec2
vec2_add(Vec2 a, Vec2 b) {
Vec2 result = {
.x = a.x + b.x,
.y = a.y + b.y,
};
return result;
}
static inline Vec2
vec2_sub(Vec2 a, Vec2 b) {
Vec2 result = {
.x = a.x - b.x,
.y = a.y - b.y,
};
return result;
}
static inline Vec2
vec2(f32 x, f32 y) {
Vec2 result = { x, y };
return result;
}
static inline f32
vec2_dot(Vec2 a, Vec2 b) {
return a.x * b.x + a.y * b.y;
}
static inline f32
vec2_norm2(Vec2 v) {
return vec2_dot(v, v);
}
static inline f32
vec2_norm(Vec2 v) {
return sqrtf(vec2_norm2(v));
}
static inline f32
vec2_dist(Vec2 a, Vec2 b) {
return vec2_norm(vec2_sub(a, b));
}
typedef struct Rect2i {
int x, y, w, h;
} Rect2i;
typedef struct Rect2f {
f32 x, y, w, h;
} Rect2f;
static inline Rect2f
rect2f(f32 x, f32 y, f32 w, f32 h) {
Rect2f result = { x, y, w, h };
return result;
}