diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-02-26 16:18:27 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-02-26 16:18:27 -0700 |
commit | 560706708d7ff4a57880f855573fd525ebd309fe (patch) | |
tree | 0ee5cd6955d18cd5ce2ad83cbe90d190daa338f0 /libmisc | |
parent | 4a4998bc256f079f7a1a6393d3944c7458c29574 (diff) | |
parent | 8a231f17a865fbae5b4548f0aba80554b3c39d72 (diff) |
Merge branch 'lukeshu/misc'
Diffstat (limited to 'libmisc')
-rw-r--r-- | libmisc/include/libmisc/macro.h | 8 | ||||
-rw-r--r-- | libmisc/include/libmisc/private.h | 7 | ||||
-rw-r--r-- | libmisc/tests/test_macro.c | 25 |
3 files changed, 33 insertions, 7 deletions
diff --git a/libmisc/include/libmisc/macro.h b/libmisc/include/libmisc/macro.h index fe61410..b3e235c 100644 --- a/libmisc/include/libmisc/macro.h +++ b/libmisc/include/libmisc/macro.h @@ -17,9 +17,11 @@ /* numeric */ #define LM_ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0])) -#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) ) -#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */ -#define LM_NEXT_POWER_OF_2(x) ( (x) ? 1ULL<<((sizeof(unsigned long long)*8)-__builtin_clzll(x)) : 1) +#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) ) /** Return ceil(n/d) */ +#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */ +#define LM_ROUND_DOWN(n, d) ( ((n)/(d)) * (d) ) /** Return `n` rounded down to the nearest multiple of `d` */ +#define LM_NEXT_POWER_OF_2(x) ( (x) ? 1ULL<<((sizeof(unsigned long long)*8)-__builtin_clzll(x)) : 1) /** Return the lowest power of 2 that is > x */ +#define LM_FLOORLOG2(x) ((sizeof(unsigned long long)*8)-__builtin_clzll(x)-1) /** Return floor(log_2(x) */ /* strings */ diff --git a/libmisc/include/libmisc/private.h b/libmisc/include/libmisc/private.h index 1db7915..c5382a7 100644 --- a/libmisc/include/libmisc/private.h +++ b/libmisc/include/libmisc/private.h @@ -1,6 +1,6 @@ /* libmisc/private.h - Utilities to hide struct fields * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -10,7 +10,8 @@ #include <libmisc/macro.h> #define YES LM_SENTINEL() -#define BEGIN_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(struct {) -#define END_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(} LM_CAT2_(_HIDDEN_, __COUNTER__);) +#define IS_IMPLEMENTATION_FOR(name) LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name) +#define BEGIN_PRIVATE(name) LM_IF(IS_IMPLEMENTATION_FOR(name))()(struct {) +#define END_PRIVATE(name) LM_IF(IS_IMPLEMENTATION_FOR(name))()(} LM_CAT2_(_HIDDEN_, __COUNTER__);) #endif /* _LIBMISC_PRIVATE_H_ */ diff --git a/libmisc/tests/test_macro.c b/libmisc/tests/test_macro.c index 7cbf9d3..69655d1 100644 --- a/libmisc/tests/test_macro.c +++ b/libmisc/tests/test_macro.c @@ -1,6 +1,6 @@ /* libmisc/tests/test_macro.c - Tests for <libmisc/macro.h> * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -9,6 +9,7 @@ #include "test.h" int main() { + printf("== LM_NEXT_POWER_OF_2 =====================================\n"); /* valid down to 0. */ test_assert(LM_NEXT_POWER_OF_2(0) == 1); test_assert(LM_NEXT_POWER_OF_2(1) == 2); @@ -28,5 +29,27 @@ int main() { /* Valid up to 0x8000000000000000-1 = (1<<63)-1 */ test_assert(LM_NEXT_POWER_OF_2(0x8000000000000000) == 0); /* :( */ + printf("== LM_FLOORLOG2 ===========================================\n"); + /* valid down to 1. */ + test_assert(LM_FLOORLOG2(1) == 0); + test_assert(LM_FLOORLOG2(2) == 1); + test_assert(LM_FLOORLOG2(3) == 1); + test_assert(LM_FLOORLOG2(4) == 2); + test_assert(LM_FLOORLOG2(5) == 2); + test_assert(LM_FLOORLOG2(6) == 2); + test_assert(LM_FLOORLOG2(7) == 2); + test_assert(LM_FLOORLOG2(8) == 3); + /* ... */ + test_assert(LM_FLOORLOG2(16) == 4); + /* ... */ + test_assert(LM_FLOORLOG2(0x80000000) == 31); + /* ... */ + test_assert(LM_FLOORLOG2(0xFFFFFFFF) == 31); + test_assert(LM_FLOORLOG2(0x100000000) == 32); + /* ... */ + test_assert(LM_FLOORLOG2(0x8000000000000000) == 63); + /* ... */ + test_assert(LM_FLOORLOG2(0xFFFFFFFFFFFFFFFF) == 63); + return 0; } |