From cf6ab6bb2b800fae859ccc735f398d22a7336a00 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Sun, 24 Sep 2017 08:20:48 -0700 Subject: Changes imported from Abseil "staging" branch: - b527a3e4b36b644ac424e3c525b1cd393f6f6c40 Fix some typos in the usage examples by Jorg Brown - 82be4a9adf3bb0ddafc0d46274969c99afffe870 Fix typo in optional.h comment. by Abseil Team - d6ee63bf8fc51fba074c23b33cebc28c808d7f07 Remove internal-only identifiers from code. by Daniel Katz - f9c3ad2f0d73f53b21603638af8b4bed636e79f4 Use easier understandable names for absl::StartsWith and ... by Abseil Team - 7c16c14fefee89c927b8789d6043c4691bcffc9b Add -Wno-missing-prototypes back to the LLVM copts. by Derek Mauro - 2f4b7d2e50c7023240242f1e15db60ccd7e8768d IWYU | absl/strings by Juemin Yang - a99cbcc1daa34a2d6a2bb26de275e05173cc77e9 IWYU | absl/type by Juemin Yang - 12e1146d0fc76c071d7e0ebaabb62f0a984fae66 Use LLVM_FLAGS and LLVM_TEST_FLAGS when --compiler=llvm. by Derek Mauro - cd6bea616abda558d0bace5bd77455662a233688 IWYU | absl/debugging by Juemin Yang - d9a7382e59d46a8581b6b7a31cd5a48bb89326e9 IWYU | absl/synchronization by Juemin Yang - 07ec7d6d5a4a666f4183c5d0ed9c342baa7b24bc IWYU | absl/numeric by Juemin Yang - 12bfe40051f4270f8707e191af5652f83f2f750c Remove the RoundTrip{Float,Double}ToBuffer routines from ... by Jorg Brown - eeb4fd67c9d97f66cb9475c3c5e51ab132f1c810 Adds conversion functions for converting between absl/tim... by Greg Miller - 59a2108d05d4ea85dc5cc11e49b2cd2335d4295a Change Substitute to use %.6g formatting rather than 15/1... by Jorg Brown - 394becb48e0fcd161642cdaac5120d32567e0ef8 IWYU | absl/meta by Juemin Yang - 1e5da6e8da336699b2469dcf6dda025b9b0ec4c9 Rewrite atomic_hook.h to not use std::atomic under Wi... by Greg Falcon GitOrigin-RevId: b527a3e4b36b644ac424e3c525b1cd393f6f6c40 Change-Id: I14e331d91c956ef045ac7927091a9f179716de0c --- absl/time/time.h | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) (limited to 'absl/time/time.h') diff --git a/absl/time/time.h b/absl/time/time.h index 302c76037e6f..6976343708be 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -361,7 +361,7 @@ Duration Hours(T n) { // Example: // // absl::Duration d = absl::Milliseconds(1500); -// int64_t isec = ToInt64Seconds(d); // isec == 1 +// int64_t isec = ToInt64Seconds(d); // isec == 1 int64_t ToInt64Nanoseconds(Duration d); int64_t ToInt64Microseconds(Duration d); int64_t ToInt64Milliseconds(Duration d); @@ -391,6 +391,46 @@ double ToDoubleSeconds(Duration d); double ToDoubleMinutes(Duration d); double ToDoubleHours(Duration d); +// FromChrono() +// +// Converts any of the pre-defined std::chrono durations to an absl::Duration. +// +// Example: +// +// std::chrono::milliseconds ms(123); +// absl::Duration d = absl::FromChrono(ms); +constexpr Duration FromChrono(const std::chrono::nanoseconds& d); +constexpr Duration FromChrono(const std::chrono::microseconds& d); +constexpr Duration FromChrono(const std::chrono::milliseconds& d); +constexpr Duration FromChrono(const std::chrono::seconds& d); +constexpr Duration FromChrono(const std::chrono::minutes& d); +constexpr Duration FromChrono(const std::chrono::hours& d); + +// ToChronoNanoseconds() +// ToChronoMicroseconds() +// ToChronoMilliseconds() +// ToChronoSeconds() +// ToChronoMinutes() +// ToChronoHours() +// +// Converts an absl::Duration to any of the pre-defined std::chrono durations. +// If overflow would occur, the returned value will saturate at the min/max +// chrono duration value instead. +// +// Example: +// +// absl::Duration d = absl::Microseconds(123); +// auto x = absl::ToChronoMicroseconds(d); +// auto y = absl::ToChronoNanoseconds(d); // x == y +// auto z = absl::ToChronoSeconds(absl::InfiniteDuration()); +// // z == std::chrono::seconds::max() +std::chrono::nanoseconds ToChronoNanoseconds(Duration d); +std::chrono::microseconds ToChronoMicroseconds(Duration d); +std::chrono::milliseconds ToChronoMilliseconds(Duration d); +std::chrono::seconds ToChronoSeconds(Duration d); +std::chrono::minutes ToChronoMinutes(Duration d); +std::chrono::hours ToChronoHours(Duration d); + // InfiniteDuration() // // Returns an infinite `Duration`. To get a `Duration` representing negative @@ -445,7 +485,7 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { bool ParseDuration(const std::string& dur_string, Duration* d); // Flag Support -// TODO(b/63899288) copybara strip once dependencies are removed. +// TODO(absl-team): Remove once dependencies are removed. // ParseFlag() // @@ -790,6 +830,30 @@ Time TimeFromTimeval(timeval tv); timespec ToTimespec(Time t); timeval ToTimeval(Time t); +// FromChrono() +// +// Converts a std::chrono::system_clock::time_point to an absl::Time. +// +// Example: +// +// auto tp = std::chrono::system_clock::from_time_t(123); +// absl::Time t = absl::FromChrono(tp); +// // t == absl::FromTimeT(123) +Time FromChrono(const std::chrono::system_clock::time_point& tp); + +// ToChronoTime() +// +// Converts an absl::Time to a std::chrono::system_clock::time_point. If +// overflow would occur, the returned value will saturate at the min/max time +// point value instead. +// +// Example: +// +// absl::Time t = absl::FromTimeT(123); +// auto tp = absl::ToChronoTime(t); +// // tp == std::chrono::system_clock::from_time_t(123); +std::chrono::system_clock::time_point ToChronoTime(absl::Time); + // RFC3339_full // RFC3339_sec // @@ -917,7 +981,7 @@ bool ParseTime(const std::string& format, const std::string& input, bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, Time* time, std::string* err); -// TODO(b/63899288) copybara strip once dependencies are removed. +// TODO(absl-team): Remove once dependencies are removed. // ParseFlag() // UnparseFlag() @@ -1072,6 +1136,81 @@ constexpr int64_t NegateAndSubtractOne(int64_t n) { // knowledge, we would need to add-in/subtract-out UnixEpoch() respectively. constexpr Time FromUnixDuration(Duration d) { return Time(d); } constexpr Duration ToUnixDuration(Time t) { return t.rep_; } + +template +constexpr absl::Duration FromInt64(int64_t v, std::ratio<1, N>) { + static_assert(0 < N && N <= 1000 * 1000 * 1000, "Unsupported ratio"); + // Subsecond ratios cannot overflow. + return MakeNormalizedDuration( + v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N); +} +constexpr absl::Duration FromInt64(int64_t v, std::ratio<60>) { + return Minutes(v); +} +constexpr absl::Duration FromInt64(int64_t v, std::ratio<3600>) { + return Hours(v); +} + +// IsValidRep64(0) is true if the expression `int64_t{std::declval()}` is +// valid. That is, if a T can be assigned to an int64_t without narrowing. +template +constexpr auto IsValidRep64(int) + -> decltype(int64_t{std::declval()}, bool()) { + return true; +} +template +constexpr auto IsValidRep64(char) -> bool { + return false; +} + +// Converts a std::chrono::duration to an absl::Duration. +template +constexpr absl::Duration FromChrono( + const std::chrono::duration& d) { + static_assert(IsValidRep64(0), "duration::rep is invalid"); + return FromInt64(int64_t{d.count()}, Period{}); +} + +template +int64_t ToInt64(absl::Duration d, Ratio) { + // Note: This may be used on MSVC, which may have a system_clock period of + // std::ratio<1, 10 * 1000 * 1000> + return ToInt64Seconds(d * Ratio::den / Ratio::num); +} +// Fastpath implementations for the 6 common duration units. +inline int64_t ToInt64(absl::Duration d, std::nano) { + return ToInt64Nanoseconds(d); +} +inline int64_t ToInt64(absl::Duration d, std::micro) { + return ToInt64Microseconds(d); +} +inline int64_t ToInt64(absl::Duration d, std::milli) { + return ToInt64Milliseconds(d); +} +inline int64_t ToInt64(absl::Duration d, std::ratio<1>) { + return ToInt64Seconds(d); +} +inline int64_t ToInt64(absl::Duration d, std::ratio<60>) { + return ToInt64Minutes(d); +} +inline int64_t ToInt64(absl::Duration d, std::ratio<3600>) { + return ToInt64Hours(d); +} + +// Converts an absl::Duration to a chrono duration of type T. +template +T ToChronoDuration(absl::Duration d) { + using Rep = typename T::rep; + using Period = typename T::period; + static_assert(IsValidRep64(0), "duration::rep is invalid"); + if (time_internal::IsInfiniteDuration(d)) + return d < ZeroDuration() ? T::min() : T::max(); + const auto v = ToInt64(d, Period{}); + if (v > std::numeric_limits::max()) return T::max(); + if (v < std::numeric_limits::min()) return T::min(); + return T{v}; +} + } // namespace time_internal constexpr bool operator<(Duration lhs, Duration rhs) { @@ -1156,6 +1295,25 @@ constexpr Duration InfiniteDuration() { return time_internal::MakeDuration(std::numeric_limits::max(), ~0U); } +constexpr Duration FromChrono(const std::chrono::nanoseconds& d) { + return time_internal::FromChrono(d); +} +constexpr Duration FromChrono(const std::chrono::microseconds& d) { + return time_internal::FromChrono(d); +} +constexpr Duration FromChrono(const std::chrono::milliseconds& d) { + return time_internal::FromChrono(d); +} +constexpr Duration FromChrono(const std::chrono::seconds& d) { + return time_internal::FromChrono(d); +} +constexpr Duration FromChrono(const std::chrono::minutes& d) { + return time_internal::FromChrono(d); +} +constexpr Duration FromChrono(const std::chrono::hours& d) { + return time_internal::FromChrono(d); +} + constexpr Time FromUnixNanos(int64_t ns) { return time_internal::FromUnixDuration(Nanoseconds(ns)); } -- cgit 1.4.1