diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-05-26 00:47:54 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-05-26 00:48:06 +0200 |
commit | a1db1cd9e22e77041d5f1360f1d1ccdc52b86306 (patch) | |
tree | c1cc6dc9c17885a0789028f7a55c7126f33beee7 /asl/base | |
parent | 54b95b16629f0cd4bc30e6899e00019b3ab94012 (diff) |
Implement chunked_buffer
Diffstat (limited to 'asl/base')
-rw-r--r-- | asl/base/bit_tests.cpp | 4 | ||||
-rw-r--r-- | asl/base/meta.hpp | 20 | ||||
-rw-r--r-- | asl/base/numeric.hpp | 17 | ||||
-rw-r--r-- | asl/base/numeric_tests.cpp | 52 |
4 files changed, 86 insertions, 7 deletions
diff --git a/asl/base/bit_tests.cpp b/asl/base/bit_tests.cpp index fa05fab..972bc72 100644 --- a/asl/base/bit_tests.cpp +++ b/asl/base/bit_tests.cpp @@ -39,6 +39,10 @@ ASL_TEST(popcount) // NOLINT(*-cognitive-complexity) ASL_TEST(countr_zero) { ASL_TEST_EXPECT(asl::countr_zero(uint8_t{0}) == 8); + ASL_TEST_EXPECT(asl::countr_zero(uint8_t{1}) == 0); + ASL_TEST_EXPECT(asl::countr_zero(uint8_t{2}) == 1); + ASL_TEST_EXPECT(asl::countr_zero(uint8_t{4}) == 2); + ASL_TEST_EXPECT(asl::countr_zero(uint8_t{8}) == 3); ASL_TEST_EXPECT(asl::countr_zero(uint8_t{255}) == 0); ASL_TEST_EXPECT(asl::countr_zero(uint8_t{0b00011100}) == 2); ASL_TEST_EXPECT(asl::countr_zero(uint8_t{0b10101010}) == 1); diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp index e050e69..b17d761 100644 --- a/asl/base/meta.hpp +++ b/asl/base/meta.hpp @@ -249,28 +249,32 @@ template<> struct _integer_traits<uint8_t> { static constexpr bool kSigned = false; static constexpr bool kUnsigned = true; - using as_signed = int8_t; + using as_signed = int8_t; + using as_unsigned = uint8_t; }; template<> struct _integer_traits<uint16_t> { static constexpr bool kSigned = false; static constexpr bool kUnsigned = true; - using as_signed = int16_t; + using as_signed = int16_t; + using as_unsigned = uint16_t; }; template<> struct _integer_traits<uint32_t> { static constexpr bool kSigned = false; static constexpr bool kUnsigned = true; - using as_signed = int32_t; + using as_signed = int32_t; + using as_unsigned = uint32_t; }; template<> struct _integer_traits<uint64_t> { static constexpr bool kSigned = false; static constexpr bool kUnsigned = true; - using as_signed = int64_t; + using as_signed = int64_t; + using as_unsigned = uint64_t; }; template<> struct _integer_traits<int8_t> @@ -278,6 +282,7 @@ template<> struct _integer_traits<int8_t> static constexpr bool kSigned = true; static constexpr bool kUnsigned = false; using as_unsigned = uint8_t; + using as_signed = int8_t; }; template<> struct _integer_traits<int16_t> @@ -285,6 +290,7 @@ template<> struct _integer_traits<int16_t> static constexpr bool kSigned = true; static constexpr bool kUnsigned = false; using as_unsigned = uint16_t; + using as_signed = int16_t; }; template<> struct _integer_traits<int32_t> @@ -292,6 +298,7 @@ template<> struct _integer_traits<int32_t> static constexpr bool kSigned = true; static constexpr bool kUnsigned = false; using as_unsigned = uint32_t; + using as_signed = int32_t; }; template<> struct _integer_traits<int64_t> @@ -299,6 +306,7 @@ template<> struct _integer_traits<int64_t> static constexpr bool kSigned = true; static constexpr bool kUnsigned = false; using as_unsigned = uint64_t; + using as_signed = int64_t; }; template<typename T> concept is_signed_integer = _integer_traits<T>::kSigned; @@ -306,8 +314,8 @@ template<typename T> concept is_unsigned_integer = _integer_traits<T>::kUnsigned template<typename T> concept is_integer = is_signed_integer<T> || is_unsigned_integer<T>; -template<is_signed_integer T> using as_unsigned_integer = _integer_traits<T>::as_unsigned; -template<is_unsigned_integer T> using as_signed_integer = _integer_traits<T>::as_signed; +template<is_integer T> using as_unsigned_integer = _integer_traits<T>::as_unsigned; +template<is_integer T> using as_signed_integer = _integer_traits<T>::as_signed; template<typename T> concept is_enum = __is_enum(T); diff --git a/asl/base/numeric.hpp b/asl/base/numeric.hpp index bbd229d..8d3b8ef 100644 --- a/asl/base/numeric.hpp +++ b/asl/base/numeric.hpp @@ -7,6 +7,7 @@ #include "asl/base/integers.hpp" #include "asl/base/bit.hpp" #include "asl/base/meta.hpp" +#include "asl/base/assert.hpp" namespace asl { @@ -14,10 +15,24 @@ namespace asl template<is_integer T> constexpr bool is_pow2(T x) { - using unsigned_type = select_t<is_unsigned_integer<T>, T, as_unsigned_integer<T>>; + using unsigned_type = as_unsigned_integer<T>; return x > 0 && has_single_bit(static_cast<unsigned_type>(x)); } +template<is_integer T> +constexpr T round_down_pow2(T x, T div) +{ + ASL_ASSERT(is_pow2(div)); + return x & (-div); +} + +template<is_integer T> +constexpr T round_up_pow2(T x, T div) +{ + ASL_ASSERT(is_pow2(div)); + return (x + (div - 1)) & (-div); +} + template<typename T> concept is_numeric = is_integer<T> || is_floating_point<T>; diff --git a/asl/base/numeric_tests.cpp b/asl/base/numeric_tests.cpp index cfbc1ac..afcc12a 100644 --- a/asl/base/numeric_tests.cpp +++ b/asl/base/numeric_tests.cpp @@ -13,4 +13,56 @@ ASL_TEST(is_pow2) ASL_TEST_EXPECT(!asl::is_pow2(6)); ASL_TEST_EXPECT(!asl::is_pow2(1978)); ASL_TEST_EXPECT(!asl::is_pow2(0)); + ASL_TEST_EXPECT(asl::is_pow2(4U)); + ASL_TEST_EXPECT(asl::is_pow2(uint64_t{65536})); +} + +ASL_TEST(round_down_pow2) // NOLINT +{ + ASL_TEST_EXPECT(asl::round_down_pow2(0, 1) == 0); + ASL_TEST_EXPECT(asl::round_down_pow2(1, 1) == 1); + ASL_TEST_EXPECT(asl::round_down_pow2(2, 1) == 2); + ASL_TEST_EXPECT(asl::round_down_pow2(3, 1) == 3); + ASL_TEST_EXPECT(asl::round_down_pow2(-1, 1) == -1); + ASL_TEST_EXPECT(asl::round_down_pow2(-2, 1) == -2); + ASL_TEST_EXPECT(asl::round_down_pow2(-3, 1) == -3); + + ASL_TEST_EXPECT(asl::round_down_pow2(0U, 1U) == 0U); + ASL_TEST_EXPECT(asl::round_down_pow2(1U, 1U) == 1U); + ASL_TEST_EXPECT(asl::round_down_pow2(2U, 1U) == 2U); + ASL_TEST_EXPECT(asl::round_down_pow2(3U, 1U) == 3U); + + ASL_TEST_EXPECT(asl::round_down_pow2(0, 16) == 0); + ASL_TEST_EXPECT(asl::round_down_pow2(1, 16) == 0); + ASL_TEST_EXPECT(asl::round_down_pow2(8, 16) == 0); + ASL_TEST_EXPECT(asl::round_down_pow2(15, 16) == 0); + ASL_TEST_EXPECT(asl::round_down_pow2(16, 16) == 16); + ASL_TEST_EXPECT(asl::round_down_pow2(17, 16) == 16); + ASL_TEST_EXPECT(asl::round_down_pow2(255, 16) == 240); + ASL_TEST_EXPECT(asl::round_down_pow2(-255, 16) == -256); +} + +ASL_TEST(round_up_pow2) // NOLINT +{ + ASL_TEST_EXPECT(asl::round_up_pow2(0, 1) == 0); + ASL_TEST_EXPECT(asl::round_up_pow2(1, 1) == 1); + ASL_TEST_EXPECT(asl::round_up_pow2(2, 1) == 2); + ASL_TEST_EXPECT(asl::round_up_pow2(3, 1) == 3); + ASL_TEST_EXPECT(asl::round_up_pow2(-1, 1) == -1); + ASL_TEST_EXPECT(asl::round_up_pow2(-2, 1) == -2); + ASL_TEST_EXPECT(asl::round_up_pow2(-3, 1) == -3); + + ASL_TEST_EXPECT(asl::round_up_pow2(0U, 1U) == 0U); + ASL_TEST_EXPECT(asl::round_up_pow2(1U, 1U) == 1U); + ASL_TEST_EXPECT(asl::round_up_pow2(2U, 1U) == 2U); + ASL_TEST_EXPECT(asl::round_up_pow2(3U, 1U) == 3U); + + ASL_TEST_EXPECT(asl::round_up_pow2(0, 16) == 0); + ASL_TEST_EXPECT(asl::round_up_pow2(1, 16) == 16); + ASL_TEST_EXPECT(asl::round_up_pow2(8, 16) == 16); + ASL_TEST_EXPECT(asl::round_up_pow2(15, 16) == 16); + ASL_TEST_EXPECT(asl::round_up_pow2(16, 16) == 16); + ASL_TEST_EXPECT(asl::round_up_pow2(17, 16) == 32); + ASL_TEST_EXPECT(asl::round_up_pow2(255, 16) == 256); + ASL_TEST_EXPECT(asl::round_up_pow2(-255, 16) == -240); } |