forked from mpusz/mp-units
Merge branch 'master' of github.com:mpusz/units
This commit is contained in:
@@ -264,6 +264,9 @@ inline constexpr bool is_quantity_point_kind = false;
|
||||
template<typename T>
|
||||
inline constexpr bool is_quantity_like = false;
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_quantity_point_like = false;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
@@ -298,7 +301,7 @@ concept QuantityKind = detail::is_quantity_kind<T>;
|
||||
template<typename T>
|
||||
concept QuantityPointKind = detail::is_quantity_point_kind<T>;
|
||||
|
||||
// QuantityLike
|
||||
// QuantityLike, QuantityPointLike
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantity-like types (other than specialization of @c quantity)
|
||||
@@ -309,6 +312,15 @@ concept QuantityPointKind = detail::is_quantity_point_kind<T>;
|
||||
template<typename T>
|
||||
concept QuantityLike = detail::is_quantity_like<T>;
|
||||
|
||||
/**
|
||||
* @brief A concept matching all quantity point-like types (other than specialization of @c quantity_point)
|
||||
*
|
||||
* Satisfied by all types for which a correct specialization of `quantity_point_like_traits`
|
||||
* type trait is provided.
|
||||
*/
|
||||
template<typename T>
|
||||
concept QuantityPointLike = detail::is_quantity_point_like<T>;
|
||||
|
||||
// QuantityValue
|
||||
|
||||
template<typename T, typename U>
|
||||
@@ -390,6 +402,18 @@ template<typename T>
|
||||
}
|
||||
inline constexpr bool is_quantity_like<T> = true;
|
||||
|
||||
template<typename T>
|
||||
requires requires(T q) {
|
||||
typename quantity_point_like_traits<T>::dimension;
|
||||
typename quantity_point_like_traits<T>::unit;
|
||||
typename quantity_point_like_traits<T>::rep;
|
||||
requires Dimension<typename quantity_point_like_traits<T>::dimension>;
|
||||
requires Unit<typename quantity_point_like_traits<T>::unit>;
|
||||
requires QuantityValue<typename quantity_point_like_traits<T>::rep>;
|
||||
{ quantity_point_like_traits<T>::relative(q) } -> QuantityLike;
|
||||
}
|
||||
inline constexpr bool is_quantity_point_like<T> = true;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace units
|
||||
|
||||
@@ -36,4 +36,15 @@ struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
|
||||
[[nodiscard]] static constexpr rep count(const std::chrono::duration<Rep, Period>& q) { return q.count(); }
|
||||
};
|
||||
|
||||
template<typename C, typename Rep, typename Period>
|
||||
struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::duration<Rep, Period>>> {
|
||||
using dimension = physical::si::dim_time;
|
||||
using unit = downcast_unit<dimension, ratio(Period::num, Period::den)>;
|
||||
using rep = Rep;
|
||||
[[nodiscard]] static constexpr auto relative(
|
||||
const std::chrono::time_point<C, std::chrono::duration<Rep, Period>>& qp) {
|
||||
return qp.time_since_epoch();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace units
|
||||
|
||||
@@ -85,4 +85,17 @@ struct quantity_values {
|
||||
template<typename T>
|
||||
struct quantity_like_traits;
|
||||
|
||||
/**
|
||||
* @brief Provides support for external quantity point-like types
|
||||
*
|
||||
* The type trait should provide the following nested type aliases: @c dimension, @c unit, @c rep,
|
||||
* and a static member function @c relative(T) that will return the quantity-like value of the quantity point.
|
||||
*
|
||||
* Usage example can be found in @c units/chrono.h header file.
|
||||
*
|
||||
* @tparam T the type to provide support for
|
||||
*/
|
||||
template<typename T>
|
||||
struct quantity_point_like_traits;
|
||||
|
||||
} // namespace units
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
using quantity_point_like_type = quantity_point<typename quantity_point_like_traits<QP>::dimension,
|
||||
typename quantity_point_like_traits<QP>::unit, typename quantity_point_like_traits<QP>::rep>;
|
||||
|
||||
/**
|
||||
* @brief A quantity point
|
||||
*
|
||||
@@ -63,6 +67,11 @@ public:
|
||||
requires std::is_constructible_v<quantity_type, Q>
|
||||
constexpr explicit quantity_point(const Q& q) : q_{q} {}
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
constexpr explicit quantity_point(const QP& qp)
|
||||
requires std::is_constructible_v<quantity_type, decltype(quantity_point_like_traits<QP>::relative(qp))>
|
||||
: q_{quantity_point_like_traits<QP>::relative(qp)} {}
|
||||
|
||||
template<QuantityPoint QP2>
|
||||
requires std::is_convertible_v<typename QP2::quantity_type, quantity_type>
|
||||
constexpr quantity_point(const QP2& qp) : q_{qp.relative()} {}
|
||||
@@ -182,6 +191,9 @@ template<QuantityLike Q>
|
||||
quantity_point(Q) -> quantity_point<typename quantity_like_traits<Q>::dimension,
|
||||
typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
explicit quantity_point(QP) -> quantity_point_like_type<QP>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
|
||||
@@ -67,6 +67,10 @@ public:
|
||||
requires std::is_constructible_v<quantity_type, Q>
|
||||
constexpr explicit quantity_point_kind(const Q& q) : qk_{q} {}
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
requires std::is_constructible_v<quantity_point<dimension, U, Rep>, QP>
|
||||
constexpr explicit quantity_point_kind(const QP& qp) : qk_{quantity_point_like_traits<QP>::relative(qp)} {}
|
||||
|
||||
constexpr explicit quantity_point_kind(const quantity_point<dimension, U, Rep>& qp) : qk_{qp.relative()} {}
|
||||
|
||||
constexpr explicit quantity_point_kind(const quantity_kind_type& qk) : qk_{qk} {}
|
||||
|
||||
Reference in New Issue
Block a user