From 7ab7ed3ee2110d071bd94f6dad6b073981068e71 Mon Sep 17 00:00:00 2001 From: shweet Date: Tue, 11 Nov 2025 20:41:39 -0500 Subject: [PATCH] kill me pete --- include/stdckdint.h | 90 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 include/stdckdint.h diff --git a/include/stdckdint.h b/include/stdckdint.h new file mode 100644 index 0000000..dcc7bca --- /dev/null +++ b/include/stdckdint.h @@ -0,0 +1,90 @@ +#pragma once + +#include +#include +#include +#include + +#ifndef __STDC_VERSION_STDCKDINT_H__ + #define __STDC_VERSION_STDCKDINT_H__ 202311L + + #define __CKD_ADD_UNSIGNED(name, type) \ + static inline bool ckd_add_##name(type* result, type a, type b) \ + { \ + type tmp = (type)(a + b); \ + *result = tmp; \ + return tmp < a; \ + } + + #define __CKD_SUB_UNSIGNED(name, type) \ + static inline bool ckd_sub_##name(type* result, type a, type b) \ + { \ + *result = (type)(a - b); \ + return a < b; \ + } + + #define __CKD_ADD_SIGNED(name, type, min_v, max_v) \ + static inline bool ckd_add_##name(type* result, type a, type b) \ + { \ + const type minValue = (type)(min_v); \ + const type maxValue = (type)(max_v); \ + const type tmp = (type)(a + b); \ + *result = tmp; \ + return (b > 0 && a > (type)(maxValue - b)) || (b < 0 && a < (type)(minValue - b)); \ + } + + #define __CKD_SUB_SIGNED(name, type, min_v, max_v) \ + static inline bool ckd_sub_##name(type* result, type a, type b) \ + { \ + const type minValue = (type)(min_v); \ + const type maxValue = (type)(max_v); \ + const type tmp = (type)(a - b); \ + *result = tmp; \ + return (b > 0 && a < (type)(minValue + b)) || (b < 0 && a > (type)(maxValue + b)); \ + } + +__CKD_ADD_UNSIGNED(u8, uint8_t) +__CKD_ADD_UNSIGNED(u16, uint16_t) +__CKD_ADD_UNSIGNED(u32, uint32_t) +__CKD_ADD_UNSIGNED(u64, uint64_t) +__CKD_ADD_UNSIGNED(usz, size_t) + +__CKD_SUB_UNSIGNED(u8, uint8_t) +__CKD_SUB_UNSIGNED(u16, uint16_t) +__CKD_SUB_UNSIGNED(u32, uint32_t) +__CKD_SUB_UNSIGNED(u64, uint64_t) +__CKD_SUB_UNSIGNED(usz, size_t) + +__CKD_ADD_SIGNED(i8, int8_t, INT8_MIN, INT8_MAX) +__CKD_ADD_SIGNED(i16, int16_t, INT16_MIN, INT16_MAX) +__CKD_ADD_SIGNED(i32, int32_t, INT32_MIN, INT32_MAX) +__CKD_ADD_SIGNED(i64, int64_t, INT64_MIN, INT64_MAX) + +__CKD_SUB_SIGNED(i8, int8_t, INT8_MIN, INT8_MAX) +__CKD_SUB_SIGNED(i16, int16_t, INT16_MIN, INT16_MAX) +__CKD_SUB_SIGNED(i32, int32_t, INT32_MIN, INT32_MAX) +__CKD_SUB_SIGNED(i64, int64_t, INT64_MIN, INT64_MAX) + + #undef __CKD_ADD_UNSIGNED + #undef __CKD_SUB_UNSIGNED + #undef __CKD_ADD_SIGNED + #undef __CKD_SUB_SIGNED + + #define __CKD_DISPATCH(result, a, b, add_fn, sub_fn) \ + (_Generic((result), \ + uint8_t*: add_fn##_u8, \ + const uint8_t*: add_fn##_u8, \ + unsigned char*: add_fn##_u8, \ + uint16_t*: add_fn##_u16, \ + uint32_t*: add_fn##_u32, \ + uint64_t*: add_fn##_u64, \ + size_t*: add_fn##_usz, \ + int8_t*: add_fn##_i8, \ + int16_t*: add_fn##_i16, \ + int32_t*: add_fn##_i32, \ + int64_t*: add_fn##_i64)(result, a, b)) + + #define ckd_add(result, a, b) __CKD_DISPATCH(result, a, b, ckd_add, ckd_sub) + #define ckd_sub(result, a, b) __CKD_DISPATCH(result, a, b, ckd_add, ckd_sub) + +#endif /* __STDC_VERSION_STDCKDINT_H__ */