feat: ReferenceOf concept added

This commit is contained in:
Mateusz Pusz
2023-05-14 09:35:18 +02:00
parent 27cd47b7af
commit c33e3a584d
4 changed files with 39 additions and 26 deletions

View File

@@ -48,15 +48,13 @@ template<typename T>
concept Quantity = requires(T* t) { detail::to_base_specialization_of_quantity(t); }; concept Quantity = requires(T* t) { detail::to_base_specialization_of_quantity(t); };
/** /**
* @brief A concept matching all quantities with provided dimension or reference * @brief A concept matching all quantities with provided dimension or quantity spec
* *
* Satisfied by all quantities with a dimension/reference being the instantiation derived from * Satisfied by all quantities with a dimension/quantity_spec being the instantiation derived from
* the provided dimension/reference type. * the provided dimension/quantity_spec type.
*/ */
template<typename Q, auto V> template<typename Q, auto V>
concept QuantityOf = concept QuantityOf = Quantity<Q> && ReferenceOf<std::remove_const_t<decltype(Q::reference)>, V>;
Quantity<Q> && ((Dimension<std::remove_const_t<decltype(V)>> && Q::dimension == V) ||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible(Q::quantity_spec, V)));
/** /**
* @brief A concept matching all external quantities like types * @brief A concept matching all external quantities like types

View File

@@ -68,7 +68,8 @@ concept PointOrigin = QuantityPoint<T> || detail::is_derived_from_specialization
* Satisfied by all quantity point origins that are defined using a provided quantity specification. * Satisfied by all quantity point origins that are defined using a provided quantity specification.
*/ */
template<typename T, auto Q> template<typename T, auto Q>
concept PointOriginFor = PointOrigin<T> && QuantitySpec<std::remove_const_t<decltype(Q)>> && implicitly_convertible(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, template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
RepresentationOf<get_quantity_spec(R).character> Rep> RepresentationOf<get_quantity_spec(R).character> Rep>
@@ -86,16 +87,16 @@ inline constexpr bool is_quantity_point<T> = true;
} // namespace detail } // namespace detail
/** /**
* @brief A concept matching all quantity points with provided dimension or reference * @brief A concept matching all quantity points with provided dimension or quantity spec
* *
* Satisfied by all quantity points with a dimension/reference being the instantiation derived from * Satisfied by all quantity points with a dimension/quantity_spec being the instantiation derived from
* the provided dimension/reference type. * the provided dimension/quantity_spec type, or quantity points having the origin with the same
* `absolute_point_origin`.
*/ */
template<typename QP, auto V> template<typename QP, auto V>
concept QuantityPointOf = concept QuantityPointOf =
QuantityPoint<QP> && QuantityPoint<QP> &&
((Dimension<std::remove_const_t<decltype(V)>> && QP::dimension == V) || (ReferenceOf<std::remove_const_t<decltype(QP::reference)>, V> ||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible(QP::quantity_spec, V)) ||
(PointOrigin<std::remove_const_t<decltype(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)>>)); std::same_as<std::remove_const_t<decltype(QP::absolute_point_origin)>, std::remove_const_t<decltype(V)>>));

View File

@@ -48,4 +48,32 @@ inline constexpr bool is_specialization_of_reference<reference<Q, U>> = true;
template<typename T> template<typename T>
concept Reference = AssociatedUnit<T> || detail::is_specialization_of_reference<T>; concept Reference = AssociatedUnit<T> || detail::is_specialization_of_reference<T>;
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u);
template<auto Q, auto U>
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference<Q, U>)
{
return Q;
}
[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; }
template<auto Q, auto U>
[[nodiscard]] consteval Unit auto get_unit(reference<Q, U>)
{
return U;
}
/**
* @brief A concept matching all references with provided dimension or quantity spec
*
* Satisfied by all references with a dimension/quantity_spec being the instantiation derived from
* the provided dimension/quantity_spec type.
*/
template<typename T, auto V>
concept ReferenceOf =
Reference<T> &&
((Dimension<std::remove_const_t<decltype(V)>> && get_quantity_spec(T{}).dimension == V) ||
(QuantitySpec<std::remove_const_t<decltype(V)>> && implicitly_convertible(get_quantity_spec(T{}), V)));
} // namespace mp_units } // namespace mp_units

View File

@@ -34,20 +34,6 @@ namespace mp_units {
return detail::get_associated_quantity(u); return detail::get_associated_quantity(u);
} }
template<auto Q, auto U>
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference<Q, U>)
{
return Q;
}
[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; }
template<auto Q, auto U>
[[nodiscard]] consteval Unit auto get_unit(reference<Q, U>)
{
return U;
}
/** /**
* @brief Quantity reference type * @brief Quantity reference type
* *