Add a math::round_up_to_multiple_of<N>() utility Diffs= bb7d5ac4c Add a math::round_up_to_multiple_of<N>() utility (#6061) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index e292a4a..5f1cbb1 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -6ee7cea9edb3efb81318bc5a8a1db2c6a28c011a +bb7d5ac4ccbe04a80c8469b56da55b9b92a70ef6
diff --git a/include/rive/math/math_types.hpp b/include/rive/math/math_types.hpp index a830408..3dd14bf 100644 --- a/include/rive/math/math_types.hpp +++ b/include/rive/math/math_types.hpp
@@ -81,6 +81,15 @@ return (doubleBits >> 52) - 1022; #endif } + +// Returns x rounded up to the next multiple of N. +// If x is already a multiple of N, returns x. +template <size_t N> RIVE_ALWAYS_INLINE constexpr size_t round_up_to_multiple_of(size_t x) +{ + static_assert(N != 0 && (N & (N - 1)) == 0, + "math::round_up_to_multiple_of<> only supports powers of 2."); + return (x + (N - 1)) & ~(N - 1); +} } // namespace math template <typename T> T lerp(const T& a, const T& b, float t) { return a + (b - a) * t; }
diff --git a/test/math_test.cpp b/test/math_test.cpp index 63bfabf..4bf0006 100644 --- a/test/math_test.cpp +++ b/test/math_test.cpp
@@ -61,8 +61,8 @@ CHECK(std::isnan(math::bit_cast<float>(0x7fc00000))); } -// Check math::nextlog2. -TEST_CASE("nextlog2", "[math]") +// Check math::msb. +TEST_CASE("msb", "[math]") { CHECK(math::msb(0) == 0); CHECK(math::msb(1) == 1); @@ -80,3 +80,20 @@ } CHECK(math::msb(0xffffffff) == 32); } + +// Check math::round_up_to_multiple_of. +TEST_CASE("round_up_to_multiple_of", "[math]") +{ + CHECK(math::round_up_to_multiple_of<4>(0) == 0); + CHECK(math::round_up_to_multiple_of<4>(3) == 4); + CHECK(math::round_up_to_multiple_of<8>(16) == 16); + CHECK(math::round_up_to_multiple_of<8>(24) == 24); + CHECK(math::round_up_to_multiple_of<8>(25) == 32); + CHECK(math::round_up_to_multiple_of<8>(31) == 32); + CHECK(math::round_up_to_multiple_of<8>(32) == 32); + for (size_t i = 0; i < 10; ++i) + { + CHECK(math::round_up_to_multiple_of<1>(i) == i); + } + CHECK(math::round_up_to_multiple_of<2>(~size_t(0)) == 0); +}