refactor: QuantitySpec convertibility concepts replaced with direct function calls

This commit is contained in:
Mateusz Pusz
2024-12-09 15:55:21 +01:00
parent 6d93f7385a
commit 09488409d2
5 changed files with 12 additions and 12 deletions

View File

@@ -71,7 +71,7 @@ concept ValuePreservingTo = Representation<std::remove_cvref_t<FromRep>> && Repr
template<typename QFrom, typename QTo> template<typename QFrom, typename QTo>
concept QuantityConvertibleTo = concept QuantityConvertibleTo =
Quantity<QFrom> && Quantity<QTo> && QuantitySpecConvertibleTo<QFrom::quantity_spec, QTo::quantity_spec> && Quantity<QFrom> && Quantity<QTo> && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) &&
UnitConvertibleTo<QFrom::unit, QTo::unit> && UnitConvertibleTo<QFrom::unit, QTo::unit> &&
ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> && ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> &&
// TODO consider providing constraints of sudo_cast here rather than testing if it can be called (its return type is // TODO consider providing constraints of sudo_cast here rather than testing if it can be called (its return type is

View File

@@ -57,7 +57,7 @@ namespace mp_units {
* @tparam ToQS a quantity specification to use for a target quantity * @tparam ToQS a quantity specification to use for a target quantity
*/ */
template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
requires detail::QuantitySpecCastableTo<Q::quantity_spec, ToQS> requires(castable(Q::quantity_spec, ToQS))
[[nodiscard]] constexpr Quantity auto quantity_cast(FwdQ&& q) [[nodiscard]] constexpr Quantity auto quantity_cast(FwdQ&& q)
{ {
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, Q::unit)}; return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, Q::unit)};
@@ -81,7 +81,7 @@ template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t
* @tparam ToQS a quantity specification to use for a target quantity point * @tparam ToQS a quantity specification to use for a target quantity point
*/ */
template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
requires detail::QuantitySpecCastableTo<QP::quantity_spec, ToQS> requires(castable(QP::quantity_spec, ToQS))
[[nodiscard]] constexpr QuantityPoint auto quantity_cast(FwdQP&& qp) [[nodiscard]] constexpr QuantityPoint auto quantity_cast(FwdQP&& qp)
{ {
return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_), return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),

View File

@@ -151,7 +151,7 @@ struct quantity_spec_interface : quantity_spec_interface_base {
} }
template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> requires(explicitly_convertible(Q::quantity_spec, Self{}))
[[nodiscard]] constexpr Quantity auto operator()(this Self self, FwdQ&& q) [[nodiscard]] constexpr Quantity auto operator()(this Self self, FwdQ&& q)
{ {
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(self, Q::unit)}; return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(self, Q::unit)};
@@ -164,7 +164,7 @@ struct quantity_spec_interface : quantity_spec_interface_base {
} }
template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self> template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self>
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}> requires(explicitly_convertible(Q::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const [[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
{ {
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_,
@@ -357,7 +357,7 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
} }
template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self> template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self>
requires detail::QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}> requires(explicitly_convertible(Q::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const [[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
{ {
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_,
@@ -398,12 +398,12 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
// clang-format on // clang-format on
#if MP_UNITS_API_NO_CRTP #if MP_UNITS_API_NO_CRTP
template<detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq, detail::QSProperty auto... Args> template<detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq, detail::QSProperty auto... Args>
requires(detail::QuantitySpecExplicitlyConvertibleTo<Eq, QS>) requires(explicitly_convertible(Eq, QS))
struct quantity_spec<QS, Eq, Args...> : detail::quantity_spec_interface { struct quantity_spec<QS, Eq, Args...> : detail::quantity_spec_interface {
#else #else
template<typename Self, detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq, template<typename Self, detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq,
detail::QSProperty auto... Args> detail::QSProperty auto... Args>
requires(detail::QuantitySpecExplicitlyConvertibleTo<Eq, QS>) requires(explicitly_convertible(Eq, QS))
struct quantity_spec<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Self> { struct quantity_spec<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Self> {
#endif #endif
using _base_type_ = quantity_spec; using _base_type_ = quantity_spec;
@@ -1547,8 +1547,8 @@ template<QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto q) { return q; } [[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto q) { return q; }
template<QuantitySpec Q1, QuantitySpec Q2> template<QuantitySpec Q1, QuantitySpec Q2>
requires detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q1{}), detail::get_kind_tree_root(Q2{})> || requires(implicitly_convertible(detail::get_kind_tree_root(Q1{}), detail::get_kind_tree_root(Q2{}))) ||
detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q2{}), detail::get_kind_tree_root(Q1{})> (implicitly_convertible(detail::get_kind_tree_root(Q2{}), detail::get_kind_tree_root(Q1{})))
[[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(Q1 q1, Q2 q2) [[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(Q1 q1, Q2 q2)
{ {
using QQ1 = decltype(detail::remove_kind(q1)); using QQ1 = decltype(detail::remove_kind(q1));

View File

@@ -134,7 +134,7 @@ concept QuantitySpecCastableTo = QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(Fro
MP_UNITS_EXPORT template<typename T, auto QS> MP_UNITS_EXPORT template<typename T, auto QS>
concept QuantitySpecOf = concept QuantitySpecOf =
QuantitySpec<T> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && detail::QuantitySpecConvertibleTo<T{}, QS> && QuantitySpec<T> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && (implicitly_convertible(T{}, QS)) &&
// the below is to make the following work // the below is to make the following work
// static_assert(ReferenceOf<si::radian, isq::angular_measure>); // static_assert(ReferenceOf<si::radian, isq::angular_measure>);
// static_assert(!ReferenceOf<si::radian, dimensionless>); // static_assert(!ReferenceOf<si::radian, dimensionless>);

View File

@@ -106,7 +106,7 @@ concept AssociatedUnit = Unit<U> && detail::has_associated_quantity(U{});
MP_UNITS_EXPORT template<typename U, auto QS> MP_UNITS_EXPORT template<typename U, auto QS>
concept UnitOf = concept UnitOf =
AssociatedUnit<U> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && AssociatedUnit<U> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> &&
detail::QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && (implicitly_convertible(get_quantity_spec(U{}), QS)) &&
// the below is to make `dimensionless[radian]` invalid // the below is to make `dimensionless[radian]` invalid
(get_kind(QS) == get_kind(get_quantity_spec(U{})) || !detail::NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); (get_kind(QS) == get_kind(get_quantity_spec(U{})) || !detail::NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>);