Last active
August 19, 2024 15:02
-
-
Save g-berthiaume/84160d113e5639e480eae9a0ef3af1ba to your computer and use it in GitHub Desktop.
godbolt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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