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); };
/**
* @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
* the provided dimension/reference type.
* Satisfied by all quantities with a dimension/quantity_spec being the instantiation derived from
* the provided dimension/quantity_spec type.
*/
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(Q::quantity_spec, V)));
concept QuantityOf = Quantity<Q> && ReferenceOf<std::remove_const_t<decltype(Q::reference)>, V>;
/**
* @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.
*/
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,
RepresentationOf<get_quantity_spec(R).character> Rep>
@@ -86,16 +87,16 @@ inline constexpr bool is_quantity_point<T> = true;
} // 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
* the provided dimension/reference type.
* Satisfied by all quantity points with a dimension/quantity_spec being the instantiation derived from
* the provided dimension/quantity_spec type, or quantity points having the origin with the same
* `absolute_point_origin`.
*/
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(QP::quantity_spec, V)) ||
(ReferenceOf<std::remove_const_t<decltype(QP::reference)>, 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)>>));

View File

@@ -48,4 +48,32 @@ inline constexpr bool is_specialization_of_reference<reference<Q, U>> = true;
template<typename 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

View File

@@ -34,20 +34,6 @@ namespace mp_units {
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
*