mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-06 05:34:27 +02:00
feat: leveled quantity specification conversion introduced
This commit is contained in:
@@ -55,11 +55,11 @@ class quantity;
|
||||
*
|
||||
* @tparam ToQS a quantity specification to use for a target quantity
|
||||
*/
|
||||
template<QuantitySpec auto ToQS, Quantity Q>
|
||||
requires(interconvertible(ToQS, get_quantity_spec(Q::reference)))
|
||||
template<QuantitySpec auto ToQS, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> && castable_to(get_quantity_spec(Q::reference), ToQS)
|
||||
[[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q)
|
||||
{
|
||||
constexpr reference<ToQS, Q::unit> r;
|
||||
constexpr reference<ToQS, std::remove_cvref_t<Q>::unit> r;
|
||||
return std::forward<Q>(q).number() * r;
|
||||
}
|
||||
|
||||
|
@@ -54,21 +54,9 @@ concept Quantity = requires(T* t) { detail::to_base_specialization_of_quantity(t
|
||||
* the provided dimension/reference type.
|
||||
*/
|
||||
template<typename Q, auto V>
|
||||
concept QuantityOf = Quantity<Q> && ((Dimension<std::remove_const_t<decltype(V)>> && Q::dimension == V) ||
|
||||
(QuantitySpec<std::remove_const_t<decltype(V)>> && Q::quantity_spec == V) ||
|
||||
(Reference<std::remove_const_t<decltype(V)>> && Q::reference == V));
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantities with provided dimension or reference
|
||||
*
|
||||
* Satisfied by all quantities with a dimension/reference being the instantiation derived from
|
||||
* the provided dimension/reference type.
|
||||
*/
|
||||
template<typename Q, auto V>
|
||||
concept WeakQuantityOf =
|
||||
concept QuantityOf =
|
||||
Quantity<Q> && ((Dimension<std::remove_const_t<decltype(V)>> && Q::dimension == V) ||
|
||||
(QuantitySpec<std::remove_const_t<decltype(V)>> && interconvertible(Q::quantity_spec, V)) ||
|
||||
(Reference<std::remove_const_t<decltype(V)>> && Q::dimension == V.dimension && Q::unit == V.unit));
|
||||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible_to(Q::quantity_spec, V)));
|
||||
|
||||
/**
|
||||
* @brief A concept matching all external quantities like types
|
||||
|
@@ -95,8 +95,7 @@ template<typename QP, auto V>
|
||||
concept QuantityPointOf =
|
||||
QuantityPoint<QP> &&
|
||||
((Dimension<std::remove_const_t<decltype(V)>> && QP::dimension == V) ||
|
||||
(QuantitySpec<std::remove_const_t<decltype(V)>> && QP::quantity_spec == V) ||
|
||||
(Reference<std::remove_const_t<decltype(V)>> && QP::reference == V) ||
|
||||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible_to(QP::quantity_spec, V)) ||
|
||||
(PointOrigin<std::remove_const_t<decltype(V)>> &&
|
||||
std::same_as<std::remove_const_t<decltype(QP::absolute_point_origin)>, std::remove_const_t<decltype(V)>>));
|
||||
|
||||
|
@@ -43,7 +43,7 @@ namespace detail {
|
||||
* @tparam To a target quantity type to cast to
|
||||
*/
|
||||
template<Quantity To, auto R, typename Rep>
|
||||
requires(interconvertible(To::reference, R)) &&
|
||||
requires(castable_to(get_quantity_spec(R), To::quantity_spec)) &&
|
||||
((get_unit(R) == To::unit && std::constructible_from<typename To::rep, Rep>) ||
|
||||
(get_unit(R) != To::unit)) // && scalable_with_<typename To::rep>))
|
||||
// TODO how to constrain the second part here?
|
||||
|
@@ -122,19 +122,19 @@ struct reference {
|
||||
template<auto Q2, auto U2>
|
||||
[[nodiscard]] friend consteval bool convertible_to(reference, reference<Q2, U2>)
|
||||
{
|
||||
return convertible_to(Q, Q2) && convertible_to(U, U2);
|
||||
return implicitly_convertible_to(Q, Q2) && convertible_to(U, U2);
|
||||
}
|
||||
|
||||
template<AssociatedUnit U2>
|
||||
[[nodiscard]] friend consteval bool convertible_to(reference, U2 u2)
|
||||
{
|
||||
return convertible_to(Q, get_quantity_spec(u2)) && convertible_to(U, u2);
|
||||
return implicitly_convertible_to(Q, get_quantity_spec(u2)) && convertible_to(U, u2);
|
||||
}
|
||||
|
||||
template<AssociatedUnit U1>
|
||||
[[nodiscard]] friend consteval bool convertible_to(U1 u1, reference)
|
||||
{
|
||||
return convertible_to(get_quantity_spec(u1), Q) && convertible_to(u1, U);
|
||||
return implicitly_convertible_to(get_quantity_spec(u1), Q) && convertible_to(u1, U);
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user