Skip to content

Instantly share code, notes, and snippets.

@g-berthiaume
Last active August 19, 2024 15:02
Show Gist options
  • Save g-berthiaume/84160d113e5639e480eae9a0ef3af1ba to your computer and use it in GitHub Desktop.
Save g-berthiaume/84160d113e5639e480eae9a0ef3af1ba to your computer and use it in GitHub Desktop.
godbolt
// Did you know that [Compiler Explorer](godbolt.org) allows you to include any file
// from the internet ?
//
// Just add the following line to your C source:
//
// #include
// <https://gist.githubusercontent.com/g-berthiaume/84160d113e5639e480eae9a0ef3af1ba/raw/1fde54c83ec3ff74dad536e0bb36d14d4db4e36b/godbolt_utils.h>
//
// This file's purpose is to create a collection of utilities for increasing my productivity on
// godbolt. This file is unlicensed. Do what you want with it. :^)
// g-berthiaume - 2024
#include <assert.h>
#include <stdbool.h>
#include <stddef.h> //< offsetof, ptrdiff_t and size_t
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
// types
//
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef ptrdiff_t isize;
#define U8_MAX UINT8_MAX
#define U16_MAX UINT16_MAX
#define U32_MAX UINT32_MAX
#define U64_MAX UINT64_MAX
#define U8_MIN (0)
#define U16_MIN (0)
#define U32_MIN (0)
#define U64_MIN (0)
#define I8_MAX INT8_MAX
#define I16_MAX INT16_MAX
#define I32_MAX INT32_MAX
#define I64_MAX INT64_MAX
#define I8_MIN INT8_MIN
#define I16_MIN INT16_MIN
#define I32_MIN INT32_MIN
#define I64_MIN INT64_MIN
#define ISIZE_MIN PTRDIFF_MIN
#define ISIZE_MAX PTRDIFF_MAX
//
// utils
//
#define ABS(a) (((a) < 0) ? -(a) : (a))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN3(a, b, c) (MIN(MIN(a, b), c))
#define MAX3(a, b, c) (MAX(MAX(a, b), c))
#define MIN4(a, b, c, d) (MIN(MIN(MIN(a, b), c), d))
#define MAX4(a, b, c, d) (MAX(MAX(MAX(a, b), c), d))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define CLAMP_TOP(x, top) MIN((x), (top))
#define CLAMP_BOTTOM(x, bottom) MAX((x), (bottom))
#define IS_BETWEEN(_number_, _min_, _max_) (((_number_) > (_min_)) && ((_number_) < (_max_)))
#define IS_WITHIN(_number_, _min_, _max_) (((_number_) >= (_min_)) && ((_number_) <= (_max_)))
#define COUNT_OF(...) (ptrdiff_t)(sizeof(__VA_ARGS__) / sizeof(*__VA_ARGS__))
#define SIZE_OF(type) ((ptrdiff_t)sizeof(type))
#define LENGTH_OF(type) (COUNT_OF(type) - 1)
#define ROUND_UP(x, align) ((((uint64_t)(x) + ((uint64_t)(align) - 1)) / (uint64_t)(align)) * (uint64_t)(align))
#define ROUND_DOWN(x, align) (((uint64_t)(x) / (uint64_t)(align)) * (uint64_t)(align))
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define DIV_ROUND_DOWN(n, d) ((n) / (d)) //< This API is provided for symetry :^)
#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : ((n) + ((d) / 2)) / (d))
#define printfln(fmt, ...) printf(fmt "\r\n", __VA_ARGS__)
// ASSERT
#define COMPTIME_ASSERT(test_for_true) \
_Static_assert((test_for_true), "(" #test_for_true ") failed")
#define COMPTIME_ASSERT_MSG(test_for_true, message) /* */ \
_Static_assert((test_for_true), (message))
//
// slices
//
#define SLICE_TYPE(data_type_) \
struct \
{ \
data_type_ *data; \
ptrdiff_t len; \
}
// clang-format off
#define SLICE_IS_VALID(slice) ((slice).data != NULL)
#define SLICE_IS_NON_EMPTY(slice) (SLICE_IS_VALID(slice) ? ((slice).len > 0) : 0)
#define SLICE(...) IMPL_SLICE(__VA_ARGS__)
#define SLICE_P(...) IMPL_SLICE_P(__VA_ARGS__)
#include <stdint.h>
typedef SLICE_TYPE(int8_t) SliceI8_t;
typedef SLICE_TYPE(uint8_t) SliceU8_t;
typedef SLICE_TYPE(int16_t) SliceI16_t;
typedef SLICE_TYPE(uint16_t) SliceU16_t;
typedef SLICE_TYPE(int32_t) SliceI32_t;
typedef SLICE_TYPE(uint32_t) SliceU32_t;
typedef SLICE_TYPE(int64_t) SliceI64_t;
typedef SLICE_TYPE(uint64_t) SliceU64_t;
typedef SLICE_TYPE(float) SliceFloat_t;
typedef SLICE_TYPE(double) SliceDouble_t;
typedef SLICE_TYPE(size_t) SliceUSize_t;
typedef SLICE_TYPE(ptrdiff_t) SliceISize_t;
typedef SLICE_TYPE(uintptr_t) SliceUIntptr_t;
typedef SLICE_TYPE(intptr_t) SliceIntptr_t;
typedef SLICE_TYPE(char) SliceChar_t;
typedef SLICE_TYPE(signed char) SliceIChar_t;
typedef SLICE_TYPE(unsigned char) SliceUChar_t;
typedef SLICE_TYPE(short) SliceShort_t;
typedef SLICE_TYPE(unsigned short) SliceUShort_t;
typedef SLICE_TYPE(int) SliceInt_t;
typedef SLICE_TYPE(unsigned int) SliceUInt_t;
typedef SLICE_TYPE(long) SliceLong_t;
typedef SLICE_TYPE(unsigned long) SliceULong_t;
typedef SLICE_TYPE(long long) SliceLongLong_t;
typedef SLICE_TYPE(unsigned long long) SliceULongLong_t;
#define IMPL_SLICE(...) IMPL_SLICE_DISPATCH(__VA_ARGS__, IMPL_SLICE_3_ARG, IMPL_SLICE_2_ARG, IMPL_SLICE_1_ARG)(__VA_ARGS__)
#define IMPL_SLICE_DISPATCH(_1_ARG, _2_ARG, _3_ARG, NAME, ...) NAME
#define IMPL_SLICE_1_ARG(arr_) IMPL_SLICE_P_2_ARG((arr_), IMPL_SLICE_COUNT_OF(arr_))
#define IMPL_SLICE_2_ARG(arr_, stop_) IMPL_SLICE_P_3_ARG((arr_), IMPL_SLICE_COUNT_OF(arr_), (stop_))
#define IMPL_SLICE_3_ARG(arr_, start_, stop_) IMPL_SLICE_P_4_ARG((arr_), IMPL_SLICE_COUNT_OF(arr_), (start_), (stop_))
#define IMPL_SLICE_P(...) IMPL_SLICE_P_DISPATCH(__VA_ARGS__, IMPL_SLICE_P_4_ARG, IMPL_SLICE_P_3_ARG, IMPL_SLICE_P_2_ARG, SLICE_P_CANT_HAVE_1_ARG)(__VA_ARGS__)
#define IMPL_SLICE_P_DISPATCH(_1_ARG, _2_ARG, _3_ARG, _4_ARG, NAME, ...) NAME
#define IMPL_SLICE_P_2_ARG(arr_, len_) IMPL_SLICE_SAFE((arr_), (len_), (0), (len_)) //< Slice is [0:len_]
#define IMPL_SLICE_P_3_ARG(arr_, len_, stop_) IMPL_SLICE_SAFE((arr_), (len_), (0), (stop_)) //< Slice is [0:stop_]
#define IMPL_SLICE_P_4_ARG(arr_, len_, start_, stop_) IMPL_SLICE_SAFE((arr_), (len_), (start_), (stop_)) //< Slice is [start_:stop_]
#define IMPL_SLICE_SAFE(arr_, len_, start_, stop_) IMPL_SLICE_UNSAFE(arr_, (IMPL_SLICE_SAFE_START(len_, start_)), (IMPL_SLICE_SAFE_STOP(len_, start_, stop_)))
#define IMPL_SLICE_SAFE_START(len_, start_) IMPL_SLICE_CLAMP((start_), 0, (len_))
#define IMPL_SLICE_SAFE_STOP(len_, start_, stop_) IMPL_SLICE_CLAMP((stop_), IMPL_SLICE_CLAMP((start_), 0, (len_)), (len_))
#define IMPL_SLICE_UNSAFE(arr_, start_, stop_) {.data = (&arr_[(start_)]), .len = ((stop_) - (start_))}
#define IMPL_SLICE_COUNT_OF(arr_) \
((ptrdiff_t)(sizeof(arr_) / sizeof(0 [arr_]) * \
IMPL_SLICE_STATIC_ASSERT_EXPR(IMPL_SLICE_IS_ARRAY(arr_), \
"SLICE failed: " #arr_ " must be an array")))
#define IMPL_SLICE_STATIC_ASSERT_EXPR(expr_, msg_) \
(!!sizeof(struct { \
_Static_assert((expr_), msg_); \
char c; \
}))
#define IMPL_SLICE_IS_ARRAY(maybe_arr_) \
_Generic(&(maybe_arr_), typeof (*maybe_arr_)(*)[]: 1, default: 0)
#define IMPL_SLICE_CLAMP(x_, low_, high_) \
(((x_) > (high_)) ? (high_) : (((x_) < (low_)) ? (low_) : (x_)))
// clang-format on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment