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>
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> &&
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

View File

@ -57,7 +57,7 @@ namespace mp_units {
* @tparam ToQS a quantity specification to use for a target quantity
*/
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)
{
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
*/
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)
{
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>>
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}>
requires(explicitly_convertible(Q::quantity_spec, Self{}))
[[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)};
@ -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>
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}>
requires(explicitly_convertible(Q::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
{
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>
requires detail::QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}>
requires(explicitly_convertible(Q::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
{
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
#if MP_UNITS_API_NO_CRTP
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 {
#else
template<typename Self, 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<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Self> {
#endif
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; }
template<QuantitySpec Q1, QuantitySpec Q2>
requires detail::QuantitySpecConvertibleTo<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{})>
requires(implicitly_convertible(detail::get_kind_tree_root(Q1{}), detail::get_kind_tree_root(Q2{}))) ||
(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)
{
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>
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
// static_assert(ReferenceOf<si::radian, isq::angular_measure>);
// 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>
concept UnitOf =
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
(get_kind(QS) == get_kind(get_quantity_spec(U{})) || !detail::NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>);