fix: common_unit handling fixed for some corner cases
This commit is contained in:
1 parent
07e4e795c1
commit
569f27af8b
7 files changed
+58
-12
No files matched your search
@@ -26,7 +26,12 @@
|
||||
#include <mp-units/framework/quantity_spec.h>
|
||||
#include <mp-units/framework/unit_concepts.h>
|
||||
|
||||
namespace mp_units::detail {
|
||||
namespace mp_units {
|
||||
|
||||
template<Unit U1, Unit U2, Unit... Rest>
|
||||
struct common_unit;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<AssociatedUnit U>
|
||||
[[nodiscard]] consteval auto all_are_kinds(U);
|
||||
@@ -61,6 +66,12 @@ template<AssociatedUnit U>
|
||||
template<AssociatedUnit U>
|
||||
using to_quantity_spec = decltype(get_associated_quantity_impl(U{}));
|
||||
|
||||
template<typename... Us>
|
||||
[[nodiscard]] consteval auto get_associated_quantity_impl(common_unit<Us...>)
|
||||
{
|
||||
return get_common_quantity_spec(get_associated_quantity_impl(Us{})...);
|
||||
}
|
||||
|
||||
template<AssociatedUnit U>
|
||||
[[nodiscard]] consteval auto get_associated_quantity_impl(U u)
|
||||
{
|
||||
@@ -83,4 +94,6 @@ template<AssociatedUnit U>
|
||||
return get_associated_quantity_impl(u);
|
||||
}
|
||||
|
||||
} // namespace mp_units::detail
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mp_units
|
||||
@@ -93,16 +93,17 @@ concept HaveCommonReferenceImpl = requires { get_common_reference(R1, R2); };
|
||||
template<auto R1, auto R2>
|
||||
concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>;
|
||||
|
||||
template<typename Func, Quantity Q1, Quantity Q2>
|
||||
using common_quantity_for = quantity<get_common_reference(Q1::reference, Q2::reference),
|
||||
std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
|
||||
|
||||
template<typename Func, typename Q1, typename Q2>
|
||||
concept CommonlyInvocableQuantities =
|
||||
Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> &&
|
||||
std::convertible_to<Q1, common_quantity_for<Func, Q1, Q2>> &&
|
||||
std::convertible_to<Q2, common_quantity_for<Func, Q1, Q2>> &&
|
||||
InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec).character>;
|
||||
|
||||
template<typename Func, Quantity Q1, Quantity Q2>
|
||||
requires CommonlyInvocableQuantities<Func, Q1, Q2>
|
||||
using common_quantity_for = quantity<get_common_reference(Q1::reference, Q2::reference),
|
||||
std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
|
||||
|
||||
template<auto R1, auto R2, typename Rep1, typename Rep2>
|
||||
concept SameValueAs = SameReference<R1, R2> && std::same_as<Rep1, Rep2>;
|
||||
|
||||
|
||||
@@ -60,9 +60,6 @@ import std;
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
template<Unit U1, Unit U2, Unit... Rest>
|
||||
struct common_unit;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
@@ -784,9 +781,18 @@ constexpr Out unit_symbol_impl(Out out, const scaled_unit_impl<M, U>& u, const u
|
||||
template<typename... Us, Unit U>
|
||||
[[nodiscard]] consteval Unit auto get_common_unit_in(common_unit<Us...>, U u)
|
||||
{
|
||||
auto get_magnitude = [&]() {
|
||||
if constexpr (requires { common_unit<Us...>::mag; })
|
||||
return common_unit<Us...>::mag;
|
||||
else
|
||||
return mag<1>;
|
||||
};
|
||||
constexpr auto canonical_u = get_canonical_unit(u);
|
||||
constexpr Magnitude auto mag = common_unit<Us...>::mag / canonical_u.mag;
|
||||
return scaled_unit<mag, U>{};
|
||||
constexpr Magnitude auto cmag = get_magnitude() / canonical_u.mag;
|
||||
if constexpr (cmag == mag<1>)
|
||||
return u;
|
||||
else
|
||||
return scaled_unit<cmag, U>{};
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, typename U, typename... Rest>
|
||||
|
||||
Reference in new issue
Block a user