mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 12:24:26 +02:00
feat: conversion from quantity_point
to std::chrono::time_point
added
Refers #316
This commit is contained in:
@@ -79,12 +79,47 @@ They are provided in a dedicated header file::
|
||||
The same header file provides additional conversion helpers from ``mp-units`` to
|
||||
the C++ Standard Library types:
|
||||
|
||||
- an explicit conversion of `quantity` to ``std::chrono::duration``::
|
||||
|
||||
template<QuantityOf<isq::si::dim_time> Q>
|
||||
constexpr auto to_std_duration(const Q& q);
|
||||
|
||||
- an alias that provides a conversion from `ratio` to ``std::ratio``::
|
||||
|
||||
template<ratio R>
|
||||
using to_std_ratio = /* ... */
|
||||
|
||||
- an explicit conversion of `quantity` of `isq::si::dim_time` to ``std::chrono::duration``::
|
||||
|
||||
template<typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto to_std_duration(const quantity<isq::si::dim_time, U, Rep>& q)
|
||||
|
||||
- an explicit conversion of `quantity_point` that previously originated from ``std::chrono``
|
||||
to ``std::chrono::time_point``::
|
||||
|
||||
template<typename C, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto to_std_time_point(const quantity_point<clock_origin<C>, U, Rep>& qp)
|
||||
|
||||
.. note::
|
||||
|
||||
Only `quantity_point` that was created from a ``std::chrono::time_point`` of a specific
|
||||
``std::chrono`` clock can be converted back to ``std::chrono`` domain::
|
||||
|
||||
const auto qp1 = quantity_point{sys_seconds{1s}};
|
||||
const auto tp1 = to_std_time_point(qp1); // OK
|
||||
|
||||
conat auto qp2 = quantity_point{1 * s};
|
||||
const auto tp2 = to_std_time_point(qp2); // Compile-time Error
|
||||
|
||||
Here is an example of how interoperatibility described in this chapter can be used in practice::
|
||||
|
||||
using namespace units::aliases::isq::si;
|
||||
using timestamp = quantity_point<clock_origin<std::chrono::system_clock>, si::second>;
|
||||
|
||||
const auto start_time = timestamp(std::chrono::system_clock::now()); // std::chrono -> units
|
||||
const auto velocity = speed::km_per_h<>(825);
|
||||
const auto distance = length::km<>(8111);
|
||||
const auto flight_time = distance / velocity;
|
||||
const auto exp_end_time = start_time + flight_time;
|
||||
|
||||
const auto tp = to_std_time_point(exp_end_time); // units -> std::chrono
|
||||
const auto tp_sec = std::chrono::floor<std::chrono::seconds>(tp);
|
||||
const auto tp_days = std::chrono::floor<std::chrono::days>(tp_sec);
|
||||
const auto ymd = std::chrono::year_month_day(tp_days);
|
||||
const auto tod = tp_sec - tp_days;
|
||||
const auto hms = std::chrono::hh_mm_ss(tod);
|
||||
|
@@ -47,8 +47,7 @@ struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::durati
|
||||
using origin = clock_origin<C>;
|
||||
using unit = downcast_unit<typename origin::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) {
|
||||
[[nodiscard]] static constexpr auto relative(const std::chrono::time_point<C, std::chrono::duration<Rep, Period>>& qp) {
|
||||
return qp.time_since_epoch();
|
||||
}
|
||||
};
|
||||
@@ -84,10 +83,17 @@ constexpr auto to_std_ratio_impl()
|
||||
template<auto R>
|
||||
using to_std_ratio = decltype(detail::to_std_ratio_impl<R>());
|
||||
|
||||
template<QuantityOf<isq::si::dim_time> Q>
|
||||
constexpr auto to_std_duration(const Q& q)
|
||||
template<typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto to_std_duration(const quantity<isq::si::dim_time, U, Rep>& q)
|
||||
{
|
||||
return std::chrono::duration<typename Q::rep, to_std_ratio<Q::unit::ratio>>(q.number());
|
||||
return std::chrono::duration<Rep, to_std_ratio<U::ratio>>(q.number());
|
||||
}
|
||||
|
||||
template<typename C, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto to_std_time_point(const quantity_point<clock_origin<C>, U, Rep>& qp)
|
||||
{
|
||||
using ret_type = std::chrono::time_point<C, std::chrono::duration<Rep, to_std_ratio<U::ratio>>>;
|
||||
return ret_type(to_std_duration(qp.relative()));
|
||||
}
|
||||
|
||||
} // namespace units
|
||||
|
@@ -90,12 +90,19 @@ static_assert(10_q_m / quantity{2s} == 5_q_m_per_s);
|
||||
static_assert(quantity_point{sys_seconds{1s}} + 1_q_s == time_point<std::chrono::system_clock, si::second>{2_q_s});
|
||||
static_assert(quantity_point{sys_seconds{1s}} + 1_q_min == time_point<std::chrono::system_clock, si::second>{61_q_s});
|
||||
|
||||
// to_duration
|
||||
// to_std_duration
|
||||
static_assert(to_std_duration(1_q_s) == 1s);
|
||||
static_assert(to_std_duration(2_q_h) == 2h);
|
||||
static_assert(to_std_duration(3_q_ns) == 3ns);
|
||||
static_assert(to_std_duration(quantity{1s}) == 1s);
|
||||
static_assert(to_std_duration(quantity{2h}) == 2h);
|
||||
static_assert(to_std_duration(quantity{3ns}) == 3ns);
|
||||
static_assert(is_same_v<decltype(to_std_duration(1_q_s))::period, std::ratio<1>>);
|
||||
static_assert(is_same_v<decltype(to_std_duration(2_q_h))::period, std::ratio<3600>>);
|
||||
static_assert(is_same_v<decltype(to_std_duration(3_q_ns))::period, std::nano>);
|
||||
|
||||
// to_std_time_point
|
||||
static_assert(to_std_time_point(quantity_point{sys_seconds{1s}}) == sys_seconds{1s});
|
||||
static_assert(to_std_time_point(quantity_point{sys_days{sys_days::duration{1}}}) == sys_days{sys_days::duration{1}});
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user