about summary refs log tree commit diff
path: root/absl/time/time.h
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2017-10-11T00·07-0700
committerGennadiy Rozental <rogeeff@gmail.com>2017-10-11T15·01-0400
commit029795a9b5281379f892fbbe3f9a400d5a33f5cc (patch)
treeb461dbd4c1e212917a0f849e1e0dfc4c036f7ee7 /absl/time/time.h
parent962e9931d546cd6f062894e15283cea02c7d3220 (diff)
Changes imported from Abseil "staging" branch:
  - 3e05f2c346a9faf07088c49d590d49a9199e7edd Simplify Duration's operator-() by Jorg Brown <jorg@google.com>
  - 3c4942375a6d17e887bb6ab7cf2d0e763d58a511 Rewrite `noexcept(noexcept(allocator_type()))` to instead... by Matt Calabrese <calabrese@google.com>
  - 02f35a684201a6aa9f70e8b0a041993676f2d230 Fix comment on remove_prefix since the function is not re... by Abseil Team <absl-team@google.com>
  - ceb40aba8031e0ccec9cd49da844882df100c56f Fix mutex_test under TSAN. by Derek Mauro <dmauro@google.com>
  - 7bd12e7ddc5d074e1b9c9f037879211fa1d81f8c Slight wording tweaks for "adopting" wrappers by Abseil Team <absl-team@google.com>
  - c3580afe092e0357d40b1769314f36da1b887c65 Internal cleanup. by Greg Miller <jgm@google.com>

GitOrigin-RevId: 3e05f2c346a9faf07088c49d590d49a9199e7edd
Change-Id: If3df72fba3803398cfcbb323fb4cb84ec55511aa
Diffstat (limited to 'absl/time/time.h')
-rw-r--r--absl/time/time.h37
1 files changed, 17 insertions, 20 deletions
diff --git a/absl/time/time.h b/absl/time/time.h
index 093f168df4..c01977b003 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -1126,8 +1126,10 @@ constexpr Duration OppositeInfinity(Duration d) {
              : MakeDuration(std::numeric_limits<int64_t>::min(), ~0U);
 }
 
-// Returns (-n)-1 (equivalently -(n+1)) without overflowing on any input value.
+// Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow.
 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;
 }
 
@@ -1232,31 +1234,26 @@ constexpr bool operator==(Duration lhs, Duration rhs) {
 constexpr Duration operator-(Duration d) {
   // This is a little interesting because of the special cases.
   //
-  // Infinities stay infinite, and just change direction.
+  // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're
+  // dealing with an integral number of seconds, and the only special case is
+  // the maximum negative finite duration, which can't be negated.
   //
-  // The maximum negative finite duration can't be negated (at least, not
-  // on a two's complement machine), so we return infinity for that case.
-  // Next we dispatch the case where rep_lo_ is zero, observing that it's
-  // safe to negate rep_hi_ in this case because it's not int64_t-min (or
-  // else we'd have handled it above, returning InfiniteDuration()).
+  // Infinities stay infinite, and just change direction.
   //
   // Finally we're in the case where rep_lo_ is non-zero, and we can borrow
   // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1
   // is safe).
-  return time_internal::IsInfiniteDuration(d)
-             ? time_internal::OppositeInfinity(d)
-             : (time_internal::GetRepHi(d) ==
-                    std::numeric_limits<int64_t>::min() &&
-                time_internal::GetRepLo(d) == 0)
+  return time_internal::GetRepLo(d) == 0
+             ? time_internal::GetRepHi(d) == std::numeric_limits<int64_t>::min()
                    ? InfiniteDuration()
-                   : (time_internal::GetRepLo(d) == 0)
-                         ? time_internal::MakeDuration(
-                               -time_internal::GetRepHi(d))
-                         : time_internal::MakeDuration(
-                               time_internal::NegateAndSubtractOne(
-                                   time_internal::GetRepHi(d)),
-                               time_internal::kTicksPerSecond -
-                                   time_internal::GetRepLo(d));
+                   : time_internal::MakeDuration(-time_internal::GetRepHi(d))
+             : time_internal::IsInfiniteDuration(d)
+                   ? time_internal::OppositeInfinity(d)
+                   : time_internal::MakeDuration(
+                         time_internal::NegateAndSubtractOne(
+                             time_internal::GetRepHi(d)),
+                         time_internal::kTicksPerSecond -
+                             time_internal::GetRepLo(d));
 }
 
 constexpr Duration Nanoseconds(int64_t n) {