Export of internal Abseil changes.
-- cd076f55c1fa600131f6dda392533dfe61679fc0 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 224008762 -- e05f62b01286d51044ff86ec6ef565749b9faf82 by Abseil Team <absl-team@google.com>: Create a pow10() test helper function to compute guaranteed-precise double values of 10^x. Not all standard libraries ship bit-accurate pow() functions, causing tests to fail that rely on expected values generated by it. PiperOrigin-RevId: 223883762 -- fd88e5e3f7ab80f7f5df9fd1488cd58b4573be69 by Abseil Team <absl-team@google.com>: Remove some absl:: qualifications to work around inline namespace bugs on MSVC 2015. PiperOrigin-RevId: 223869642 -- 6276cfff969d596edd36a2bbaba65ee045808903 by Abseil Team <absl-team@google.com>: Update absl/memory/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223854224 -- 359de9afc7a34c975fd3e0cbc52afd96637d97bd by Chris Kennelly <ckennelly@google.com>: Mark spinlock_benchmark_common as alwayslink = 1. PiperOrigin-RevId: 223844536 -- 450cd8cbe2789a6d54ed1eb87170259bb334f8b9 by Abseil Team <absl-team@google.com>: Support .* (pointer-to-member dereference) expressions in demangle.cc. PiperOrigin-RevId: 223826797 -- 772ca92179c3634f3e31a80bbc272ed8022e3572 by Abseil Team <absl-team@google.com>: Fix misspellings in absl::variant comments and replace a ' with a `. PiperOrigin-RevId: 223807911 -- 35dcdc2fbf299d195658aac101887f6dcad1de2f by Abseil Team <absl-team@google.com>: Bug fix in CMakeLists.txt file (SRCS --> HDRS). The compressed_tuple header-only library is being defined with the SRCS parameter instead of the HDRS parameter and this has been observed to cause some builds on some platforms to attempt to create a static library from it which fails since there are no .cc sources. PiperOrigin-RevId: 223805367 -- 4a57a3d2045bb137c0c97958e45ce425190b8d3e by Chris Kennelly <ckennelly@google.com>: Add test that absl::make_unique value initializes memory. PiperOrigin-RevId: 223801819 -- dfe8289d7f4dcc6bb568a26aaf192a89e896bdfd by Chris Kennelly <ckennelly@google.com>: SpinLock: Use exchange to avoid missing wakeups. The default fast path for SpinLock::Unlock does not use an atomic. If the SpinLock becomes contended while we are unlocking between lockword_.load and lockword_.store, we will fail to wake up the new waiter. This can cause unexpected latency spikes. PiperOrigin-RevId: 223800369 -- 9b9d35df786482f0016f77dd31691eff81503d23 by Abseil Team <absl-team@google.com>: Update absl/hash/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223755819 -- c2014e2704b87e7cdce2d2a0287c7e2397752296 by Abseil Team <absl-team@google.com>: Update absl/debugging/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223751986 -- d83a4e09126400e3fd80645cb03ee558f532271e by Derek Mauro <dmauro@google.com>: Cleanup synchronization benchmarks. PiperOrigin-RevId: 223589416 -- fad140b473586531b5b12843f942ec27dfcf5e93 by CJ Johnson <johnsoncj@google.com>: Makes unifies the order of forward_iterator and input_iterator overloads PiperOrigin-RevId: 223580660 -- 6cd7c96faa7cc5f79f574e35a1b13837ef187d05 by Abseil Team <absl-team@google.com>: Internal Change. PiperOrigin-RevId: 223561629 -- bd2e545356b0f548af0e3c14bb2f7f0e712e49d0 by Shaindel Schwartz <shaindel@google.com>: Remove misleading comments. try_emplace() does not exist for the hash_set containers. PiperOrigin-RevId: 223543089 -- 0cd380a53b587eb7aacc4003a4a3bbb6c78d7c10 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 223512551 -- 7156dfee599cb72e9adddfe0e6ae07a95ddf10bb by Greg Miller <jgm@google.com>: Fixes UB that would result from constructing, multiplying, or dividing a Duration with a double "NaN" value. This CL changes the absl::Duration *implementation* to return an InfiniteDuration value that has the same sign as the given NaN. PiperOrigin-RevId: 223407499 -- 196b7d18609958267951882baf7f9429e49bcafa by CJ Johnson <johnsoncj@google.com>: Addresses NVCC+MSVC compilation bug where `inlined_capacity()` was not considered valid in constexpr PiperOrigin-RevId: 223397718 GitOrigin-RevId: cd076f55c1fa600131f6dda392533dfe61679fc0 Change-Id: I5423ca6470f661a7c6f73aa8fee49990446f157f
This commit is contained in:
		
							parent
							
								
									926bfeb9ff
								
							
						
					
					
						commit
						44b0fafc62
					
				
					 30 changed files with 1126 additions and 383 deletions
				
			
		| 
						 | 
					@ -17,6 +17,12 @@
 | 
				
			||||||
# We require 3.0 for modern, target-based CMake.  We require 3.1 for the use of
 | 
					# We require 3.0 for modern, target-based CMake.  We require 3.1 for the use of
 | 
				
			||||||
# CXX_STANDARD in our targets.
 | 
					# CXX_STANDARD in our targets.
 | 
				
			||||||
cmake_minimum_required(VERSION 3.1)
 | 
					cmake_minimum_required(VERSION 3.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Compiler id for Apple Clang is now AppleClang.
 | 
				
			||||||
 | 
					if (POLICY CMP0025)
 | 
				
			||||||
 | 
					  cmake_policy(SET CMP0025 NEW)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project(absl)
 | 
					project(absl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake)
 | 
					list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake)
 | 
				
			||||||
| 
						 | 
					@ -68,6 +74,12 @@ set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}")
 | 
				
			||||||
# -fexceptions
 | 
					# -fexceptions
 | 
				
			||||||
set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}")
 | 
					set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
 | 
				
			||||||
 | 
					  set(ABSL_USING_CLANG ON)
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					  set(ABSL_USING_CLANG OFF)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# find dependencies
 | 
					# find dependencies
 | 
				
			||||||
## pthread
 | 
					## pthread
 | 
				
			||||||
