chromium/third_party/abseil-cpp/absl/time/duration.cc

// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// The implementation of the absl::Duration class, which is declared in
// //absl/time.h.  This class behaves like a numeric type; it has no public
// methods and is used only through the operators defined here.
//
// Implementation notes:
//
// An absl::Duration is represented as
//
//   rep_hi_ : (int64_t)  Whole seconds
//   rep_lo_ : (uint32_t) Fractions of a second
//
// The seconds value (rep_hi_) may be positive or negative as appropriate.
// The fractional seconds (rep_lo_) is always a positive offset from rep_hi_.
// The API for Duration guarantees at least nanosecond resolution, which
// means rep_lo_ could have a max value of 1B - 1 if it stored nanoseconds.
// However, to utilize more of the available 32 bits of space in rep_lo_,
// we instead store quarters of a nanosecond in rep_lo_ resulting in a max
// value of 4B - 1.  This allows us to correctly handle calculations like
// 0.5 nanos + 0.5 nanos = 1 nano.  The following example shows the actual
// Duration rep using quarters of a nanosecond.
//
//    2.5 sec = {rep_hi_=2,  rep_lo_=2000000000}  // lo = 4 * 500000000
//   -2.5 sec = {rep_hi_=-3, rep_lo_=2000000000}
//
// Infinite durations are represented as Durations with the rep_lo_ field set
// to all 1s.
//
//   +InfiniteDuration:
//     rep_hi_ : kint64max
//     rep_lo_ : ~0U
//
//   -InfiniteDuration:
//     rep_hi_ : kint64min
//     rep_lo_ : ~0U
//
// Arithmetic overflows/underflows to +/- infinity and saturates.

#if defined(_MSC_VER)
#include <winsock2.h>  // for timeval
#endif

#include <algorithm>
#include <cassert>
#include <chrono>  // NOLINT(build/c++11)
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <limits>
#include <string>

#include "absl/base/attributes.h"
#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "absl/time/time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace {

kTicksPerNanosecond;
kTicksPerSecond;

constexpr int64_t kint64max =;
constexpr int64_t kint64min =;

// Can't use std::isinfinite() because it doesn't exist on windows.
inline bool IsFinite(double d) {}

inline bool IsValidDivisor(double d) {}

// *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 by adjusting *sec accordingly.
inline void NormalizeTicks(int64_t* sec, int64_t* ticks) {}

// Makes a uint128 from the absolute value of the given scalar.
inline uint128 MakeU128(int64_t a) {}

// Makes a uint128 count of ticks out of the absolute value of the Duration.
inline uint128 MakeU128Ticks(Duration d) {}

// Breaks a uint128 of ticks into a Duration.
inline Duration MakeDurationFromU128(uint128 u128, bool is_neg) {}

// Convert between int64_t and uint64_t, preserving representation. This
// allows us to do arithmetic in the unsigned domain, where overflow has
// well-defined behavior. See operator+=() and operator-=().
//
// C99 7.20.1.1.1, as referenced by C++11 18.4.1.2, says, "The typedef
// name intN_t designates a signed integer type with width N, no padding
// bits, and a two's complement representation." So, we can convert to
// and from the corresponding uint64_t value using a bit cast.
inline uint64_t EncodeTwosComp(int64_t v) {}
inline int64_t DecodeTwosComp(uint64_t v) {}

// Note: The overflow detection in this function is done using greater/less *or
// equal* because kint64max/min is too large to be represented exactly in a
// double (which only has 53 bits of precision). In order to avoid assigning to
// rep->hi a double value that is too large for an int64_t (and therefore is
// undefined), we must consider computations that equal kint64max/min as a
// double as overflow cases.
inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) {}

// A functor that's similar to std::multiplies<T>, except this returns the max
// T value instead of overflowing. This is only defined for uint128.
template <typename Ignored>
struct SafeMultiply {};

// Scales (i.e., multiplies or divides, depending on the Operation template)
// the Duration d by the int64_t r.
template <template <typename> class Operation>
inline Duration ScaleFixed(Duration d, int64_t r) {}

// Scales (i.e., multiplies or divides, depending on the Operation template)
// the Duration d by the double r.
template <template <typename> class Operation>
inline Duration ScaleDouble(Duration d, double r) {}

// Tries to divide num by den as fast as possible by looking for common, easy
// cases. If the division was done, the quotient is in *q and the remainder is
// in *rem and true will be returned.
inline bool IDivFastPath(const Duration num, const Duration den, int64_t* q,
                         Duration* rem) {}

}  // namespace

namespace {

int64_t IDivSlowPath(bool satq, const Duration num, const Duration den,
                     Duration* rem) {}

// The 'satq' argument indicates whether the quotient should saturate at the
// bounds of int64_t.  If it does saturate, the difference will spill over to
// the remainder.  If it does not saturate, the remainder remain accurate,
// but the returned quotient will over/underflow int64_t and should not be used.
ABSL_ATTRIBUTE_ALWAYS_INLINE inline int64_t IDivDurationImpl(bool satq,
                                                             const Duration num,
                                                             const Duration den,
                                                             Duration* rem) {}

}  // namespace

