namespace std {
template<typename Rep, typename Period>
ostream& operator<<(ostream& m, const chrono::duration<Rep, Period>& t) {
- if constexpr (chrono::treat_as_floating_point_v<Rep>) {
+ if constexpr (chrono::treat_as_floating_point_v<Rep> ||
+ Period::den > 1) {
using seconds_t = chrono::duration<float>;
::fmt::print(m, "{:.9}", chrono::duration_cast<seconds_t>(t));
} else {
ASSERT_TRUE(s[26] == '-' || s[26] == '+');
ASSERT_EQ(s.substr(0, 9), "2019-04-2");
}
+
+namespace {
+ template<typename Rep, typename Period>
+ std::string to_string(const chrono::duration<Rep, Period>& t)
+ {
+ std::ostringstream ss;
+ ss << t;
+ return ss.str();
+ }
+
+ void float_format_eq(string_view lhs,
+ string_view rhs,
+ unsigned precision)
+ {
+ const float TOLERANCE = 10.0F / pow(10.0F, static_cast<float>(precision));
+ ASSERT_FALSE(lhs.empty());
+ ASSERT_EQ(lhs.back(), 's');
+ float lhs_v = std::stof(string{lhs, 0, lhs.find('s')});
+ ASSERT_NE(lhs.npos, lhs.find('.'));
+ ASSERT_EQ(precision, lhs.find('s') - lhs.find('.') - 1);
+
+ ASSERT_FALSE(rhs.empty());
+ ASSERT_EQ(rhs.back(), 's');
+ float rhs_v = std::stof(string{rhs, 0, rhs.find('s')});
+ EXPECT_NEAR(lhs_v, rhs_v, TOLERANCE);
+ ASSERT_NE(rhs.npos, rhs.find('.'));
+ EXPECT_EQ(precision, rhs.find('s') - rhs.find('.') - 1);
+ }
+}
+
+TEST(TimeDurations, print) {
+ float_format_eq("0.123456700s",
+ to_string(std::chrono::duration_cast<ceph::timespan>(0.1234567s)),
+ 9);
+ float_format_eq("-0.123456700s",
+ to_string(std::chrono::duration_cast<ceph::signedspan>(-0.1234567s)),
+ 9);
+ EXPECT_EQ("42s", to_string(42s));
+ float_format_eq("0.123000000s", to_string(123ms), 9);
+}