diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-10-27 17:21:29 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-10-27 17:25:15 -0400 |
commit | 515cda3e3763484af448ad1bc599d583eeeadb18 (patch) | |
tree | 80e862e5d553fbf80e98b73700a6d851be98313b | |
parent | 1f9776901b86b97bbb9c16dd814aeab27eea0e25 (diff) | |
download | bfs-515cda3e3763484af448ad1bc599d583eeeadb18.tar.xz |
bit: Add bswap() overloads for every primitive type
Fixes: https://github.com/tavianator/bfs/issues/145
-rw-r--r-- | src/bit.h | 43 | ||||
-rw-r--r-- | tests/bit.c | 7 |
2 files changed, 41 insertions, 9 deletions
@@ -198,15 +198,35 @@ static inline uint8_t bswap_u8(uint8_t n) { return n; } -/** - * Reverse the byte order of an integer. - */ -#define bswap(n) \ - _Generic((n), \ - uint8_t: bswap_u8, \ - uint16_t: bswap_u16, \ - uint32_t: bswap_u32, \ - uint64_t: bswap_u64)(n) +#if UCHAR_WIDTH == 8 +# define bswap_uc bswap_u8 +#endif + +#if USHRT_WIDTH == 16 +# define bswap_us bswap_u16 +#elif USHRT_WIDTH == 32 +# define bswap_us bswap_u32 +#elif USHRT_WIDTH == 64 +# define bswap_us bswap_u64 +#endif + +#if UINT_WIDTH == 16 +# define bswap_ui bswap_u16 +#elif UINT_WIDTH == 32 +# define bswap_ui bswap_u32 +#elif UINT_WIDTH == 64 +# define bswap_ui bswap_u64 +#endif + +#if ULONG_WIDTH == 32 +# define bswap_ul bswap_u32 +#elif ULONG_WIDTH == 64 +# define bswap_ul bswap_u64 +#endif + +#if ULLONG_WIDTH == 64 +# define bswap_ull bswap_u64 +#endif // Define an overload for each unsigned type #define UINT_OVERLOADS(macro) \ @@ -225,6 +245,11 @@ static inline uint8_t bswap_u8(uint8_t n) { unsigned long: name##_ul, \ unsigned long long: name##_ull) +/** + * Reverse the byte order of an integer. + */ +#define bswap(n) UINT_SELECT(n, bswap)(n) + // C23 polyfill: bit utilities #if __STDC_VERSION_STDBIT_H__ >= C23 diff --git a/tests/bit.c b/tests/bit.c index cc95785..5a3871d 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -81,6 +81,13 @@ void check_bit(void) { check_eq(bswap((uint32_t)0x12345678), 0x78563412); check_eq(bswap((uint64_t)0x1234567812345678), 0x7856341278563412); + // Make sure we can bswap() every unsigned type + (void)bswap((unsigned char)0); + (void)bswap((unsigned short)0); + (void)bswap(0U); + (void)bswap(0UL); + (void)bswap(0ULL); + check_eq(count_ones(0x0U), 0); check_eq(count_ones(0x1U), 1); check_eq(count_ones(0x2U), 1); |