int64_t IDivDuration(Duration num, Duration den, Duration* rem) {}

//
// Additive operators.
//

Duration& Duration::operator+=(Duration rhs) {}

Duration& Duration::operator-=(Duration rhs) {}

//
// Multiplicative operators.
//

Duration& Duration::operator*=(int64_t r) {}

Duration& Duration::operator*=(double r) {}

Duration& Duration::operator/=(int64_t r) {}

Duration& Duration::operator/=(double r) {}

Duration& Duration::operator%=(Duration rhs) {}

double FDivDuration(Duration num, Duration den) {}

//
// Trunc/Floor/Ceil.
//

Duration Trunc(Duration d, Duration unit) {}

Duration Floor(const Duration d, const Duration unit) {}

Duration Ceil(const Duration d, const Duration unit) {}

//
// Factory functions.
//

Duration DurationFromTimespec(timespec ts) {}

Duration DurationFromTimeval(timeval tv) {}

//
// Conversion to other duration types.
//

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) {}

double ToDoubleNanoseconds(Duration d) {}
double ToDoubleMicroseconds(Duration d) {}
double ToDoubleMilliseconds(Duration d) {}
double ToDoubleSeconds(Duration d) {}
double ToDoubleMinutes(Duration d) {}
double ToDoubleHours(Duration d) {}

timespec ToTimespec(Duration d) {}

timeval ToTimeval(Duration d) {}

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) {}

//
// To/From string formatting.
//

namespace {

// Formats a positive 64-bit integer in the given field width.  Note that
// it is up to the caller of Format64() to ensure that there is sufficient
// space before ep to hold the conversion.
char* Format64(char* ep, int width, int64_t v) {}

// Helpers for FormatDuration() that format 'n' and append it to 'out'
// followed by the given 'unit'.  If 'n' formats to "0", nothing is
// appended (not even the unit).

// A type that encapsulates how to display a value of a particular unit. For
// values that are displayed with fractional parts, the precision indicates
// where to round the value. The precision varies with the display unit because
// a Duration can hold only quarters of a nanosecond, so displaying information
// beyond that is just noise.
//
// For example, a microsecond value of 42.00025xxxxx should not display beyond 5
// fractional digits, because it is in the noise of what a Duration can
// represent.
struct DisplayUnit {};
ABSL_CONST_INIT const DisplayUnit kDisplayNano =;
ABSL_CONST_INIT const DisplayUnit kDisplayMicro =;
ABSL_CONST_INIT const DisplayUnit kDisplayMilli =;
ABSL_CONST_INIT const DisplayUnit kDisplaySec =;
ABSL_CONST_INIT const DisplayUnit kDisplayMin =;  // prec ignored
ABSL_CONST_INIT const DisplayUnit kDisplayHour =;  // prec ignored

void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) {}

// Note: unit.prec is limited to double's digits10 value (typically 15) so it
// always fits in buf[].
void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) {}

}  // namespace

// From Go's doc at https://golang.org/pkg/time/#Duration.String
//   [FormatDuration] returns a string representing the duration in the
//   form "72h3m0.5s". Leading zero units are omitted.  As a special
//   case, durations less than one second format use a smaller unit
//   (milli-, micro-, or nanoseconds) to ensure that the leading digit
//   is non-zero.
// Unlike Go, we format the zero duration as 0, with no unit.
std::string FormatDuration(Duration d) {}

namespace {

// A helper for ParseDuration() that parses a leading number from the given
// string and stores the result in *int_part/*frac_part/*frac_scale.  The
// given string pointer is modified to point to the first unconsumed char.
bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part,
                           int64_t* frac_part, int64_t* frac_scale) {}

// A helper for ParseDuration() that parses a leading unit designator (e.g.,
// ns, us, ms, s, m, h) from the given string and stores the resulting unit
// in "*unit".  The given string pointer is modified to point to the first
// unconsumed char.
bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) {}

}  // namespace

// From Go's doc at https://golang.org/pkg/time/#ParseDuration
//   [ParseDuration] parses a duration string. A duration string is
//   a possibly signed sequence of decimal numbers, each with optional
//   fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m".
//   Valid time units are "ns", "us" "ms", "s", "m", "h".
bool ParseDuration(absl::string_view dur_sv, Duration* d) {}

bool AbslParseFlag(absl::string_view text, Duration* dst, std::string*) {}

std::string AbslUnparseFlag(Duration d) {}
bool ParseFlag(const std::string& text, Duration* dst, std::string* ) {}

std::string UnparseFlag(Duration d) {}

ABSL_NAMESPACE_END
}  // namespace absl