diff options
Diffstat (limited to 'abseil-cpp/absl/time/time.h')
-rw-r--r-- | abseil-cpp/absl/time/time.h | 680 |
1 files changed, 456 insertions, 224 deletions
diff --git a/abseil-cpp/absl/time/time.h b/abseil-cpp/absl/time/time.h index 37f6131..3758080 100644 --- a/abseil-cpp/absl/time/time.h +++ b/abseil-cpp/absl/time/time.h @@ -78,11 +78,13 @@ struct timeval; #include <cmath> #include <cstdint> #include <ctime> +#include <limits> #include <ostream> #include <string> #include <type_traits> #include <utility> +#include "absl/base/config.h" #include "absl/base/macros.h" #include "absl/strings/string_view.h" #include "absl/time/civil_time.h" @@ -97,19 +99,24 @@ class TimeZone; // Defined below namespace time_internal { int64_t IDivDuration(bool satq, Duration num, Duration den, Duration* rem); -constexpr Time FromUnixDuration(Duration d); -constexpr Duration ToUnixDuration(Time t); -constexpr int64_t GetRepHi(Duration d); -constexpr uint32_t GetRepLo(Duration d); -constexpr Duration MakeDuration(int64_t hi, uint32_t lo); -constexpr Duration MakeDuration(int64_t hi, int64_t lo); -inline Duration MakePosDoubleDuration(double n); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixDuration(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ToUnixDuration(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t GetRepHi(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr uint32_t GetRepLo(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi, + uint32_t lo); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi, + int64_t lo); +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration MakePosDoubleDuration(double n); constexpr int64_t kTicksPerNanosecond = 4; constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond; template <std::intmax_t N> -constexpr Duration FromInt64(int64_t v, std::ratio<1, N>); -constexpr Duration FromInt64(int64_t v, std::ratio<60>); -constexpr Duration FromInt64(int64_t v, std::ratio<3600>); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, + std::ratio<1, N>); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, + std::ratio<60>); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, + std::ratio<3600>); template <typename T> using EnableIfIntegral = typename std::enable_if< std::is_integral<T>::value || std::is_enum<T>::value, int>::type; @@ -120,7 +127,7 @@ using EnableIfFloat = // Duration // -// The `absl::Duration` class represents a signed, fixed-length span of time. +// The `absl::Duration` class represents a signed, fixed-length amount of time. // A `Duration` is generated using a unit-specific factory function, or is // the result of subtracting one `absl::Time` from another. Durations behave // like unit-safe integers and they support all the natural integer-like @@ -162,7 +169,7 @@ class Duration { constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration // Copyable. -#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910 +#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1930 // Explicitly defining the constexpr copy constructor avoids an MSVC bug. constexpr Duration(const Duration& d) : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {} @@ -181,23 +188,39 @@ class Duration { Duration& operator%=(Duration rhs); // Overloads that forward to either the int64_t or double overloads above. - // Integer operands must be representable as int64_t. - template <typename T> + // Integer operands must be representable as int64_t. Integer division is + // truncating, so values less than the resolution will be returned as zero. + // Floating-point multiplication and division is rounding (halfway cases + // rounding away from zero), so values less than the resolution may be + // returned as either the resolution or zero. In particular, `d / 2.0` + // can produce `d` when it is the resolution and "even". + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator*=(T r) { int64_t x = r; return *this *= x; } - template <typename T> + + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator/=(T r) { int64_t x = r; return *this /= x; } - Duration& operator*=(float r) { return *this *= static_cast<double>(r); } - Duration& operator/=(float r) { return *this /= static_cast<double>(r); } + + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator*=(T r) { + double x = r; + return *this *= x; + } + + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator/=(T r) { + double x = r; + return *this /= x; + } template <typename H> friend H AbslHashValue(H h, Duration d) { - return H::combine(std::move(h), d.rep_hi_, d.rep_lo_); + return H::combine(std::move(h), d.rep_hi_.Get(), d.rep_lo_); } private: @@ -206,42 +229,138 @@ class Duration { friend constexpr Duration time_internal::MakeDuration(int64_t hi, uint32_t lo); constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {} - int64_t rep_hi_; + + // We store `rep_hi_` 4-byte rather than 8-byte aligned to avoid 4 bytes of + // tail padding. + class HiRep { + public: + // Default constructor default-initializes `hi_`, which has the same + // semantics as default-initializing an `int64_t` (undetermined value). + HiRep() = default; + + HiRep(const HiRep&) = default; + HiRep& operator=(const HiRep&) = default; + + explicit constexpr HiRep(const int64_t value) + : // C++17 forbids default-initialization in constexpr contexts. We can + // remove this in C++20. +#if defined(ABSL_IS_BIG_ENDIAN) && ABSL_IS_BIG_ENDIAN + hi_(0), + lo_(0) +#else + lo_(0), + hi_(0) +#endif + { + *this = value; + } + + constexpr int64_t Get() const { + const uint64_t unsigned_value = + (static_cast<uint64_t>(hi_) << 32) | static_cast<uint64_t>(lo_); + // `static_cast<int64_t>(unsigned_value)` is implementation-defined + // before c++20. On all supported platforms the behaviour is that mandated + // by c++20, i.e. "If the destination type is signed, [...] the result is + // the unique value of the destination type equal to the source value + // modulo 2^n, where n is the number of bits used to represent the + // destination type." + static_assert( + (static_cast<int64_t>((std::numeric_limits<uint64_t>::max)()) == + int64_t{-1}) && + (static_cast<int64_t>(static_cast<uint64_t>( + (std::numeric_limits<int64_t>::max)()) + + 1) == + (std::numeric_limits<int64_t>::min)()), + "static_cast<int64_t>(uint64_t) does not have c++20 semantics"); + return static_cast<int64_t>(unsigned_value); + } + + constexpr HiRep& operator=(const int64_t value) { + // "If the destination type is unsigned, the resulting value is the + // smallest unsigned value equal to the source value modulo 2^n + // where `n` is the number of bits used to represent the destination + // type". + const auto unsigned_value = static_cast<uint64_t>(value); + hi_ = static_cast<uint32_t>(unsigned_value >> 32); + lo_ = static_cast<uint32_t>(unsigned_value); + return *this; + } + + private: + // Notes: + // - Ideally we would use a `char[]` and `std::bitcast`, but the latter + // does not exist (and is not constexpr in `absl`) before c++20. + // - Order is optimized depending on endianness so that the compiler can + // turn `Get()` (resp. `operator=()`) into a single 8-byte load (resp. + // store). +#if defined(ABSL_IS_BIG_ENDIAN) && ABSL_IS_BIG_ENDIAN + uint32_t hi_; + uint32_t lo_; +#else + uint32_t lo_; + uint32_t hi_; +#endif + }; + HiRep rep_hi_; uint32_t rep_lo_; }; // Relational Operators -constexpr bool operator<(Duration lhs, Duration rhs); -constexpr bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; } -constexpr bool operator>=(Duration lhs, Duration rhs) { return !(lhs < rhs); } -constexpr bool operator<=(Duration lhs, Duration rhs) { return !(rhs < lhs); } -constexpr bool operator==(Duration lhs, Duration rhs); -constexpr bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs, + Duration rhs); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>(Duration lhs, + Duration rhs) { + return rhs < lhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>=(Duration lhs, + Duration rhs) { + return !(lhs < rhs); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<=(Duration lhs, + Duration rhs) { + return !(rhs < lhs); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs, + Duration rhs); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator!=(Duration lhs, + Duration rhs) { + return !(lhs == rhs); +} // Additive Operators -constexpr Duration operator-(Duration d); -inline Duration operator+(Duration lhs, Duration rhs) { return lhs += rhs; } -inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration operator-(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator+(Duration lhs, + Duration rhs) { + return lhs += rhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator-(Duration lhs, + Duration rhs) { + return lhs -= rhs; +} // Multiplicative Operators // Integer operands must be representable as int64_t. template <typename T> -Duration operator*(Duration lhs, T rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator*(Duration lhs, T rhs) { return lhs *= rhs; } template <typename T> -Duration operator*(T lhs, Duration rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator*(T lhs, Duration rhs) { return rhs *= lhs; } template <typename T> -Duration operator/(Duration lhs, T rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator/(Duration lhs, T rhs) { return lhs /= rhs; } -inline int64_t operator/(Duration lhs, Duration rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t operator/(Duration lhs, + Duration rhs) { return time_internal::IDivDuration(true, lhs, rhs, &lhs); // trunc towards zero } -inline Duration operator%(Duration lhs, Duration rhs) { return lhs %= rhs; } +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator%(Duration lhs, + Duration rhs) { + return lhs %= rhs; +} // IDivDuration() // @@ -288,18 +407,20 @@ inline int64_t IDivDuration(Duration num, Duration den, Duration* rem) { // // double d = absl::FDivDuration(absl::Milliseconds(1500), absl::Seconds(1)); // // d == 1.5 -double FDivDuration(Duration num, Duration den); +ABSL_ATTRIBUTE_CONST_FUNCTION double FDivDuration(Duration num, Duration den); // ZeroDuration() // // Returns a zero-length duration. This function behaves just like the default // constructor, but the name helps make the semantics clear at call sites. -constexpr Duration ZeroDuration() { return Duration(); } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ZeroDuration() { + return Duration(); +} // AbsDuration() // // Returns the absolute value of a duration. -inline Duration AbsDuration(Duration d) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration AbsDuration(Duration d) { return (d < ZeroDuration()) ? -d : d; } @@ -311,7 +432,7 @@ inline Duration AbsDuration(Duration d) { // // absl::Duration d = absl::Nanoseconds(123456789); // absl::Duration a = absl::Trunc(d, absl::Microseconds(1)); // 123456us -Duration Trunc(Duration d, Duration unit); +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Trunc(Duration d, Duration unit); // Floor() // @@ -322,7 +443,7 @@ Duration Trunc(Duration d, Duration unit); // // absl::Duration d = absl::Nanoseconds(123456789); // absl::Duration b = absl::Floor(d, absl::Microseconds(1)); // 123456us -Duration Floor(Duration d, Duration unit); +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Floor(Duration d, Duration unit); // Ceil() // @@ -333,7 +454,7 @@ Duration Floor(Duration d, Duration unit); // // absl::Duration d = absl::Nanoseconds(123456789); // absl::Duration c = absl::Ceil(d, absl::Microseconds(1)); // 123457us -Duration Ceil(Duration d, Duration unit); +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Ceil(Duration d, Duration unit); // InfiniteDuration() // @@ -369,7 +490,7 @@ Duration Ceil(Duration d, Duration unit); // // The examples involving the `/` operator above also apply to `IDivDuration()` // and `FDivDuration()`. -constexpr Duration InfiniteDuration(); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration InfiniteDuration(); // Nanoseconds() // Microseconds() @@ -392,12 +513,30 @@ constexpr Duration InfiniteDuration(); // // absl::Duration a = absl::Seconds(60); // absl::Duration b = absl::Minutes(1); // b == a -constexpr Duration Nanoseconds(int64_t n); -constexpr Duration Microseconds(int64_t n); -constexpr Duration Milliseconds(int64_t n); -constexpr Duration Seconds(int64_t n); -constexpr Duration Minutes(int64_t n); -constexpr Duration Hours(int64_t n); +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Nanoseconds(T n) { + return time_internal::FromInt64(n, std::nano{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Microseconds(T n) { + return time_internal::FromInt64(n, std::micro{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Milliseconds(T n) { + return time_internal::FromInt64(n, std::milli{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Seconds(T n) { + return time_internal::FromInt64(n, std::ratio<1>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Minutes(T n) { + return time_internal::FromInt64(n, std::ratio<60>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Hours(T n) { + return time_internal::FromInt64(n, std::ratio<3600>{}); +} // Factory overloads for constructing `Duration` values from a floating-point // number of the unit indicated by the factory function's name. These functions @@ -409,19 +548,19 @@ constexpr Duration Hours(int64_t n); // auto a = absl::Seconds(1.5); // OK // auto b = absl::Milliseconds(1500); // BETTER template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Nanoseconds(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Nanoseconds(T n) { return n * Nanoseconds(1); } template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Microseconds(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Microseconds(T n) { return n * Microseconds(1); } template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Milliseconds(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Milliseconds(T n) { return n * Milliseconds(1); } template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Seconds(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Seconds(T n) { if (n >= 0) { // Note: `NaN >= 0` is false. if (n >= static_cast<T>((std::numeric_limits<int64_t>::max)())) { return InfiniteDuration(); @@ -435,11 +574,11 @@ Duration Seconds(T n) { } } template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Minutes(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Minutes(T n) { return n * Minutes(1); } template <typename T, time_internal::EnableIfFloat<T> = 0> -Duration Hours(T n) { +ABSL_ATTRIBUTE_CONST_FUNCTION Duration Hours(T n) { return n * Hours(1); } @@ -451,21 +590,22 @@ Duration Hours(T n) { // ToInt64Hours() // // Helper functions that convert a Duration to an integral count of the -// indicated unit. These functions are shorthand for the `IDivDuration()` -// function above; see its documentation for details about overflow, etc. +// indicated unit. These return the same results as the `IDivDuration()` +// function, though they usually do so more efficiently; see the +// documentation of `IDivDuration()` for details about overflow, etc. // // Example: // // absl::Duration d = absl::Milliseconds(1500); // int64_t isec = absl::ToInt64Seconds(d); // isec == 1 -int64_t ToInt64Nanoseconds(Duration d); -int64_t ToInt64Microseconds(Duration d); -int64_t ToInt64Milliseconds(Duration d); -int64_t ToInt64Seconds(Duration d); -int64_t ToInt64Minutes(Duration d); -int64_t ToInt64Hours(Duration d); - -// ToDoubleNanoSeconds() +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Nanoseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Microseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Milliseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Seconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Minutes(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Hours(Duration d); + +// ToDoubleNanoseconds() // ToDoubleMicroseconds() // ToDoubleMilliseconds() // ToDoubleSeconds() @@ -480,12 +620,12 @@ int64_t ToInt64Hours(Duration d); // // absl::Duration d = absl::Milliseconds(1500); // double dsec = absl::ToDoubleSeconds(d); // dsec == 1.5 -double ToDoubleNanoseconds(Duration d); -double ToDoubleMicroseconds(Duration d); -double ToDoubleMilliseconds(Duration d); -double ToDoubleSeconds(Duration d); -double ToDoubleMinutes(Duration d); -double ToDoubleHours(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleNanoseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMicroseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMilliseconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleSeconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMinutes(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleHours(Duration d); // FromChrono() // @@ -495,12 +635,18 @@ double ToDoubleHours(Duration d); // // 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); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::nanoseconds& d); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::microseconds& d); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::milliseconds& d); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::seconds& d); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::minutes& d); +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::hours& d); // ToChronoNanoseconds() // ToChronoMicroseconds() @@ -520,24 +666,33 @@ constexpr Duration FromChrono(const std::chrono::hours& 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); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::nanoseconds ToChronoNanoseconds( + Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::microseconds ToChronoMicroseconds( + Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::milliseconds ToChronoMilliseconds( + Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::seconds ToChronoSeconds(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::minutes ToChronoMinutes(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::hours ToChronoHours(Duration d); // FormatDuration() // // Returns a string representing the duration in the form "72h3m0.5s". // Returns "inf" or "-inf" for +/- `InfiniteDuration()`. -std::string FormatDuration(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION std::string FormatDuration(Duration d); // Output stream operator. inline std::ostream& operator<<(std::ostream& os, Duration d) { return os << FormatDuration(d); } +// Support for StrFormat(), StrCat() etc. +template <typename Sink> +void AbslStringify(Sink& sink, Duration d) { + sink.Append(FormatDuration(d)); +} + // ParseDuration() // // Parses a duration string consisting of a possibly signed sequence of @@ -547,10 +702,20 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(absl::string_view dur_string, Duration* d); -// Support for flag values of type Duration. Duration flags must be specified -// in a format that is valid input for absl::ParseDuration(). +// AbslParseFlag() +// +// Parses a command-line flag string representation `text` into a Duration +// value. Duration flags must be specified in a format that is valid input for +// `absl::ParseDuration()`. bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error); + + +// AbslUnparseFlag() +// +// Unparses a Duration value into a command-line string representation using +// the format specified by `absl::ParseDuration()`. std::string AbslUnparseFlag(Duration d); + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Duration* dst, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -637,9 +802,8 @@ class Time { // `absl::TimeZone`. // // Deprecated. Use `absl::TimeZone::CivilInfo`. - struct - Breakdown { - int64_t year; // year (e.g., 2013) + struct ABSL_DEPRECATED("Use `absl::TimeZone::CivilInfo`.") Breakdown { + int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] int hour; // hour of day [0:23] @@ -664,7 +828,10 @@ class Time { // Returns the breakdown of this instant in the given TimeZone. // // Deprecated. Use `absl::TimeZone::At(Time)`. + ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING + ABSL_DEPRECATED("Use `absl::TimeZone::At(Time)`.") Breakdown In(TimeZone tz) const; + ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING template <typename H> friend H AbslHashValue(H h, Time t) { @@ -685,48 +852,69 @@ class Time { }; // Relational Operators -constexpr bool operator<(Time lhs, Time rhs) { return lhs.rep_ < rhs.rep_; } -constexpr bool operator>(Time lhs, Time rhs) { return rhs < lhs; } -constexpr bool operator>=(Time lhs, Time rhs) { return !(lhs < rhs); } -constexpr bool operator<=(Time lhs, Time rhs) { return !(rhs < lhs); } -constexpr bool operator==(Time lhs, Time rhs) { return lhs.rep_ == rhs.rep_; } -constexpr bool operator!=(Time lhs, Time rhs) { return !(lhs == rhs); } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Time lhs, Time rhs) { + return lhs.rep_ < rhs.rep_; +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>(Time lhs, Time rhs) { + return rhs < lhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>=(Time lhs, Time rhs) { + return !(lhs < rhs); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<=(Time lhs, Time rhs) { + return !(rhs < lhs); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Time lhs, Time rhs) { + return lhs.rep_ == rhs.rep_; +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator!=(Time lhs, Time rhs) { + return !(lhs == rhs); +} // Additive Operators -inline Time operator+(Time lhs, Duration rhs) { return lhs += rhs; } -inline Time operator+(Duration lhs, Time rhs) { return rhs += lhs; } -inline Time operator-(Time lhs, Duration rhs) { return lhs -= rhs; } -inline Duration operator-(Time lhs, Time rhs) { return lhs.rep_ - rhs.rep_; } +ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator+(Time lhs, Duration rhs) { + return lhs += rhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator+(Duration lhs, Time rhs) { + return rhs += lhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator-(Time lhs, Duration rhs) { + return lhs -= rhs; +} +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator-(Time lhs, Time rhs) { + return lhs.rep_ - rhs.rep_; +} // UnixEpoch() // // Returns the `absl::Time` representing "1970-01-01 00:00:00.0 +0000". -constexpr Time UnixEpoch() { return Time(); } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time UnixEpoch() { return Time(); } // UniversalEpoch() // // Returns the `absl::Time` representing "0001-01-01 00:00:00.0 +0000", the // epoch of the ICU Universal Time Scale. -constexpr Time UniversalEpoch() { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time UniversalEpoch() { // 719162 is the number of days from 0001-01-01 to 1970-01-01, // assuming the Gregorian calendar. - return Time(time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, 0U)); + return Time( + time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, uint32_t{0})); } // InfiniteFuture() // // Returns an `absl::Time` that is infinitely far in the future. -constexpr Time InfiniteFuture() { - return Time( - time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time InfiniteFuture() { + return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), + ~uint32_t{0})); } // InfinitePast() // // Returns an `absl::Time` that is infinitely far in the past. -constexpr Time InfinitePast() { - return Time( - time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U)); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time InfinitePast() { + return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), + ~uint32_t{0})); } // FromUnixNanos() @@ -737,14 +925,15 @@ constexpr Time InfinitePast() { // FromUDate() // FromUniversal() // -// Creates an `absl::Time` from a variety of other representations. -constexpr Time FromUnixNanos(int64_t ns); -constexpr Time FromUnixMicros(int64_t us); -constexpr Time FromUnixMillis(int64_t ms); -constexpr Time FromUnixSeconds(int64_t s); -constexpr Time FromTimeT(time_t t); -Time FromUDate(double udate); -Time FromUniversal(int64_t universal); +// Creates an `absl::Time` from a variety of other representations. See +// https://unicode-org.github.io/icu/userguide/datetime/universaltimescale.html +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixNanos(int64_t ns); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMicros(int64_t us); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMillis(int64_t ms); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixSeconds(int64_t s); +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromTimeT(time_t t); +ABSL_ATTRIBUTE_CONST_FUNCTION Time FromUDate(double udate); +ABSL_ATTRIBUTE_CONST_FUNCTION Time FromUniversal(int64_t universal); // ToUnixNanos() // ToUnixMicros() @@ -754,17 +943,19 @@ Time FromUniversal(int64_t universal); // ToUDate() // ToUniversal() // -// Converts an `absl::Time` to a variety of other representations. Note that -// these operations round down toward negative infinity where necessary to -// adjust to the resolution of the result type. Beware of possible time_t -// over/underflow in ToTime{T,val,spec}() on 32-bit platforms. -int64_t ToUnixNanos(Time t); -int64_t ToUnixMicros(Time t); -int64_t ToUnixMillis(Time t); -int64_t ToUnixSeconds(Time t); -time_t ToTimeT(Time t); -double ToUDate(Time t); -int64_t ToUniversal(Time t); +// Converts an `absl::Time` to a variety of other representations. See +// https://unicode-org.github.io/icu/userguide/datetime/universaltimescale.html +// +// Note that these operations round down toward negative infinity where +// necessary to adjust to the resolution of the result type. Beware of +// possible time_t over/underflow in ToTime{T,val,spec}() on 32-bit platforms. +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixNanos(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixMicros(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixMillis(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixSeconds(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION time_t ToTimeT(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION double ToUDate(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUniversal(Time t); // DurationFromTimespec() // DurationFromTimeval() @@ -780,14 +971,14 @@ int64_t ToUniversal(Time t); // and gettimeofday(2)), so conversion functions are provided for both cases. // The "to timespec/val" direction is easily handled via overloading, but // for "from timespec/val" the desired type is part of the function name. -Duration DurationFromTimespec(timespec ts); -Duration DurationFromTimeval(timeval tv); -timespec ToTimespec(Duration d); -timeval ToTimeval(Duration d); -Time TimeFromTimespec(timespec ts); -Time TimeFromTimeval(timeval tv); -timespec ToTimespec(Time t); -timeval ToTimeval(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION Duration DurationFromTimespec(timespec ts); +ABSL_ATTRIBUTE_CONST_FUNCTION Duration DurationFromTimeval(timeval tv); +ABSL_ATTRIBUTE_CONST_FUNCTION timespec ToTimespec(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION timeval ToTimeval(Duration d); +ABSL_ATTRIBUTE_CONST_FUNCTION Time TimeFromTimespec(timespec ts); +ABSL_ATTRIBUTE_CONST_FUNCTION Time TimeFromTimeval(timeval tv); +ABSL_ATTRIBUTE_CONST_FUNCTION timespec ToTimespec(Time t); +ABSL_ATTRIBUTE_CONST_FUNCTION timeval ToTimeval(Time t); // FromChrono() // @@ -798,7 +989,8 @@ timeval ToTimeval(Time t); // 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); +ABSL_ATTRIBUTE_PURE_FUNCTION Time +FromChrono(const std::chrono::system_clock::time_point& tp); // ToChronoTime() // @@ -811,10 +1003,15 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // 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(Time); +ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::system_clock::time_point + ToChronoTime(Time); -// Support for flag values of type Time. Time flags must be specified in a -// format that matches absl::RFC3339_full. For example: +// AbslParseFlag() +// +// Parses the command-line flag string representation `text` into a Time value. +// Time flags must be specified in a format that matches absl::RFC3339_full. +// +// For example: // // --start_time=2016-01-02T03:04:05.678+08:00 // @@ -824,7 +1021,13 @@ std::chrono::system_clock::time_point ToChronoTime(Time); // seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag // and add that duration to absl::UnixEpoch() to get an absl::Time. bool AbslParseFlag(absl::string_view text, Time* t, std::string* error); + +// AbslUnparseFlag() +// +// Unparses a Time value into a command-line string representation using +// the format specified by `absl::ParseTime()`. std::string AbslUnparseFlag(Time t); + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Time* t, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -1073,22 +1276,25 @@ inline TimeZone LocalTimeZone() { // absl::Time t = ...; // absl::TimeZone tz = ...; // const auto cd = absl::ToCivilDay(t, tz); -inline CivilSecond ToCivilSecond(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilSecond ToCivilSecond(Time t, + TimeZone tz) { return tz.At(t).cs; // already a CivilSecond } -inline CivilMinute ToCivilMinute(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilMinute ToCivilMinute(Time t, + TimeZone tz) { return CivilMinute(tz.At(t).cs); } -inline CivilHour ToCivilHour(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilHour ToCivilHour(Time t, TimeZone tz) { return CivilHour(tz.At(t).cs); } -inline CivilDay ToCivilDay(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilDay ToCivilDay(Time t, TimeZone tz) { return CivilDay(tz.At(t).cs); } -inline CivilMonth ToCivilMonth(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilMonth ToCivilMonth(Time t, + TimeZone tz) { return CivilMonth(tz.At(t).cs); } -inline CivilYear ToCivilYear(Time t, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilYear ToCivilYear(Time t, TimeZone tz) { return CivilYear(tz.At(t).cs); } @@ -1104,7 +1310,8 @@ inline CivilYear ToCivilYear(Time t, TimeZone tz) { // being when two non-existent civil times map to the same transition time. // // Note: Accepts civil times of any alignment. -inline Time FromCivil(CivilSecond ct, TimeZone tz) { +ABSL_ATTRIBUTE_PURE_FUNCTION inline Time FromCivil(CivilSecond ct, + TimeZone tz) { const auto ti = tz.At(ct); if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans; return ti.pre; @@ -1118,8 +1325,7 @@ inline Time FromCivil(CivilSecond ct, TimeZone tz) { // `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`. // // Deprecated. Use `absl::TimeZone::TimeInfo`. -struct - TimeConversion { +struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion { Time pre; // time calculated using the pre-transition offset Time trans; // when the civil-time discontinuity occurred Time post; // time calculated using the post-transition offset @@ -1153,8 +1359,11 @@ struct // // absl::ToCivilDay(tc.pre, tz).day() == 1 // // Deprecated. Use `absl::TimeZone::At(CivilSecond)`. +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING +ABSL_DEPRECATED("Use `absl::TimeZone::At(CivilSecond)`.") TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, int min, int sec, TimeZone tz); +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING // FromDateTime() // @@ -1171,27 +1380,34 @@ TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, // Deprecated. Use `absl::FromCivil(CivilSecond, TimeZone)`. Note that the // behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil // times. If you care about that see `absl::TimeZone::At(absl::CivilSecond)`. -inline Time FromDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz) { +ABSL_DEPRECATED("Use `absl::FromCivil(CivilSecond, TimeZone)`.") +inline Time FromDateTime(int64_t year, int mon, int day, int hour, int min, + int sec, TimeZone tz) { + ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre; + ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING } // FromTM() // // Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and // `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3) -// for a description of the expected values of the tm fields. If the indicated -// time instant is not unique (see `absl::TimeZone::At(absl::CivilSecond)` -// above), the `tm_isdst` field is consulted to select the desired instant -// (`tm_isdst` > 0 means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0 -// means use the post-transition offset). -Time FromTM(const struct tm& tm, TimeZone tz); +// for a description of the expected values of the tm fields. If the civil time +// is unique (see `absl::TimeZone::At(absl::CivilSecond)` above), the matching +// time instant is returned. Otherwise, the `tm_isdst` field is consulted to +// choose between the possible results. For a repeated civil time, `tm_isdst != +// 0` returns the matching DST instant, while `tm_isdst == 0` returns the +// matching non-DST instant. For a skipped civil time there is no matching +// instant, so `tm_isdst != 0` returns the DST instant, and `tm_isdst == 0` +// returns the non-DST instant, that would have matched if the transition never +// happened. +ABSL_ATTRIBUTE_PURE_FUNCTION Time FromTM(const struct tm& tm, TimeZone tz); // ToTM() // // Converts the given `absl::Time` to a struct tm using the given time zone. // See ctime(3) for a description of the values of the tm fields. -struct tm ToTM(Time t, TimeZone tz); +ABSL_ATTRIBUTE_PURE_FUNCTION struct tm ToTM(Time t, TimeZone tz); // RFC3339_full // RFC3339_sec @@ -1250,19 +1466,26 @@ ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // `absl::InfinitePast()`, the returned string will be exactly "infinite-past". // In both cases the given format string and `absl::TimeZone` are ignored. // -std::string FormatTime(absl::string_view format, Time t, TimeZone tz); +ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(absl::string_view format, + Time t, TimeZone tz); // Convenience functions that format the given time using the RFC3339_full // format. The first overload uses the provided TimeZone, while the second // uses LocalTimeZone(). -std::string FormatTime(Time t, TimeZone tz); -std::string FormatTime(Time t); +ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t, TimeZone tz); +ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t); // Output stream operator. inline std::ostream& operator<<(std::ostream& os, Time t) { return os << FormatTime(t); } +// Support for StrFormat(), StrCat() etc. +template <typename Sink> +void AbslStringify(Sink& sink, Time t) { + sink.Append(FormatTime(t)); +} + // ParseTime() // // Parses an input string according to the provided format string and @@ -1334,21 +1557,23 @@ namespace time_internal { // Creates a Duration with a given representation. // REQUIRES: hi,lo is a valid representation of a Duration as specified // in time/duration.cc. -constexpr Duration MakeDuration(int64_t hi, uint32_t lo = 0) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi, + uint32_t lo = 0) { return Duration(hi, lo); } -constexpr Duration MakeDuration(int64_t hi, int64_t lo) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi, + int64_t lo) { return MakeDuration(hi, static_cast<uint32_t>(lo)); } // Make a Duration value from a floating-point number, as long as that number // is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as // it's positive and can be converted to int64_t without risk of UB. -inline Duration MakePosDoubleDuration(double n) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration MakePosDoubleDuration(double n) { const int64_t int_secs = static_cast<int64_t>(n); const uint32_t ticks = static_cast<uint32_t>( - (n - static_cast<double>(int_secs)) * kTicksPerSecond + 0.5); + std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); return ticks < kTicksPerSecond ? MakeDuration(int_secs, ticks) : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); @@ -1358,28 +1583,37 @@ inline Duration MakePosDoubleDuration(double n) { // pair. sec may be positive or negative. ticks must be in the range // -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it // will be normalized to a positive value in the resulting Duration. -constexpr Duration MakeNormalizedDuration(int64_t sec, int64_t ticks) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeNormalizedDuration( + int64_t sec, int64_t ticks) { return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond) : MakeDuration(sec, ticks); } // Provide access to the Duration representation. -constexpr int64_t GetRepHi(Duration d) { return d.rep_hi_; } -constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t GetRepHi(Duration d) { + return d.rep_hi_.Get(); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr uint32_t GetRepLo(Duration d) { + return d.rep_lo_; +} // Returns true iff d is positive or negative infinity. -constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool IsInfiniteDuration(Duration d) { + return GetRepLo(d) == ~uint32_t{0}; +} // Returns an infinite Duration with the opposite sign. // REQUIRES: IsInfiniteDuration(d) -constexpr Duration OppositeInfinity(Duration d) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration OppositeInfinity(Duration d) { return GetRepHi(d) < 0 - ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U) - : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U); + ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~uint32_t{0}) + : MakeDuration((std::numeric_limits<int64_t>::min)(), + ~uint32_t{0}); } // Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow. -constexpr int64_t NegateAndSubtractOne(int64_t n) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t NegateAndSubtractOne( + int64_t n) { // Note: Good compilers will optimize this expression to ~n when using // a two's-complement representation (which is required for int64_t). return (n < 0) ? -(n + 1) : (-n) - 1; @@ -1389,23 +1623,30 @@ constexpr int64_t NegateAndSubtractOne(int64_t n) { // functions depend on the above mentioned choice of the Unix epoch for the // Time representation (and both need to be Time friends). Without this // 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_; } +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixDuration(Duration d) { + return Time(d); +} +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ToUnixDuration(Time t) { + return t.rep_; +} template <std::intmax_t N> -constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr 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 Duration FromInt64(int64_t v, std::ratio<60>) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, + std::ratio<60>) { return (v <= (std::numeric_limits<int64_t>::max)() / 60 && v >= (std::numeric_limits<int64_t>::min)() / 60) ? MakeDuration(v * 60) : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } -constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, + std::ratio<3600>) { return (v <= (std::numeric_limits<int64_t>::max)() / 3600 && v >= (std::numeric_limits<int64_t>::min)() / 3600) ? MakeDuration(v * 3600) @@ -1425,40 +1666,44 @@ constexpr auto IsValidRep64(char) -> bool { // Converts a std::chrono::duration to an absl::Duration. template <typename Rep, typename Period> -constexpr Duration FromChrono(const std::chrono::duration<Rep, Period>& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::duration<Rep, Period>& d) { static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid"); return FromInt64(int64_t{d.count()}, Period{}); } template <typename Ratio> -int64_t ToInt64(Duration d, Ratio) { +ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64(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(Duration d, std::nano) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::nano) { return ToInt64Nanoseconds(d); } -inline int64_t ToInt64(Duration d, std::micro) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::micro) { return ToInt64Microseconds(d); } -inline int64_t ToInt64(Duration d, std::milli) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::milli) { return ToInt64Milliseconds(d); } -inline int64_t ToInt64(Duration d, std::ratio<1>) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, + std::ratio<1>) { return ToInt64Seconds(d); } -inline int64_t ToInt64(Duration d, std::ratio<60>) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, + std::ratio<60>) { return ToInt64Minutes(d); } -inline int64_t ToInt64(Duration d, std::ratio<3600>) { +ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, + std::ratio<3600>) { return ToInt64Hours(d); } // Converts an absl::Duration to a chrono duration of type T. template <typename T> -T ToChronoDuration(Duration d) { +ABSL_ATTRIBUTE_CONST_FUNCTION T ToChronoDuration(Duration d) { using Rep = typename T::rep; using Period = typename T::period; static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid"); @@ -1472,42 +1717,23 @@ T ToChronoDuration(Duration d) { } // namespace time_internal -constexpr Duration Nanoseconds(int64_t n) { - return time_internal::FromInt64(n, std::nano{}); -} -constexpr Duration Microseconds(int64_t n) { - return time_internal::FromInt64(n, std::micro{}); -} -constexpr Duration Milliseconds(int64_t n) { - return time_internal::FromInt64(n, std::milli{}); -} -constexpr Duration Seconds(int64_t n) { - return time_internal::FromInt64(n, std::ratio<1>{}); -} -constexpr Duration Minutes(int64_t n) { - return time_internal::FromInt64(n, std::ratio<60>{}); -} -constexpr Duration Hours(int64_t n) { - return time_internal::FromInt64(n, std::ratio<3600>{}); -} - -constexpr bool operator<(Duration lhs, Duration rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs, + Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) - : time_internal::GetRepHi(lhs) == - (std::numeric_limits<int64_t>::min)() - ? time_internal::GetRepLo(lhs) + 1 < - time_internal::GetRepLo(rhs) + 1 - : time_internal::GetRepLo(lhs) < - time_internal::GetRepLo(rhs); + : time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)() + ? time_internal::GetRepLo(lhs) + 1 < + time_internal::GetRepLo(rhs) + 1 + : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs); } -constexpr bool operator==(Duration lhs, Duration rhs) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs, + Duration rhs) { return time_internal::GetRepHi(lhs) == time_internal::GetRepHi(rhs) && time_internal::GetRepLo(lhs) == time_internal::GetRepLo(rhs); } -constexpr Duration operator-(Duration d) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration operator-(Duration d) { // This is a little interesting because of the special cases. // // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're @@ -1533,47 +1759,53 @@ constexpr Duration operator-(Duration d) { time_internal::GetRepLo(d)); } -constexpr Duration InfiniteDuration() { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration InfiniteDuration() { return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), - ~0U); + ~uint32_t{0}); } -constexpr Duration FromChrono(const std::chrono::nanoseconds& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::nanoseconds& d) { return time_internal::FromChrono(d); } -constexpr Duration FromChrono(const std::chrono::microseconds& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::microseconds& d) { return time_internal::FromChrono(d); } -constexpr Duration FromChrono(const std::chrono::milliseconds& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::milliseconds& d) { return time_internal::FromChrono(d); } -constexpr Duration FromChrono(const std::chrono::seconds& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::seconds& d) { return time_internal::FromChrono(d); } -constexpr Duration FromChrono(const std::chrono::minutes& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::minutes& d) { return time_internal::FromChrono(d); } -constexpr Duration FromChrono(const std::chrono::hours& d) { +ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono( + const std::chrono::hours& d) { return time_internal::FromChrono(d); } -constexpr Time FromUnixNanos(int64_t ns) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixNanos(int64_t ns) { return time_internal::FromUnixDuration(Nanoseconds(ns)); } -constexpr Time FromUnixMicros(int64_t us) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMicros(int64_t us) { return time_internal::FromUnixDuration(Microseconds(us)); } -constexpr Time FromUnixMillis(int64_t ms) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMillis(int64_t ms) { return time_internal::FromUnixDuration(Milliseconds(ms)); } -constexpr Time FromUnixSeconds(int64_t s) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixSeconds(int64_t s) { return time_internal::FromUnixDuration(Seconds(s)); } -constexpr Time FromTimeT(time_t t) { +ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromTimeT(time_t t) { return time_internal::FromUnixDuration(Seconds(t)); } |