From f03298e76d76914de056b57412f722a806a0af50 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Sat, 15 Feb 2025 01:16:30 -0700 Subject: [PATCH] :bug: Fix `sized` issue with indivisible sizes Problem: - `sized` does not work correctly when the sizes of `T` and `U` are not multiples, for example when computing the number of 4-byte values required to hold N 3-byte values. Solution: - Fix it. --- include/stdx/utility.hpp | 2 +- test/utility.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/stdx/utility.hpp b/include/stdx/utility.hpp index c138b96..8a1a71b 100644 --- a/include/stdx/utility.hpp +++ b/include/stdx/utility.hpp @@ -116,7 +116,7 @@ template if constexpr (sizeof(T) == sizeof(U)) { return sz; } else if constexpr (sizeof(T) > sizeof(U)) { - return sz * (sizeof(T) / sizeof(U)); + return (sz * sizeof(T) / sizeof(U)) + (sizeof(T) % sizeof(U) & 1u); } else { return (sz * sizeof(T) + sizeof(U) - 1) / sizeof(U); } diff --git a/test/utility.cpp b/test/utility.cpp index c13b48c..df96466 100644 --- a/test/utility.cpp +++ b/test/utility.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -130,6 +131,18 @@ TEST_CASE("sized aliases", "[utility]") { static_assert(stdx::sized64{1}.in() == 1); } +TEST_CASE("sized in (downsize not divisible)", "[utility]") { + using T = std::array; + static_assert(sizeof(T) == 3); + static_assert(stdx::sized{2}.in() == 3); +} + +TEST_CASE("sized in (upsize not divisible)", "[utility]") { + using T = std::array; + static_assert(sizeof(T) == 3); + static_assert(stdx::sized{3}.in() == 3); +} + TEST_CASE("CX_VALUE structural value", "[utility]") { auto x = CX_VALUE(42); static_assert(x() == 42);