From bc05d527ea6a04568b6a66fd68ad4960ecdb8977 Mon Sep 17 00:00:00 2001 From: Chip Hogg Date: Fri, 24 Nov 2023 20:14:48 -0500 Subject: [PATCH] Add `as_chrono_duration()` utility This makes it easy to convert any Au duration quantity to an exactly-equivalent `std::chrono::duration`. Fixes #187. --- au/au.hh | 10 ++++++++++ au/au_test.cc | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/au/au.hh b/au/au.hh index 5ff2d4d8..9f0a810d 100644 --- a/au/au.hh +++ b/au/au.hh @@ -34,4 +34,14 @@ struct CorrespondingQuantity> { static constexpr ChronoDuration construct_from_value(Rep x) { return ChronoDuration{x}; } }; +// Convert any Au duration quantity to an equivalent `std::chrono::duration`. +template +constexpr auto as_chrono_duration(Quantity dt) { + constexpr auto ratio = unit_ratio(U{}, seconds); + static_assert(is_rational(ratio), "Cannot convert to chrono::duration with non-rational ratio"); + return std::chrono::duration(numerator(ratio)), + get_value(denominator(ratio))>>{dt}; +} + } // namespace au diff --git a/au/au_test.cc b/au/au_test.cc index 3ec0170e..4ddb87d8 100644 --- a/au/au_test.cc +++ b/au/au_test.cc @@ -49,6 +49,13 @@ TEST(DurationQuantity, InterconvertsWithIndirectlyEquivalentChronoDuration) { EXPECT_THAT(from_chrono, SameTypeAndValue(seconds(1.234))); } +TEST(AsChronoDuration, ProducesExpectedResults) { + constexpr auto original = milli(seconds)(12.3f); + constexpr auto result = as_chrono_duration(original); + EXPECT_THAT(result.count(), SameTypeAndValue(12.3f)); + EXPECT_THAT(as_quantity(result), QuantityEquivalent(original)); +} + TEST(Conversions, SupportIntMHzToU32Hz) { constexpr QuantityU32 freq = mega(hertz)(40); EXPECT_THAT(freq, SameTypeAndValue(hertz(40'000'000u)));