find_package(Threads REQUIRED)
 | 
					find_package(Threads REQUIRED)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,7 @@ cc_library(
 | 
				
			||||||
        "internal/identity.h",
 | 
					        "internal/identity.h",
 | 
				
			||||||
        "internal/inline_variable.h",
 | 
					        "internal/inline_variable.h",
 | 
				
			||||||
        "internal/invoke.h",
 | 
					        "internal/invoke.h",
 | 
				
			||||||
 | 
					        "internal/scheduling_mode.h",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    copts = ABSL_DEFAULT_COPTS,
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
    visibility = [
 | 
					    visibility = [
 | 
				
			||||||
| 
						 | 
					@ -313,6 +314,33 @@ cc_test(
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_library(
 | 
				
			||||||
 | 
					    name = "spinlock_benchmark_common",
 | 
				
			||||||
 | 
					    testonly = 1,
 | 
				
			||||||
 | 
					    srcs = ["internal/spinlock_benchmark.cc"],
 | 
				
			||||||
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
 | 
					    visibility = [
 | 
				
			||||||
 | 
					        "//absl/base:__pkg__",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":base",
 | 
				
			||||||
 | 
					        ":base_internal",
 | 
				
			||||||
 | 
					        "//absl/synchronization",
 | 
				
			||||||
 | 
					        "@com_github_google_benchmark//:benchmark_main",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    alwayslink = 1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_binary(
 | 
				
			||||||
 | 
					    name = "spinlock_benchmark",
 | 
				
			||||||
 | 
					    testonly = 1,
 | 
				
			||||||
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":spinlock_benchmark_common",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_library(
 | 
					cc_library(
 | 
				
			||||||
    name = "endian",
 | 
					    name = "endian",
 | 
				
			||||||
    hdrs = [
 | 
					    hdrs = [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,8 +101,8 @@ class LOCKABLE SpinLock {
 | 
				
			||||||
  inline void Unlock() UNLOCK_FUNCTION() {
 | 
					  inline void Unlock() UNLOCK_FUNCTION() {
 | 
				
			||||||
    ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
 | 
					    ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
 | 
				
			||||||
    uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
 | 
					    uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
 | 
				
			||||||
    lockword_.store(lock_value & kSpinLockCooperative,
 | 
					    lock_value = lockword_.exchange(lock_value & kSpinLockCooperative,
 | 
				
			||||||
                    std::memory_order_release);
 | 
					                                    std::memory_order_release);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((lock_value & kSpinLockDisabledScheduling) != 0) {
 | 
					    if ((lock_value & kSpinLockDisabledScheduling) != 0) {
 | 
				
			||||||
      base_internal::SchedulingGuard::EnableRescheduling(true);
 | 
					      base_internal::SchedulingGuard::EnableRescheduling(true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								absl/base/internal/spinlock_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								absl/base/internal/spinlock_benchmark.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					// Copyright 2018 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// See also //absl/synchronization:mutex_benchmark for a comparison of SpinLock
 | 
				
			||||||
 | 
					// and Mutex performance under varying levels of contention.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/base/internal/raw_logging.h"
 | 
				
			||||||
 | 
					#include "absl/base/internal/scheduling_mode.h"
 | 
				
			||||||
 | 
					#include "absl/base/internal/spinlock.h"
 | 
				
			||||||
 | 
					#include "absl/synchronization/internal/create_thread_identity.h"
 | 
				
			||||||
 | 
					#include "benchmark/benchmark.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <absl::base_internal::SchedulingMode scheduling_mode>
 | 
				
			||||||
 | 
					static void BM_SpinLock(benchmark::State& state) {
 | 
				
			||||||
 | 
					  // Ensure a ThreadIdentity is installed.
 | 
				
			||||||
 | 
					  ABSL_INTERNAL_CHECK(
 | 
				
			||||||
 | 
					      absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() !=
 | 
				
			||||||
 | 
					          nullptr,
 | 
				
			||||||
 | 
					      "GetOrCreateCurrentThreadIdentity() failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static auto* spinlock = new absl::base_internal::SpinLock(scheduling_mode);
 | 
				
			||||||
 | 
					  for (auto _ : state) {
 | 
				
			||||||
 | 
					    absl::base_internal::SpinLockHolder holder(spinlock);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_TEMPLATE(BM_SpinLock,
 | 
				
			||||||
 | 
					                   absl::base_internal::SCHEDULE_KERNEL_ONLY)
 | 
				
			||||||
 | 
					    ->UseRealTime()
 | 
				
			||||||
 | 
					    ->Threads(1)
 | 
				
			||||||
 | 
					    ->ThreadPerCpu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_TEMPLATE(BM_SpinLock,
 | 
				
			||||||
 | 
					                   absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL)
 | 
				
			||||||
 | 
					    ->UseRealTime()
 | 
				
			||||||
 | 
					    ->Threads(1)
 | 
				
			||||||
 | 
					    ->ThreadPerCpu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ absl_cc_library(
 | 
				
			||||||
absl_cc_library(
 | 
					absl_cc_library(
 | 
				
			||||||
  NAME
 | 
					  NAME
 | 
				
			||||||
    compressed_tuple
 | 
					    compressed_tuple
 | 
				
			||||||
  SRCS
 | 
					  HDRS
 | 
				
			||||||
   "internal/compressed_tuple.h"
 | 
					   "internal/compressed_tuple.h"
 | 
				
			||||||
  DEPS
 | 
					  DEPS
 | 
				
			||||||
    absl::utility
 | 
					    absl::utility
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -279,8 +279,7 @@ class flat_hash_set
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // The element may be constructed even if there already is an element with the
 | 
					  // The element may be constructed even if there already is an element with the
 | 
				
			||||||
  // key in the container, in which case the newly constructed element will be
 | 
					  // key in the container, in which case the newly constructed element will be
 | 
				
			||||||
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
 | 
					  // destroyed immediately.
 | 
				
			||||||
  // copyable or moveable.
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
					  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
				
			||||||
  using Base::emplace;
 | 
					  using Base::emplace;
 | 
				
			||||||
| 
						 | 
					@ -294,8 +293,7 @@ class flat_hash_set
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // The element may be constructed even if there already is an element with the
 | 
					  // The element may be constructed even if there already is an element with the
 | 
				
			||||||
  // key in the container, in which case the newly constructed element will be
 | 
					  // key in the container, in which case the newly constructed element will be
 | 
				
			||||||
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
 | 
					  // destroyed immediately.
 | 
				
			||||||
  // copyable or moveable.
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
					  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
				
			||||||
  using Base::emplace_hint;
 | 
					  using Base::emplace_hint;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,12 +66,11 @@ namespace absl {
 | 
				
			||||||
// designed to cover the same API footprint as covered by `std::vector`.
 | 
					// designed to cover the same API footprint as covered by `std::vector`.
 | 
				
			||||||
template <typename T, size_t N, typename A = std::allocator<T>>
 | 
					template <typename T, size_t N, typename A = std::allocator<T>>
 | 
				
			||||||
class InlinedVector {
 | 
					class InlinedVector {
 | 
				
			||||||
 | 
					  static_assert(N > 0, "InlinedVector requires inline capacity greater than 0");
 | 
				
			||||||
  constexpr static typename A::size_type inlined_capacity() {
 | 
					  constexpr static typename A::size_type inlined_capacity() {
 | 
				
			||||||
    return static_cast<typename A::size_type>(N);
 | 
					    return static_cast<typename A::size_type>(N);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static_assert(inlined_capacity() > 0, "InlinedVector needs inlined capacity");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template <typename Iterator>
 | 
					  template <typename Iterator>
 | 
				
			||||||
  using DisableIfIntegral =
 | 
					  using DisableIfIntegral =
 | 
				
			||||||
      absl::enable_if_t<!std::is_integral<Iterator>::value>;
 | 
					      absl::enable_if_t<!std::is_integral<Iterator>::value>;
 | 
				
			||||||
| 
						 | 
					@ -131,7 +130,8 @@ class InlinedVector {
 | 
				
			||||||
  InlinedVector(std::initializer_list<value_type> init_list,
 | 
					  InlinedVector(std::initializer_list<value_type> init_list,
 | 
				
			||||||
                const allocator_type& alloc = allocator_type())
 | 
					                const allocator_type& alloc = allocator_type())
 | 
				
			||||||
      : allocator_and_tag_(alloc) {
 | 
					      : allocator_and_tag_(alloc) {
 | 
				
			||||||
    AppendRange(init_list.begin(), init_list.end());
 | 
					    AppendRange(init_list.begin(), init_list.end(),
 | 
				
			||||||
 | 
					                IteratorCategory<decltype(init_list.begin())>{});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates an inlined vector with elements constructed from the provided
 | 
					  // Creates an inlined vector with elements constructed from the provided
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ class InlinedVector {
 | 
				
			||||||
  InlinedVector(InputIterator first, InputIterator last,
 | 
					  InlinedVector(InputIterator first, InputIterator last,
 | 
				
			||||||
                const allocator_type& alloc = allocator_type())
 | 
					                const allocator_type& alloc = allocator_type())
 | 
				
			||||||
      : allocator_and_tag_(alloc) {
 | 
					      : allocator_and_tag_(alloc) {
 | 
				
			||||||
    AppendRange(first, last);
 | 
					    AppendRange(first, last, IteratorCategory<InputIterator>{});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates a copy of `other` using `other`'s allocator.
 | 
					  // Creates a copy of `other` using `other`'s allocator.
 | 
				
			||||||
| 
						 | 
					@ -366,7 +366,6 @@ class InlinedVector {
 | 
				
			||||||
  // Returns a copy of the allocator of the inlined vector.
 | 
					  // Returns a copy of the allocator of the inlined vector.
 | 
				
			||||||
  allocator_type get_allocator() const { return allocator(); }
 | 
					  allocator_type get_allocator() const { return allocator(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // ---------------------------------------------------------------------------
 | 
					  // ---------------------------------------------------------------------------
 | 
				
			||||||
  // InlinedVector Member Mutators
 | 
					  // InlinedVector Member Mutators
 | 
				
			||||||
  // ---------------------------------------------------------------------------
 | 
					  // ---------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -376,7 +375,8 @@ class InlinedVector {
 | 
				
			||||||
  // Replaces the contents of the inlined vector with copies of the elements in
 | 
					  // Replaces the contents of the inlined vector with copies of the elements in
 | 
				
			||||||
  // the provided `std::initializer_list`.
 | 
					  // the provided `std::initializer_list`.
 | 
				
			||||||
  InlinedVector& operator=(std::initializer_list<value_type> init_list) {
 | 
					  InlinedVector& operator=(std::initializer_list<value_type> init_list) {
 | 
				
			||||||
    AssignRange(init_list.begin(), init_list.end());
 | 
					    AssignRange(init_list.begin(), init_list.end(),
 | 
				
			||||||
 | 
					                IteratorCategory<decltype(init_list.begin())>{});
 | 
				
			||||||
    return *this;
 | 
					    return *this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -453,14 +453,15 @@ class InlinedVector {
 | 
				
			||||||
  // inlined vector with copies of the values in the provided
 | 
					  // inlined vector with copies of the values in the provided
 | 
				
			||||||
  // `std::initializer_list`.
 | 
					  // `std::initializer_list`.
 | 
				
			||||||
  void assign(std::initializer_list<value_type> init_list) {
 | 
					  void assign(std::initializer_list<value_type> init_list) {
 | 
				
			||||||
    AssignRange(init_list.begin(), init_list.end());
 | 
					    AssignRange(init_list.begin(), init_list.end(),
 | 
				
			||||||
 | 
					                IteratorCategory<decltype(init_list.begin())>{});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Overload of `InlinedVector::assign()` to replace the contents of the
 | 
					  // Overload of `InlinedVector::assign()` to replace the contents of the
 | 
				
			||||||
  // inlined vector with values constructed from the range [`first`, `last`).
 | 
					  // inlined vector with values constructed from the range [`first`, `last`).
 | 
				
			||||||
  template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr>
 | 
					  template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr>
 | 
				
			||||||
  void assign(InputIterator first, InputIterator last) {
 | 
					  void assign(InputIterator first, InputIterator last) {
 | 
				
			||||||
    AssignRange(first, last);
 | 
					    AssignRange(first, last, IteratorCategory<InputIterator>{});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // `InlinedVector::resize()`
 | 
					  // `InlinedVector::resize()`
 | 
				
			||||||
| 
						 | 
					@ -844,41 +845,29 @@ class InlinedVector {
 | 
				
			||||||
  // Destroy [`from`, `to`) in place.
 | 
					  // Destroy [`from`, `to`) in place.
 | 
				
			||||||
  void Destroy(pointer from, pointer to);
 | 
					  void Destroy(pointer from, pointer to);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename Iterator>
 | 
					 | 
				
			||||||
  void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) {
 | 
					 | 
				
			||||||
    std::copy(first, last, std::back_inserter(*this));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template <typename Iterator>
 | 
					  template <typename Iterator>
 | 
				
			||||||
  void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag);
 | 
					  void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename Iterator>
 | 
					  template <typename Iterator>
 | 
				
			||||||
  void AppendRange(Iterator first, Iterator last) {
 | 
					  void AppendRange(Iterator first, Iterator last, std::input_iterator_tag);
 | 
				
			||||||
    AppendRange(first, last, IteratorCategory<Iterator>());
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template <typename Iterator>
 | 
					 | 
				
			||||||
  void AssignRange(Iterator first, Iterator last, std::input_iterator_tag);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename Iterator>
 | 
					  template <typename Iterator>
 | 
				
			||||||
  void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag);
 | 
					  void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename Iterator>
 | 
					  template <typename Iterator>
 | 
				
			||||||
  void AssignRange(Iterator first, Iterator last) {
 | 
					  void AssignRange(Iterator first, Iterator last, std::input_iterator_tag);
 | 
				
			||||||
    AssignRange(first, last, IteratorCategory<Iterator>());
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  iterator InsertWithCount(const_iterator position, size_type n,
 | 
					  iterator InsertWithCount(const_iterator position, size_type n,
 | 
				
			||||||
                           const_reference v);
 | 
					                           const_reference v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename InputIterator>
 | 
					 | 
				
			||||||
  iterator InsertWithRange(const_iterator position, InputIterator first,
 | 
					 | 
				
			||||||
                           InputIterator last, std::input_iterator_tag);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template <typename ForwardIterator>
 | 
					  template <typename ForwardIterator>
 | 
				
			||||||
  iterator InsertWithRange(const_iterator position, ForwardIterator first,
 | 
					  iterator InsertWithRange(const_iterator position, ForwardIterator first,
 | 
				
			||||||
                           ForwardIterator last, std::forward_iterator_tag);
 | 
					                           ForwardIterator last, std::forward_iterator_tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename InputIterator>
 | 
				
			||||||
 | 
					  iterator InsertWithRange(const_iterator position, InputIterator first,
 | 
				
			||||||
 | 
					                           InputIterator last, std::input_iterator_tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Stores either the inlined or allocated representation
 | 
					  // Stores either the inlined or allocated representation
 | 
				
			||||||
  union Rep {
 | 
					  union Rep {
 | 
				
			||||||
    using ValueTypeBuffer =
 | 
					    using ValueTypeBuffer =
 | 
				
			||||||
| 
						 | 
					@ -889,7 +878,7 @@ class InlinedVector {
 | 
				
			||||||
    // Structs wrap the buffers to perform indirection that solves a bizarre
 | 
					    // Structs wrap the buffers to perform indirection that solves a bizarre
 | 
				
			||||||
    // compilation error on Visual Studio (all known versions).
 | 
					    // compilation error on Visual Studio (all known versions).
 | 
				
			||||||
    struct InlinedRep {
 | 
					    struct InlinedRep {
 | 
				
			||||||
      ValueTypeBuffer inlined[inlined_capacity()];
 | 
					      ValueTypeBuffer inlined[N];
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    struct AllocatedRep {
 | 
					    struct AllocatedRep {
 | 
				
			||||||
      AllocationBuffer allocation;
 | 
					      AllocationBuffer allocation;
 | 
				
			||||||
| 
						 | 
					@ -1364,15 +1353,8 @@ void InlinedVector<T, N, A>::AppendRange(Iterator first, Iterator last,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T, size_t N, typename A>
 | 
					template <typename T, size_t N, typename A>
 | 
				
			||||||
template <typename Iterator>
 | 
					template <typename Iterator>
 | 
				
			||||||
void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last,
 | 
					void InlinedVector<T, N, A>::AppendRange(Iterator first, Iterator last,
 | 
				
			||||||
                                         std::input_iterator_tag) {
 | 
					                                         std::input_iterator_tag) {
 | 
				
			||||||
  // Optimized to avoid reallocation.
 | 
					 | 
				
			||||||
  // Prefer reassignment to copy construction for elements.
 | 
					 | 
				
			||||||
  iterator out = begin();
 | 
					 | 
				
			||||||
  for (; first != last && out != end(); ++first, ++out) {
 | 
					 | 
				
			||||||
    *out = *first;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  erase(out, end());
 | 
					 | 
				
			||||||
  std::copy(first, last, std::back_inserter(*this));
 | 
					  std::copy(first, last, std::back_inserter(*this));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1398,6 +1380,20 @@ void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, size_t N, typename A>
 | 
				
			||||||
 | 
					template <typename Iterator>
 | 
				
			||||||
 | 
					void InlinedVector<T, N, A>::AssignRange(Iterator first, Iterator last,
 | 
				
			||||||
 | 
					                                         std::input_iterator_tag) {
 | 
				
			||||||
 | 
					  // Optimized to avoid reallocation.
 | 
				
			||||||
 | 
					  // Prefer reassignment to copy construction for elements.
 | 
				
			||||||
 | 
					  iterator out = begin();
 | 
				
			||||||
 | 
					  for (; first != last && out != end(); ++first, ++out) {
 | 
				
			||||||
 | 
					    *out = *first;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  erase(out, end());
 | 
				
			||||||
 | 
					  std::copy(first, last, std::back_inserter(*this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T, size_t N, typename A>
 | 
					template <typename T, size_t N, typename A>
 | 
				
			||||||
auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position,
 | 
					auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position,
 | 
				
			||||||
                                             size_type n, const_reference v)
 | 
					                                             size_type n, const_reference v)
 | 
				
			||||||
| 
						 | 
					@ -1413,20 +1409,6 @@ auto InlinedVector<T, N, A>::InsertWithCount(const_iterator position,
 | 
				
			||||||
  return it_pair.first;
 | 
					  return it_pair.first;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T, size_t N, typename A>
 | 
					 | 
				
			||||||
template <typename InputIterator>
 | 
					 | 
				
			||||||
auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position,
 | 
					 | 
				
			||||||
                                             InputIterator first,
 | 
					 | 
				
			||||||
                                             InputIterator last,
 | 
					 | 
				
			||||||
                                             std::input_iterator_tag)
 | 
					 | 
				
			||||||
    -> iterator {
 | 
					 | 
				
			||||||
  assert(position >= begin() && position <= end());
 | 
					 | 
				
			||||||
  size_type index = position - cbegin();
 | 
					 | 
				
			||||||
  size_type i = index;
 | 
					 | 
				
			||||||
  while (first != last) insert(begin() + i++, *first++);
 | 
					 | 
				
			||||||
  return begin() + index;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template <typename T, size_t N, typename A>
 | 
					template <typename T, size_t N, typename A>
 | 
				
			||||||
template <typename ForwardIterator>
 | 
					template <typename ForwardIterator>
 | 
				
			||||||
auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position,
 | 
					auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position,
 | 
				
			||||||
| 
						 | 
					@ -1446,6 +1428,20 @@ auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position,
 | 
				
			||||||
  return it_pair.first;
 | 
					  return it_pair.first;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, size_t N, typename A>
 | 
				
			||||||
 | 
					template <typename InputIterator>
 | 
				
			||||||
 | 
					auto InlinedVector<T, N, A>::InsertWithRange(const_iterator position,
 | 
				
			||||||
 | 
					                                             InputIterator first,
 | 
				
			||||||
 | 
					                                             InputIterator last,
 | 
				
			||||||
 | 
					                                             std::input_iterator_tag)
 | 
				
			||||||
 | 
					    -> iterator {
 | 
				
			||||||
 | 
					  assert(position >= begin() && position <= end());
 | 
				
			||||||
 | 
					  size_type index = position - cbegin();
 | 
				
			||||||
 | 
					  size_type i = index;
 | 
				
			||||||
 | 
					  while (first != last) insert(begin() + i++, *first++);
 | 
				
			||||||
 | 
					  return begin() + index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
 | 
					#endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,8 +253,10 @@ template <class From, class To>
 | 
				
			||||||
using CopyConst =
 | 
					using CopyConst =
 | 
				
			||||||
    typename std::conditional<std::is_const<From>::value, const To, To>::type;
 | 
					    typename std::conditional<std::is_const<From>::value, const To, To>::type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note: We're not qualifying this with absl:: because it doesn't compile under
 | 
				
			||||||
 | 
					// MSVC.
 | 
				
			||||||
template <class T>
 | 
					template <class T>
 | 
				
			||||||
using SliceType = absl::Span<T>;
 | 
					using SliceType = Span<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This namespace contains no types. It prevents functions defined in it from
 | 
					// This namespace contains no types. It prevents functions defined in it from
 | 
				
			||||||
// being found by ADL.
 | 
					// being found by ADL.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/container/internal/raw_hash_set.h"
 | 
					#include "absl/container/internal/raw_hash_set.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <atomic>
 | 
				
			||||||
#include <cstddef>
 | 
					#include <cstddef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/base/config.h"
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
| 
						 | 
					@ -29,7 +30,7 @@ inline size_t RandomSeed() {
 | 
				
			||||||
  static thread_local size_t counter = 0;
 | 
					  static thread_local size_t counter = 0;
 | 
				
			||||||
  size_t value = ++counter;
 | 
					  size_t value = ++counter;
 | 
				
			||||||
#else   // ABSL_HAVE_THREAD_LOCAL
 | 
					#else   // ABSL_HAVE_THREAD_LOCAL
 | 
				
			||||||
  static std::atomic<size_t> counter;
 | 
					  static std::atomic<size_t> counter(0);
 | 
				
			||||||
  size_t value = counter.fetch_add(1, std::memory_order_relaxed);
 | 
					  size_t value = counter.fetch_add(1, std::memory_order_relaxed);
 | 
				
			||||||
#endif  // ABSL_HAVE_THREAD_LOCAL
 | 
					#endif  // ABSL_HAVE_THREAD_LOCAL
 | 
				
			||||||
  return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter));
 | 
					  return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -273,8 +273,7 @@ class node_hash_set
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // The element may be constructed even if there already is an element with the
 | 
					  // The element may be constructed even if there already is an element with the
 | 
				
			||||||
  // key in the container, in which case the newly constructed element will be
 | 
					  // key in the container, in which case the newly constructed element will be
 | 
				
			||||||
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
 | 
					  // destroyed immediately.
 | 
				
			||||||
  // copyable or moveable.
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
					  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
				
			||||||
  using Base::emplace;
 | 
					  using Base::emplace;
 | 
				
			||||||
| 
						 | 
					@ -288,8 +287,7 @@ class node_hash_set
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // The element may be constructed even if there already is an element with the
 | 
					  // The element may be constructed even if there already is an element with the
 | 
				
			||||||
  // key in the container, in which case the newly constructed element will be
 | 
					  // key in the container, in which case the newly constructed element will be
 | 
				
			||||||
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
 | 
					  // destroyed immediately.
 | 
				
			||||||
  // copyable or moveable.
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
					  // If rehashing occurs due to the insertion, all iterators are invalidated.
 | 
				
			||||||
  using Base::emplace_hint;
 | 
					  using Base::emplace_hint;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,204 +14,297 @@
 | 
				
			||||||
# limitations under the License.
 | 
					# limitations under the License.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND DEBUGGING_PUBLIC_HEADERS
 | 
					absl_cc_library(
 | 
				
			||||||
  "failure_signal_handler.h"
 | 
					  NAME
 | 
				
			||||||
  "leak_check.h"
 | 
					 | 
				
			||||||
  "stacktrace.h"
 | 
					 | 
				
			||||||
  "symbolize.h"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TODO(cohenjon) The below is all kinds of wrong.  Make this match what we do in
 | 
					 | 
				
			||||||
# Bazel
 | 
					 | 
				
			||||||
list(APPEND DEBUGGING_INTERNAL_HEADERS
 | 
					 | 
				
			||||||
  "internal/address_is_readable.h"
 | 
					 | 
				
			||||||
  "internal/demangle.h"
 | 
					 | 
				
			||||||
  "internal/elf_mem_image.h"
 | 
					 | 
				
			||||||
  "internal/examine_stack.h"
 | 
					 | 
				
			||||||
  "internal/stacktrace_config.h"
 | 
					 | 
				
			||||||
  "internal/symbolize.h"
 | 
					 | 
				
			||||||
  "internal/vdso_support.h"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND DEBUGGING_INTERNAL_SRC
 | 
					 | 
				
			||||||
  "internal/address_is_readable.cc"
 | 
					 | 
				
			||||||
  "internal/elf_mem_image.cc"
 | 
					 | 
				
			||||||
  "internal/vdso_support.cc"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND STACKTRACE_SRC
 | 
					 | 
				
			||||||
  "stacktrace.cc"
 | 
					 | 
				
			||||||
  ${DEBUGGING_INTERNAL_SRC}
 | 
					 | 
				
			||||||
  ${DEBUGGING_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
  ${DEBUGGING_INTERNAL_HEADERS}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND SYMBOLIZE_SRC
 | 
					 | 
				
			||||||
  "symbolize.cc"
 | 
					 | 
				
			||||||
  "symbolize_elf.inc"
 | 
					 | 
				
			||||||
  "symbolize_unimplemented.inc"
 | 
					 | 
				
			||||||
  "symbolize_win32.inc"
 | 
					 | 
				
			||||||
  "internal/demangle.cc"
 | 
					 | 
				
			||||||
  ${DEBUGGING_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
  ${DEBUGGING_INTERNAL_HEADERS}
 | 
					 | 
				
			||||||
  ${DEBUGGING_INTERNAL_SRC}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND FAILURE_SIGNAL_HANDLER_SRC
 | 
					 | 
				
			||||||
  "failure_signal_handler.cc"
 | 
					 | 
				
			||||||
  ${DEBUGGING_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND EXAMINE_STACK_SRC
 | 
					 | 
				
			||||||
  "internal/examine_stack.cc"
 | 
					 | 
				
			||||||
  ${DEBUGGING_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
  ${DEBUGGING_INTERNAL_HEADERS}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_stacktrace
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${STACKTRACE_SRC}
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    stacktrace
 | 
					    stacktrace
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "stacktrace.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "stacktrace.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::debugging_internal
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_library(
 | 
					absl_cc_library(
 | 
				
			||||||
  TARGET
 | 
					  NAME
 | 
				
			||||||
    absl_symbolize
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${SYMBOLIZE_SRC}
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    absl::base
 | 
					 | 
				
			||||||
    absl::malloc_internal
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    symbolize
 | 
					    symbolize
 | 
				
			||||||
)
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "symbolize.h"
 | 
				
			||||||
absl_library(
 | 
					    "internal/symbolize.h"
 | 
				
			||||||
  TARGET
 | 
					  SRCS
 | 
				
			||||||
    absl_failure_signal_handler
 | 
					    "symbolize.cc"
 | 
				
			||||||
  SOURCES
 | 
					    "symbolize_elf.inc"
 | 
				
			||||||
    ${FAILURE_SIGNAL_HANDLER_SRC}
 | 
					    "symbolize_unimplemented.inc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					    "symbolize_win32.inc"
 | 
				
			||||||
    absl_base absl::examine_stack absl::stacktrace absl_synchronization
 | 
					  COPTS
 | 
				
			||||||
  EXPORT_NAME
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
    failure_signal_handler
 | 
					  DEPS
 | 
				
			||||||
)
 | 
					    absl::debugging_internal
 | 
				
			||||||
 | 
					    absl::demangle_internal
 | 
				
			||||||
# Internal-only. Projects external to Abseil should not depend
 | 
					 | 
				
			||||||
# directly on this library.
 | 
					 | 
				
			||||||
absl_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_examine_stack
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${EXAMINE_STACK_SRC}
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    examine_stack
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND LEAK_CHECK_SRC
 | 
					 | 
				
			||||||
  "leak_check.cc"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# leak_check library
 | 
					 | 
				
			||||||
absl_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_leak_check
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${LEAK_CHECK_SRC}
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    absl_base
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    leak_check
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# component target
 | 
					 | 
				
			||||||
absl_header_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_debugging
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    absl_stacktrace absl_leak_check
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    debugging
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
## TESTS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND STACK_CONSUMPTION_SRC
 | 
					 | 
				
			||||||
  "internal/stack_consumption.cc"
 | 
					 | 
				
			||||||
  "internal/stack_consumption.h"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_stack_consumption
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${STACK_CONSUMPTION_SRC}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_stack_consumption_test
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    "internal/stack_consumption_test.cc"
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    absl_stack_consumption
 | 
					 | 
				
			||||||
    absl::base
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::malloc_internal
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND DEMANGLE_TEST_SRC "internal/demangle_test.cc")
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    demangle_test
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${DEMANGLE_TEST_SRC}
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    absl_symbolize absl_stack_consumption
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND SYMBOLIZE_TEST_SRC "symbolize_test.cc")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    symbolize_test
 | 
					    symbolize_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${SYMBOLIZE_TEST_SRC}
 | 
					    "symbolize_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    absl::base absl::memory absl_symbolize absl_stack_consumption
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::stack_consumption
 | 
				
			||||||
 | 
					    absl::symbolize
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::memory
 | 
				
			||||||
 | 
					    gmock
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND FAILURE_SIGNAL_HANDLER_TEST_SRC "failure_signal_handler_test.cc")
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    examine_stack
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "internal/examine_stack.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/examine_stack.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::stacktrace
 | 
				
			||||||
 | 
					    absl::symbolize
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_test(
 | 
					absl_cc_library(
 | 
				
			||||||
  TARGET
 | 
					  NAME
 | 
				
			||||||
 | 
					    failure_signal_handler
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "failure_signal_handler.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "failure_signal_handler.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::examine_stack
 | 
				
			||||||
 | 
					    absl::stacktrace
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::config
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
    failure_signal_handler_test
 | 
					    failure_signal_handler_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${FAILURE_SIGNAL_HANDLER_TEST_SRC}
 | 
					    "failure_signal_handler_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    absl_examine_stack
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
    absl_failure_signal_handler
 | 
					  DEPS
 | 
				
			||||||
    absl_stacktrace
 | 
					    absl::failure_signal_handler
 | 
				
			||||||
    absl_symbolize
 | 
					    absl::stacktrace
 | 
				
			||||||
 | 
					    absl::symbolize
 | 
				
			||||||
    absl::base
 | 
					    absl::base
 | 
				
			||||||
    absl::strings
 | 
					    absl::strings
 | 
				
			||||||
 | 
					    Threads::Threads
 | 
				
			||||||
 | 
					    gmock
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test leak_check_test
 | 
					absl_cc_library(
 | 
				
			||||||
list(APPEND LEAK_CHECK_TEST_SRC "leak_check_test.cc")
 | 
					  NAME
 | 
				
			||||||
 | 
					    debugging_internal
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "internal/address_is_readable.h"
 | 
				
			||||||
 | 
					    "internal/elf_mem_image.h"
 | 
				
			||||||
 | 
					    "internal/stacktrace_aarch64-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_arm-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_config.h"
 | 
				
			||||||
 | 
					    "internal/stacktrace_generic-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_powerpc-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_unimplemented-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_win32-inl.inc"
 | 
				
			||||||
 | 
					    "internal/stacktrace_x86-inl.inc"
 | 
				
			||||||
 | 
					    "internal/vdso_support.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/address_is_readable.cc"
 | 
				
			||||||
 | 
					    "internal/elf_mem_image.cc"
 | 
				
			||||||
 | 
					    "internal/vdso_support.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::dynamic_annotations
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_test(
 | 
					absl_cc_library(
 | 
				
			||||||
  TARGET
 | 
					  NAME
 | 
				
			||||||
 | 
					    demangle_internal
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "internal/demangle.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/demangle.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    demangle_test
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/demangle_test.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::demangle_internal
 | 
				
			||||||
 | 
					    absl::stack_consumption
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::memory
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    leak_check
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:leak_check.h>"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:leak_check.cc>"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    leak_check_disable
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "leak_check_disable.cc"
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# TODO(cohenjon) Move into the copts code.
 | 
				
			||||||
 | 
					if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
 | 
				
			||||||
 | 
					  set(ABSL_LSAN_LINKOPTS "-fsanitize=leak")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    leak_check_api_enabled_for_testing
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "leak_check.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "leak_check.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    $<$<BOOL:${ABSL_USING_CLANG}>:-DLEAK_SANITIZER>
 | 
				
			||||||
 | 
					  TESTONLY
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    leak_check_api_disabled_for_testing
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "leak_check.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "leak_check.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    "-ULEAK_SANITIZER"
 | 
				
			||||||
 | 
					  TESTONLY
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
    leak_check_test
 | 
					    leak_check_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${LEAK_CHECK_TEST_SRC}
 | 
					    "leak_check_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    absl_leak_check
 | 
					    "$<$<CXX_COMPILER_ID:Clang>:-DABSL_EXPECT_LEAK_SANITIZER>"
 | 
				
			||||||
 | 
					  LINKOPTS
 | 
				
			||||||
 | 
					    "${ABSL_LSAN_LINKOPTS}"
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::leak_check_api_enabled_for_testing
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    leak_check_no_lsan_test
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "leak_check_test.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    "-UABSL_EXPECT_LEAK_SANITIZER"
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::leak_check_api_disabled_for_testing
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    disabled_leak_check_test
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "leak_check_fail_test.cc"
 | 
				
			||||||
 | 
					  LINKOPTS
 | 
				
			||||||
 | 
					    "${ABSL_LSAN_LINKOPTS}"
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::leak_check_api_enabled_for_testing
 | 
				
			||||||
 | 
					    absl::leak_check_disable
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    stack_consumption
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "internal/stack_consumption.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/stack_consumption.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					  TESTONLY
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    stack_consumption_test
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/stack_consumption_test.cc"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::stack_consumption
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# component target
 | 
				
			||||||
 | 
					absl_cc_library(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    debugging
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::stacktrace
 | 
				
			||||||
 | 
					    absl::leak_check
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1636,6 +1636,15 @@ static bool ParseExpression(State *state) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  state->parse_state = copy;
 | 
					  state->parse_state = copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Pointer-to-member access expressions.  This parses the same as a binary
 | 
				
			||||||
 | 
					  // operator, but it's implemented separately because "ds" shouldn't be
 | 
				
			||||||
 | 
					  // accepted in other contexts that parse an operator name.
 | 
				
			||||||
 | 
					  if (ParseTwoCharToken(state, "ds") && ParseExpression(state) &&
 | 
				
			||||||
 | 
					      ParseExpression(state)) {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  state->parse_state = copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Parameter pack expansion
 | 
					  // Parameter pack expansion
 | 
				
			||||||
  if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) {
 | 
					  if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,40 +14,30 @@
 | 
				
			||||||
# limitations under the License.
 | 
					# limitations under the License.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND HASH_PUBLIC_HEADERS
 | 
					absl_cc_library(
 | 
				
			||||||
  "hash.h"
 | 
					  NAME
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND HASH_INTERNAL_HEADERS
 | 
					 | 
				
			||||||
  "internal/city.h"
 | 
					 | 
				
			||||||
  "internal/hash.h"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# absl_hash library
 | 
					 | 
				
			||||||
list(APPEND HASH_SRC
 | 
					 | 
				
			||||||
  "internal/city.cc"
 | 
					 | 
				
			||||||
  "internal/hash.cc"
 | 
					 | 
				
			||||||
  ${HASH_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
  ${HASH_INTERNAL_HEADERS}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(HASH_PUBLIC_LIBRARIES absl::hash absl::fixed_array absl::strings absl::str_format absl::utility)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_hash
 | 
					 | 
				
			||||||
  SOURCES
 | 
					 | 
				
			||||||
    ${HASH_SRC}
 | 
					 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
    ${HASH_PUBLIC_LIBRARIES}
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    hash
 | 
					    hash
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "hash.h"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/hash.cc"
 | 
				
			||||||
 | 
					    "internal/hash.h"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::endian
 | 
				
			||||||
 | 
					    absl::fixed_array
 | 
				
			||||||
 | 
					    absl::meta
 | 
				
			||||||
 | 
					    absl::int128
 | 
				
			||||||
 | 
					    absl::strings
 | 
				
			||||||
 | 
					    absl::optional
 | 
				
			||||||
 | 
					    absl::variant
 | 
				
			||||||
 | 
					    absl::utility
 | 
				
			||||||
 | 
					    absl::city
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
## TESTS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_cc_library(
 | 
					absl_cc_library(
 | 
				
			||||||
  NAME
 | 
					  NAME
 | 
				
			||||||
    hash_testing
 | 
					    hash_testing
 | 
				
			||||||
| 
						 | 
					@ -62,11 +52,29 @@ absl_cc_library(
 | 
				
			||||||
  TESTONLY
 | 
					  TESTONLY
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
 | 
					  NAME
 | 
				
			||||||
 | 
					    hash_test
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					   "hash_test.cc"
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::hash
 | 
				
			||||||
 | 
					    absl::hash_testing
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::flat_hash_set
 | 
				
			||||||
 | 
					    absl::spy_hash_state
 | 
				
			||||||
 | 
					    absl::meta
 | 
				
			||||||
 | 
					    absl::int128
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_cc_library(
 | 
					absl_cc_library(
 | 
				
			||||||
  NAME
 | 
					  NAME
 | 
				
			||||||
    spy_hash_state
 | 
					    spy_hash_state
 | 
				
			||||||
  HDRS
 | 
					  HDRS
 | 
				
			||||||
    "internal/spy_hash_state.h"
 | 
					    "internal/spy_hash_state.h"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
  DEPS
 | 
					  DEPS
 | 
				
			||||||
    absl::hash
 | 
					    absl::hash
 | 
				
			||||||
    absl::strings
 | 
					    absl::strings
 | 
				
			||||||
| 
						 | 
					@ -74,32 +82,30 @@ absl_cc_library(
 | 
				
			||||||
  TESTONLY
 | 
					  TESTONLY
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# testing support
 | 
					absl_cc_library(
 | 
				
			||||||
set(HASH_TEST_HEADERS hash_testing.h internal/spy_hash_state.h)
 | 
					  NAME
 | 
				
			||||||
set(HASH_TEST_PUBLIC_LIBRARIES absl::hash absl::flat_hash_set absl::numeric absl::strings absl::str_format)
 | 
					    city
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
# hash_test
 | 
					    "internal/city.h"
 | 
				
			||||||
set(HASH_TEST_SRC "hash_test.cc" ${HASH_TEST_HEADERS})
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "internal/city.cc"
 | 
				
			||||||
absl_test(
 | 
					  COPTS
 | 
				
			||||||
  TARGET
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
    hash_test
 | 
					  DEPS
 | 
				
			||||||
  SOURCES
 | 
					    absl::config
 | 
				
			||||||
    ${HASH_TEST_SRC}
 | 
					    absl::core_headers
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					    absl::endian
 | 
				
			||||||
    ${HASH_TEST_PUBLIC_LIBRARIES}
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# hash_test
 | 
					absl_cc_test(
 | 
				
			||||||
set(CITY_TEST_SRC "internal/city_test.cc")
 | 
					  NAME
 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    city_test
 | 
					    city_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${CITY_TEST_SRC}
 | 
					    "internal/city_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    ${HASH_TEST_PUBLIC_LIBRARIES}
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::city
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,55 +14,45 @@
 | 
				
			||||||
# limitations under the License.
 | 
					# limitations under the License.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
list(APPEND MEMORY_PUBLIC_HEADERS
 | 
					absl_cc_library(
 | 
				
			||||||
  "memory.h"
 | 
					  NAME
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_header_library(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    absl_memory
 | 
					 | 
				
			||||||
  EXPORT_NAME
 | 
					 | 
				
			||||||
    memory
 | 
					    memory
 | 
				
			||||||
 | 
					  HDRS
 | 
				
			||||||
 | 
					    "memory.h"
 | 
				
			||||||
 | 
					  COPTS
 | 
				
			||||||
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    absl::meta
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					absl_cc_test(
 | 
				
			||||||
## TESTS
 | 
					  NAME
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# test memory_test
 | 
					 | 
				
			||||||
list(APPEND MEMORY_TEST_SRC
 | 
					 | 
				
			||||||
  "memory_test.cc"
 | 
					 | 
				
			||||||
  ${MEMORY_PUBLIC_HEADERS}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
set(MEMORY_TEST_PUBLIC_LIBRARIES absl::base absl::memory)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    memory_test
 | 
					    memory_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${MEMORY_TEST_SRC}
 | 
					    "memory_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    ${MEMORY_TEST_PUBLIC_LIBRARIES}
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::memory
 | 
				
			||||||
 | 
					    absl::base
 | 
				
			||||||
 | 
					    absl::core_headers
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_cc_test(
 | 
				
			||||||
# test memory_exception_safety_test
 | 
					  NAME
 | 
				
			||||||
set(MEMORY_EXCEPTION_SAFETY_TEST_SRC "memory_exception_safety_test.cc")
 | 
					 | 
				
			||||||
set(MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
 | 
					 | 
				
			||||||
  absl::memory
 | 
					 | 
				
			||||||
  absl_internal_exception_safety_testing
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
absl_test(
 | 
					 | 
				
			||||||
  TARGET
 | 
					 | 
				
			||||||
    memory_exception_safety_test
 | 
					    memory_exception_safety_test
 | 
				
			||||||
  SOURCES
 | 
					  SRCS
 | 
				
			||||||
    ${MEMORY_EXCEPTION_SAFETY_TEST_SRC}
 | 
					    "memory_exception_safety_test.cc"
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  COPTS
 | 
				
			||||||
    ${MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
 | 
					    ${ABSL_TEST_COPTS}
 | 
				
			||||||
  PRIVATE_COMPILE_FLAGS
 | 
					 | 
				
			||||||
    ${ABSL_EXCEPTIONS_FLAG}
 | 
					    ${ABSL_EXCEPTIONS_FLAG}
 | 
				
			||||||
 | 
					  LINKOPTS
 | 
				
			||||||
 | 
					    ${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::memory
 | 
				
			||||||
 | 
					    absl::exception_safety_testing
 | 
				
			||||||
 | 
					    gmock_main
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,45 @@ TEST(MakeUniqueTest, Basic) {
 | 
				
			||||||
  EXPECT_EQ("hi", *p);
 | 
					  EXPECT_EQ("hi", *p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// InitializationVerifier fills in a pattern when allocated so we can
 | 
				
			||||||
 | 
					// distinguish between its default and value initialized states (without
 | 
				
			||||||
 | 
					// accessing truly uninitialized memory).
 | 
				
			||||||
 | 
					struct InitializationVerifier {
 | 
				
			||||||
 | 
					  static constexpr int kDefaultScalar = 0x43;
 | 
				
			||||||
 | 
					  static constexpr int kDefaultArray = 0x4B;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void* operator new(size_t n) {
 | 
				
			||||||
 | 
					    void* ret = ::operator new(n);
 | 
				
			||||||
 | 
					    memset(ret, kDefaultScalar, n);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void* operator new[](size_t n) {
 | 
				
			||||||
 | 
					    void* ret = ::operator new[](n);
 | 
				
			||||||
 | 
					    memset(ret, kDefaultArray, n);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int a;
 | 
				
			||||||
 | 
					  int b;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Initialization, MakeUnique) {
 | 
				
			||||||
 | 
					  auto p = absl::make_unique<InitializationVerifier>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p->a);
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p->b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Initialization, MakeUniqueArray) {
 | 
				
			||||||
 | 
					  auto p = absl::make_unique<InitializationVerifier[]>(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p[0].a);
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p[0].b);
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p[1].a);
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, p[1].b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct MoveOnly {
 | 
					struct MoveOnly {
 | 
				
			||||||
  MoveOnly() = default;
 | 
					  MoveOnly() = default;
 | 
				
			||||||
  explicit MoveOnly(int i1) : ip1{new int{i1}} {}
 | 
					  explicit MoveOnly(int i1) : ip1{new int{i1}} {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -413,6 +413,7 @@ cc_test(
 | 
				
			||||||
    copts = ABSL_TEST_COPTS,
 | 
					    copts = ABSL_TEST_COPTS,
 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":pow10_helper",
 | 
				
			||||||
        ":strings",
 | 
					        ":strings",
 | 
				
			||||||
        "//absl/base",
 | 
					        "//absl/base",
 | 
				
			||||||
        "//absl/base:core_headers",
 | 
					        "//absl/base:core_headers",
 | 
				
			||||||
| 
						 | 
					@ -471,6 +472,8 @@ cc_test(
 | 
				
			||||||
    srcs = ["charconv_test.cc"],
 | 
					    srcs = ["charconv_test.cc"],
 | 
				
			||||||
    copts = ABSL_TEST_COPTS,
 | 
					    copts = ABSL_TEST_COPTS,
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":pow10_helper",
 | 
				
			||||||
 | 
					        ":str_format",
 | 
				
			||||||
        ":strings",
 | 
					        ":strings",
 | 
				
			||||||
        "//absl/base",
 | 
					        "//absl/base",
 | 
				
			||||||
        "@com_google_googletest//:gtest_main",
 | 
					        "@com_google_googletest//:gtest_main",
 | 
				
			||||||
| 
						 | 
					@ -659,3 +662,23 @@ cc_test(
 | 
				
			||||||
        "@com_google_googletest//:gtest_main",
 | 
					        "@com_google_googletest//:gtest_main",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_library(
 | 
				
			||||||
 | 
					    name = "pow10_helper",
 | 
				
			||||||
 | 
					    testonly = True,
 | 
				
			||||||
 | 
					    srcs = ["internal/pow10_helper.cc"],
 | 
				
			||||||
 | 
					    hdrs = ["internal/pow10_helper.h"],
 | 
				
			||||||
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_test(
 | 
				
			||||||
 | 
					    name = "pow10_helper_test",
 | 
				
			||||||
 | 
					    srcs = ["internal/pow10_helper_test.cc"],
 | 
				
			||||||
 | 
					    copts = ABSL_TEST_COPTS,
 | 
				
			||||||
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":pow10_helper",
 | 
				
			||||||
 | 
					        ":str_format",
 | 
				
			||||||
 | 
					        "@com_google_googletest//:gtest_main",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,6 +131,15 @@ absl_library(
 | 
				
			||||||
    absl::strings
 | 
					    absl::strings
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# pow10_helper
 | 
				
			||||||
 | 
					absl_library(
 | 
				
			||||||
 | 
					  TARGET
 | 
				
			||||||
 | 
					    pow10_helper
 | 
				
			||||||
 | 
					  SOURCES
 | 
				
			||||||
 | 
					    "internal/pow10_helper.cc"
 | 
				
			||||||
 | 
					    "internal/pow10_helper.h"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
## TESTS
 | 
					## TESTS
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -316,7 +325,7 @@ absl_test(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test numbers_test
 | 
					# test numbers_test
 | 
				
			||||||
set(NUMBERS_TEST_SRC "numbers_test.cc")
 | 
					set(NUMBERS_TEST_SRC "numbers_test.cc")
 | 
				
			||||||
set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings)
 | 
					set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings pow10_helper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_test(
 | 
					absl_test(
 | 
				
			||||||
  TARGET
 | 
					  TARGET
 | 
				
			||||||
| 
						 | 
					@ -358,7 +367,7 @@ absl_test(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test charconv_test
 | 
					# test charconv_test
 | 
				
			||||||
set(CHARCONV_TEST_SRC "charconv_test.cc")
 | 
					set(CHARCONV_TEST_SRC "charconv_test.cc")
 | 
				
			||||||
set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings)
 | 
					set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings absl::str_format pow10_helper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_test(
 | 
					absl_test(
 | 
				
			||||||
  TARGET
 | 
					  TARGET
 | 
				
			||||||
| 
						 | 
					@ -460,3 +469,13 @@ absl_test(
 | 
				
			||||||
    absl::base
 | 
					    absl::base
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# test pow10_helper_test
 | 
				
			||||||
 | 
					absl_test(
 | 
				
			||||||
 | 
					  TARGET
 | 
				
			||||||
 | 
					    pow10_helper_test
 | 
				
			||||||
 | 
					  SOURCES
 | 
				
			||||||
 | 
					    "internal/pow10_helper_test.cc"
 | 
				
			||||||
 | 
					  PUBLIC_LIBRARIES
 | 
				
			||||||
 | 
					    pow10_helper
 | 
				
			||||||
 | 
					    absl::str_format
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gmock/gmock.h"
 | 
					#include "gmock/gmock.h"
 | 
				
			||||||
#include "gtest/gtest.h"
 | 
					#include "gtest/gtest.h"
 | 
				
			||||||
 | 
					#include "absl/strings/internal/pow10_helper.h"
 | 
				
			||||||
#include "absl/strings/str_cat.h"
 | 
					#include "absl/strings/str_cat.h"
 | 
				
			||||||
 | 
					#include "absl/strings/str_format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _MSC_FULL_VER
 | 
					#ifdef _MSC_FULL_VER
 | 
				
			||||||
#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
 | 
					#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
 | 
				
			||||||
| 
						 | 
					@ -31,6 +33,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using absl::strings_internal::Pow10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if ABSL_COMPILER_DOES_EXACT_ROUNDING
 | 
					#if ABSL_COMPILER_DOES_EXACT_ROUNDING
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that the given string is accepted by absl::from_chars, and that it
 | 
					// Tests that the given string is accepted by absl::from_chars, and that it
 | 
				
			||||||
| 
						 | 
					@ -678,7 +682,8 @@ void TestOverflowAndUnderflow(
 | 
				
			||||||
    auto result =
 | 
					    auto result =
 | 
				
			||||||
        absl::from_chars(input.data(), input.data() + input.size(), actual);
 | 
					        absl::from_chars(input.data(), input.data() + input.size(), actual);
 | 
				
			||||||
    EXPECT_EQ(result.ec, std::errc());
 | 
					    EXPECT_EQ(result.ec, std::errc());
 | 
				
			||||||
    EXPECT_EQ(expected, actual);
 | 
					    EXPECT_EQ(expected, actual)
 | 
				
			||||||
 | 
					        << absl::StrFormat("%a vs %a", expected, actual);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // test legal values near upper_bound
 | 
					  // test legal values near upper_bound
 | 
				
			||||||
  for (index = upper_bound, step = 1; index > lower_bound;
 | 
					  for (index = upper_bound, step = 1; index > lower_bound;
 | 
				
			||||||
| 
						 | 
					@ -690,7 +695,8 @@ void TestOverflowAndUnderflow(
 | 
				
			||||||
    auto result =
 | 
					    auto result =
 | 
				
			||||||
        absl::from_chars(input.data(), input.data() + input.size(), actual);
 | 
					        absl::from_chars(input.data(), input.data() + input.size(), actual);
 | 
				
			||||||
    EXPECT_EQ(result.ec, std::errc());
 | 
					    EXPECT_EQ(result.ec, std::errc());
 | 
				
			||||||
    EXPECT_EQ(expected, actual);
 | 
					    EXPECT_EQ(expected, actual)
 | 
				
			||||||
 | 
					        << absl::StrFormat("%a vs %a", expected, actual);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // Test underflow values below lower_bound
 | 
					  // Test underflow values below lower_bound
 | 
				
			||||||
  for (index = lower_bound - 1, step = 1; index > -1000000;
 | 
					  for (index = lower_bound - 1, step = 1; index > -1000000;
 | 
				
			||||||
| 
						 | 
					@ -747,7 +753,7 @@ TEST(FromChars, HexdecimalFloatLimits) {
 | 
				
			||||||
// acceptable exponents in this test.
 | 
					// acceptable exponents in this test.
 | 
				
			||||||
TEST(FromChars, DecimalDoubleLimits) {
 | 
					TEST(FromChars, DecimalDoubleLimits) {
 | 
				
			||||||
  auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
 | 
					  auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
 | 
				
			||||||
  auto expected_gen = [](int index) { return std::pow(10.0, index); };
 | 
					  auto expected_gen = [](int index) { return Pow10(index); };
 | 
				
			||||||
  TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
 | 
					  TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -759,7 +765,7 @@ TEST(FromChars, DecimalDoubleLimits) {
 | 
				
			||||||
// acceptable exponents in this test.
 | 
					// acceptable exponents in this test.
 | 
				
			||||||
TEST(FromChars, DecimalFloatLimits) {
 | 
					TEST(FromChars, DecimalFloatLimits) {
 | 
				
			||||||
  auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
 | 
					  auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
 | 
				
			||||||
  auto expected_gen = [](int index) { return std::pow(10.0, index); };
 | 
					  auto expected_gen = [](int index) { return Pow10(index); };
 | 
				
			||||||
  TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
 | 
					  TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										120
									
								
								absl/strings/internal/pow10_helper.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								absl/strings/internal/pow10_helper.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,120 @@
 | 
				
			||||||
 | 
					// Copyright 2018 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/strings/internal/pow10_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					namespace strings_internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The exact value of 1e23 falls precisely halfway between two representable
 | 
				
			||||||
 | 
					// doubles. Furthermore, the rounding rules we prefer (break ties by rounding
 | 
				
			||||||
 | 
					// to the nearest even) dictate in this case that the number should be rounded
 | 
				
			||||||
 | 
					// down, but this is not completely specified for floating-point literals in
 | 
				
			||||||
 | 
					// C++. (It just says to use the default rounding mode of the standard
 | 
				
			||||||
 | 
					// library.) We ensure the result we want by using a number that has an
 | 
				
			||||||
 | 
					// unambiguous correctly rounded answer.
 | 
				
			||||||
 | 
					constexpr double k1e23 = 9999999999999999e7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr double kPowersOfTen[] = {
 | 
				
			||||||
 | 
					    0.0,    1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316,
 | 
				
			||||||
 | 
					    1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307,
 | 
				
			||||||
 | 
					    1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298,
 | 
				
			||||||
 | 
					    1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290, 1e-289,
 | 
				
			||||||
 | 
					    1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280,
 | 
				
			||||||
 | 
					    1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271,
 | 
				
			||||||
 | 
					    1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262,
 | 
				
			||||||
 | 
					    1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253,
 | 
				
			||||||
 | 
					    1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244,
 | 
				
			||||||
 | 
					    1e-243, 1e-242, 1e-241, 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235,
 | 
				
			||||||
 | 
					    1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226,
 | 
				
			||||||
 | 
					    1e-225, 1e-224, 1e-223, 1e-222, 1e-221, 1e-220, 1e-219, 1e-218, 1e-217,
 | 
				
			||||||
 | 
					    1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208,
 | 
				
			||||||
 | 
					    1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199,
 | 
				
			||||||
 | 
					    1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190,
 | 
				
			||||||
 | 
					    1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181,
 | 
				
			||||||
 | 
					    1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172,
 | 
				
			||||||
 | 
					    1e-171, 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163,
 | 
				
			||||||
 | 
					    1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154,
 | 
				
			||||||
 | 
					    1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145,
 | 
				
			||||||
 | 
					    1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137, 1e-136,
 | 
				
			||||||
 | 
					    1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127,
 | 
				
			||||||
 | 
					    1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120, 1e-119, 1e-118,
 | 
				
			||||||
 | 
					    1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109,
 | 
				
			||||||
 | 
					    1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, 1e-100,
 | 
				
			||||||
 | 
					    1e-99,  1e-98,  1e-97,  1e-96,  1e-95,  1e-94,  1e-93,  1e-92,  1e-91,
 | 
				
			||||||
 | 
					    1e-90,  1e-89,  1e-88,  1e-87,  1e-86,  1e-85,  1e-84,  1e-83,  1e-82,
 | 
				
			||||||
 | 
					    1e-81,  1e-80,  1e-79,  1e-78,  1e-77,  1e-76,  1e-75,  1e-74,  1e-73,
 | 
				
			||||||
 | 
					    1e-72,  1e-71,  1e-70,  1e-69,  1e-68,  1e-67,  1e-66,  1e-65,  1e-64,
 | 
				
			||||||
 | 
					    1e-63,  1e-62,  1e-61,  1e-60,  1e-59,  1e-58,  1e-57,  1e-56,  1e-55,
 | 
				
			||||||
 | 
					    1e-54,  1e-53,  1e-52,  1e-51,  1e-50,  1e-49,  1e-48,  1e-47,  1e-46,
 | 
				
			||||||
 | 
					    1e-45,  1e-44,  1e-43,  1e-42,  1e-41,  1e-40,  1e-39,  1e-38,  1e-37,
 | 
				
			||||||
 | 
					    1e-36,  1e-35,  1e-34,  1e-33,  1e-32,  1e-31,  1e-30,  1e-29,  1e-28,
 | 
				
			||||||
 | 
					    1e-27,  1e-26,  1e-25,  1e-24,  1e-23,  1e-22,  1e-21,  1e-20,  1e-19,
 | 
				
			||||||
 | 
					    1e-18,  1e-17,  1e-16,  1e-15,  1e-14,  1e-13,  1e-12,  1e-11,  1e-10,
 | 
				
			||||||
 | 
					    1e-9,   1e-8,   1e-7,   1e-6,   1e-5,   1e-4,   1e-3,   1e-2,   1e-1,
 | 
				
			||||||
 | 
					    1e+0,   1e+1,   1e+2,   1e+3,   1e+4,   1e+5,   1e+6,   1e+7,   1e+8,
 | 
				
			||||||
 | 
					    1e+9,   1e+10,  1e+11,  1e+12,  1e+13,  1e+14,  1e+15,  1e+16,  1e+17,
 | 
				
			||||||
 | 
					    1e+18,  1e+19,  1e+20,  1e+21,  1e+22,  k1e23,  1e+24,  1e+25,  1e+26,
 | 
				
			||||||
 | 
					    1e+27,  1e+28,  1e+29,  1e+30,  1e+31,  1e+32,  1e+33,  1e+34,  1e+35,
 | 
				
			||||||
 | 
					    1e+36,  1e+37,  1e+38,  1e+39,  1e+40,  1e+41,  1e+42,  1e+43,  1e+44,
 | 
				
			||||||
 | 
					    1e+45,  1e+46,  1e+47,  1e+48,  1e+49,  1e+50,  1e+51,  1e+52,  1e+53,
 | 
				
			||||||
 | 
					    1e+54,  1e+55,  1e+56,  1e+57,  1e+58,  1e+59,  1e+60,  1e+61,  1e+62,
 | 
				
			||||||
 | 
					    1e+63,  1e+64,  1e+65,  1e+66,  1e+67,  1e+68,  1e+69,  1e+70,  1e+71,
 | 
				
			||||||
 | 
					    1e+72,  1e+73,  1e+74,  1e+75,  1e+76,  1e+77,  1e+78,  1e+79,  1e+80,
 | 
				
			||||||
 | 
					    1e+81,  1e+82,  1e+83,  1e+84,  1e+85,  1e+86,  1e+87,  1e+88,  1e+89,
 | 
				
			||||||
 | 
					    1e+90,  1e+91,  1e+92,  1e+93,  1e+94,  1e+95,  1e+96,  1e+97,  1e+98,
 | 
				
			||||||
 | 
					    1e+99,  1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107,
 | 
				
			||||||
 | 
					    1e+108, 1e+109, 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116,
 | 
				
			||||||
 | 
					    1e+117, 1e+118, 1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125,
 | 
				
			||||||
 | 
					    1e+126, 1e+127, 1e+128, 1e+129, 1e+130, 1e+131, 1e+132, 1e+133, 1e+134,
 | 
				
			||||||
 | 
					    1e+135, 1e+136, 1e+137, 1e+138, 1e+139, 1e+140, 1e+141, 1e+142, 1e+143,
 | 
				
			||||||
 | 
					    1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 1e+150, 1e+151, 1e+152,
 | 
				
			||||||
 | 
					    1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 1e+160, 1e+161,
 | 
				
			||||||
 | 
					    1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169, 1e+170,
 | 
				
			||||||
 | 
					    1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179,
 | 
				
			||||||
 | 
					    1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188,
 | 
				
			||||||
 | 
					    1e+189, 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197,
 | 
				
			||||||
 | 
					    1e+198, 1e+199, 1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206,
 | 
				
			||||||
 | 
					    1e+207, 1e+208, 1e+209, 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215,
 | 
				
			||||||
 | 
					    1e+216, 1e+217, 1e+218, 1e+219, 1e+220, 1e+221, 1e+222, 1e+223, 1e+224,
 | 
				
			||||||
 | 
					    1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 1e+230, 1e+231, 1e+232, 1e+233,
 | 
				
			||||||
 | 
					    1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239, 1e+240, 1e+241, 1e+242,
 | 
				
			||||||
 | 
					    1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 1e+250, 1e+251,
 | 
				
			||||||
 | 
					    1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 1e+260,
 | 
				
			||||||
 | 
					    1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269,
 | 
				
			||||||
 | 
					    1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278,
 | 
				
			||||||
 | 
					    1e+279, 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287,
 | 
				
			||||||
 | 
					    1e+288, 1e+289, 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296,
 | 
				
			||||||
 | 
					    1e+297, 1e+298, 1e+299, 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305,
 | 
				
			||||||
 | 
					    1e+306, 1e+307, 1e+308,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double Pow10(int exp) {
 | 
				
			||||||
 | 
					  if (exp < -324) {
 | 
				
			||||||
 | 
					    return 0.0;
 | 
				
			||||||
 | 
					  } else if (exp > 308) {
 | 
				
			||||||
 | 
					    return INFINITY;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    return kPowersOfTen[exp + 324];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace strings_internal
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
							
								
								
									
										36
									
								
								absl/strings/internal/pow10_helper.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								absl/strings/internal/pow10_helper.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Copyright 2018 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This test helper library contains a table of powers of 10, to guarantee
 | 
				
			||||||
 | 
					// precise values are computed across the full range of doubles. We can't rely
 | 
				
			||||||
 | 
					// on the pow() function, because not all standard libraries ship a version
 | 
				
			||||||
 | 
					// that is precise.
 | 
				
			||||||
 | 
					#ifndef ABSL_STRINGS_POW10_HELPER_H_
 | 
				
			||||||
 | 
					#define ABSL_STRINGS_POW10_HELPER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					namespace strings_internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Computes the precise value of 10^exp. (I.e. the nearest representable
 | 
				
			||||||
 | 
					// double to the exact value, rounding to nearest-even in the (single) case of
 | 
				
			||||||
 | 
					// being exactly halfway between.)
 | 
				
			||||||
 | 
					double Pow10(int exp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace strings_internal
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_STRINGS_POW10_HELPER_H_
 | 
				
			||||||
							
								
								
									
										120
									
								
								absl/strings/internal/pow10_helper_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								absl/strings/internal/pow10_helper_test.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,120 @@
 | 
				
			||||||
 | 
					// Copyright 2018 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
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      http://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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/strings/internal/pow10_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gtest/gtest.h"
 | 
				
			||||||
 | 
					#include "absl/strings/str_format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					namespace strings_internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct TestCase {
 | 
				
			||||||
 | 
					  int power;           // Testing Pow10(power)
 | 
				
			||||||
 | 
					  uint64_t significand;  // Raw bits of the expected value
 | 
				
			||||||
 | 
					  int radix;           // significand is adjusted by 2^radix
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Pow10HelperTest, Works) {
 | 
				
			||||||
 | 
					  // The logic in pow10_helper.cc is so simple that theoretically we don't even
 | 
				
			||||||
 | 
					  // need a test. However, we're paranoid and believe that there may be
 | 
				
			||||||
 | 
					  // compilers that don't round floating-point literals correctly, even though
 | 
				
			||||||
 | 
					  // it is specified by the standard. We check various edge cases, just to be
 | 
				
			||||||
 | 
					  // sure.
 | 
				
			||||||
 | 
					  constexpr TestCase kTestCases[] = {
 | 
				
			||||||
 | 
					      // Subnormals
 | 
				
			||||||
 | 
					      {-323, 0x2, -1074},
 | 
				
			||||||
 | 
					      {-322, 0x14, -1074},
 | 
				
			||||||
 | 
					      {-321, 0xca, -1074},
 | 
				
			||||||
 | 
					      {-320, 0x7e8, -1074},
 | 
				
			||||||
 | 
					      {-319, 0x4f10, -1074},
 | 
				
			||||||
 | 
					      {-318, 0x316a2, -1074},
 | 
				
			||||||
 | 
					      {-317, 0x1ee257, -1074},
 | 
				
			||||||
 | 
					      {-316, 0x134d761, -1074},
 | 
				
			||||||
 | 
					      {-315, 0xc1069cd, -1074},
 | 
				
			||||||
 | 
					      {-314, 0x78a42205, -1074},
 | 
				
			||||||
 | 
					      {-313, 0x4b6695433, -1074},
 | 
				
			||||||
 | 
					      {-312, 0x2f201d49fb, -1074},
 | 
				
			||||||
 | 
					      {-311, 0x1d74124e3d1, -1074},
 | 
				
			||||||
 | 
					      {-310, 0x12688b70e62b, -1074},
 | 
				
			||||||
 | 
					      {-309, 0xb8157268fdaf, -1074},
 | 
				
			||||||
 | 
					      {-308, 0x730d67819e8d2, -1074},
 | 
				
			||||||
 | 
					      // Values that are very close to rounding the other way.
 | 
				
			||||||
 | 
					      // Comment shows difference of significand from the true value.
 | 
				
			||||||
 | 
					      {-307, 0x11fa182c40c60d, -1072},  // -.4588
 | 
				
			||||||
 | 
					      {-290, 0x18f2b061aea072, -1016},  //  .4854
 | 
				
			||||||
 | 
					      {-276, 0x11BA03F5B21000, -969},   //  .4709
 | 
				
			||||||
 | 
					      {-259, 0x1899C2F6732210, -913},   //  .4830
 | 
				
			||||||
 | 
					      {-252, 0x1D53844EE47DD1, -890},   // -.4743
 | 
				
			||||||
 | 
					      {-227, 0x1E5297287C2F45, -807},   // -.4708
 | 
				
			||||||
 | 
					      {-198, 0x1322E220A5B17E, -710},   // -.4714
 | 
				
			||||||
 | 
					      {-195, 0x12B010D3E1CF56, -700},   //  .4928
 | 
				
			||||||
 | 
					      {-192, 0x123FF06EEA847A, -690},   //  .4968
 | 
				
			||||||
 | 
					      {-163, 0x1708D0F84D3DE7, -594},   // -.4977
 | 
				
			||||||
 | 
					      {-145, 0x13FAAC3E3FA1F3, -534},   // -.4785
 | 
				
			||||||
 | 
					      {-111, 0x133D4032C2C7F5, -421},   //  .4774
 | 
				
			||||||
 | 
					      {-106, 0x1D5B561574765B, -405},   // -.4869
 | 
				
			||||||
 | 
					      {-104, 0x16EF5B40C2FC77, -398},   // -.4741
 | 
				
			||||||
 | 
					      {-88, 0x197683DF2F268D, -345},    // -.4738
 | 
				
			||||||
 | 
					      {-86, 0x13E497065CD61F, -338},    //  .4736
 | 
				
			||||||
 | 
					      {-76, 0x17288E1271F513, -305},    // -.4761
 | 
				
			||||||
 | 
					      {-63, 0x1A53FC9631D10D, -262},    //  .4929
 | 
				
			||||||
 | 
					      {-30, 0x14484BFEEBC2A0, -152},    //  .4758
 | 
				
			||||||
 | 
					      {-21, 0x12E3B40A0E9B4F, -122},    // -.4916
 | 
				
			||||||
 | 
					      {-5, 0x14F8B588E368F1, -69},      //  .4829
 | 
				
			||||||
 | 
					      {23, 0x152D02C7E14AF6, 24},       // -.5000 (exactly, round-to-even)
 | 
				
			||||||
 | 
					      {29, 0x1431E0FAE6D721, 44},       // -.4870
 | 
				
			||||||
 | 
					      {34, 0x1ED09BEAD87C03, 60},       // -.4721
 | 
				
			||||||
 | 
					      {70, 0x172EBAD6DDC73D, 180},      //  .4733
 | 
				
			||||||
 | 
					      {105, 0x1BE7ABD3781ECA, 296},     // -.4850
 | 
				
			||||||
 | 
					      {126, 0x17A2ECC414A03F, 366},     // -.4999
 | 
				
			||||||
 | 
					      {130, 0x1CDA62055B2D9E, 379},     //  .4855
 | 
				
			||||||
 | 
					      {165, 0x115D847AD00087, 496},     // -.4913
 | 
				
			||||||
 | 
					      {172, 0x14B378469B6732, 519},     //  .4818
 | 
				
			||||||
 | 
					      {187, 0x1262DFEEBBB0F9, 569},     // -.4805
 | 
				
			||||||
 | 
					      {210, 0x18557F31326BBB, 645},     // -.4992
 | 
				
			||||||
 | 
					      {212, 0x1302CB5E6F642A, 652},     // -.4838
 | 
				
			||||||
 | 
					      {215, 0x1290BA9A38C7D1, 662},     // -.4881
 | 
				
			||||||
 | 
					      {236, 0x1F736F9B3494E9, 731},     //  .4707
 | 
				
			||||||
 | 
					      {244, 0x176EC98994F489, 758},     //  .4924
 | 
				
			||||||
 | 
					      {250, 0x1658E3AB795204, 778},     // -.4963
 | 
				
			||||||
 | 
					      {252, 0x117571DDF6C814, 785},     //  .4873
 | 
				
			||||||
 | 
					      {254, 0x1B4781EAD1989E, 791},     // -.4887
 | 
				
			||||||
 | 
					      {260, 0x1A03FDE214CAF1, 811},     //  .4784
 | 
				
			||||||
 | 
					      {284, 0x1585041B2C477F, 891},     //  .4798
 | 
				
			||||||
 | 
					      {304, 0x1D2A1BE4048F90, 957},     // -.4987
 | 
				
			||||||
 | 
					      // Out-of-range values
 | 
				
			||||||
 | 
					      {-324, 0x0, 0},
 | 
				
			||||||
 | 
					      {-325, 0x0, 0},
 | 
				
			||||||
 | 
					      {-326, 0x0, 0},
 | 
				
			||||||
 | 
					      {309, 1, 2000},
 | 
				
			||||||
 | 
					      {310, 1, 2000},
 | 
				
			||||||
 | 
					      {311, 1, 2000},
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  for (const TestCase& test_case : kTestCases) {
 | 
				
			||||||
 | 
					    EXPECT_EQ(Pow10(test_case.power),
 | 
				
			||||||
 | 
					              std::ldexp(test_case.significand, test_case.radix))
 | 
				
			||||||
 | 
					        << absl::StrFormat("Failure for Pow10(%d): %a vs %a", test_case.power,
 | 
				
			||||||
 | 
					                           Pow10(test_case.power),
 | 
				
			||||||
 | 
					                           std::ldexp(test_case.significand, test_case.radix));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					}  // namespace strings_internal
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,7 @@
 | 
				
			||||||
#include "absl/strings/str_cat.h"
 | 
					#include "absl/strings/str_cat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/strings/internal/numbers_test_common.h"
 | 
					#include "absl/strings/internal/numbers_test_common.h"
 | 
				
			||||||
 | 
					#include "absl/strings/internal/pow10_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -871,7 +872,7 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int exponent = -324; exponent <= 308; ++exponent) {
 | 
					    for (int exponent = -324; exponent <= 308; ++exponent) {
 | 
				
			||||||
      double powten = pow(10.0, exponent);
 | 
					      double powten = absl::strings_internal::Pow10(exponent);
 | 
				
			||||||
      if (powten == 0) powten = 5e-324;
 | 
					      if (powten == 0) powten = 5e-324;
 | 
				
			||||||
      if (kFloatNumCases >= 1e9) {
 | 
					      if (kFloatNumCases >= 1e9) {
 | 
				
			||||||
        // The exhaustive test takes a very long time, so log progress.
 | 
					        // The exhaustive test takes a very long time, so log progress.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,18 +170,32 @@ cc_test(
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_test(
 | 
					cc_library(
 | 
				
			||||||
    name = "mutex_benchmark",
 | 
					    name = "mutex_benchmark_common",
 | 
				
			||||||
 | 
					    testonly = 1,
 | 
				
			||||||
    srcs = ["mutex_benchmark.cc"],
 | 
					    srcs = ["mutex_benchmark.cc"],
 | 
				
			||||||
    copts = ABSL_TEST_COPTS,
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
    tags = ["benchmark"],
 | 
					    visibility = [
 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					        "//absl/synchronization:__pkg__",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        ":synchronization",
 | 
					        ":synchronization",
 | 
				
			||||||
        ":thread_pool",
 | 
					        ":thread_pool",
 | 
				
			||||||
        "//absl/base",
 | 
					        "//absl/base",
 | 
				
			||||||
 | 
					        "//absl/base:base_internal",
 | 
				
			||||||
        "@com_github_google_benchmark//:benchmark_main",
 | 
					        "@com_github_google_benchmark//:benchmark_main",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    alwayslink = 1,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_binary(
 | 
				
			||||||
 | 
					    name = "mutex_benchmark",
 | 
				
			||||||
 | 
					    testonly = 1,
 | 
				
			||||||
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":mutex_benchmark_common",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_test(
 | 
					cc_test(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,16 +12,154 @@
 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <mutex>  // NOLINT(build/c++11)
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark/benchmark.h"
 | 
					#include "absl/base/internal/cycleclock.h"
 | 
				
			||||||
#include "absl/base/internal/sysinfo.h"
 | 
					#include "absl/base/internal/spinlock.h"
 | 
				
			||||||
#include "absl/synchronization/blocking_counter.h"
 | 
					#include "absl/synchronization/blocking_counter.h"
 | 
				
			||||||
#include "absl/synchronization/internal/thread_pool.h"
 | 
					#include "absl/synchronization/internal/thread_pool.h"
 | 
				
			||||||
#include "absl/synchronization/mutex.h"
 | 
					#include "absl/synchronization/mutex.h"
 | 
				
			||||||
 | 
					#include "benchmark/benchmark.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BM_Mutex(benchmark::State& state) {
 | 
				
			||||||
 | 
					  static absl::Mutex* mu = new absl::Mutex;
 | 
				
			||||||
 | 
					  for (auto _ : state) {
 | 
				
			||||||
 | 
					    absl::MutexLock lock(mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void DelayNs(int64_t ns, int* data) {
 | 
				
			||||||
 | 
					  int64_t end = absl::base_internal::CycleClock::Now() +
 | 
				
			||||||
 | 
					                ns * absl::base_internal::CycleClock::Frequency() / 1e9;
 | 
				
			||||||
 | 
					  while (absl::base_internal::CycleClock::Now() < end) {
 | 
				
			||||||
 | 
					    ++(*data);
 | 
				
			||||||
 | 
					    benchmark::DoNotOptimize(*data);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename MutexType>
 | 
				
			||||||
 | 
					class RaiiLocker {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit RaiiLocker(MutexType* mu) : mu_(mu) { mu_->Lock(); }
 | 
				
			||||||
 | 
					  ~RaiiLocker() { mu_->Unlock(); }
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  MutexType* mu_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <>
 | 
				
			||||||
 | 
					class RaiiLocker<std::mutex> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit RaiiLocker(std::mutex* mu) : mu_(mu) { mu_->lock(); }
 | 
				
			||||||
 | 
					  ~RaiiLocker() { mu_->unlock(); }
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  std::mutex* mu_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename MutexType>
 | 
				
			||||||
 | 
					void BM_Contended(benchmark::State& state) {
 | 
				
			||||||
 | 
					  struct Shared {
 | 
				
			||||||
 | 
					    MutexType mu;
 | 
				
			||||||
 | 
					    int data = 0;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  static auto* shared = new Shared;
 | 
				
			||||||
 | 
					  int local = 0;
 | 
				
			||||||
 | 
					  for (auto _ : state) {
 | 
				
			||||||
 | 
					    // Here we model both local work outside of the critical section as well as
 | 
				
			||||||
 | 
					    // some work inside of the critical section. The idea is to capture some
 | 
				
			||||||
 | 
					    // more or less realisitic contention levels.
 | 
				
			||||||
 | 
					    // If contention is too low, the benchmark won't measure anything useful.
 | 
				
			||||||
 | 
					    // If contention is unrealistically high, the benchmark will favor
 | 
				
			||||||
 | 
					    // bad mutex implementations that block and otherwise distract threads
 | 
				
			||||||
 | 
					    // from the mutex and shared state for as much as possible.
 | 
				
			||||||
 | 
					    // To achieve this amount of local work is multiplied by number of threads
 | 
				
			||||||
 | 
					    // to keep ratio between local work and critical section approximately
 | 
				
			||||||
 | 
					    // equal regardless of number of threads.
 | 
				
			||||||
 | 
					    DelayNs(100 * state.threads, &local);
 | 
				
			||||||
 | 
					    RaiiLocker<MutexType> locker(&shared->mu);
 | 
				
			||||||
 | 
					    DelayNs(state.range(0), &shared->data);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_TEMPLATE(BM_Contended, absl::Mutex)
 | 
				
			||||||
 | 
					    ->UseRealTime()
 | 
				
			||||||
 | 
					    // ThreadPerCpu poorly handles non-power-of-two CPU counts.
 | 
				
			||||||
 | 
					    ->Threads(1)
 | 
				
			||||||
 | 
					    ->Threads(2)
 | 
				
			||||||
 | 
					    ->Threads(4)
 | 
				
			||||||
 | 
					    ->Threads(6)
 | 
				
			||||||
 | 
					    ->Threads(8)
 | 
				
			||||||
 | 
					    ->Threads(12)
 | 
				
			||||||
 | 
					    ->Threads(16)
 | 
				
			||||||
 | 
					    ->Threads(24)
 | 
				
			||||||
 | 
					    ->Threads(32)
 | 
				
			||||||
 | 
					    ->Threads(48)
 | 
				
			||||||
 | 
					    ->Threads(64)
 | 
				
			||||||
 | 
					    ->Threads(96)
 | 
				
			||||||
 | 
					    ->Threads(128)
 | 
				
			||||||
 | 
					    ->Threads(192)
 | 
				
			||||||
 | 
					    ->Threads(256)
 | 
				
			||||||
 | 
					    // Some empirically chosen amounts of work in critical section.
 | 
				
			||||||
 | 
					    // 1 is low contention, 200 is high contention and few values in between.
 | 
				
			||||||
 | 
					    ->Arg(1)
 | 
				
			||||||
 | 
					    ->Arg(20)
 | 
				
			||||||
 | 
					    ->Arg(50)
 | 
				
			||||||
 | 
					    ->Arg(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_TEMPLATE(BM_Contended, absl::base_internal::SpinLock)
 | 
				
			||||||
 | 
					    ->UseRealTime()
 | 
				
			||||||
 | 
					    // ThreadPerCpu poorly handles non-power-of-two CPU counts.
 | 
				
			||||||
 | 
					    ->Threads(1)
 | 
				
			||||||
 | 
					    ->Threads(2)
 | 
				
			||||||
 | 
					    ->Threads(4)
 | 
				
			||||||
 | 
					    ->Threads(6)
 | 
				
			||||||
 | 
					    ->Threads(8)
 | 
				
			||||||
 | 
					    ->Threads(12)
 | 
				
			||||||
 | 
					    ->Threads(16)
 | 
				
			||||||
 | 
					    ->Threads(24)
 | 
				
			||||||
 | 
					    ->Threads(32)
 | 
				
			||||||
 | 
					    ->Threads(48)
 | 
				
			||||||
 | 
					    ->Threads(64)
 | 
				
			||||||
 | 
					    ->Threads(96)
 | 
				
			||||||
 | 
					    ->Threads(128)
 | 
				
			||||||
 | 
					    ->Threads(192)
 | 
				
			||||||
 | 
					    ->Threads(256)
 | 
				
			||||||
 | 
					    // Some empirically chosen amounts of work in critical section.
 | 
				
			||||||
 | 
					    // 1 is low contention, 200 is high contention and few values in between.
 | 
				
			||||||
 | 
					    ->Arg(1)
 | 
				
			||||||
 | 
					    ->Arg(20)
 | 
				
			||||||
 | 
					    ->Arg(50)
 | 
				
			||||||
 | 
					    ->Arg(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_TEMPLATE(BM_Contended, std::mutex)
 | 
				
			||||||
 | 
					    ->UseRealTime()
 | 
				
			||||||
 | 
					    // ThreadPerCpu poorly handles non-power-of-two CPU counts.
 | 
				
			||||||
 | 
					    ->Threads(1)
 | 
				
			||||||
 | 
					    ->Threads(2)
 | 
				
			||||||
 | 
					    ->Threads(4)
 | 
				
			||||||
 | 
					    ->Threads(6)
 | 
				
			||||||
 | 
					    ->Threads(8)
 | 
				
			||||||
 | 
					    ->Threads(12)
 | 
				
			||||||
 | 
					    ->Threads(16)
 | 
				
			||||||
 | 
					    ->Threads(24)
 | 
				
			||||||
 | 
					    ->Threads(32)
 | 
				
			||||||
 | 
					    ->Threads(48)
 | 
				
			||||||
 | 
					    ->Threads(64)
 | 
				
			||||||
 | 
					    ->Threads(96)
 | 
				
			||||||
 | 
					    ->Threads(128)
 | 
				
			||||||
 | 
					    ->Threads(192)
 | 
				
			||||||
 | 
					    ->Threads(256)
 | 
				
			||||||
 | 
					    // Some empirically chosen amounts of work in critical section.
 | 
				
			||||||
 | 
					    // 1 is low contention, 200 is high contention and few values in between.
 | 
				
			||||||
 | 
					    ->Arg(1)
 | 
				
			||||||
 | 
					    ->Arg(20)
 | 
				
			||||||
 | 
					    ->Arg(50)
 | 
				
			||||||
 | 
					    ->Arg(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Measure the overhead of conditions on mutex release (when they must be
 | 
					// Measure the overhead of conditions on mutex release (when they must be
 | 
				
			||||||
// evaluated).  Mutex has (some) support for equivalence classes allowing
 | 
					// evaluated).  Mutex has (some) support for equivalence classes allowing
 | 
				
			||||||
// Conditions with the same function/argument to potentially not be multiply
 | 
					// Conditions with the same function/argument to potentially not be multiply
 | 
				
			||||||
| 
						 | 
					@ -82,13 +220,4 @@ constexpr int kMaxConditionWaiters = 1024;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);
 | 
					BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BM_ContendedMutex(benchmark::State& state) {
 | 
					 | 
				
			||||||
  static absl::Mutex* mu = new absl::Mutex;
 | 
					 | 
				
			||||||
  for (auto _ : state) {
 | 
					 | 
				
			||||||
    absl::MutexLock lock(mu);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_ContendedMutex)->Threads(1);
 | 
					 | 
				
			||||||
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +52,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/base/macros.h"
 | 
				
			||||||
#include "absl/synchronization/mutex.h"
 | 
					#include "absl/synchronization/mutex.h"
 | 
				
			||||||
#include "absl/time/time.h"
 | 
					#include "absl/time/time.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,10 +78,16 @@ constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Can't use std::isinfinite() because it doesn't exist on windows.
 | 
					// Can't use std::isinfinite() because it doesn't exist on windows.
 | 
				
			||||||
inline bool IsFinite(double d) {
 | 
					inline bool IsFinite(double d) {
 | 
				
			||||||
 | 
					  if (std::isnan(d)) return false;
 | 
				
			||||||
  return d != std::numeric_limits<double>::infinity() &&
 | 
					  return d != std::numeric_limits<double>::infinity() &&
 | 
				
			||||||
         d != -std::numeric_limits<double>::infinity();
 | 
					         d != -std::numeric_limits<double>::infinity();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline bool IsValidDivisor(double d) {
 | 
				
			||||||
 | 
					  if (std::isnan(d)) return false;
 | 
				
			||||||
 | 
					  return d != 0.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Can't use std::round() because it is only available in C++11.
 | 
					// Can't use std::round() because it is only available in C++11.
 | 
				
			||||||
// Note that we ignore the possibility of floating-point over/underflow.
 | 
					// Note that we ignore the possibility of floating-point over/underflow.
 | 
				
			||||||
template <typename Double>
 | 
					template <typename Double>
 | 
				
			||||||
| 
						 | 
					@ -455,7 +461,7 @@ Duration& Duration::operator/=(int64_t r) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Duration& Duration::operator/=(double r) {
 | 
					Duration& Duration::operator/=(double r) {
 | 
				
			||||||
  if (time_internal::IsInfiniteDuration(*this) || r == 0.0) {
 | 
					  if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) {
 | 
				
			||||||
    const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
 | 
					    const bool is_neg = (std::signbit(r) != 0) != (rep_hi_ < 0);
 | 
				
			||||||
    return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
 | 
					    return *this = is_neg ? -InfiniteDuration() : InfiniteDuration();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -803,6 +803,40 @@ TEST(Duration, DivisionByZero) {
 | 
				
			||||||
  EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero));
 | 
					  EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Duration, NaN) {
 | 
				
			||||||
 | 
					  // Note that IEEE 754 does not define the behavior of a nan's sign when it is
 | 
				
			||||||
 | 
					  // copied, so the code below allows for either + or - InfiniteDuration.
 | 
				
			||||||
 | 
					#define TEST_NAN_HANDLING(NAME, NAN)           \
 | 
				
			||||||
 | 
					  do {                                         \
 | 
				
			||||||
 | 
					    const auto inf = absl::InfiniteDuration(); \
 | 
				
			||||||
 | 
					    auto x = NAME(NAN);                        \
 | 
				
			||||||
 | 
					    EXPECT_TRUE(x == inf || x == -inf);        \
 | 
				
			||||||
 | 
					    auto y = NAME(42);                         \
 | 
				
			||||||
 | 
					    y *= NAN;                                  \
 | 
				
			||||||
 | 
					    EXPECT_TRUE(y == inf || y == -inf);        \
 | 
				
			||||||
 | 
					    auto z = NAME(42);                         \
 | 
				
			||||||
 | 
					    z /= NAN;                                  \
 | 
				
			||||||
 | 
					    EXPECT_TRUE(z == inf || z == -inf);        \
 | 
				
			||||||
 | 
					  } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const double nan = std::numeric_limits<double>::quiet_NaN();
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Nanoseconds, nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Microseconds, nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Milliseconds, nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Seconds, nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Minutes, nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Hours, nan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Nanoseconds, -nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Microseconds, -nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Milliseconds, -nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Seconds, -nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Minutes, -nan);
 | 
				
			||||||
 | 
					  TEST_NAN_HANDLING(absl::Hours, -nan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef TEST_NAN_HANDLING
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(Duration, Range) {
 | 
					TEST(Duration, Range) {
 | 
				
			||||||
  const absl::Duration range = ApproxYears(100 * 1e9);
 | 
					  const absl::Duration range = ApproxYears(100 * 1e9);
 | 
				
			||||||
  const absl::Duration range_future = range;
 | 
					  const absl::Duration range_future = range;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,7 @@
 | 
				
			||||||
#include <winsock2.h>
 | 
					#include <winsock2.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <chrono>  // NOLINT(build/c++11)
 | 
					#include <chrono>  // NOLINT(build/c++11)
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include <ctime>
 | 
					#include <ctime>
 | 
				
			||||||
#include <ostream>
 | 
					#include <ostream>
 | 
				
			||||||
| 
						 | 
					@ -411,10 +412,12 @@ Duration Milliseconds(T n) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template <typename T, time_internal::EnableIfFloat<T> = 0>
 | 
					template <typename T, time_internal::EnableIfFloat<T> = 0>
 | 
				
			||||||
Duration Seconds(T n) {
 | 
					Duration Seconds(T n) {
 | 
				
			||||||
  if (n >= 0) {
 | 
					  if (n >= 0) {  // Note: `NaN >= 0` is false.
 | 
				
			||||||
    if (n >= (std::numeric_limits<int64_t>::max)()) return InfiniteDuration();
 | 
					    if (n >= (std::numeric_limits<int64_t>::max)()) return InfiniteDuration();
 | 
				
			||||||
    return time_internal::MakePosDoubleDuration(n);
 | 
					    return time_internal::MakePosDoubleDuration(n);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
 | 
					    if (std::isnan(n))
 | 
				
			||||||
 | 
					      return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration();
 | 
				
			||||||
    if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration();
 | 
					    if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration();
 | 
				
			||||||
    return -time_internal::MakePosDoubleDuration(-n);
 | 
					    return -time_internal::MakePosDoubleDuration(-n);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
// Implementation details of absl/types/variant.h, pulled into a
 | 
					// Implementation details of absl/types/variant.h, pulled into a
 | 
				
			||||||
// separate file to avoid cluttering the top of the API header with
 | 
					// separate file to avoid cluttering the top of the API header with
 | 
				
			||||||
// implementation details.
 | 
					// implementation details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef ABSL_TYPES_variant_internal_H_
 | 
					#ifndef ABSL_TYPES_variant_internal_H_
 | 
				
			||||||
#define ABSL_TYPES_variant_internal_H_
 | 
					#define ABSL_TYPES_variant_internal_H_
 | 
				
			||||||
| 
						 | 
					@ -1234,23 +1235,29 @@ using VariantCopyBase = absl::conditional_t<
 | 
				
			||||||
// Base that is dependent on whether or not the move-assign can be trivial.
 | 
					// Base that is dependent on whether or not the move-assign can be trivial.
 | 
				
			||||||
template <class... T>
 | 
					template <class... T>
 | 
				
			||||||
using VariantMoveAssignBase = absl::conditional_t<
 | 
					using VariantMoveAssignBase = absl::conditional_t<
 | 
				
			||||||
    absl::disjunction<absl::conjunction<absl::is_move_assignable<Union<T...>>,
 | 
					    absl::disjunction<
 | 
				
			||||||
                                        std::is_move_constructible<Union<T...>>,
 | 
					        absl::conjunction<absl::is_move_assignable<Union<T...>>,
 | 
				
			||||||
                                        std::is_destructible<Union<T...>>>,
 | 
					                          std::is_move_constructible<Union<T...>>,
 | 
				
			||||||
                      absl::negation<absl::conjunction<
 | 
					                          std::is_destructible<Union<T...>>>,
 | 
				
			||||||
                          std::is_move_constructible<T>...,
 | 
					        absl::negation<absl::conjunction<std::is_move_constructible<T>...,
 | 
				
			||||||
                          absl::is_move_assignable<T>...>>>::value,
 | 
					                                         // Note: We're not qualifying this with
 | 
				
			||||||
 | 
					                                         // absl:: because it doesn't compile
 | 
				
			||||||
 | 
					                                         // under MSVC.
 | 
				
			||||||
 | 
					                                         is_move_assignable<T>...>>>::value,
 | 
				
			||||||
    VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;
 | 
					    VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Base that is dependent on whether or not the copy-assign can be trivial.
 | 
					// Base that is dependent on whether or not the copy-assign can be trivial.
 | 
				
			||||||
template <class... T>
 | 
					template <class... T>
 | 
				
			||||||
using VariantCopyAssignBase = absl::conditional_t<
 | 
					using VariantCopyAssignBase = absl::conditional_t<
 | 
				
			||||||
    absl::disjunction<absl::conjunction<absl::is_copy_assignable<Union<T...>>,
 | 
					    absl::disjunction<
 | 
				
			||||||
                                        std::is_copy_constructible<Union<T...>>,
 | 
					        absl::conjunction<absl::is_copy_assignable<Union<T...>>,
 | 
				
			||||||
                                        std::is_destructible<Union<T...>>>,
 | 
					                          std::is_copy_constructible<Union<T...>>,
 | 
				
			||||||
                      absl::negation<absl::conjunction<
 | 
					                          std::is_destructible<Union<T...>>>,
 | 
				
			||||||
                          std::is_copy_constructible<T>...,
 | 
					        absl::negation<absl::conjunction<std::is_copy_constructible<T>...,
 | 
				
			||||||
                          absl::is_copy_assignable<T>...>>>::value,
 | 
					                                         // Note: We're not qualifying this with
 | 
				
			||||||
 | 
					                                         // absl:: because it doesn't compile
 | 
				
			||||||
 | 
					                                         // under MSVC.
 | 
				
			||||||
 | 
					                                         is_copy_assignable<T>...>>>::value,
 | 
				
			||||||
    VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;
 | 
					    VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <class... T>
 | 
					template <class... T>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,7 @@ namespace absl {
 | 
				
			||||||
// absl::variant
 | 
					// absl::variant
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// An 'absl::variant` type is a form of type-safe union. An `absl::variant` --
 | 
					// An `absl::variant` type is a form of type-safe union. An `absl::variant` --
 | 
				
			||||||
// except in exceptional cases -- always holds a value of one of its alternative
 | 
					// except in exceptional cases -- always holds a value of one of its alternative
 | 
				
			||||||
// types.
 | 
					// types.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// variant_size
 | 
					// variant_size
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Returns the number of alterative types available for a given `absl::variant`
 | 
					// Returns the number of alternative types available for a given `absl::variant`
 | 
				
			||||||
// type as a compile-time constant expression. As this is a class template, it
 | 
					// type as a compile-time constant expression. As this is a class template, it
 | 
				
			||||||
// is not generally useful for accessing the number of alternative types of
 | 
					// is not generally useful for accessing the number of alternative types of
 | 
				
			||||||
// any given `absl::variant` instance.
 | 
					// any given `absl::variant` instance.
 | 
				
			||||||
| 
						 | 
					@ -454,7 +454,7 @@ class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
 | 
				
			||||||
                                  std::is_object<Tn>...>::value,
 | 
					                                  std::is_object<Tn>...>::value,
 | 
				
			||||||
                "Attempted to instantiate a variant containing a non-object "
 | 
					                "Attempted to instantiate a variant containing a non-object "
 | 
				
			||||||
                "type.");
 | 
					                "type.");
 | 
				
			||||||
  // Intentionally not qualifing `negation` with `absl::` to work around a bug
 | 
					  // Intentionally not qualifying `negation` with `absl::` to work around a bug
 | 
				
			||||||
  // in MSVC 2015 with inline namespace and variadic template.
 | 
					  // in MSVC 2015 with inline namespace and variadic template.
 | 
				
			||||||
  static_assert(absl::conjunction<negation<std::is_array<T0> >,
 | 
					  static_assert(absl::conjunction<negation<std::is_array<T0> >,
 | 
				
			||||||
                                  negation<std::is_array<Tn> >...>::value,
 | 
					                                  negation<std::is_array<Tn> >...>::value,
 | 
				
			||||||
| 
						 | 
					@ -562,7 +562,7 @@ class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Assignment Operators
 | 
					  // Assignment Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Copy assignement operator
 | 
					  // Copy assignment operator
 | 
				
			||||||
  variant& operator=(const variant& other) = default;
 | 
					  variant& operator=(const variant& other) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Move assignment operator
 | 
					  // Move assignment operator
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue