mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-31 19:04:27 +02:00
refactor: QuantitySpec
convertibility concepts replaced with direct function calls
This commit is contained in:
@@ -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
|
||||||
|
@@ -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_),
|
||||||
|
@@ -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));
|
||||||
|
@@ -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>);
|
||||||
|
@@ -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>);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user