refactor: quantity_spec casts functions renamed

This commit is contained in:
Mateusz Pusz
2023-04-08 19:49:51 +02:00
parent c54aa9b0eb
commit d65393b4e2
8 changed files with 196 additions and 195 deletions
@@ -56,7 +56,7 @@ class quantity;
* @tparam ToQS a quantity specification to use for a target quantity
*/
template<QuantitySpec auto ToQS, typename Q>
requires Quantity<std::remove_cvref_t<Q>> && (castable_to(std::remove_cvref_t<Q>::quantity_spec, ToQS))
requires Quantity<std::remove_cvref_t<Q>> && (castable(std::remove_cvref_t<Q>::quantity_spec, ToQS))
[[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q)
{
constexpr reference<ToQS, std::remove_cvref_t<Q>::unit> r;
@@ -56,7 +56,7 @@ concept Quantity = requires(T* t) { detail::to_base_specialization_of_quantity(t
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)>> && implicitly_convertible_to(Q::quantity_spec, V)));
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible(Q::quantity_spec, V)));
/**
* @brief A concept matching all external quantities like types
@@ -68,7 +68,7 @@ concept PointOrigin = QuantityPoint<T> || detail::is_derived_from_specialization
* Satisfied by all quantity point origins that are defined using a provided quantity specification.
*/
template<typename T, auto Q>
concept PointOriginFor = PointOrigin<T> && QuantitySpec<std::remove_const_t<decltype(Q)>> && Q == T::quantity_spec;
concept PointOriginFor = PointOrigin<T> && QuantitySpec<std::remove_const_t<decltype(Q)>> && implicitly_convertible(Q, T::quantity_spec);
template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
RepresentationOf<get_quantity_spec(R).character> Rep>
@@ -95,7 +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)>> && implicitly_convertible_to(QP::quantity_spec, V)) ||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible(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)>>));
+1 -1
View File
@@ -43,7 +43,7 @@ namespace detail {
* @tparam To a target quantity type to cast to
*/
template<Quantity To, auto R, typename Rep>
requires(castable_to(get_quantity_spec(R), To::quantity_spec)) &&
requires(castable(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?
+1 -1
View File
@@ -58,7 +58,7 @@ concept Harmonic = // exposition only
template<typename QFrom, typename QTo>
concept QuantityConvertibleTo = // exposition only
Quantity<QFrom> && Quantity<QTo> && implicitly_convertible_to(QFrom::quantity_spec, QTo::quantity_spec) &&
Quantity<QFrom> && Quantity<QTo> && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) &&
convertible_to(QFrom::unit, QTo::unit) && requires(QFrom q) { detail::sudo_cast<QTo>(q); } &&
(treat_as_floating_point<typename QTo::rep> ||
(!treat_as_floating_point<typename QFrom::rep> && Harmonic<QFrom::unit, QTo::unit>));
+17 -18
View File
@@ -323,12 +323,12 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
#ifdef __cpp_explicit_this_parameter
template<detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
one_of<quantity_character> auto... Args>
requires requires { QS._equation_; } && (implicitly_convertible_to(Eq, QS._equation_))
requires requires { QS._equation_; } && (implicitly_convertible(Eq, QS._equation_))
struct quantity_spec<QS, Eq, Args...> : quantity_spec<QS, Args...> {
#else
template<typename Self, detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
auto... Args>
requires requires { QS._equation_; } && (implicitly_convertible_to(Eq, QS._equation_))
requires requires { QS._equation_; } && (implicitly_convertible(Eq, QS._equation_))
struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
#endif
static constexpr auto _equation_ = Eq;
@@ -684,7 +684,7 @@ template<ratio Complexity, IntermediateDerivedQuantitySpec Q>
}
template<QuantitySpec Q1, QuantitySpec Q2>
[[nodiscard]] consteval convertible_to_result convertible_to_impl(Q1 q1, Q2 q2)
[[nodiscard]] consteval convertible_to_result convertible_impl(Q1 q1, Q2 q2)
{
using enum convertible_to_result;
@@ -695,9 +695,9 @@ template<QuantitySpec Q1, QuantitySpec Q2>
else if constexpr (QuantityKindSpec<Q1> || QuantityKindSpec<Q2>) {
if constexpr (IntermediateDerivedQuantitySpec<Q1> &&
NamedQuantitySpec<std::remove_const_t<decltype(remove_kind(q2))>>)
return convertible_to_impl(get_kind(q1), remove_kind(q2));
return convertible_impl(get_kind(q1), remove_kind(q2));
else
return convertible_to_impl(get_kind(q1), get_kind(q2)) != no ? yes : no;
return convertible_impl(get_kind(q1), get_kind(q2)) != no ? yes : no;
} else if constexpr (IntermediateDerivedQuantitySpec<Q1> && IntermediateDerivedQuantitySpec<Q2>)
return are_ingredients_convertible_to(q1, q2);
else if constexpr (NamedQuantitySpec<Q1> && NamedQuantitySpec<Q2>) {
@@ -710,15 +710,15 @@ template<QuantitySpec Q1, QuantitySpec Q2>
} else if constexpr (IntermediateDerivedQuantitySpec<Q1>) {
auto q1_exploded = explode<get_complexity(q2)>(q1);
if constexpr (NamedQuantitySpec<std::remove_const_t<decltype(q1_exploded)>>)
return convertible_to_impl(q1_exploded, q2);
return convertible_impl(q1_exploded, q2);
else if constexpr (requires { q2._equation_; })
return convertible_to_impl(q1_exploded, q2._equation_);
return convertible_impl(q1_exploded, q2._equation_);
} else if constexpr (IntermediateDerivedQuantitySpec<Q2>) {
auto q2_exploded = explode<get_complexity(q1)>(q2);
if constexpr (NamedQuantitySpec<std::remove_const_t<decltype(q2_exploded)>>)
return convertible_to_impl(q2_exploded, q1);
return convertible_impl(q1, q2_exploded);
else if constexpr (requires { q1._equation_; })
return std::min(explicit_conversion, convertible_to_impl(q1._equation_, q2_exploded));
return std::min(explicit_conversion, convertible_impl(q1._equation_, q2_exploded));
}
return no;
}
@@ -726,21 +726,21 @@ template<QuantitySpec Q1, QuantitySpec Q2>
} // namespace detail
template<QuantitySpec Q1, QuantitySpec Q2>
[[nodiscard]] consteval bool implicitly_convertible_to(Q1 q1, Q2 q2)
[[nodiscard]] consteval bool implicitly_convertible(Q1 q1, Q2 q2)
{
return detail::convertible_to_impl(q1, q2) == detail::convertible_to_result::yes;
return detail::convertible_impl(q1, q2) == detail::convertible_to_result::yes;
}
template<QuantitySpec Q1, QuantitySpec Q2>
[[nodiscard]] consteval bool explicitly_convertible_to(Q1 q1, Q2 q2)
[[nodiscard]] consteval bool explicitly_convertible(Q1 q1, Q2 q2)
{
return detail::convertible_to_impl(q1, q2) >= detail::convertible_to_result::explicit_conversion;
return detail::convertible_impl(q1, q2) >= detail::convertible_to_result::explicit_conversion;
}
template<QuantitySpec Q1, QuantitySpec Q2>
[[nodiscard]] consteval bool castable_to(Q1 q1, Q2 q2)
[[nodiscard]] consteval bool castable(Q1 q1, Q2 q2)
{
return detail::convertible_to_impl(q1, q2) >= detail::convertible_to_result::cast;
return detail::convertible_impl(q1, q2) >= detail::convertible_to_result::cast;
}
namespace detail {
@@ -783,14 +783,13 @@ template<QuantitySpec Q>
template<QuantitySpec Q1, QuantitySpec Q2>
[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(Q1 q1, Q2 q2)
requires(implicitly_convertible_to(get_kind(q1), get_kind(q2)) ||
implicitly_convertible_to(get_kind(q2), get_kind(q1)))
requires(implicitly_convertible(get_kind(q1), get_kind(q2)) || implicitly_convertible(get_kind(q2), get_kind(q1)))
{
if constexpr (q1 == q2)
return q1;
else if constexpr (detail::have_common_base(q1, q2))
return detail::get_common_base(q1, q2);
else if constexpr (implicitly_convertible_to(get_kind(q1), get_kind(q2)))
else if constexpr (implicitly_convertible(get_kind(q1), get_kind(q2)))
return get_kind(q2);
else
return get_kind(q1);
+3 -3
View File
@@ -122,19 +122,19 @@ struct reference {
template<auto Q2, auto U2>
[[nodiscard]] friend consteval bool convertible_to(reference, reference<Q2, U2>)
{
return implicitly_convertible_to(Q, Q2) && convertible_to(U, U2);
return implicitly_convertible(Q, Q2) && convertible_to(U, U2);
}
template<AssociatedUnit U2>
[[nodiscard]] friend consteval bool convertible_to(reference, U2 u2)
{
return implicitly_convertible_to(Q, get_quantity_spec(u2)) && convertible_to(U, u2);
return implicitly_convertible(Q, get_quantity_spec(u2)) && convertible_to(U, u2);
}
template<AssociatedUnit U1>
[[nodiscard]] friend consteval bool convertible_to(U1 u1, reference)
{
return implicitly_convertible_to(get_quantity_spec(u1), Q) && convertible_to(u1, U);
return implicitly_convertible(get_quantity_spec(u1), Q) && convertible_to(u1, U);
}
};