Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): factor out common quantity-like requirements #627

Open
JohelEGP opened this issue Oct 14, 2024 · 2 comments
Open

refactor(core): factor out common quantity-like requirements #627

JohelEGP opened this issue Oct 14, 2024 · 2 comments

Comments

@JohelEGP
Copy link
Collaborator

Title: refactor(core): factor out common quantity-like requirements

Description:

QuantityLike and QuantityPointLike share many requirements:

template<typename T>
concept QuantityLike = requires {
quantity_like_traits<T>::reference;
requires Reference<std::remove_const_t<decltype(quantity_like_traits<T>::reference)>>;
typename quantity_like_traits<T>::rep;
requires RepresentationOf<typename quantity_like_traits<T>::rep,
get_quantity_spec(quantity_like_traits<T>::reference).character>;
} && requires(T q, typename quantity_like_traits<T>::rep v) {
{ quantity_like_traits<T>::to_numerical_value(q) } -> detail::ConversionSpecOf<typename quantity_like_traits<T>::rep>;
{ quantity_like_traits<T>::from_numerical_value(v) } -> detail::ConversionSpecOf<T>;
};

MP_UNITS_EXPORT template<typename T>
concept QuantityPointLike = requires {
quantity_point_like_traits<T>::reference;
requires Reference<std::remove_const_t<decltype(quantity_point_like_traits<T>::reference)>>;
quantity_point_like_traits<T>::point_origin;
requires PointOrigin<std::remove_const_t<decltype(quantity_point_like_traits<T>::point_origin)>>;
typename quantity_point_like_traits<T>::rep;
requires RepresentationOf<typename quantity_point_like_traits<T>::rep,
get_quantity_spec(quantity_point_like_traits<T>::reference).character>;
} && requires(T qp, typename quantity_point_like_traits<T>::rep v) {
{
quantity_point_like_traits<T>::to_numerical_value(qp)
} -> detail::ConversionSpecOf<typename quantity_point_like_traits<T>::rep>;
{ quantity_point_like_traits<T>::from_numerical_value(v) } -> detail::ConversionSpecOf<T>;
};

I suggest factoring them out, for example:

template<typename T, template<typename> typename Traits>
concept detail::qty_like = requires(const T& qty, const Traits<T>::rep& num) {
  typename quantity<Traits<T>::reference, typename Traits<T>::rep>;
  { Traits<T>::to_numerical_value(qty) } -> std::same_as<typename Traits<T>::rep>;
  { Traits<T>::from_numerical_value(num) } -> std::same_as<T>;
  { Traits<T>::explicit_import } -> std::same_as<const bool>;
  { Traits<T>::explicit_export } -> std::same_as<const bool>;
  typename std::bool_constant<Traits<T>::explicit_import>;
  typename std::bool_constant<Traits<T>::explicit_export>;
};

template<typename T>
concept quantity_like = detail::qty_like<T, quantity_like_traits>;

template<typename T>
concept quantity_point_like =
  detail::qty_like<T, quantity_point_like_traits> &&  //
  requires {
    typename quantity_point<quantity_point_like_traits<T>::reference,
                            typename quantity_point_like_traits<T>::point_origin,
                            typename quantity_point_like_traits<T>::rep>;
  };

See also:

@JohelEGP
Copy link
Collaborator Author

Don't we need to restrict T to not be a specialization of quantity and quantity_point?

@mpusz
Copy link
Owner

mpusz commented Oct 14, 2024

Good points!

Interfaces were different, but we unified them with #531. I am fine with refactoring as long as we do not provide public subsumptions between those two concepts.

Don't we need to restrict T to not be a specialization of quantity and quantity_point?

Another good idea. But we should use derived_from_specialization_of instead, as some users do inherit from our types, and we already account for that in interfaces (e.g., operators).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants