diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c4326c9d..23f48c5c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -34,6 +34,7 @@ - fix: downcasting facility for non-default-constructible types - fix: restore user-warnings within the library implementation - fix: the text symbol of `foot_pound_force` and `foot_pound_force_per_second` + - fix: quantity modulo arithmetics fixed - (!) build: Conan testing version is now hosted on [Artifactory](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units) - (!) build: Linear Algebra is now hosted on its [Artifactory](https://twonington.jfrog.io/artifactory/api/conan/conan-oss) - (!) build: `BUILD_DOCS` CMake option renamed to `UNITS_BUILD_DOCS` diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index 13c519ab..c40b9992 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -426,25 +426,15 @@ template return detail::make_quantity(lhs.number() / rhs.number()); } -template - requires (!floating_point_) && (!floating_point_) && - quantity_value_for_, Rep1, Rep2> -[[nodiscard]] constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using unit = downcast_unit; - using ret = quantity, Rep1, Rep2>>; - return ret(lhs.number() % rhs.number()); -} - -template Q2> +template requires (!floating_point_) && (!floating_point_) && + (QuantityEquivalentTo || Dimensionless) && quantity_value_for_, typename Q1::rep, typename Q2::rep> [[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs) { gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using ret = common_quantity_for, Q1, Q2>; - return ret(ret(lhs).number() % ret(rhs).number()); + using ret = quantity, typename Q1::rep, typename Q2::rep>>; + return ret(lhs.number() % rhs.number()); } template Q2> diff --git a/test/unit_test/static/quantity_kind_test.cpp b/test/unit_test/static/quantity_kind_test.cpp index 1cc20856..5ffea7fe 100644 --- a/test/unit_test/static/quantity_kind_test.cpp +++ b/test/unit_test/static/quantity_kind_test.cpp @@ -612,7 +612,7 @@ static_assert(same(height(2. * m) / (3 * s), rate_of_climb(2 * m) * dimensionless(3), width(6 * cm))); static_assert(same(dimensionless(2) * width(3 * m), width(6 * cm))); static_assert(same(width(2 * m) / dimensionless(3), width(2. / 3 * hm))); -static_assert(same(width(2 * m) % dimensionless(3), width(2 * cm))); +static_assert(same(width(2 * m) % dimensionless(3), width(2 * m))); static_assert(same(height(2 * m) / (3 * m), quantity_kind, one, int>(0))); diff --git a/test/unit_test/static/quantity_test.cpp b/test/unit_test/static/quantity_test.cpp index 6c16f0f0..de56d789 100644 --- a/test/unit_test/static/quantity_test.cpp +++ b/test/unit_test/static/quantity_test.cpp @@ -399,7 +399,7 @@ static_assert(is_same_v>); static_assert(compare(1)), length>); static_assert(compare(1) * 1_q_m), length>); static_assert(compare(1)), length>); -static_assert(compare(1)), length>); +static_assert(compare(1)), length>); static_assert(compare>); static_assert(compare>); static_assert(compare>); @@ -433,7 +433,7 @@ static_assert(compare(1) / 1._q_s), frequency, long double>>); static_assert(compare>); static_assert(compare>); -static_assert(compare(1)), length>); +static_assert(compare(1)), length>); static_assert(compare(1)), length>); static_assert(is_same_v>); @@ -475,7 +475,7 @@ static_assert(is_same_v>); static_assert(is_same_v>); static_assert(is_same_v>); -static_assert(is_same_v>); +static_assert(is_same_v>); // different dimensions static_assert(compare>); @@ -545,7 +545,7 @@ static_assert((7_q_m % 2).number() == 1); static_assert((7_q_m % quantity{2}).number() == 1); static_assert((7_q_m % dimensionless(2)).number() == 1); static_assert((7_q_m % 2_q_m).number() == 1); -static_assert((7_q_km % 2000_q_m).number() == 1000); +static_assert((7_q_km % 2000_q_m).number() == 7); static_assert((10_q_km2 * 10_q_km2) / 50_q_km2 == 2_q_km2); @@ -560,8 +560,7 @@ static_assert(quantity_cast(10_q_km / 5_q_m).number() == 2000); static_assert((10_q_s * 2_q_kHz).number() == 20); -// unit constants - +// quantity references static_assert(2_q_m * (1 * m) == (2_q_m2)); static_assert(2_q_m2 / (1 * m) == (2_q_m)); @@ -787,4 +786,62 @@ static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr2 = quotient_remainder_theorem(3 * km, 400 * m); +static_assert(qr2 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr3 = quotient_remainder_theorem(3 * km, 2 * m); +static_assert(qr3 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr4 = quotient_remainder_theorem(3 * km, 400'000 * mm); +static_assert(qr4 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr5 = quotient_remainder_theorem(3 * km, 2'000 * mm); +static_assert(qr5 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr6 = quotient_remainder_theorem(3 * km, 400 * mm); +static_assert(qr6 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr7 = quotient_remainder_theorem(3 * km, 2 * mm); +static_assert(qr7 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr8 = quotient_remainder_theorem(3'000 * m, 400); +static_assert(qr8 == 3'000 * m); +static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr9 = quotient_remainder_theorem(3'000 * m, quantity(400)); +static_assert(qr9 == 3'000 * m); +static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr10 = quotient_remainder_theorem(3 * km, quantity(400)); +static_assert(qr10 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr11 = quotient_remainder_theorem(3 * km, quantity(2)); +static_assert(qr11 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr12 = quotient_remainder_theorem(3 * km, dimensionless, int>(400)); +static_assert(qr12 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + } // namespace