From 246defb9b243c1f1150dfb570f9977e5ccb29a1f Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 1 Oct 2024 21:36:33 +0200 Subject: [PATCH] fix: constraits for magnitude added for `scaled_unit` and fixed `common_unit` instantiating it incorrectly --- src/core/include/mp-units/framework/unit.h | 19 ++++++++++++++++++- .../mp-units/framework/unit_concepts.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index 46b56436..6982f667 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -59,6 +59,9 @@ import std; namespace mp_units { +template +struct common_unit; + namespace detail { template @@ -112,6 +115,9 @@ template template [[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit_impl&); +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const common_unit&); + template struct unit_less : std::bool_constant() < type_name()> {}; @@ -237,6 +243,7 @@ struct scaled_unit_impl : detail::unit_interface, detail::propagate_point_origin * instantiate this type automatically based on the unit arithmetic equation provided by the user. */ template + requires(M != magnitude<>{} && M != mag<1>) struct scaled_unit final : detail::scaled_unit_impl {}; namespace detail { @@ -412,7 +419,10 @@ template constexpr auto canonical_lhs = get_canonical_unit(U1{}); constexpr auto canonical_rhs = get_canonical_unit(U2{}); constexpr auto common_magnitude = _common_magnitude(canonical_lhs.mag, canonical_rhs.mag); - return scaled_unit{}; + if constexpr (common_magnitude == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit>{}; } [[nodiscard]] consteval Unit auto get_common_scaled_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest) @@ -441,6 +451,7 @@ template struct common_unit final : decltype(detail::get_common_scaled_unit(U1{}, U2{}, Rest{}...))::_base_type_ { using _base_type_ = common_unit; // exposition only + static constexpr auto _common_unit_ = detail::get_common_scaled_unit(U1{}, U2{}, Rest{}...); }; namespace detail { @@ -524,6 +535,12 @@ template return canonical_unit{M * base.mag, base.reference_unit}; } +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const common_unit& u) +{ + return get_canonical_unit_impl(u._common_unit_, u._common_unit_); +} + template [[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) { diff --git a/src/core/include/mp-units/framework/unit_concepts.h b/src/core/include/mp-units/framework/unit_concepts.h index f752a22e..5cdfc997 100644 --- a/src/core/include/mp-units/framework/unit_concepts.h +++ b/src/core/include/mp-units/framework/unit_concepts.h @@ -46,6 +46,7 @@ MP_UNITS_EXPORT template concept Unit = std::derived_from && std::is_final_v; template + requires(M != magnitude<>{} && M != mag<1>) struct scaled_unit; MP_UNITS_EXPORT template