mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 10:27: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
|
- refactor: `quantity` `op+()` and `op-()` reimplemented in terms of `reference` rather then `quantity` types
|
||||||
- feat: `std::format` support for compliant compilers added
|
- feat: `std::format` support for compliant compilers added
|
||||||
- feat: HEP system support added (thanks [@RalphSteinhagen](https://github.com/RalphSteinhagen))
|
- 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: add `quantity_point::origin`, like `std::chrono::time_point::clock`
|
||||||
- fix: account for different dimensions in `quantity_point_cast`'s constraint
|
- fix: account for different dimensions in `quantity_point_cast`'s constraint
|
||||||
- build: Minimum Conan version changed to 1.40
|
- build: Minimum Conan version changed to 1.40
|
||||||
|
@ -65,3 +65,26 @@ provide a deduction guide from `QuantityPointLike`::
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
static_assert((quantity_point{std::chrono::sys_seconds{1s}} + 1 * s).relative() == 2s);
|
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>
|
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;
|
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
|
} // 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
|
} // 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_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});
|
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
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user