mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-29 18:07:16 +02:00
feat: conversion helpers from mp-units
to std::chrono
types added
Resolves #316
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
- refactor: `quantity` `op+()` and `op-()` reimplemented in terms of `reference` rather then `quantity` types
|
||||
- feat: `std::format` support for compliant compilers added
|
||||
- feat: HEP system support added (thanks [@RalphSteinhagen](https://github.com/RalphSteinhagen))
|
||||
- feat: conversion helpers from `mp-units` to `std::chrono` types added
|
||||
- (!) fix: add `quantity_point::origin`, like `std::chrono::time_point::clock`
|
||||
- fix: account for different dimensions in `quantity_point_cast`'s constraint
|
||||
- build: Minimum Conan version changed to 1.40
|
||||
|
@ -65,3 +65,26 @@ provide a deduction guide from `QuantityPointLike`::
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static_assert((quantity_point{std::chrono::sys_seconds{1s}} + 1 * s).relative() == 2s);
|
||||
|
||||
|
||||
Interoperability with the C++ Standard Library
|
||||
----------------------------------------------
|
||||
|
||||
The above ``std::chrono``-specific customization points are already predefined in the ``mp-units``
|
||||
library for both ``std::chrono::duration`` as well as ``std::chrono::time_point``.
|
||||
They are provided in a dedicated header file::
|
||||
|
||||
#include <units/chrono.h>
|
||||
|
||||
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 = /* ... */
|
||||
|
@ -58,6 +58,36 @@ namespace detail {
|
||||
template<typename C, typename Rep, typename Period>
|
||||
inline constexpr bool is_quantity_point_like<std::chrono::time_point<C, std::chrono::duration<Rep, Period>>> = true;
|
||||
|
||||
constexpr std::intmax_t pow_10(std::intmax_t v)
|
||||
{
|
||||
gsl_Expects(v > 0);
|
||||
std::intmax_t res = 1;
|
||||
for(std::intmax_t i = 0; i < v; i++)
|
||||
res *= 10;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<ratio R>
|
||||
constexpr auto to_std_ratio_impl()
|
||||
{
|
||||
if constexpr(R.exp == 0)
|
||||
return std::ratio<R.num, R.den>{};
|
||||
else if constexpr(R.exp > 0)
|
||||
return std::ratio<R.num * pow_10(R.exp), R.den>{};
|
||||
else
|
||||
return std::ratio<R.num, R.den * pow_10(-R.exp)>{};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// TODO ICE below on gcc-11 when `ratio` is used instead of `auto`
|
||||
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)
|
||||
{
|
||||
return std::chrono::duration<typename Q::rep, to_std_ratio<Q::unit::ratio>>(q.number());
|
||||
}
|
||||
|
||||
} // namespace units
|
||||
|
@ -90,4 +90,12 @@ 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
|
||||
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(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>);
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user