abseil-cpp/absl/time/duration.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // The implementation of the absl::Duration class, which is declared in
16 // //absl/time.h. This class behaves like a numeric type; it has no public
17 // methods and is used only through the operators defined here.
18 //
19 // Implementation notes:
20 //
21 // An absl::Duration is represented as
22 //
23 // rep_hi_ : (int64_t) Whole seconds
24 // rep_lo_ : (uint32_t) Fractions of a second
25 //
26 // The seconds value (rep_hi_) may be positive or negative as appropriate.
27 // The fractional seconds (rep_lo_) is always a positive offset from rep_hi_.
28 // The API for Duration guarantees at least nanosecond resolution, which
29 // means rep_lo_ could have a max value of 1B - 1 if it stored nanoseconds.
30 // However, to utilize more of the available 32 bits of space in rep_lo_,
31 // we instead store quarters of a nanosecond in rep_lo_ resulting in a max
32 // value of 4B - 1. This allows us to correctly handle calculations like
33 // 0.5 nanos + 0.5 nanos = 1 nano. The following example shows the actual
34 // Duration rep using quarters of a nanosecond.
35 //
36 // 2.5 sec = {rep_hi_=2, rep_lo_=2000000000} // lo = 4 * 500000000
37 // -2.5 sec = {rep_hi_=-3, rep_lo_=2000000000}
38 //
39 // Infinite durations are represented as Durations with the rep_lo_ field set
40 // to all 1s.
41 //
42 // +InfiniteDuration:
43 // rep_hi_ : kint64max
44 // rep_lo_ : ~0U
45 //
46 // -InfiniteDuration:
47 // rep_hi_ : kint64min
48 // rep_lo_ : ~0U
49 //
50 // Arithmetic overflows/underflows to +/- infinity and saturates.
51 
52 #if defined(_MSC_VER)
53 #include <winsock2.h> // for timeval
54 #endif
55 
56 #include <algorithm>
57 #include <cassert>
58 #include <cctype>
59 #include <cerrno>
60 #include <cmath>
61 #include <cstdint>
62 #include <cstdlib>
63 #include <cstring>
64 #include <ctime>
65 #include <functional>
66 #include <limits>
67 #include <string>
68 
69 #include "absl/base/casts.h"
70 #include "absl/base/macros.h"
71 #include "absl/numeric/int128.h"
72 #include "absl/strings/string_view.h"
73 #include "absl/strings/strip.h"
74 #include "absl/time/time.h"
75 
76 namespace absl {
78 
79 namespace {
80 
83 
86 
87 // Can't use std::isinfinite() because it doesn't exist on windows.
88 inline bool IsFinite(double d) {
89  if (std::isnan(d)) return false;
90  return d != std::numeric_limits<double>::infinity() &&
91  d != -std::numeric_limits<double>::infinity();
92 }
93 
94 inline bool IsValidDivisor(double d) {
95  if (std::isnan(d)) return false;
96  return d != 0.0;
97 }
98 
99 // Can't use std::round() because it is only available in C++11.
100 // Note that we ignore the possibility of floating-point over/underflow.
101 template <typename Double>
102 inline double Round(Double d) {
103  return d < 0 ? std::ceil(d - 0.5) : std::floor(d + 0.5);
104 }
105 
106 // *sec may be positive or negative. *ticks must be in the range
107 // -kTicksPerSecond < *ticks < kTicksPerSecond. If *ticks is negative it
108 // will be normalized to a positive value by adjusting *sec accordingly.
109 inline void NormalizeTicks(int64_t* sec, int64_t* ticks) {
110  if (*ticks < 0) {
111  --*sec;
113  }
114 }
115 
116 // Makes a uint128 from the absolute value of the given scalar.
118  uint128 u128 = 0;
119  if (a < 0) {
120  ++u128;
121  ++a; // Makes it safe to negate 'a'
122  a = -a;
123  }
124  u128 += static_cast<uint64_t>(a);
125  return u128;
126 }
127 
128 // Makes a uint128 count of ticks out of the absolute value of the Duration.
130  int64_t rep_hi = time_internal::GetRepHi(d);
131  uint32_t rep_lo = time_internal::GetRepLo(d);
132  if (rep_hi < 0) {
133  ++rep_hi;
134  rep_hi = -rep_hi;
135  rep_lo = kTicksPerSecond - rep_lo;
136  }
137  uint128 u128 = static_cast<uint64_t>(rep_hi);
138  u128 *= static_cast<uint64_t>(kTicksPerSecond);
139  u128 += rep_lo;
140  return u128;
141 }
142 
143 // Breaks a uint128 of ticks into a Duration.
145  int64_t rep_hi;
146  uint32_t rep_lo;
147  const uint64_t h64 = Uint128High64(u128);
148  const uint64_t l64 = Uint128Low64(u128);
149  if (h64 == 0) { // fastpath
150  const uint64_t hi = l64 / kTicksPerSecond;
151  rep_hi = static_cast<int64_t>(hi);
152  rep_lo = static_cast<uint32_t>(l64 - hi * kTicksPerSecond);
153  } else {
154  // kMaxRepHi64 is the high 64 bits of (2^63 * kTicksPerSecond).
155  // Any positive tick count whose high 64 bits are >= kMaxRepHi64
156  // is not representable as a Duration. A negative tick count can
157  // have its high 64 bits == kMaxRepHi64 but only when the low 64
158  // bits are all zero, otherwise it is not representable either.
159  const uint64_t kMaxRepHi64 = 0x77359400UL;
160  if (h64 >= kMaxRepHi64) {
161  if (is_neg && h64 == kMaxRepHi64 && l64 == 0) {
162  // Avoid trying to represent -kint64min below.
164  }
165  return is_neg ? -InfiniteDuration() : InfiniteDuration();
166  }
167  const uint128 kTicksPerSecond128 = static_cast<uint64_t>(kTicksPerSecond);
168  const uint128 hi = u128 / kTicksPerSecond128;
169  rep_hi = static_cast<int64_t>(Uint128Low64(hi));
170  rep_lo =
171  static_cast<uint32_t>(Uint128Low64(u128 - hi * kTicksPerSecond128));
172  }
173  if (is_neg) {
174  rep_hi = -rep_hi;
175  if (rep_lo != 0) {
176  --rep_hi;
177  rep_lo = kTicksPerSecond - rep_lo;
178  }
179  }
180  return time_internal::MakeDuration(rep_hi, rep_lo);
181 }
182 
183 // Convert between int64_t and uint64_t, preserving representation. This
184 // allows us to do arithmetic in the unsigned domain, where overflow has
185 // well-defined behavior. See operator+=() and operator-=().
186 //
187 // C99 7.20.1.1.1, as referenced by C++11 18.4.1.2, says, "The typedef
188 // name intN_t designates a signed integer type with width N, no padding
189 // bits, and a two's complement representation." So, we can convert to
190 // and from the corresponding uint64_t value using a bit cast.
192  return absl::bit_cast<uint64_t>(v);
193 }
194 inline int64_t DecodeTwosComp(uint64_t v) { return absl::bit_cast<int64_t>(v); }
195 
196 // Note: The overflow detection in this function is done using greater/less *or
197 // equal* because kint64max/min is too large to be represented exactly in a
198 // double (which only has 53 bits of precision). In order to avoid assigning to
199 // rep->hi a double value that is too large for an int64_t (and therefore is
200 // undefined), we must consider computations that equal kint64max/min as a
201 // double as overflow cases.
202 inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) {
203  double c = a_hi + b_hi;
204  if (c >= static_cast<double>(kint64max)) {
205  *d = InfiniteDuration();
206  return false;
207  }
208  if (c <= static_cast<double>(kint64min)) {
209  *d = -InfiniteDuration();
210  return false;
211  }
213  return true;
214 }
215 
216 // A functor that's similar to std::multiplies<T>, except this returns the max
217 // T value instead of overflowing. This is only defined for uint128.
218 template <typename Ignored>
219 struct SafeMultiply {
221  // b hi is always zero because it originated as an int64_t.
222  assert(Uint128High64(b) == 0);
223  // Fastpath to avoid the expensive overflow check with division.
224  if (Uint128High64(a) == 0) {
225  return (((Uint128Low64(a) | Uint128Low64(b)) >> 32) == 0)
226  ? static_cast<uint128>(Uint128Low64(a) * Uint128Low64(b))
227  : a * b;
228  }
229  return b == 0 ? b : (a > kuint128max / b) ? kuint128max : a * b;
230  }
231 };
232 
233 // Scales (i.e., multiplies or divides, depending on the Operation template)
234 // the Duration d by the int64_t r.
235 template <template <typename> class Operation>
237  const uint128 a = MakeU128Ticks(d);
238  const uint128 b = MakeU128(r);
239  const uint128 q = Operation<uint128>()(a, b);
240  const bool is_neg = (time_internal::GetRepHi(d) < 0) != (r < 0);
241  return MakeDurationFromU128(q, is_neg);
242 }
243 
244 // Scales (i.e., multiplies or divides, depending on the Operation template)
245 // the Duration d by the double r.
246 template <template <typename> class Operation>
247 inline Duration ScaleDouble(Duration d, double r) {
248  Operation<double> op;
249  double hi_doub = op(time_internal::GetRepHi(d), r);
250  double lo_doub = op(time_internal::GetRepLo(d), r);
251 
252  double hi_int = 0;
253  double hi_frac = std::modf(hi_doub, &hi_int);
254 
255  // Moves hi's fractional bits to lo.
256  lo_doub /= kTicksPerSecond;
257  lo_doub += hi_frac;
258 
259  double lo_int = 0;
260  double lo_frac = std::modf(lo_doub, &lo_int);
261 
262  // Rolls lo into hi if necessary.
263  int64_t lo64 = Round(lo_frac * kTicksPerSecond);
264 
265  Duration ans;
266  if (!SafeAddRepHi(hi_int, lo_int, &ans)) return ans;
267  int64_t hi64 = time_internal::GetRepHi(ans);
268  if (!SafeAddRepHi(hi64, lo64 / kTicksPerSecond, &ans)) return ans;
269  hi64 = time_internal::GetRepHi(ans);
270  lo64 %= kTicksPerSecond;
271  NormalizeTicks(&hi64, &lo64);
272  return time_internal::MakeDuration(hi64, lo64);
273 }
274 
275 // Tries to divide num by den as fast as possible by looking for common, easy
276 // cases. If the division was done, the quotient is in *q and the remainder is
277 // in *rem and true will be returned.
278 inline bool IDivFastPath(const Duration num, const Duration den, int64_t* q,
279  Duration* rem) {
280  // Bail if num or den is an infinity.
283  return false;
284 
287  int64_t den_hi = time_internal::GetRepHi(den);
288  uint32_t den_lo = time_internal::GetRepLo(den);
289 
290  if (den_hi == 0 && den_lo == kTicksPerNanosecond) {
291  // Dividing by 1ns
292  if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000000) {
293  *q = num_hi * 1000000000 + num_lo / kTicksPerNanosecond;
294  *rem = time_internal::MakeDuration(0, num_lo % den_lo);
295  return true;
296  }
297  } else if (den_hi == 0 && den_lo == 100 * kTicksPerNanosecond) {
298  // Dividing by 100ns (common when converting to Universal time)
299  if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 10000000) {
300  *q = num_hi * 10000000 + num_lo / (100 * kTicksPerNanosecond);
301  *rem = time_internal::MakeDuration(0, num_lo % den_lo);
302  return true;
303  }
304  } else if (den_hi == 0 && den_lo == 1000 * kTicksPerNanosecond) {
305  // Dividing by 1us
306  if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000000) {
307  *q = num_hi * 1000000 + num_lo / (1000 * kTicksPerNanosecond);
308  *rem = time_internal::MakeDuration(0, num_lo % den_lo);
309  return true;
310  }
311  } else if (den_hi == 0 && den_lo == 1000000 * kTicksPerNanosecond) {
312  // Dividing by 1ms
313  if (num_hi >= 0 && num_hi < (kint64max - kTicksPerSecond) / 1000) {
314  *q = num_hi * 1000 + num_lo / (1000000 * kTicksPerNanosecond);
315  *rem = time_internal::MakeDuration(0, num_lo % den_lo);
316  return true;
317  }
318  } else if (den_hi > 0 && den_lo == 0) {
319  // Dividing by positive multiple of 1s
320  if (num_hi >= 0) {
321  if (den_hi == 1) {
322  *q = num_hi;
323  *rem = time_internal::MakeDuration(0, num_lo);
324  return true;
325  }
326  *q = num_hi / den_hi;
327  *rem = time_internal::MakeDuration(num_hi % den_hi, num_lo);
328  return true;
329  }
330  if (num_lo != 0) {
331  num_hi += 1;
332  }
333  int64_t quotient = num_hi / den_hi;
334  int64_t rem_sec = num_hi % den_hi;
335  if (rem_sec > 0) {
336  rem_sec -= den_hi;
337  quotient += 1;
338  }
339  if (num_lo != 0) {
340  rem_sec -= 1;
341  }
342  *q = quotient;
343  *rem = time_internal::MakeDuration(rem_sec, num_lo);
344  return true;
345  }
346 
347  return false;
348 }
349 
350 } // namespace
351 
352 namespace time_internal {
353 
354 // The 'satq' argument indicates whether the quotient should saturate at the
355 // bounds of int64_t. If it does saturate, the difference will spill over to
356 // the remainder. If it does not saturate, the remainder remain accurate,
357 // but the returned quotient will over/underflow int64_t and should not be used.
358 int64_t IDivDuration(bool satq, const Duration num, const Duration den,
359  Duration* rem) {
360  int64_t q = 0;
361  if (IDivFastPath(num, den, &q, rem)) {
362  return q;
363  }
364 
365  const bool num_neg = num < ZeroDuration();
366  const bool den_neg = den < ZeroDuration();
367  const bool quotient_neg = num_neg != den_neg;
368 
370  *rem = num_neg ? -InfiniteDuration() : InfiniteDuration();
371  return quotient_neg ? kint64min : kint64max;
372  }
374  *rem = num;
375  return 0;
376  }
377 
378  const uint128 a = MakeU128Ticks(num);
379  const uint128 b = MakeU128Ticks(den);
380  uint128 quotient128 = a / b;
381 
382  if (satq) {
383  // Limits the quotient to the range of int64_t.
384  if (quotient128 > uint128(static_cast<uint64_t>(kint64max))) {
385  quotient128 = quotient_neg ? uint128(static_cast<uint64_t>(kint64min))
386  : uint128(static_cast<uint64_t>(kint64max));
387  }
388  }
389 
390  const uint128 remainder128 = a - quotient128 * b;
391  *rem = MakeDurationFromU128(remainder128, num_neg);
392 
393  if (!quotient_neg || quotient128 == 0) {
394  return Uint128Low64(quotient128) & kint64max;
395  }
396  // The quotient needs to be negated, but we need to carefully handle
397  // quotient128s with the top bit on.
398  return -static_cast<int64_t>(Uint128Low64(quotient128 - 1) & kint64max) - 1;
399 }
400 
401 } // namespace time_internal
402 
403 //
404 // Additive operators.
405 //
406 
408  if (time_internal::IsInfiniteDuration(*this)) return *this;
409  if (time_internal::IsInfiniteDuration(rhs)) return *this = rhs;
410  const int64_t orig_rep_hi = rep_hi_;
411  rep_hi_ =
413  if (rep_lo_ >= kTicksPerSecond - rhs.rep_lo_) {
416  }
417  rep_lo_ += rhs.rep_lo_;
418  if (rhs.rep_hi_ < 0 ? rep_hi_ > orig_rep_hi : rep_hi_ < orig_rep_hi) {
419  return *this = rhs.rep_hi_ < 0 ? -InfiniteDuration() : InfiniteDuration();
420  }
421  return *this;
422 }
423 
425  if (time_internal::IsInfiniteDuration(*this)) return *this;
427  return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
428  }
429  const int64_t orig_rep_hi = rep_hi_;
430  rep_hi_ =
432  if (rep_lo_ < rhs.rep_lo_) {
435  }
436  rep_lo_ -= rhs.rep_lo_;
437  if (rhs.rep_hi_ < 0 ? rep_hi_ < orig_rep_hi : rep_hi_ > orig_rep_hi) {
438  return *this = rhs.rep_hi_ >= 0 ? -InfiniteDuration() : InfiniteDuration();
439  }
440  return *this;
441 }
442 
443 //
444 // Multiplicative operators.
445 //
446 
449  const bool is_neg = (r < 0) != (rep_hi_ < 0);
450  return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
451  }
452  return *this = ScaleFixed<SafeMultiply>(*this, r);
453 }
454 
456  if (time_internal::IsInfiniteDuration(*this) || !IsFinite(r)) {
457  const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
458  return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
459  }
460  return *this = ScaleDouble<std::multiplies>(*this, r);
461 }
462 
464  if (time_internal::IsInfiniteDuration(*this) || r == 0) {
465  const bool is_neg = (r < 0) != (rep_hi_ < 0);
466  return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
467  }
468  return *this = ScaleFixed<std::divides>(*this, r);
469 }
470 
473  const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
474  return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
475  }
476  return *this = ScaleDouble<std::divides>(*this, r);
477 }
478 
480  time_internal::IDivDuration(false, *this, rhs, this);
481  return *this;
482 }
483 
485  // Arithmetic with infinity is sticky.
487  return (num < ZeroDuration()) == (den < ZeroDuration())
488  ? std::numeric_limits<double>::infinity()
489  : -std::numeric_limits<double>::infinity();
490  }
491  if (time_internal::IsInfiniteDuration(den)) return 0.0;
492 
493  double a =
494  static_cast<double>(time_internal::GetRepHi(num)) * kTicksPerSecond +
496  double b =
497  static_cast<double>(time_internal::GetRepHi(den)) * kTicksPerSecond +
499  return a / b;
500 }
501 
502 //
503 // Trunc/Floor/Ceil.
504 //
505 
507  return d - (d % unit);
508 }
509 
510 Duration Floor(const Duration d, const Duration unit) {
511  const absl::Duration td = Trunc(d, unit);
512  return td <= d ? td : td - AbsDuration(unit);
513 }
514 
515 Duration Ceil(const Duration d, const Duration unit) {
516  const absl::Duration td = Trunc(d, unit);
517  return td >= d ? td : td + AbsDuration(unit);
518 }
519 
520 //
521 // Factory functions.
522 //
523 
525  if (static_cast<uint64_t>(ts.tv_nsec) < 1000 * 1000 * 1000) {
526  int64_t ticks = ts.tv_nsec * kTicksPerNanosecond;
527  return time_internal::MakeDuration(ts.tv_sec, ticks);
528  }
529  return Seconds(ts.tv_sec) + Nanoseconds(ts.tv_nsec);
530 }
531 
533  if (static_cast<uint64_t>(tv.tv_usec) < 1000 * 1000) {
536  }
537  return Seconds(tv.tv_sec) + Microseconds(tv.tv_usec);
538 }
539 
540 //
541 // Conversion to other duration types.
542 //
543 
545  if (time_internal::GetRepHi(d) >= 0 &&
546  time_internal::GetRepHi(d) >> 33 == 0) {
547  return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
549  }
550  return d / Nanoseconds(1);
551 }
553  if (time_internal::GetRepHi(d) >= 0 &&
554  time_internal::GetRepHi(d) >> 43 == 0) {
555  return (time_internal::GetRepHi(d) * 1000 * 1000) +
557  }
558  return d / Microseconds(1);
559 }
561  if (time_internal::GetRepHi(d) >= 0 &&
562  time_internal::GetRepHi(d) >> 53 == 0) {
563  return (time_internal::GetRepHi(d) * 1000) +
564  (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000 * 1000));
565  }
566  return d / Milliseconds(1);
567 }
570  if (time_internal::IsInfiniteDuration(d)) return hi;
571  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
572  return hi;
573 }
576  if (time_internal::IsInfiniteDuration(d)) return hi;
577  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
578  return hi / 60;
579 }
582  if (time_internal::IsInfiniteDuration(d)) return hi;
583  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
584  return hi / (60 * 60);
585 }
586 
588  return FDivDuration(d, Nanoseconds(1));
589 }
591  return FDivDuration(d, Microseconds(1));
592 }
594  return FDivDuration(d, Milliseconds(1));
595 }
597  return FDivDuration(d, Seconds(1));
598 }
600  return FDivDuration(d, Minutes(1));
601 }
603  return FDivDuration(d, Hours(1));
604 }
605 
606 timespec ToTimespec(Duration d) {
607  timespec ts;
609  int64_t rep_hi = time_internal::GetRepHi(d);
610  uint32_t rep_lo = time_internal::GetRepLo(d);
611  if (rep_hi < 0) {
612  // Tweak the fields so that unsigned division of rep_lo
613  // maps to truncation (towards zero) for the timespec.
614  rep_lo += kTicksPerNanosecond - 1;
615  if (rep_lo >= kTicksPerSecond) {
616  rep_hi += 1;
617  rep_lo -= kTicksPerSecond;
618  }
619  }
620  ts.tv_sec = rep_hi;
621  if (ts.tv_sec == rep_hi) { // no time_t narrowing
622  ts.tv_nsec = rep_lo / kTicksPerNanosecond;
623  return ts;
624  }
625  }
626  if (d >= ZeroDuration()) {
627  ts.tv_sec = std::numeric_limits<time_t>::max();
628  ts.tv_nsec = 1000 * 1000 * 1000 - 1;
629  } else {
630  ts.tv_sec = std::numeric_limits<time_t>::min();
631  ts.tv_nsec = 0;
632  }
633  return ts;
634 }
635 
637  timeval tv;
638  timespec ts = ToTimespec(d);
639  if (ts.tv_sec < 0) {
640  // Tweak the fields so that positive division of tv_nsec
641  // maps to truncation (towards zero) for the timeval.
642  ts.tv_nsec += 1000 - 1;
643  if (ts.tv_nsec >= 1000 * 1000 * 1000) {
644  ts.tv_sec += 1;
645  ts.tv_nsec -= 1000 * 1000 * 1000;
646  }
647  }
648  tv.tv_sec = ts.tv_sec;
649  if (tv.tv_sec != ts.tv_sec) { // narrowing
650  if (ts.tv_sec < 0) {
651  tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
652  tv.tv_usec = 0;
653  } else {
654  tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
655  tv.tv_usec = 1000 * 1000 - 1;
656  }
657  return tv;
658  }
659  tv.tv_usec = static_cast<int>(ts.tv_nsec / 1000); // suseconds_t
660  return tv;
661 }
662 
663 std::chrono::nanoseconds ToChronoNanoseconds(Duration d) {
664  return time_internal::ToChronoDuration<std::chrono::nanoseconds>(d);
665 }
666 std::chrono::microseconds ToChronoMicroseconds(Duration d) {
667  return time_internal::ToChronoDuration<std::chrono::microseconds>(d);
668 }
669 std::chrono::milliseconds ToChronoMilliseconds(Duration d) {
670  return time_internal::ToChronoDuration<std::chrono::milliseconds>(d);
671 }
673  return time_internal::ToChronoDuration<std::chrono::seconds>(d);
674 }
675 std::chrono::minutes ToChronoMinutes(Duration d) {
676  return time_internal::ToChronoDuration<std::chrono::minutes>(d);
677 }
678 std::chrono::hours ToChronoHours(Duration d) {
679  return time_internal::ToChronoDuration<std::chrono::hours>(d);
680 }
681 
682 //
683 // To/From string formatting.
684 //
685 
686 namespace {
687 
688 // Formats a positive 64-bit integer in the given field width. Note that
689 // it is up to the caller of Format64() to ensure that there is sufficient
690 // space before ep to hold the conversion.
691 char* Format64(char* ep, int width, int64_t v) {
692  do {
693  --width;
694  *--ep = '0' + (v % 10); // contiguous digits
695  } while (v /= 10);
696  while (--width >= 0) *--ep = '0'; // zero pad
697  return ep;
698 }
699 
700 // Helpers for FormatDuration() that format 'n' and append it to 'out'
701 // followed by the given 'unit'. If 'n' formats to "0", nothing is
702 // appended (not even the unit).
703 
704 // A type that encapsulates how to display a value of a particular unit. For
705 // values that are displayed with fractional parts, the precision indicates
706 // where to round the value. The precision varies with the display unit because
707 // a Duration can hold only quarters of a nanosecond, so displaying information
708 // beyond that is just noise.
709 //
710 // For example, a microsecond value of 42.00025xxxxx should not display beyond 5
711 // fractional digits, because it is in the noise of what a Duration can
712 // represent.
713 struct DisplayUnit {
714  absl::string_view abbr;
715  int prec;
716  double pow10;
717 };
718 ABSL_CONST_INIT const DisplayUnit kDisplayNano = {"ns", 2, 1e2};
719 ABSL_CONST_INIT const DisplayUnit kDisplayMicro = {"us", 5, 1e5};
720 ABSL_CONST_INIT const DisplayUnit kDisplayMilli = {"ms", 8, 1e8};
721 ABSL_CONST_INIT const DisplayUnit kDisplaySec = {"s", 11, 1e11};
722 ABSL_CONST_INIT const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored
723 ABSL_CONST_INIT const DisplayUnit kDisplayHour = {"h", -1,
724  0.0}; // prec ignored
725 
726 void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) {
727  char buf[sizeof("2562047788015216")]; // hours in max duration
728  char* const ep = buf + sizeof(buf);
729  char* bp = Format64(ep, 0, n);
730  if (*bp != '0' || bp + 1 != ep) {
731  out->append(bp, ep - bp);
732  out->append(unit.abbr.data(), unit.abbr.size());
733  }
734 }
735 
736 // Note: unit.prec is limited to double's digits10 value (typically 15) so it
737 // always fits in buf[].
738 void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) {
739  constexpr int kBufferSize = std::numeric_limits<double>::digits10;
740  const int prec = std::min(kBufferSize, unit.prec);
741  char buf[kBufferSize]; // also large enough to hold integer part
742  char* ep = buf + sizeof(buf);
743  double d = 0;
744  int64_t frac_part = Round(std::modf(n, &d) * unit.pow10);
745  int64_t int_part = d;
746  if (int_part != 0 || frac_part != 0) {
747  char* bp = Format64(ep, 0, int_part); // always < 1000
748  out->append(bp, ep - bp);
749  if (frac_part != 0) {
750  out->push_back('.');
751  bp = Format64(ep, prec, frac_part);
752  while (ep[-1] == '0') --ep;
753  out->append(bp, ep - bp);
754  }
755  out->append(unit.abbr.data(), unit.abbr.size());
756  }
757 }
758 
759 } // namespace
760 
761 // From Go's doc at https://golang.org/pkg/time/#Duration.String
762 // [FormatDuration] returns a string representing the duration in the
763 // form "72h3m0.5s". Leading zero units are omitted. As a special
764 // case, durations less than one second format use a smaller unit
765 // (milli-, micro-, or nanoseconds) to ensure that the leading digit
766 // is non-zero.
767 // Unlike Go, we format the zero duration as 0, with no unit.
769  constexpr Duration kMinDuration = Seconds(kint64min);
770  std::string s;
771  if (d == kMinDuration) {
772  // Avoid needing to negate kint64min by directly returning what the
773  // following code should produce in that case.
774  s = "-2562047788015215h30m8s";
775  return s;
776  }
777  if (d < ZeroDuration()) {
778  s.append("-");
779  d = -d;
780  }
781  if (d == InfiniteDuration()) {
782  s.append("inf");
783  } else if (d < Seconds(1)) {
784  // Special case for durations with a magnitude < 1 second. The duration
785  // is printed as a fraction of a single unit, e.g., "1.2ms".
786  if (d < Microseconds(1)) {
787  AppendNumberUnit(&s, FDivDuration(d, Nanoseconds(1)), kDisplayNano);
788  } else if (d < Milliseconds(1)) {
789  AppendNumberUnit(&s, FDivDuration(d, Microseconds(1)), kDisplayMicro);
790  } else {
791  AppendNumberUnit(&s, FDivDuration(d, Milliseconds(1)), kDisplayMilli);
792  }
793  } else {
794  AppendNumberUnit(&s, IDivDuration(d, Hours(1), &d), kDisplayHour);
795  AppendNumberUnit(&s, IDivDuration(d, Minutes(1), &d), kDisplayMin);
796  AppendNumberUnit(&s, FDivDuration(d, Seconds(1)), kDisplaySec);
797  }
798  if (s.empty() || s == "-") {
799  s = "0";
800  }
801  return s;
802 }
803 
804 namespace {
805 
806 // A helper for ParseDuration() that parses a leading number from the given
807 // string and stores the result in *int_part/*frac_part/*frac_scale. The
808 // given string pointer is modified to point to the first unconsumed char.
809 bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part,
810  int64_t* frac_part, int64_t* frac_scale) {
811  *int_part = 0;
812  *frac_part = 0;
813  *frac_scale = 1; // invariant: *frac_part < *frac_scale
814  const char* start = *dpp;
815  for (; *dpp != ep; *dpp += 1) {
816  const int d = **dpp - '0'; // contiguous digits
817  if (d < 0 || 10 <= d) break;
818 
819  if (*int_part > kint64max / 10) return false;
820  *int_part *= 10;
821  if (*int_part > kint64max - d) return false;
822  *int_part += d;
823  }
824  const bool int_part_empty = (*dpp == start);
825  if (*dpp == ep || **dpp != '.') return !int_part_empty;
826 
827  for (*dpp += 1; *dpp != ep; *dpp += 1) {
828  const int d = **dpp - '0'; // contiguous digits
829  if (d < 0 || 10 <= d) break;
830  if (*frac_scale <= kint64max / 10) {
831  *frac_part *= 10;
832  *frac_part += d;
833  *frac_scale *= 10;
834  }
835  }
836  return !int_part_empty || *frac_scale != 1;
837 }
838 
839 // A helper for ParseDuration() that parses a leading unit designator (e.g.,
840 // ns, us, ms, s, m, h) from the given string and stores the resulting unit
841 // in "*unit". The given string pointer is modified to point to the first
842 // unconsumed char.
843 bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) {
844  size_t size = end - *start;
845  switch (size) {
846  case 0:
847  return false;
848  default:
849  switch (**start) {
850  case 'n':
851  if (*(*start + 1) == 's') {
852  *start += 2;
853  *unit = Nanoseconds(1);
854  return true;
855  }
856  break;
857  case 'u':
858  if (*(*start + 1) == 's') {
859  *start += 2;
860  *unit = Microseconds(1);
861  return true;
862  }
863  break;
864  case 'm':
865  if (*(*start + 1) == 's') {
866  *start += 2;
867  *unit = Milliseconds(1);
868  return true;
869  }
870  break;
871  default:
872  break;
873  }
875  case 1:
876  switch (**start) {
877  case 's':
878  *unit = Seconds(1);
879  *start += 1;
880  return true;
881  case 'm':
882  *unit = Minutes(1);
883  *start += 1;
884  return true;
885  case 'h':
886  *unit = Hours(1);
887  *start += 1;
888  return true;
889  default:
890  return false;
891  }
892  }
893 }
894 
895 } // namespace
896 
897 // From Go's doc at https://golang.org/pkg/time/#ParseDuration
898 // [ParseDuration] parses a duration string. A duration string is
899 // a possibly signed sequence of decimal numbers, each with optional
900 // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m".
901 // Valid time units are "ns", "us" "ms", "s", "m", "h".
903  int sign = 1;
904  if (absl::ConsumePrefix(&dur_sv, "-")) {
905  sign = -1;
906  } else {
907  absl::ConsumePrefix(&dur_sv, "+");
908  }
909  if (dur_sv.empty()) return false;
910 
911  // Special case for a string of "0".
912  if (dur_sv == "0") {
913  *d = ZeroDuration();
914  return true;
915  }
916 
917  if (dur_sv == "inf") {
918  *d = sign * InfiniteDuration();
919  return true;
920  }
921 
922  const char* start = dur_sv.data();
923  const char* end = start + dur_sv.size();
924 
925  Duration dur;
926  while (start != end) {
927  int64_t int_part;
928  int64_t frac_part;
929  int64_t frac_scale;
930  Duration unit;
931  if (!ConsumeDurationNumber(&start, end, &int_part, &frac_part,
932  &frac_scale) ||
933  !ConsumeDurationUnit(&start, end, &unit)) {
934  return false;
935  }
936  if (int_part != 0) dur += sign * int_part * unit;
937  if (frac_part != 0) dur += sign * frac_part * unit / frac_scale;
938  }
939  *d = dur;
940  return true;
941 }
942 
944  return ParseDuration(text, dst);
945 }
946 
949  return ParseDuration(text, dst);
950 }
951 
953 
955 } // namespace absl
absl::time_internal::kTicksPerNanosecond
constexpr int64_t kTicksPerNanosecond
Definition: third_party/abseil-cpp/absl/time/time.h:107
absl::ToChronoMicroseconds
std::chrono::microseconds ToChronoMicroseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:666
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
width
int width
Definition: libuv/docs/code/tty-gravity/main.c:10
absl::ABSL_NAMESPACE_BEGIN::MakeU128Ticks
uint128 MakeU128Ticks(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:129
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
absl::ParseFlag
ABSL_NAMESPACE_BEGIN bool ParseFlag(absl::string_view input, T *dst, std::string *error)
Definition: abseil-cpp/absl/flags/marshalling.h:328
absl::kuint128max
ABSL_NAMESPACE_BEGIN const ABSL_DLL uint128 kuint128max
Definition: abseil-cpp/absl/numeric/int128.cc:32
kBufferSize
static const int kBufferSize
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:135
ABSL_CONST_INIT
#define ABSL_CONST_INIT
Definition: abseil-cpp/absl/base/attributes.h:716
absl::ToChronoMilliseconds
std::chrono::milliseconds ToChronoMilliseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:669
absl::ZeroDuration
constexpr Duration ZeroDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:308
absl::time_internal::MakeDuration
constexpr Duration MakeDuration(int64_t hi, uint32_t lo)
Definition: third_party/abseil-cpp/absl/time/time.h:1392
tests.google.protobuf.internal.message_test.isnan
def isnan(val)
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:65
absl::time_internal::kTicksPerSecond
constexpr int64_t kTicksPerSecond
Definition: third_party/abseil-cpp/absl/time/time.h:108
absl::ABSL_NAMESPACE_BEGIN::SafeMultiply
Definition: abseil-cpp/absl/time/duration.cc:219
absl::Nanoseconds
constexpr Duration Nanoseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:407
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
u128
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h:115
absl::ToInt64Minutes
int64_t ToInt64Minutes(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:574
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::ABSL_NAMESPACE_BEGIN::DecodeTwosComp
int64_t DecodeTwosComp(uint64_t v)
Definition: abseil-cpp/absl/time/duration.cc:194
absl::FormatConversionChar::s
@ s
absl::UnparseFlag
std::string UnparseFlag(const T &v)
Definition: abseil-cpp/absl/flags/marshalling.h:342
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::ToInt64Microseconds
int64_t ToInt64Microseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:552
absl::Duration::operator%=
Duration & operator%=(Duration rhs)
Definition: abseil-cpp/absl/time/duration.cc:479
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::ToChronoHours
std::chrono::hours ToChronoHours(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:678
absl::ToDoubleHours
double ToDoubleHours(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:602
absl::AbslParseFlag
bool AbslParseFlag(absl::string_view text, absl::LogSeverity *dst, std::string *err)
Definition: abseil-cpp/absl/flags/marshalling.cc:202
absl::ToInt64Milliseconds
int64_t ToInt64Milliseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:560
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
absl::Floor
Duration Floor(const Duration d, const Duration unit)
Definition: abseil-cpp/absl/time/duration.cc:510
absl::time_internal::IsInfiniteDuration
constexpr bool IsInfiniteDuration(Duration d)
Definition: third_party/abseil-cpp/absl/time/time.h:1426
absl::Milliseconds
constexpr Duration Milliseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:415
absl::Uint128High64
constexpr uint64_t Uint128High64(uint128 v)
Definition: abseil-cpp/absl/numeric/int128.h:634
absl::ABSL_NAMESPACE_BEGIN::MakeU128
uint128 MakeU128(int64_t a)
Definition: abseil-cpp/absl/time/duration.cc:117
start
static uint64_t start
Definition: benchmark-pound.c:74
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::Microseconds
constexpr Duration Microseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:411
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
absl::ABSL_NAMESPACE_BEGIN::NormalizeTicks
void NormalizeTicks(int64_t *sec, int64_t *ticks)
Definition: abseil-cpp/absl/time/duration.cc:109
absl::Uint128Low64
constexpr uint64_t Uint128Low64(uint128 v)
Definition: abseil-cpp/absl/numeric/int128.h:632
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
absl::ToChronoMinutes
std::chrono::minutes ToChronoMinutes(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:675
absl::ABSL_NAMESPACE_BEGIN::kint64max
constexpr int64_t kint64max
Definition: abseil-cpp/absl/time/duration.cc:84
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
absl::Duration::rep_lo_
uint32_t rep_lo_
Definition: third_party/abseil-cpp/absl/time/time.h:221
absl::Duration::operator/=
Duration & operator/=(int64_t r)
Definition: abseil-cpp/absl/time/duration.cc:463
absl::ToDoubleMilliseconds
double ToDoubleMilliseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:593
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::ToTimeval
timeval ToTimeval(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:636
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
absl::ABSL_NAMESPACE_BEGIN::ScaleFixed
Duration ScaleFixed(Duration d, int64_t r)
Definition: abseil-cpp/absl/time/duration.cc:236
absl::Duration
Definition: third_party/abseil-cpp/absl/time/time.h:159
absl::Duration::operator*=
Duration & operator*=(int64_t r)
Definition: abseil-cpp/absl/time/duration.cc:447
absl::ABSL_NAMESPACE_BEGIN::IDivFastPath
bool IDivFastPath(const Duration num, const Duration den, int64_t *q, Duration *rem)
Definition: abseil-cpp/absl/time/duration.cc:278
absl::ToDoubleSeconds
double ToDoubleSeconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:596
absl::AbslUnparseFlag
std::string AbslUnparseFlag(absl::LogSeverity v)
Definition: abseil-cpp/absl/flags/marshalling.cc:235
absl::FDivDuration
double FDivDuration(Duration num, Duration den)
Definition: abseil-cpp/absl/time/duration.cc:484
absl::ParseDuration
bool ParseDuration(absl::string_view dur_sv, Duration *d)
Definition: abseil-cpp/absl/time/duration.cc:902
min
#define min(a, b)
Definition: qsort.h:83
absl::ABSL_NAMESPACE_BEGIN::ScaleDouble
Duration ScaleDouble(Duration d, double r)
Definition: abseil-cpp/absl/time/duration.cc:247
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::FormatDuration
std::string FormatDuration(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:768
absl::ToChronoSeconds
std::chrono::seconds ToChronoSeconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:672
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
absl::ToTimespec
timespec ToTimespec(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:606
timeval::tv_sec
long tv_sec
Definition: setup_once.h:121
timeval::tv_usec
long tv_usec
Definition: setup_once.h:122
timeval
Definition: setup_once.h:113
absl::Hours
constexpr Duration Hours(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:427
absl::time_internal::IDivDuration
int64_t IDivDuration(bool satq, const Duration num, const Duration den, Duration *rem)
Definition: abseil-cpp/absl/time/duration.cc:358
absl::ABSL_NAMESPACE_BEGIN::EncodeTwosComp
uint64_t EncodeTwosComp(int64_t v)
Definition: abseil-cpp/absl/time/duration.cc:191
fix_build_deps.r
r
Definition: fix_build_deps.py:491
absl::ToInt64Hours
int64_t ToInt64Hours(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:580
testing::internal::Double
FloatingPoint< double > Double
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h:397
absl::IDivDuration
int64_t IDivDuration(Duration num, Duration den, Duration *rem)
Definition: third_party/abseil-cpp/absl/time/time.h:285
xds_manager.num
num
Definition: xds_manager.py:56
absl::DurationFromTimeval
Duration DurationFromTimeval(timeval tv)
Definition: abseil-cpp/absl/time/duration.cc:532
absl::ToDoubleMicroseconds
double ToDoubleMicroseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:590
absl::Duration::operator-=
Duration & operator-=(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:424
absl::ABSL_NAMESPACE_BEGIN::IsFinite
bool IsFinite(double d)
Definition: abseil-cpp/absl/time/duration.cc:88
absl::Minutes
constexpr Duration Minutes(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:423
absl::Ceil
Duration Ceil(const Duration d, const Duration unit)
Definition: abseil-cpp/absl/time/duration.cc:515
absl::AbsDuration
Duration AbsDuration(Duration d)
Definition: third_party/abseil-cpp/absl/time/time.h:313
absl::ABSL_NAMESPACE_BEGIN::SafeMultiply::operator()
uint128 operator()(uint128 a, uint128 b) const
Definition: abseil-cpp/absl/time/duration.cc:220
absl::time_internal::GetRepHi
constexpr int64_t GetRepHi(Duration d)
Definition: third_party/abseil-cpp/absl/time/time.h:1422
absl::ToChronoNanoseconds
std::chrono::nanoseconds ToChronoNanoseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:663
absl::string_view::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:292
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
Duration
Definition: bloaty/third_party/protobuf/src/google/protobuf/duration.pb.h:69
absl::time_internal::GetRepLo
constexpr uint32_t GetRepLo(Duration d)
Definition: third_party/abseil-cpp/absl/time/time.h:1423
absl::ToDoubleNanoseconds
double ToDoubleNanoseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:587
make_curve25519_tables.d
int d
Definition: make_curve25519_tables.py:53
absl::Trunc
Duration Trunc(Duration d, Duration unit)
Definition: abseil-cpp/absl/time/duration.cc:506
absl::out
char * out
Definition: abseil-cpp/absl/synchronization/mutex.h:1048
absl::ABSL_NAMESPACE_BEGIN::IsValidDivisor
bool IsValidDivisor(double d)
Definition: abseil-cpp/absl/time/duration.cc:94
absl::Duration::rep_hi_
int64_t rep_hi_
Definition: third_party/abseil-cpp/absl/time/time.h:220
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::Duration::operator+=
Duration & operator+=(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:407
absl::InfiniteDuration
constexpr Duration InfiniteDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:1573
absl::ABSL_NAMESPACE_BEGIN::SafeAddRepHi
bool SafeAddRepHi(double a_hi, double b_hi, Duration *d)
Definition: abseil-cpp/absl/time/duration.cc:202
ABSL_FALLTHROUGH_INTENDED
#define ABSL_FALLTHROUGH_INTENDED
Definition: abseil-cpp/absl/base/attributes.h:641
absl::string_view::data
constexpr const_pointer data() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:336
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
absl::DurationFromTimespec
Duration DurationFromTimespec(timespec ts)
Definition: abseil-cpp/absl/time/duration.cc:524
framework.infrastructure.gcp.api.Operation
Operation
Definition: api.py:60
absl::ABSL_NAMESPACE_BEGIN::kint64min
constexpr int64_t kint64min
Definition: abseil-cpp/absl/time/duration.cc:85
ticks
static unsigned long ticks
Definition: benchmark-loop-count.c:30
absl::ABSL_NAMESPACE_BEGIN::MakeDurationFromU128
Duration MakeDurationFromU128(uint128 u128, bool is_neg)
Definition: abseil-cpp/absl/time/duration.cc:144
absl::uint128
Definition: abseil-cpp/absl/numeric/int128.h:104
absl::ToInt64Nanoseconds
int64_t ToInt64Nanoseconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:544
absl::ToDoubleMinutes
double ToDoubleMinutes(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:599
absl::ABSL_NAMESPACE_BEGIN::Round
double Round(Double d)
Definition: abseil-cpp/absl/time/duration.cc:102
absl::ConsumePrefix
ABSL_NAMESPACE_BEGIN bool ConsumePrefix(absl::string_view *str, absl::string_view expected)
Definition: abseil-cpp/absl/strings/strip.h:46
absl::ToInt64Seconds
int64_t ToInt64Seconds(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:568


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:17