Add unsigned integer wrapping functions
This commit is contained in:
parent
8b78803ad8
commit
7ec2af0c33
@ -10,6 +10,11 @@
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define GUF_UINT8_MAX 0xffu
|
||||
#define GUF_UINT16_MAX 0xffffu
|
||||
#define GUF_UINT32_MAX 0xfffffffful
|
||||
#define GUF_UINT64_MAX 0xffffffffffffffffull
|
||||
|
||||
#ifndef GUF_PLATFORM_BIG_ENDIAN
|
||||
#define GUF_PLATFORM_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
@ -19,6 +19,28 @@
|
||||
static inline uint64_t guf_rotl_u64(uint64_t x, int k) {return (1u*x << k) | (1u*x >> (64 - k));}
|
||||
static inline uint32_t guf_rotl_u32(uint32_t x, int k) {return (1u*x << k) | (1u*x >> (32 - k));}
|
||||
|
||||
// Typesafe unsigned integer wrapping functions (generated with libguf/tools/intwrap-gen.py)
|
||||
static inline uint_least8_t guf_wrap8_uint_least8_t(uint_least8_t a) { return a & GUF_UINT8_MAX; }
|
||||
static inline uint_fast8_t guf_wrap8_uint_fast8_t(uint_fast8_t a) { return a & GUF_UINT8_MAX; }
|
||||
|
||||
static inline uint_least16_t guf_wrap16_uint_least16_t(uint_least16_t a) { return a & GUF_UINT16_MAX; }
|
||||
static inline uint_fast16_t guf_wrap16_uint_fast16_t(uint_fast16_t a) { return a & GUF_UINT16_MAX; }
|
||||
|
||||
static inline uint_least32_t guf_wrap32_uint_least32_t(uint_least32_t a) { return a & GUF_UINT32_MAX; }
|
||||
static inline uint_fast32_t guf_wrap32_uint_fast32_t(uint_fast32_t a) { return a & GUF_UINT32_MAX; }
|
||||
|
||||
static inline uint_least64_t guf_wrap64_uint_least64_t(uint_least64_t a) { return a & GUF_UINT64_MAX; }
|
||||
static inline uint_fast64_t guf_wrap64_uint_fast64_t(uint_fast64_t a) { return a & GUF_UINT64_MAX; }
|
||||
|
||||
static inline unsigned char guf_wrap8_uchar(unsigned char a) { return a & GUF_UINT8_MAX; } // unsigned char: >= 8 bits
|
||||
static inline unsigned short guf_wrap16_ushort(unsigned short a) { return a & GUF_UINT16_MAX; } // unsigned short: >= 16 bits
|
||||
static inline unsigned long guf_wrap32_ulong(unsigned long a) { return a & GUF_UINT32_MAX; } // unsigned long: >= 32 bits
|
||||
static inline unsigned long long guf_wrap64_ulong_long(unsigned long long a) { return a & GUF_UINT64_MAX; } // unsigned long long: >= 64 bits
|
||||
|
||||
#define GUF_UWRAP_8(UINT) ( (UINT) & GUF_UINT8_MAX )
|
||||
#define GUF_UWRAP_16(UINT) ( (UINT) & GUF_UINT16_MAX )
|
||||
#define GUF_UWRAP_32(UINT) ( (UINT) & GUF_UINT32_MAX )
|
||||
#define GUF_UWRAP_64(UINT) ( (UINT) & GUF_UINT64_MAX )
|
||||
|
||||
// Signed min, max, clamp functions (generated with libguf/tools/min_max_clamp-gen.py)
|
||||
|
||||
|
||||
2
todo.txt
2
todo.txt
@ -1,6 +1,8 @@
|
||||
- guf_stack, guf_queue, guf_dqueue, guf_prio_queue (using a heap), guf_ringbuf
|
||||
- sort: add cpp #ifdef to remove restrict from declaration
|
||||
|
||||
- str: start_with, ends_with, find
|
||||
|
||||
- guf_wrapping_mul_TYPE: Not 100 % sure if it does not depend on implementation defined behaviour, but it shouldn't
|
||||
- https://en.cppreference.com/w/c/types/integer (apparently the signed fixed width integer types are guaranteed to be two's complement...)
|
||||
|
||||
|
||||
41
tools/intwrap-gen.py
Normal file
41
tools/intwrap-gen.py
Normal file
@ -0,0 +1,41 @@
|
||||
"""
|
||||
Generate typesafe unsigned integer wrapping functions
|
||||
"""
|
||||
|
||||
def gen_uwrap_code(uint_type: str, uint_type_abbr: str, wrap_width: int, wrap_max_uint: str) -> str:
|
||||
template = "static inline {uint_type} guf_wrap{wrap_width}_{uint_type_abbr}({uint_type} a) {{ return a & {wrap_max_uint}; }}\n"
|
||||
return template.format(uint_type = uint_type, uint_type_abbr = uint_type_abbr, wrap_width = wrap_width, wrap_max_uint = wrap_max_uint)
|
||||
|
||||
if __name__ == "__main__":
|
||||
uint_types = [
|
||||
{"uint_type": "uint_least8_t", "uint_type_abbr": "uint_least8_t", "wrap_width": 8, "wrap_max_uint": "GUF_UINT8_MAX"},
|
||||
{"uint_type": "uint_fast8_t", "uint_type_abbr": "uint_fast8_t", "wrap_width": 8, "wrap_max_uint": "GUF_UINT8_MAX"},
|
||||
|
||||
"\n",
|
||||
{"uint_type": "uint_least16_t", "uint_type_abbr": "uint_least16_t", "wrap_width": 16, "wrap_max_uint": "GUF_UINT16_MAX"},
|
||||
{"uint_type": "uint_fast16_t", "uint_type_abbr": "uint_fast16_t", "wrap_width": 16, "wrap_max_uint": "GUF_UINT16_MAX"},
|
||||
|
||||
"\n",
|
||||
{"uint_type": "uint_least32_t", "uint_type_abbr": "uint_least32_t", "wrap_width": 32, "wrap_max_uint": "GUF_UINT32_MAX"},
|
||||
{"uint_type": "uint_fast32_t", "uint_type_abbr": "uint_fast32_t", "wrap_width": 32, "wrap_max_uint": "GUF_UINT32_MAX"},
|
||||
|
||||
"\n",
|
||||
{"uint_type": "uint_least64_t", "uint_type_abbr": "uint_least64_t", "wrap_width": 64, "wrap_max_uint": "GUF_UINT64_MAX"},
|
||||
{"uint_type": "uint_fast64_t", "uint_type_abbr": "uint_fast64_t", "wrap_width": 64, "wrap_max_uint": "GUF_UINT64_MAX"},
|
||||
|
||||
"\n",
|
||||
{"uint_type": "unsigned char", "uint_type_abbr": "uchar", "wrap_width": 8, "wrap_max_uint": "GUF_UINT8_MAX"},
|
||||
{"uint_type": "unsigned short", "uint_type_abbr": "ushort", "wrap_width": 16, "wrap_max_uint": "GUF_UINT16_MAX"},
|
||||
{"uint_type": "unsigned long", "uint_type_abbr": "ulong", "wrap_width": 32, "wrap_max_uint": "GUF_UINT32_MAX"},
|
||||
{"uint_type": "unsigned long long", "uint_type_abbr": "ulong_long", "wrap_width": 64, "wrap_max_uint": "GUF_UINT64_MAX"},
|
||||
]
|
||||
|
||||
|
||||
code = "// Typesafe unsigned integer wrapping functions (generated with tools/intwrap-gen.py)\n"
|
||||
for uint_t in uint_types:
|
||||
if isinstance(uint_t, str):
|
||||
code += uint_t
|
||||
else:
|
||||
code += gen_uwrap_code(**uint_t)
|
||||
|
||||
print(code)
|
||||
Loading…
x
Reference in New Issue
Block a user