refactor: 💥 quantity_point_like_traits now use numerical value instead of the quantity

Resolves #531
This commit is contained in:
Mateusz Pusz committed 2024-07-04 16:40:40 +01:00
1 parent 360eb85d09
commit 5903e5661f
6 files changed
+50 -53

No files matched your search

@@ -174,9 +174,9 @@ struct quantity_like_traits;
* @brief Provides support for external quantity point-like types
*
* The type trait should provide nested @c reference and @c origin objects,
* a type alias @c rep, and static member functions @c to_quantity(T) that returns
* the quantity being the offset of the point from the origin and
* @c from_quantity(quantity<reference, rep>) that returns @c T form this quantity.
* a type alias @c rep, and static member functions @c to_numerical_value(T) that
* returns the raw value of the the quantity being the offset of the point from the
* origin and @c from_numerical_value(rep) that returns @c T formed this raw value.
* Both return types should be encapsulated in either @c convert_explicitly or
* @c convert_implicitly to specify if the conversion is allowed to happen implicitly.
*
@@ -201,13 +201,14 @@ public:
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>,
quantity_type>
constexpr explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())),
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_numerical_value(std::declval<QP>())),
convert_explicitly> ||
!std::convertible_to<
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>, quantity_type>)
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
quantity_point(const QP& qp) :
quantity_from_origin_is_an_implementation_detail_(quantity_point_like_traits<QP>::to_quantity(qp).value)
quantity_from_origin_is_an_implementation_detail_(quantity_point_like_traits<QP>::to_numerical_value(qp).value,
get_unit(quantity_point_like_traits<QP>::reference))
{
}
@@ -297,16 +298,20 @@ public:
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
decltype(quantity_point_like_traits<QP>::from_numerical_value(
quantity_from_origin_is_an_implementation_detail_.numerical_value_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
operator QP_() const& noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
noexcept(quantity_point_like_traits<QP>::from_numerical_value(
quantity_from_origin_is_an_implementation_detail_.numerical_value_is_an_implementation_detail_)) &&
std::is_nothrow_copy_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_).value;
return quantity_point_like_traits<QP>::from_numerical_value(
quantity_from_origin_is_an_implementation_detail_.numerical_value_is_an_implementation_detail_)
.value;
}
template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>>
@@ -315,16 +320,19 @@ public:
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
decltype(quantity_point_like_traits<QP>::from_numerical_value(
quantity_from_origin_is_an_implementation_detail_.numerical_value_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
operator QP_() && noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
noexcept(quantity_point_like_traits<QP>::from_numerical_value(
quantity_from_origin_is_an_implementation_detail_.numerical_value_is_an_implementation_detail_)) &&
std::is_nothrow_move_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_is_an_implementation_detail_))
return quantity_point_like_traits<QP>::from_numerical_value(
std::move(quantity_from_origin_is_an_implementation_detail_).numerical_value_is_an_implementation_detail_)
.value;
}
@@ -387,11 +395,10 @@ template<Quantity Q, PointOriginFor<Q::quantity_spec> PO>
quantity_point(Q q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>;
template<QuantityPointLike QP>
explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())), convert_explicitly>)
quantity_point(QP)
-> quantity_point<quantity_point_like_traits<QP>::reference, quantity_point_like_traits<QP>::point_origin,
typename quantity_point_like_traits<QP>::rep>;
explicit(is_specialization_of<decltype(quantity_point_like_traits<QP>::to_numerical_value(std::declval<QP>())),
convert_explicitly>) quantity_point(QP)
-> quantity_point<quantity_point_like_traits<QP>::reference, quantity_point_like_traits<QP>::point_origin,
typename quantity_point_like_traits<QP>::rep>;
template<auto R1, auto PO1, typename Rep1, auto R2, typename Rep2>
// TODO simplify when gcc catches up
@@ -159,14 +159,12 @@ concept QuantityPointLike = requires {
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, quantity<quantity_point_like_traits<T>::reference, typename quantity_point_like_traits<T>::rep> q) {
} && requires(T qp, typename quantity_point_like_traits<T>::rep v) {
{
quantity_point_like_traits<T>::to_quantity(qp)
} -> detail::ConversionSpecOf<
quantity<quantity_point_like_traits<T>::reference, typename quantity_point_like_traits<T>::rep>>;
quantity_point_like_traits<T>::to_numerical_value(qp)
} -> detail::ConversionSpecOf<typename quantity_point_like_traits<T>::rep>;
{
quantity_point_like_traits<T>::from_quantity(q)
quantity_point_like_traits<T>::from_numerical_value(v)
} -> detail::ConversionSpecOf<T>;
};
@@ -100,16 +100,16 @@ struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::durati
static constexpr auto point_origin = chrono_point_origin<C>;
using rep = Rep;
[[nodiscard]] static constexpr convert_implicitly<quantity<reference, rep>> to_quantity(const T& qp) noexcept(
[[nodiscard]] static constexpr convert_implicitly<rep> to_numerical_value(const T& tp) noexcept(
std::is_nothrow_copy_constructible_v<rep>)
{
return quantity{qp.time_since_epoch()};
return tp.time_since_epoch().count();
}
[[nodiscard]] static constexpr convert_implicitly<T> from_quantity(const quantity<reference, rep>& q) noexcept(
[[nodiscard]] static constexpr convert_implicitly<T> from_numerical_value(const rep& v) noexcept(
std::is_nothrow_copy_constructible_v<rep>)
{
return T(q);
return T(std::chrono::duration<Rep, Period>(v));
}
};