From 7ef8193dfc8ad1b8239f5395268e17a471c30c84 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Mon, 10 Apr 2023 19:46:50 +0200 Subject: [PATCH] fix: modulo operation logic fixed --- src/core/include/mp_units/quantity.h | 55 ------------------------- test/unit_test/static/quantity_test.cpp | 45 +++----------------- 2 files changed, 6 insertions(+), 94 deletions(-) diff --git a/src/core/include/mp_units/quantity.h b/src/core/include/mp_units/quantity.h index b61a3a85..22434f24 100644 --- a/src/core/include/mp_units/quantity.h +++ b/src/core/include/mp_units/quantity.h @@ -284,34 +284,6 @@ public: return *this; } - template - requires(!Quantity) && (!treat_as_floating_point) && (!treat_as_floating_point) && - requires(rep a, const Rep2 b) { - { - a %= b - } -> std::same_as; - } - constexpr quantity& operator%=(const Rep2& rhs) - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - number_ %= rhs; - return *this; - } - - template Q> - requires(Q::unit == ::mp_units::one) && (!treat_as_floating_point) && - (!treat_as_floating_point) && requires(rep a, const typename Q::rep b) { - { - a %= b - } -> std::same_as; - } - constexpr quantity& operator%=(const Q& rhs) - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - number_ %= rhs.number(); - return *this; - } - constexpr quantity& operator%=(const quantity& q) requires(!treat_as_floating_point) && requires(rep a, rep b) { { @@ -398,23 +370,6 @@ public: return v / q.number() * (::mp_units::one / reference); } - template - requires(!Quantity) && (!treat_as_floating_point) && (!treat_as_floating_point) && - detail::InvokeResultIsRepresentationOf, rep, Value> - [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v) - { - gsl_ExpectsAudit(v != quantity_values::zero()); - return (q.number() % v) * reference; - } - - [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) - requires(!treat_as_floating_point) && - detail::InvokeResultIsRepresentationOf, rep, rep> - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return (lhs.number() % rhs.number()) * reference; - } - template requires(!treat_as_floating_point) && (!treat_as_floating_point) && requires { @@ -428,16 +383,6 @@ public: return (ret(lhs).number() % ret(rhs).number()) * ref; } - template - requires(!treat_as_floating_point) && (!treat_as_floating_point) && - (Q::dimension == dimension_one) && (Q::unit == ::mp_units::one) && - detail::InvokeResultIsRepresentationOf, rep, typename Q::rep> - [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const Q& rhs) - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return (lhs.number() % rhs.number()) * reference; - } - template requires requires { common_reference(reference, Q::reference); } && std::equality_comparable_with diff --git a/test/unit_test/static/quantity_test.cpp b/test/unit_test/static/quantity_test.cpp index 89939539..97030117 100644 --- a/test/unit_test/static/quantity_test.cpp +++ b/test/unit_test/static/quantity_test.cpp @@ -376,10 +376,8 @@ static_assert((1 * m += 1 * m).number() == 2); static_assert((2 * m -= 1 * m).number() == 1); static_assert((1 * m *= 2).number() == 2); static_assert((2 * m /= 2).number() == 1); -static_assert((7 * m %= 2).number() == 1); static_assert((1 * m *= 2 * one).number() == 2); static_assert((2 * m /= 2 * one).number() == 1); -static_assert((7 * m %= 2 * one).number() == 1); static_assert((7 * m %= 2 * m).number() == 1); // different types @@ -393,24 +391,8 @@ static_assert((2.5 * m *= 3 * one).number() == 7.5); static_assert((7.5 * m /= 3 * one).number() == 2.5); static_assert((3500 * m %= 1 * km).number() == 500); -static_assert((std::uint8_t(255) * m %= 256).number() == [] { - std::uint8_t ui(255); - return ui %= 256; -}()); -static_assert((std::uint8_t(255) * m %= 256 * one).number() == [] { - std::uint8_t ui(255); - return ui %= 256; -}()); // static_assert((std::uint8_t(255) * m %= 256 * m).number() != [] { std::uint8_t ui(255); return ui %= 256; }()); // // UB -static_assert((std::uint8_t(255) * m %= 257).number() == [] { - std::uint8_t ui(255); - return ui %= 257; -}()); -static_assert((std::uint8_t(255) * m %= 257 * one).number() == [] { - std::uint8_t ui(255); - return ui %= 257; -}()); // TODO: Fix static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] { std::uint8_t ui(255); @@ -532,7 +514,6 @@ static_assert(is_of_type<4 * m % (2 * m), quantity>); static_assert(is_of_type<1'234 * m % (1 * km), quantity>); static_assert(is_of_type<1 * km % (300 * m), quantity>); static_assert(is_of_type<4 * one % (2 * one), quantity>); -static_assert(is_of_type<4 * one % 2, quantity>); // check for integral types promotion static_assert(is_same_v); @@ -669,7 +650,6 @@ static_assert((7 * m % (2 * m)).number() == 1); static_assert((7 * km % (2000 * m)).number() == 1000); static_assert((1300 * m % (1 * km)).number() == 300); static_assert((7 * one % (2 * one)).number() == 1); -static_assert((7 * one % 2).number() == 1); static_assert((10 * m2 * (10 * m2)) / (50 * m2) == 2 * m2); @@ -699,6 +679,10 @@ static_assert(4 % (2 * one) == 0); // modulo arithmetics +static_assert(5 * h % (120 * min) == 60 * min); +static_assert(300 * min % (2 * h) == 60 * min); +static_assert(300 * min % (120 * min) == 60 * min); + constexpr auto quotient_remainder_theorem(auto q1, auto q2) { auto quotient = q1 / q2; @@ -707,26 +691,9 @@ constexpr auto quotient_remainder_theorem(auto q1, auto q2) return q; } +// this works only if two quantities have the same unit +static_assert(quotient_remainder_theorem(7 * m, 3 * m) == 7 * m); static_assert(quotient_remainder_theorem(3'000 * m, 400 * m) == 3'000 * m); -// static_assert(quotient_remainder_theorem(3 * km, 400 * m) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 2 * m) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 400'000 * mm) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 2'000 * mm) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 400 * mm) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 2 * mm) == 3 * km); -// static_assert(quotient_remainder_theorem(3'000 * m, 400) == 3'000 * m); -// static_assert(quotient_remainder_theorem(3'000 * m, 400 * one) == 3'000 * m); -// static_assert(quotient_remainder_theorem(3 * km, 400 * one) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 2 * one) == 3 * km); -// static_assert(quotient_remainder_theorem(3 * km, 400 * (mag * one)) == 3 * km); - -static_assert((7 * m / (3 * m)) * (3 * m) + (7 * m) % (3 * m) == 7 * m); -static_assert((7 * m / 3) * 3 + (7 * m) % 3 == 7 * m); -static_assert((7 * m / (3 * one)) * (3 * one) + (7 * m) % (3 * one) == 7 * m); -static_assert((7 / (3 * one)) * (3 * one) + 7 % (3 * one) == 7); - -// static_assert((7 * km / (2500 * m)) * (2500 * m) + (7 * km) % (2500 * m) == 7 * km); -// static_assert((7500 * m / (3 * km)) * (3 * km) + (75000 * m) % (3 * km) == 7500 * m); static_assert(is_same_v); static_assert(is_same_v);