merging, restoring .ci/abseil-cpp.json
This commit is contained in:
		
						commit
						31adde521b
					
				
					 6 changed files with 93 additions and 88 deletions
				
			
		| 
						 | 
					@ -82,7 +82,8 @@ class InlinedVector {
 | 
				
			||||||
  using reverse_iterator = std::reverse_iterator<iterator>;
 | 
					  using reverse_iterator = std::reverse_iterator<iterator>;
 | 
				
			||||||
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 | 
					  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  InlinedVector() noexcept(noexcept(allocator_type()))
 | 
					  InlinedVector() noexcept(
 | 
				
			||||||
 | 
					      std::is_nothrow_default_constructible<allocator_type>::value)
 | 
				
			||||||
      : allocator_and_tag_(allocator_type()) {}
 | 
					      : allocator_and_tag_(allocator_type()) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  explicit InlinedVector(const allocator_type& alloc) noexcept
 | 
					  explicit InlinedVector(const allocator_type& alloc) noexcept
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,8 +38,8 @@ namespace absl {
 | 
				
			||||||
// Function Template: WrapUnique()
 | 
					// Function Template: WrapUnique()
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Transfers ownership of a raw pointer to a `std::unique_ptr`. The returned
 | 
					//  Adopts ownership from a raw pointer and transfers it to the returned
 | 
				
			||||||
// value is a `std::unique_ptr` of deduced type.
 | 
					//  `std::unique_ptr`, whose type is deduced.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//   X* NewX(int, int);
 | 
					//   X* NewX(int, int);
 | 
				
			||||||
| 
						 | 
					@ -169,8 +169,8 @@ typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
 | 
				
			||||||
// Function Template: RawPtr()
 | 
					// Function Template: RawPtr()
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Extracts the raw pointer from a pointer-like 'ptr'. `absl::RawPtr` is useful
 | 
					// Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is
 | 
				
			||||||
// within templates that need to handle a complement of raw pointers,
 | 
					// useful within templates that need to handle a complement of raw pointers,
 | 
				
			||||||
// `std::nullptr_t`, and smart pointers.
 | 
					// `std::nullptr_t`, and smart pointers.
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
auto RawPtr(T&& ptr) -> decltype(&*ptr) {
 | 
					auto RawPtr(T&& ptr) -> decltype(&*ptr) {
 | 
				
			||||||
| 
						 | 
					@ -183,9 +183,9 @@ inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
 | 
				
			||||||
// Function Template: ShareUniquePtr()
 | 
					// Function Template: ShareUniquePtr()
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Transforms a `std::unique_ptr` rvalue into a `std::shared_ptr`. The returned
 | 
					// Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced
 | 
				
			||||||
// value is a `std::shared_ptr` of deduced type and ownership is transferred to
 | 
					// type. Ownership (if any) of the held value is transferred to the returned
 | 
				
			||||||
// the shared pointer.
 | 
					// shared pointer.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -194,8 +194,11 @@ inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
 | 
				
			||||||
//     CHECK_EQ(*sp, 10);
 | 
					//     CHECK_EQ(*sp, 10);
 | 
				
			||||||
//     CHECK(up == nullptr);
 | 
					//     CHECK(up == nullptr);
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Note that this conversion is correct even when T is an array type, although
 | 
					// Note that this conversion is correct even when T is an array type, and more
 | 
				
			||||||
// the resulting shared pointer may not be very useful.
 | 
					// generally it works for *any* deleter of the `unique_ptr` (single-object
 | 
				
			||||||
 | 
					// deleter, array deleter, or any custom deleter), since the deleter is adopted
 | 
				
			||||||
 | 
					// by the shared pointer as well. The deleter is copied (unless it is a
 | 
				
			||||||
 | 
					// reference).
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a
 | 
					// Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a
 | 
				
			||||||
// null shared pointer does not attempt to call the deleter.
 | 
					// null shared pointer does not attempt to call the deleter.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,9 +295,8 @@ class string_view {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // string_view::remove_prefix()
 | 
					  // string_view::remove_prefix()
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Removes the first `n` characters from the `string_view`, returning a
 | 
					  // Removes the first `n` characters from the `string_view`. Note that the
 | 
				
			||||||
  // pointer to the new first character. Note that the underlying std::string is not
 | 
					  // underlying std::string is not changed, only the view.
 | 
				
			||||||
  // changed, only the view.
 | 
					 | 
				
			||||||
  void remove_prefix(size_type n) {
 | 
					  void remove_prefix(size_type n) {
 | 
				
			||||||
    assert(n <= length_);
 | 
					    assert(n <= length_);
 | 
				
			||||||
    ptr_ += n;
 | 
					    ptr_ += n;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,8 +89,6 @@ static void CheckSumG0G1(void *v) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void TestMu(TestContext *cxt, int c) {
 | 
					static void TestMu(TestContext *cxt, int c) {
 | 
				
			||||||
  SetInvariantChecked(false);
 | 
					 | 
				
			||||||
  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
 | 
					 | 
				
			||||||
  for (int i = 0; i != cxt->iterations; i++) {
 | 
					  for (int i = 0; i != cxt->iterations; i++) {
 | 
				
			||||||
    absl::MutexLock l(&cxt->mu);
 | 
					    absl::MutexLock l(&cxt->mu);
 | 
				
			||||||
    int a = cxt->g0 + 1;
 | 
					    int a = cxt->g0 + 1;
 | 
				
			||||||
| 
						 | 
					@ -100,8 +98,6 @@ static void TestMu(TestContext *cxt, int c) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void TestTry(TestContext *cxt, int c) {
 | 
					static void TestTry(TestContext *cxt, int c) {
 | 
				
			||||||
  SetInvariantChecked(false);
 | 
					 | 
				
			||||||
  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
 | 
					 | 
				
			||||||
  for (int i = 0; i != cxt->iterations; i++) {
 | 
					  for (int i = 0; i != cxt->iterations; i++) {
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      std::this_thread::yield();
 | 
					      std::this_thread::yield();
 | 
				
			||||||
| 
						 | 
					@ -122,8 +118,6 @@ static void TestR20ms(TestContext *cxt, int c) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void TestRW(TestContext *cxt, int c) {
 | 
					static void TestRW(TestContext *cxt, int c) {
 | 
				
			||||||
  SetInvariantChecked(false);
 | 
					 | 
				
			||||||
  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
 | 
					 | 
				
			||||||
  if ((c & 1) == 0) {
 | 
					  if ((c & 1) == 0) {
 | 
				
			||||||
    for (int i = 0; i != cxt->iterations; i++) {
 | 
					    for (int i = 0; i != cxt->iterations; i++) {
 | 
				
			||||||
      absl::WriterMutexLock l(&cxt->mu);
 | 
					      absl::WriterMutexLock l(&cxt->mu);
 | 
				
			||||||
| 
						 | 
					@ -356,68 +350,58 @@ static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
 | 
				
			||||||
  cv->Signal();
 | 
					  cv->Signal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Basis for the parameterized tests configured below.
 | 
					// Code common to RunTest() and RunTestWithInvariantDebugging().
 | 
				
			||||||
static int RunTest(void (*test)(TestContext *cxt, int), int threads,
 | 
					static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
 | 
				
			||||||
                   int iterations, int operations) {
 | 
					                         int threads, int iterations, int operations) {
 | 
				
			||||||
  TestContext cxt;
 | 
					 | 
				
			||||||
  absl::Mutex mu2;
 | 
					  absl::Mutex mu2;
 | 
				
			||||||
  absl::CondVar cv2;
 | 
					  absl::CondVar cv2;
 | 
				
			||||||
  int c0;
 | 
					  int c0 = 0;
 | 
				
			||||||
  int c1;
 | 
					  int c1 = 0;
 | 
				
			||||||
 | 
					  cxt->g0 = 0;
 | 
				
			||||||
  // run with large thread count for full test and to get timing
 | 
					  cxt->g1 = 0;
 | 
				
			||||||
 | 
					  cxt->iterations = iterations;
 | 
				
			||||||
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
					  cxt->threads = threads;
 | 
				
			||||||
  absl::EnableMutexInvariantDebugging(false);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  c0 = 0;
 | 
					 | 
				
			||||||
  c1 = 0;
 | 
					 | 
				
			||||||
  cxt.g0 = 0;
 | 
					 | 
				
			||||||
  cxt.g1 = 0;
 | 
					 | 
				
			||||||
  cxt.iterations = iterations;
 | 
					 | 
				
			||||||
  cxt.threads = threads;
 | 
					 | 
				
			||||||
  absl::synchronization_internal::ThreadPool tp(threads);
 | 
					  absl::synchronization_internal::ThreadPool tp(threads);
 | 
				
			||||||
  for (int i = 0; i != threads; i++) {
 | 
					  for (int i = 0; i != threads; i++) {
 | 
				
			||||||
    tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
 | 
					    tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
 | 
				
			||||||
                          std::function<void(int)>(
 | 
					                          std::function<void(int)>(
 | 
				
			||||||
                              std::bind(test, &cxt, std::placeholders::_1))));
 | 
					                              std::bind(test, cxt, std::placeholders::_1))));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  mu2.Lock();
 | 
					  mu2.Lock();
 | 
				
			||||||
  while (c1 != threads) {
 | 
					  while (c1 != threads) {
 | 
				
			||||||
    cv2.Wait(&mu2);
 | 
					    cv2.Wait(&mu2);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  mu2.Unlock();
 | 
					  mu2.Unlock();
 | 
				
			||||||
  int saved_g0 = cxt.g0;
 | 
					  return cxt->g0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // run again with small number of iterations to test invariant checking
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
					 | 
				
			||||||
  absl::EnableMutexInvariantDebugging(true);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  SetInvariantChecked(true);
 | 
					 | 
				
			||||||
  c0 = 0;
 | 
					 | 
				
			||||||
  c1 = 0;
 | 
					 | 
				
			||||||
  cxt.g0 = 0;
 | 
					 | 
				
			||||||
  cxt.g1 = 0;
 | 
					 | 
				
			||||||
  cxt.iterations = (iterations > 10 ? 10 : iterations);
 | 
					 | 
				
			||||||
  cxt.threads = threads;
 | 
					 | 
				
			||||||
  for (int i = 0; i != threads; i++) {
 | 
					 | 
				
			||||||
    tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
 | 
					 | 
				
			||||||
                          std::function<void(int)>(
 | 
					 | 
				
			||||||
                              std::bind(test, &cxt, std::placeholders::_1))));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  mu2.Lock();
 | 
					 | 
				
			||||||
  while (c1 != threads) {
 | 
					 | 
				
			||||||
    cv2.Wait(&mu2);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  mu2.Unlock();
 | 
					 | 
				
			||||||
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
					 | 
				
			||||||
  ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return saved_g0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Basis for the parameterized tests configured below.
 | 
				
			||||||
 | 
					static int RunTest(void (*test)(TestContext *cxt, int), int threads,
 | 
				
			||||||
 | 
					                   int iterations, int operations) {
 | 
				
			||||||
 | 
					  TestContext cxt;
 | 
				
			||||||
 | 
					  return RunTestCommon(&cxt, test, threads, iterations, operations);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Like RunTest(), but sets an invariant on the tested Mutex and
 | 
				
			||||||
 | 
					// verifies that the invariant check happened. The invariant function
 | 
				
			||||||
 | 
					// will be passed the TestContext* as its arg and must call
 | 
				
			||||||
 | 
					// SetInvariantChecked(true);
 | 
				
			||||||
 | 
					#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
				
			||||||
 | 
					static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
 | 
				
			||||||
 | 
					                                         int threads, int iterations,
 | 
				
			||||||
 | 
					                                         int operations,
 | 
				
			||||||
 | 
					                                         void (*invariant)(void *)) {
 | 
				
			||||||
 | 
					  absl::EnableMutexInvariantDebugging(true);
 | 
				
			||||||
 | 
					  SetInvariantChecked(false);
 | 
				
			||||||
 | 
					  TestContext cxt;
 | 
				
			||||||
 | 
					  cxt.mu.EnableInvariantDebugging(invariant, &cxt);
 | 
				
			||||||
 | 
					  int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
 | 
				
			||||||
 | 
					  ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
 | 
				
			||||||
 | 
					  absl::EnableMutexInvariantDebugging(false);  // Restore.
 | 
				
			||||||
 | 
					  return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --------------------------------------------------------
 | 
					// --------------------------------------------------------
 | 
				
			||||||
// Test for fix of bug in TryRemove()
 | 
					// Test for fix of bug in TryRemove()
 | 
				
			||||||
struct TimeoutBugStruct {
 | 
					struct TimeoutBugStruct {
 | 
				
			||||||
| 
						 | 
					@ -1463,6 +1447,13 @@ TEST_P(MutexVariableThreadCountTest, Mutex) {
 | 
				
			||||||
  int iterations = ScaleIterations(10000000) / threads;
 | 
					  int iterations = ScaleIterations(10000000) / threads;
 | 
				
			||||||
  int operations = threads * iterations;
 | 
					  int operations = threads * iterations;
 | 
				
			||||||
  EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
 | 
					  EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
 | 
				
			||||||
 | 
					#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
				
			||||||
 | 
					  iterations = std::min(iterations, 10);
 | 
				
			||||||
 | 
					  operations = threads * iterations;
 | 
				
			||||||
 | 
					  EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
 | 
				
			||||||
 | 
					                                          operations, CheckSumG0G1),
 | 
				
			||||||
 | 
					            operations);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_P(MutexVariableThreadCountTest, Try) {
 | 
					TEST_P(MutexVariableThreadCountTest, Try) {
 | 
				
			||||||
| 
						 | 
					@ -1470,6 +1461,13 @@ TEST_P(MutexVariableThreadCountTest, Try) {
 | 
				
			||||||
  int iterations = 1000000 / threads;
 | 
					  int iterations = 1000000 / threads;
 | 
				
			||||||
  int operations = iterations * threads;
 | 
					  int operations = iterations * threads;
 | 
				
			||||||
  EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
 | 
					  EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
 | 
				
			||||||
 | 
					#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
				
			||||||
 | 
					  iterations = std::min(iterations, 10);
 | 
				
			||||||
 | 
					  operations = threads * iterations;
 | 
				
			||||||
 | 
					  EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
 | 
				
			||||||
 | 
					                                          operations, CheckSumG0G1),
 | 
				
			||||||
 | 
					            operations);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_P(MutexVariableThreadCountTest, R20ms) {
 | 
					TEST_P(MutexVariableThreadCountTest, R20ms) {
 | 
				
			||||||
| 
						 | 
					@ -1484,6 +1482,13 @@ TEST_P(MutexVariableThreadCountTest, RW) {
 | 
				
			||||||
  int iterations = ScaleIterations(20000000) / threads;
 | 
					  int iterations = ScaleIterations(20000000) / threads;
 | 
				
			||||||
  int operations = iterations * threads;
 | 
					  int operations = iterations * threads;
 | 
				
			||||||
  EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
 | 
					  EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
 | 
				
			||||||
 | 
					#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
 | 
				
			||||||
 | 
					  iterations = std::min(iterations, 10);
 | 
				
			||||||
 | 
					  operations = threads * iterations;
 | 
				
			||||||
 | 
					  EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
 | 
				
			||||||
 | 
					                                          operations, CheckSumG0G1),
 | 
				
			||||||
 | 
					            operations / 2);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_P(MutexVariableThreadCountTest, Await) {
 | 
					TEST_P(MutexVariableThreadCountTest, Await) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ const struct ZoneInfo {
 | 
				
			||||||
    {"US/Pacific",  //
 | 
					    {"US/Pacific",  //
 | 
				
			||||||
     reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
 | 
					     reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Allows use of the local time zone from a common system-specific location.
 | 
					    // Allows use of the local time zone from a system-specific location.
 | 
				
			||||||
#ifdef _MSC_VER
 | 
					#ifdef _MSC_VER
 | 
				
			||||||
    {"localtime",  //
 | 
					    {"localtime",  //
 | 
				
			||||||
     reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
 | 
					     reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1126,8 +1126,10 @@ constexpr Duration OppositeInfinity(Duration d) {
 | 
				
			||||||
             : MakeDuration(std::numeric_limits<int64_t>::min(), ~0U);
 | 
					             : 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) {
 | 
					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;
 | 
					  return (n < 0) ? -(n + 1) : (-n) - 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1232,26 +1234,21 @@ constexpr bool operator==(Duration lhs, Duration rhs) {
 | 
				
			||||||
constexpr Duration operator-(Duration d) {
 | 
					constexpr Duration operator-(Duration d) {
 | 
				
			||||||
  // This is a little interesting because of the special cases.
 | 
					  // 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
 | 
					  // Infinities stay infinite, and just change direction.
 | 
				
			||||||
  // 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()).
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Finally we're in the case where rep_lo_ is non-zero, and we can borrow
 | 
					  // 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
 | 
					  // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1
 | 
				
			||||||
  // is safe).
 | 
					  // is safe).
 | 
				
			||||||
  return time_internal::IsInfiniteDuration(d)
 | 
					  return time_internal::GetRepLo(d) == 0
 | 
				
			||||||
             ? time_internal::OppositeInfinity(d)
 | 
					             ? time_internal::GetRepHi(d) == std::numeric_limits<int64_t>::min()
 | 
				
			||||||
             : (time_internal::GetRepHi(d) ==
 | 
					 | 
				
			||||||
                    std::numeric_limits<int64_t>::min() &&
 | 
					 | 
				
			||||||
                time_internal::GetRepLo(d) == 0)
 | 
					 | 
				
			||||||
                   ? InfiniteDuration()
 | 
					                   ? InfiniteDuration()
 | 
				
			||||||
                   : (time_internal::GetRepLo(d) == 0)
 | 
					                   : time_internal::MakeDuration(-time_internal::GetRepHi(d))
 | 
				
			||||||
                         ? time_internal::MakeDuration(
 | 
					             : time_internal::IsInfiniteDuration(d)
 | 
				
			||||||
                               -time_internal::GetRepHi(d))
 | 
					                   ? time_internal::OppositeInfinity(d)
 | 
				
			||||||
                   : time_internal::MakeDuration(
 | 
					                   : time_internal::MakeDuration(
 | 
				
			||||||
                         time_internal::NegateAndSubtractOne(
 | 
					                         time_internal::NegateAndSubtractOne(
 | 
				
			||||||
                             time_internal::GetRepHi(d)),
 | 
					                             time_internal::GetRepHi(d)),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue