Export of internal Abseil changes.
-- 8becce38c862a044db194a9aea1b505796a46d6f by Abseil Team <absl-team@google.com>: Updates the FixedArray's constructors to be exception safe by preventing double deletions. Also adds exception safety tests for FixedArray to document/enforce the expected behavior. PiperOrigin-RevId: 201964431 -- 794188b401a602b4be97190fb8738066fe1f9ca5 by Derek Mauro <dmauro@google.com>: Fixes for str_format.h documentation. PiperOrigin-RevId: 201951760 -- beae3bdd6eee2cf61101102fddc35ada188f330b by Alex Strelnikov <strel@google.com>: Add numeric_limits specialization for uint128. Turns out numeric_limits is a case where the consensus is that it is okay to specialize for a user defined type. PiperOrigin-RevId: 201944736 -- b2b3444a52b36878ade1ae8801e69932b05fc4f9 by Shaindel Schwartz <shaindel@google.com>: Internal change. PiperOrigin-RevId: 201718662 -- aa924c459922f39caabfc193998c58d0f4981ac0 by Abseil Team <absl-team@google.com>: Typo fix. PiperOrigin-RevId: 201692176 -- bbfcaa7b1af331d9b97c92470608240c5c864fbc by Xiaoyi Zhang <zhangxy@google.com>: Use ABSL_HAVE_ANY/OPTIONAL/VARIANT to conditionally compile out the definition of absl::bad_any_cast, absl::bad_optional_access, absl::bad_variant_access. This would fix the issues where users #include those header directly in C++17 modes. PiperOrigin-RevId: 201683792 GitOrigin-RevId: 8becce38c862a044db194a9aea1b505796a46d6f Change-Id: I60a7ad043136a439d82c374d225a1804016b0509
This commit is contained in:
		
							parent
							
								
									4491d606df
								
							
						
					
					
						commit
						87a4c07856
					
				
					 20 changed files with 422 additions and 48 deletions
				
			
		| 
						 | 
					@ -634,7 +634,7 @@ container_algorithm_internal::ContainerIter<C> c_generate_n(C& c, Size n,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Note: `c_xx()` <algorithm> container versions for `remove()`, `remove_if()`,
 | 
					// Note: `c_xx()` <algorithm> container versions for `remove()`, `remove_if()`,
 | 
				
			||||||
// and `unique()` are omitted, because it's not clear whether or not such
 | 
					// and `unique()` are omitted, because it's not clear whether or not such
 | 
				
			||||||
// functions should call erase their supplied sequences afterwards. Either
 | 
					// functions should call erase on their supplied sequences afterwards. Either
 | 
				
			||||||
// behavior would be surprising for a different set of users.
 | 
					// behavior would be surprising for a different set of users.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,6 @@
 | 
				
			||||||
// that evaluate to a concrete mutex object whenever possible. If the mutex
 | 
					// that evaluate to a concrete mutex object whenever possible. If the mutex
 | 
				
			||||||
// you want to refer to is not in scope, you may use a member pointer
 | 
					// you want to refer to is not in scope, you may use a member pointer
 | 
				
			||||||
// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
 | 
					// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
 | 
					#ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
 | 
				
			||||||
#define ABSL_BASE_THREAD_ANNOTATIONS_H_
 | 
					#define ABSL_BASE_THREAD_ANNOTATIONS_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,17 @@ cc_test(
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_test(
 | 
				
			||||||
 | 
					    name = "fixed_array_exception_safety_test",
 | 
				
			||||||
 | 
					    srcs = ["fixed_array_exception_safety_test.cc"],
 | 
				
			||||||
 | 
					    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":fixed_array",
 | 
				
			||||||
 | 
					        "//absl/base:exception_safety_testing",
 | 
				
			||||||
 | 
					        "@com_google_googletest//:gtest_main",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_test(
 | 
					cc_test(
 | 
				
			||||||
    name = "fixed_array_benchmark",
 | 
					    name = "fixed_array_benchmark",
 | 
				
			||||||
    srcs = ["fixed_array_benchmark.cc"],
 | 
					    srcs = ["fixed_array_benchmark.cc"],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,25 @@ absl_test(
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# test fixed_array_exception_safety_test
 | 
				
			||||||
 | 
					set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC "fixed_array_exception_safety_test.cc")
 | 
				
			||||||
 | 
					set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES
 | 
				
			||||||
 | 
					  absl::container
 | 
				
			||||||
 | 
					  absl_base_internal_exception_safety_testing
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_test(
 | 
				
			||||||
 | 
					  TARGET
 | 
				
			||||||
 | 
					    fixed_array_exception_safety_test
 | 
				
			||||||
 | 
					  SOURCES
 | 
				
			||||||
 | 
					    ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC}
 | 
				
			||||||
 | 
					  PUBLIC_LIBRARIES
 | 
				
			||||||
 | 
					    ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
 | 
				
			||||||
 | 
					  PRIVATE_COMPILE_FLAGS
 | 
				
			||||||
 | 
					    ${ABSL_EXCEPTIONS_FLAG}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test inlined_vector_test
 | 
					# test inlined_vector_test
 | 
				
			||||||
set(INLINED_VECTOR_TEST_SRC "inlined_vector_test.cc")
 | 
					set(INLINED_VECTOR_TEST_SRC "inlined_vector_test.cc")
 | 
				
			||||||
set(INLINED_VECTOR_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib)
 | 
					set(INLINED_VECTOR_TEST_PUBLIC_LIBRARIES absl::base absl_throw_delegate test_instance_tracker_lib)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,33 +108,46 @@ class FixedArray {
 | 
				
			||||||
          ? kInlineBytesDefault / sizeof(value_type)
 | 
					          ? kInlineBytesDefault / sizeof(value_type)
 | 
				
			||||||
          : inlined;
 | 
					          : inlined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FixedArray(const FixedArray& other) : rep_(other.begin(), other.end()) {}
 | 
					  FixedArray(const FixedArray& other)
 | 
				
			||||||
 | 
					      : FixedArray(other.begin(), other.end()) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FixedArray(FixedArray&& other) noexcept(
 | 
					  FixedArray(FixedArray&& other) noexcept(
 | 
				
			||||||
  // clang-format off
 | 
					  // clang-format off
 | 
				
			||||||
      absl::allocator_is_nothrow<std::allocator<value_type>>::value &&
 | 
					      absl::allocator_is_nothrow<std::allocator<value_type>>::value &&
 | 
				
			||||||
  // clang-format on
 | 
					  // clang-format on
 | 
				
			||||||
          std::is_nothrow_move_constructible<value_type>::value)
 | 
					          std::is_nothrow_move_constructible<value_type>::value)
 | 
				
			||||||
      : rep_(std::make_move_iterator(other.begin()),
 | 
					      : FixedArray(std::make_move_iterator(other.begin()),
 | 
				
			||||||
             std::make_move_iterator(other.end())) {}
 | 
					                   std::make_move_iterator(other.end())) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates an array object that can store `n` elements.
 | 
					  // Creates an array object that can store `n` elements.
 | 
				
			||||||
  // Note that trivially constructible elements will be uninitialized.
 | 
					  // Note that trivially constructible elements will be uninitialized.
 | 
				
			||||||
  explicit FixedArray(size_type n) : rep_(n) {}
 | 
					  explicit FixedArray(size_type n) : rep_(n) {
 | 
				
			||||||
 | 
					    absl::memory_internal::uninitialized_default_construct_n(rep_.begin(),
 | 
				
			||||||
 | 
					                                                             size());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates an array initialized with `n` copies of `val`.
 | 
					  // Creates an array initialized with `n` copies of `val`.
 | 
				
			||||||
  FixedArray(size_type n, const value_type& val) : rep_(n, val) {}
 | 
					  FixedArray(size_type n, const value_type& val) : rep_(n) {
 | 
				
			||||||
 | 
					    std::uninitialized_fill_n(data(), size(), val);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates an array initialized with the elements from the input
 | 
					  // Creates an array initialized with the elements from the input
 | 
				
			||||||
  // range. The array's size will always be `std::distance(first, last)`.
 | 
					  // range. The array's size will always be `std::distance(first, last)`.
 | 
				
			||||||
  // REQUIRES: Iter must be a forward_iterator or better.
 | 
					  // REQUIRES: Iter must be a forward_iterator or better.
 | 
				
			||||||
  template <typename Iter, EnableIfForwardIterator<Iter> = 0>
 | 
					  template <typename Iter, EnableIfForwardIterator<Iter> = 0>
 | 
				
			||||||
  FixedArray(Iter first, Iter last) : rep_(first, last) {}
 | 
					  FixedArray(Iter first, Iter last) : rep_(std::distance(first, last)) {
 | 
				
			||||||
 | 
					    std::uninitialized_copy(first, last, data());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Creates the array from an initializer_list.
 | 
					  // Creates the array from an initializer_list.
 | 
				
			||||||
  FixedArray(std::initializer_list<T> init_list)
 | 
					  FixedArray(std::initializer_list<T> init_list)
 | 
				
			||||||
      : FixedArray(init_list.begin(), init_list.end()) {}
 | 
					      : FixedArray(init_list.begin(), init_list.end()) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ~FixedArray() {}
 | 
					  ~FixedArray() noexcept {
 | 
				
			||||||
 | 
					    for (Holder* cur = rep_.begin(); cur != rep_.end(); ++cur) {
 | 
				
			||||||
 | 
					      cur->~Holder();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Assignments are deleted because they break the invariant that the size of a
 | 
					  // Assignments are deleted because they break the invariant that the size of a
 | 
				
			||||||
  // `FixedArray` never changes.
 | 
					  // `FixedArray` never changes.
 | 
				
			||||||
| 
						 | 
					@ -431,32 +444,13 @@ class FixedArray {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Rep
 | 
					  // Rep
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // A const Rep object holds FixedArray's size and data pointer.
 | 
					  // An instance of Rep manages the inline and out-of-line memory for FixedArray
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  class Rep : public InlineSpace<inline_elements> {
 | 
					  class Rep : public InlineSpace<inline_elements> {
 | 
				
			||||||
   public:
 | 
					   public:
 | 
				
			||||||
    Rep(size_type n, const value_type& val) : n_(n), p_(MakeHolder(n)) {
 | 
					    explicit Rep(size_type n) : n_(n), p_(MakeHolder(n)) {}
 | 
				
			||||||
      std::uninitialized_fill_n(p_, n, val);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit Rep(size_type n) : n_(n), p_(MakeHolder(n)) {
 | 
					    ~Rep() noexcept {
 | 
				
			||||||
      // Loop optimizes to nothing for trivially constructible T.
 | 
					 | 
				
			||||||
      for (Holder* p = p_; p != p_ + n; ++p)
 | 
					 | 
				
			||||||
        // Note: no parens: default init only.
 | 
					 | 
				
			||||||
        // Also note '::' to avoid Holder class placement new operator.
 | 
					 | 
				
			||||||
        ::new (static_cast<void*>(p)) Holder;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    template <typename Iter>
 | 
					 | 
				
			||||||
    Rep(Iter first, Iter last)
 | 
					 | 
				
			||||||
        : n_(std::distance(first, last)), p_(MakeHolder(n_)) {
 | 
					 | 
				
			||||||
      std::uninitialized_copy(first, last, AsValue(p_));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ~Rep() {
 | 
					 | 
				
			||||||
      // Destruction must be in reverse order.
 | 
					 | 
				
			||||||
      // Loop optimizes to nothing for trivially destructible T.
 | 
					 | 
				
			||||||
      for (Holder* p = end(); p != begin();) (--p)->~Holder();
 | 
					 | 
				
			||||||
      if (IsAllocated(size())) {
 | 
					      if (IsAllocated(size())) {
 | 
				
			||||||
        std::allocator<Holder>().deallocate(p_, n_);
 | 
					        std::allocator<Holder>().deallocate(p_, n_);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										117
									
								
								absl/container/fixed_array_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								absl/container/fixed_array_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					// Copyright 2017 The Abseil Authors.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      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 <initializer_list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/container/fixed_array.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gtest/gtest.h"
 | 
				
			||||||
 | 
					#include "absl/base/internal/exception_safety_testing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr size_t kInlined = 25;
 | 
				
			||||||
 | 
					constexpr size_t kSmallSize = kInlined / 2;
 | 
				
			||||||
 | 
					constexpr size_t kLargeSize = kInlined * 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr int kInitialValue = 5;
 | 
				
			||||||
 | 
					constexpr int kUpdatedValue = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using ::testing::TestThrowingCtor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
 | 
				
			||||||
 | 
					using FixedArr = absl::FixedArray<Thrower, kInlined>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
 | 
				
			||||||
 | 
					using MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, CopyConstructor) {
 | 
				
			||||||
 | 
					  auto small = FixedArr(kSmallSize);
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(small);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  auto large = FixedArr(kLargeSize);
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(large);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, MoveConstructor) {
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(FixedArr(kSmallSize));
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(FixedArr(kLargeSize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TypeSpec::kNoThrowMove
 | 
				
			||||||
 | 
					  TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kSmallSize));
 | 
				
			||||||
 | 
					  TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kLargeSize));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, SizeConstructor) {
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(kSmallSize);
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(kLargeSize);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, SizeValueConstructor) {
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(kSmallSize, Thrower());
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(kLargeSize, Thrower());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, IteratorConstructor) {
 | 
				
			||||||
 | 
					  auto small = FixedArr(kSmallSize);
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(small.begin(), small.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  auto large = FixedArr(kLargeSize);
 | 
				
			||||||
 | 
					  TestThrowingCtor<FixedArr>(large.begin(), large.end());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, InitListConstructor) {
 | 
				
			||||||
 | 
					  constexpr int small_inlined = 3;
 | 
				
			||||||
 | 
					  using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{});
 | 
				
			||||||
 | 
					  // Test inlined allocation
 | 
				
			||||||
 | 
					  TestThrowingCtor<SmallFixedArr>(
 | 
				
			||||||
 | 
					      std::initializer_list<Thrower>{Thrower{}, Thrower{}});
 | 
				
			||||||
 | 
					  // Test out of line allocation
 | 
				
			||||||
 | 
					  TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{
 | 
				
			||||||
 | 
					      Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					testing::AssertionResult ReadMemory(FixedArr* fixed_arr) {
 | 
				
			||||||
 | 
					  // Marked volatile to prevent optimization. Used for running asan tests.
 | 
				
			||||||
 | 
					  volatile int sum = 0;
 | 
				
			||||||
 | 
					  for (const auto& thrower : *fixed_arr) {
 | 
				
			||||||
 | 
					    sum += thrower.Get();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return testing::AssertionSuccess() << "Values sum to [" << sum << "]";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(FixedArrayExceptionSafety, Fill) {
 | 
				
			||||||
 | 
					  auto test_fill = testing::MakeExceptionSafetyTester()
 | 
				
			||||||
 | 
					                       .WithInvariants(ReadMemory)
 | 
				
			||||||
 | 
					                       .WithOperation([&](FixedArr* fixed_arr_ptr) {
 | 
				
			||||||
 | 
					                         auto thrower =
 | 
				
			||||||
 | 
					                             Thrower(kUpdatedValue, testing::nothrow_ctor);
 | 
				
			||||||
 | 
					                         fixed_arr_ptr->fill(thrower);
 | 
				
			||||||
 | 
					                       });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
 | 
					      test_fill.WithInitialValue(FixedArr(kSmallSize, Thrower(kInitialValue)))
 | 
				
			||||||
 | 
					          .Test());
 | 
				
			||||||
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
 | 
					      test_fill.WithInitialValue(FixedArr(kLargeSize, Thrower(kInitialValue)))
 | 
				
			||||||
 | 
					          .Test());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
| 
						 | 
					@ -636,6 +636,39 @@ struct default_allocator_is_nothrow : std::true_type {};
 | 
				
			||||||
struct default_allocator_is_nothrow : std::false_type {};
 | 
					struct default_allocator_is_nothrow : std::false_type {};
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace memory_internal {
 | 
				
			||||||
 | 
					// TODO(b110200014): Implement proper backports
 | 
				
			||||||
 | 
					template <typename ForwardIt>
 | 
				
			||||||
 | 
					void DefaultConstruct(ForwardIt it) {
 | 
				
			||||||
 | 
					  using value_type = typename std::iterator_traits<ForwardIt>::value_type;
 | 
				
			||||||
 | 
					  ::new (static_cast<void*>(std::addressof(*it))) value_type;
 | 
				
			||||||
 | 
					}  // namespace memory_internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_EXCEPTIONS
 | 
				
			||||||
 | 
					template <typename ForwardIt, typename Size>
 | 
				
			||||||
 | 
					void uninitialized_default_construct_n(ForwardIt first, Size size) {
 | 
				
			||||||
 | 
					  for (ForwardIt cur = first; size > 0; static_cast<void>(++cur), --size) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      absl::memory_internal::DefaultConstruct(cur);
 | 
				
			||||||
 | 
					    } catch (...) {
 | 
				
			||||||
 | 
					      using value_type = typename std::iterator_traits<ForwardIt>::value_type;
 | 
				
			||||||
 | 
					      for (; first != cur; ++first) {
 | 
				
			||||||
 | 
					        first->~value_type();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      throw;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else   // ABSL_HAVE_EXCEPTIONS
 | 
				
			||||||
 | 
					template <typename ForwardIt, typename Size>
 | 
				
			||||||
 | 
					void uninitialized_default_construct_n(ForwardIt first, Size size) {
 | 
				
			||||||
 | 
					  for (; size > 0; static_cast<void>(++first), --size) {
 | 
				
			||||||
 | 
					    absl::memory_internal::DefaultConstruct(first);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_EXCEPTIONS
 | 
				
			||||||
 | 
					}  // namespace memory_internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // ABSL_MEMORY_MEMORY_H_
 | 
					#endif  // ABSL_MEMORY_MEMORY_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,11 +20,14 @@
 | 
				
			||||||
namespace absl {
 | 
					namespace absl {
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Thrower = ::testing::ThrowingValue<>;
 | 
					constexpr int kLength = 50;
 | 
				
			||||||
 | 
					using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
 | 
				
			||||||
 | 
					using ThrowerStorage =
 | 
				
			||||||
 | 
					    absl::aligned_storage_t<sizeof(Thrower), alignof(Thrower)>;
 | 
				
			||||||
 | 
					using ThrowerList = std::array<ThrowerStorage, kLength>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(MakeUnique, CheckForLeaks) {
 | 
					TEST(MakeUnique, CheckForLeaks) {
 | 
				
			||||||
  constexpr int kValue = 321;
 | 
					  constexpr int kValue = 321;
 | 
				
			||||||
  constexpr size_t kLength = 10;
 | 
					 | 
				
			||||||
  auto tester = testing::MakeExceptionSafetyTester()
 | 
					  auto tester = testing::MakeExceptionSafetyTester()
 | 
				
			||||||
                    .WithInitialValue(Thrower(kValue))
 | 
					                    .WithInitialValue(Thrower(kValue))
 | 
				
			||||||
                    // Ensures make_unique does not modify the input. The real
 | 
					                    // Ensures make_unique does not modify the input. The real
 | 
				
			||||||
| 
						 | 
					@ -45,5 +48,16 @@ TEST(MakeUnique, CheckForLeaks) {
 | 
				
			||||||
  }));
 | 
					  }));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(MemoryInternal, UninitDefaultConstructNNonTrivial) {
 | 
				
			||||||
 | 
					  EXPECT_TRUE(testing::MakeExceptionSafetyTester()
 | 
				
			||||||
 | 
					                  .WithInitialValue(ThrowerList{})
 | 
				
			||||||
 | 
					                  .WithOperation([&](ThrowerList* list_ptr) {
 | 
				
			||||||
 | 
					                    absl::memory_internal::uninitialized_default_construct_n(
 | 
				
			||||||
 | 
					                        list_ptr->data(), kLength);
 | 
				
			||||||
 | 
					                  })
 | 
				
			||||||
 | 
					                  .WithInvariants([&](...) { return true; })
 | 
				
			||||||
 | 
					                  .Test());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -611,4 +611,47 @@ TEST(AllocatorNoThrowTest, CustomAllocator) {
 | 
				
			||||||
  EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
 | 
					  EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(MemoryInternal, UninitDefaultConstructNTrivial) {
 | 
				
			||||||
 | 
					  constexpr int kInitialValue = 123;
 | 
				
			||||||
 | 
					  constexpr int kExpectedValue = kInitialValue;  // Expect no-op behavior
 | 
				
			||||||
 | 
					  constexpr int len = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct TestObj {
 | 
				
			||||||
 | 
					    int val;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  static_assert(absl::is_trivially_default_constructible<TestObj>::value, "");
 | 
				
			||||||
 | 
					  static_assert(absl::is_trivially_destructible<TestObj>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TestObj objs[len];
 | 
				
			||||||
 | 
					  for (auto& obj : objs) {
 | 
				
			||||||
 | 
					    obj.val = kInitialValue;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  absl::memory_internal::uninitialized_default_construct_n(objs, len);
 | 
				
			||||||
 | 
					  for (auto& obj : objs) {
 | 
				
			||||||
 | 
					    EXPECT_EQ(obj.val, kExpectedValue);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(MemoryInternal, UninitDefaultConstructNNonTrivial) {
 | 
				
			||||||
 | 
					  constexpr int kInitialValue = 123;
 | 
				
			||||||
 | 
					  constexpr int kExpectedValue = 0;  // Expect value-construction behavior
 | 
				
			||||||
 | 
					  constexpr int len = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct TestObj {
 | 
				
			||||||
 | 
					    int val{kExpectedValue};
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  static_assert(absl::is_trivially_destructible<TestObj>::value, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TestObj objs[len];
 | 
				
			||||||
 | 
					  for (auto& obj : objs) {
 | 
				
			||||||
 | 
					    obj.val = kInitialValue;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  absl::memory_internal::uninitialized_default_construct_n(objs, len);
 | 
				
			||||||
 | 
					  for (auto& obj : objs) {
 | 
				
			||||||
 | 
					    EXPECT_EQ(obj.val, kExpectedValue);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,3 +223,29 @@ std::ostream& operator<<(std::ostream& os, uint128 v) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace std {
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_specialized;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_signed;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_integer;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_exact;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::has_infinity;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::has_quiet_NaN;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::has_signaling_NaN;
 | 
				
			||||||
 | 
					constexpr float_denorm_style numeric_limits<absl::uint128>::has_denorm;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::has_denorm_loss;
 | 
				
			||||||
 | 
					constexpr float_round_style numeric_limits<absl::uint128>::round_style;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_iec559;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_bounded;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::is_modulo;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::digits;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::digits10;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::max_digits10;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::radix;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::min_exponent;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::min_exponent10;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::max_exponent;
 | 
				
			||||||
 | 
					constexpr int numeric_limits<absl::uint128>::max_exponent10;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::traps;
 | 
				
			||||||
 | 
					constexpr bool numeric_limits<absl::uint128>::tinyness_before;
 | 
				
			||||||
 | 
					}  // namespace std
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -219,21 +219,69 @@ std::ostream& operator<<(std::ostream& os, uint128 v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO(strel) add operator>>(std::istream&, uint128)
 | 
					// TODO(strel) add operator>>(std::istream&, uint128)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr uint128 Uint128Max() {
 | 
				
			||||||
 | 
					  return uint128(std::numeric_limits<uint64_t>::max(),
 | 
				
			||||||
 | 
					                 std::numeric_limits<uint64_t>::max());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Specialized numeric_limits for uint128.
 | 
				
			||||||
 | 
					namespace std {
 | 
				
			||||||
 | 
					template <>
 | 
				
			||||||
 | 
					class numeric_limits<absl::uint128> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  static constexpr bool is_specialized = true;
 | 
				
			||||||
 | 
					  static constexpr bool is_signed = false;
 | 
				
			||||||
 | 
					  static constexpr bool is_integer = true;
 | 
				
			||||||
 | 
					  static constexpr bool is_exact = true;
 | 
				
			||||||
 | 
					  static constexpr bool has_infinity = false;
 | 
				
			||||||
 | 
					  static constexpr bool has_quiet_NaN = false;
 | 
				
			||||||
 | 
					  static constexpr bool has_signaling_NaN = false;
 | 
				
			||||||
 | 
					  static constexpr float_denorm_style has_denorm = denorm_absent;
 | 
				
			||||||
 | 
					  static constexpr bool has_denorm_loss = false;
 | 
				
			||||||
 | 
					  static constexpr float_round_style round_style = round_toward_zero;
 | 
				
			||||||
 | 
					  static constexpr bool is_iec559 = false;
 | 
				
			||||||
 | 
					  static constexpr bool is_bounded = true;
 | 
				
			||||||
 | 
					  static constexpr bool is_modulo = true;
 | 
				
			||||||
 | 
					  static constexpr int digits = 128;
 | 
				
			||||||
 | 
					  static constexpr int digits10 = 38;
 | 
				
			||||||
 | 
					  static constexpr int max_digits10 = 0;
 | 
				
			||||||
 | 
					  static constexpr int radix = 2;
 | 
				
			||||||
 | 
					  static constexpr int min_exponent = 0;
 | 
				
			||||||
 | 
					  static constexpr int min_exponent10 = 0;
 | 
				
			||||||
 | 
					  static constexpr int max_exponent = 0;
 | 
				
			||||||
 | 
					  static constexpr int max_exponent10 = 0;
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_INTRINSIC_INT128
 | 
				
			||||||
 | 
					  static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
 | 
				
			||||||
 | 
					#else   // ABSL_HAVE_INTRINSIC_INT128
 | 
				
			||||||
 | 
					  static constexpr bool traps = numeric_limits<uint64_t>::traps;
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_INTRINSIC_INT128
 | 
				
			||||||
 | 
					  static constexpr bool tinyness_before = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 min() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 lowest() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 max() { return absl::Uint128Max(); }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 epsilon() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 round_error() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 infinity() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 quiet_NaN() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 signaling_NaN() { return 0; }
 | 
				
			||||||
 | 
					  static constexpr absl::uint128 denorm_min() { return 0; }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}  // namespace std
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO(absl-team): Implement signed 128-bit type
 | 
					// TODO(absl-team): Implement signed 128-bit type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --------------------------------------------------------------------------
 | 
					// --------------------------------------------------------------------------
 | 
				
			||||||
//                      Implementation details follow
 | 
					//                      Implementation details follow
 | 
				
			||||||
// --------------------------------------------------------------------------
 | 
					// --------------------------------------------------------------------------
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
 | 
					constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
 | 
				
			||||||
  return uint128(high, low);
 | 
					  return uint128(high, low);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr uint128 Uint128Max() {
 | 
					 | 
				
			||||||
  return uint128(std::numeric_limits<uint64_t>::max(),
 | 
					 | 
				
			||||||
                 std::numeric_limits<uint64_t>::max());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Assignment from integer types.
 | 
					// Assignment from integer types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
 | 
					inline uint128& uint128::operator=(int v) { return *this = uint128(v); }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -428,4 +428,15 @@ TEST(Uint128, ConstexprTest) {
 | 
				
			||||||
  EXPECT_EQ(minus_two, absl::MakeUint128(-1, -2));
 | 
					  EXPECT_EQ(minus_two, absl::MakeUint128(-1, -2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Uint128, NumericLimitsTest) {
 | 
				
			||||||
 | 
					  static_assert(std::numeric_limits<absl::uint128>::is_specialized, "");
 | 
				
			||||||
 | 
					  static_assert(!std::numeric_limits<absl::uint128>::is_signed, "");
 | 
				
			||||||
 | 
					  static_assert(std::numeric_limits<absl::uint128>::is_integer, "");
 | 
				
			||||||
 | 
					  EXPECT_EQ(static_cast<int>(128 * std::log10(2)),
 | 
				
			||||||
 | 
					            std::numeric_limits<absl::uint128>::digits10);
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, std::numeric_limits<absl::uint128>::min());
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, std::numeric_limits<absl::uint128>::lowest());
 | 
				
			||||||
 | 
					  EXPECT_EQ(absl::Uint128Max(), std::numeric_limits<absl::uint128>::max());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -344,13 +344,13 @@ ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat(
 | 
				
			||||||
// PrintF()
 | 
					// PrintF()
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Writes to stdout given a format std::string and zero or more arguments. This
 | 
					// Writes to stdout given a format std::string and zero or more arguments. This
 | 
				
			||||||
// function is functionally equivalent to `std::print()` (and type-safe); prefer
 | 
					// function is functionally equivalent to `std::printf()` (and type-safe);
 | 
				
			||||||
// `absl::PrintF()` over `std::printf()`.
 | 
					// prefer `absl::PrintF()` over `std::printf()`.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   std::string_view s = "Ulaanbaatar";
 | 
					//   std::string_view s = "Ulaanbaatar";
 | 
				
			||||||
//   absl::PrintF("The capital of Mongolia is: %s \n", s);
 | 
					//   absl::PrintF("The capital of Mongolia is %s", s);
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   Outputs: "The capital of Mongolia is Ulaanbaatar"
 | 
					//   Outputs: "The capital of Mongolia is Ulaanbaatar"
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -364,13 +364,13 @@ int PrintF(const FormatSpec<Args...>& format, const Args&... args) {
 | 
				
			||||||
// FPrintF()
 | 
					// FPrintF()
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Writes to a file given a format std::string and zero or more arguments. This
 | 
					// Writes to a file given a format std::string and zero or more arguments. This
 | 
				
			||||||
// function is functionally equivalent to `std::fprint()` (and type-safe);
 | 
					// function is functionally equivalent to `std::fprintf()` (and type-safe);
 | 
				
			||||||
// prefer `absl::FPrintF()` over `std::fprintf()`.
 | 
					// prefer `absl::FPrintF()` over `std::fprintf()`.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   std::string_view s = "Ulaanbaatar";
 | 
					//   std::string_view s = "Ulaanbaatar";
 | 
				
			||||||
//   absl::FPrintF("The capital of Mongolia is: %s \n", s);
 | 
					//   absl::FPrintF("The capital of Mongolia is %s", s);
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   Outputs: "The capital of Mongolia is Ulaanbaatar"
 | 
					//   Outputs: "The capital of Mongolia is Ulaanbaatar"
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -385,15 +385,17 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format,
 | 
				
			||||||
// SNPrintF()
 | 
					// SNPrintF()
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Writes to a sized buffer given a format std::string and zero or more arguments.
 | 
					// Writes to a sized buffer given a format std::string and zero or more arguments.
 | 
				
			||||||
// This function is functionally equivalent to `std::snprint()` (and type-safe);
 | 
					// This function is functionally equivalent to `std::snprintf()` (and
 | 
				
			||||||
// prefer `absl::SNPrintF()` over `std::snprintf()`.
 | 
					// type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   std::string_view s = "Ulaanbaatar";
 | 
					//   std::string_view s = "Ulaanbaatar";
 | 
				
			||||||
//   absl::FPrintF("The capital of Mongolia is: %s \n", s);
 | 
					//   char output[128];
 | 
				
			||||||
 | 
					//   absl::SNPrintF(output, sizeof(output),
 | 
				
			||||||
 | 
					//                  "The capital of Mongolia is %s", s);
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   Outputs: "The capital of Mongolia is Ulaanbaatar"
 | 
					//   Post-condition: output == "The capital of Mongolia is Ulaanbaatar"
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
template <typename... Args>
 | 
					template <typename... Args>
 | 
				
			||||||
int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format,
 | 
					int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,10 @@ cc_library(
 | 
				
			||||||
    name = "bad_any_cast",
 | 
					    name = "bad_any_cast",
 | 
				
			||||||
    hdrs = ["bad_any_cast.h"],
 | 
					    hdrs = ["bad_any_cast.h"],
 | 
				
			||||||
    copts = ABSL_DEFAULT_COPTS,
 | 
					    copts = ABSL_DEFAULT_COPTS,
 | 
				
			||||||
    deps = [":bad_any_cast_impl"],
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":bad_any_cast_impl",
 | 
				
			||||||
 | 
					        "//absl/base:config",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_library(
 | 
					cc_library(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/types/bad_any_cast.h"
 | 
					#include "absl/types/bad_any_cast.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ABSL_HAVE_STD_ANY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/base/config.h"
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
| 
						 | 
					@ -38,3 +40,5 @@ void ThrowBadAnyCast() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace any_internal
 | 
					}  // namespace any_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_ANY
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <typeinfo>
 | 
					#include <typeinfo>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STD_ANY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <any>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					using std::bad_any_cast;
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else  // ABSL_HAVE_STD_ANY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace absl {
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -54,4 +66,6 @@ namespace any_internal {
 | 
				
			||||||
}  // namespace any_internal
 | 
					}  // namespace any_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_ANY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // ABSL_TYPES_BAD_ANY_CAST_H_
 | 
					#endif  // ABSL_TYPES_BAD_ANY_CAST_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/types/bad_optional_access.h"
 | 
					#include "absl/types/bad_optional_access.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ABSL_HAVE_STD_OPTIONAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/base/config.h"
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
| 
						 | 
					@ -40,3 +42,5 @@ void throw_bad_optional_access() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace optional_internal
 | 
					}  // namespace optional_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_OPTIONAL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdexcept>
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STD_OPTIONAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <optional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					using std::bad_optional_access;
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else  // ABSL_HAVE_STD_OPTIONAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace absl {
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -57,4 +69,6 @@ namespace optional_internal {
 | 
				
			||||||
}  // namespace optional_internal
 | 
					}  // namespace optional_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_OPTIONAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
 | 
					#endif  // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "absl/types/bad_variant_access.h"
 | 
					#include "absl/types/bad_variant_access.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ABSL_HAVE_STD_VARIANT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <stdexcept>
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,3 +58,5 @@ void Rethrow() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace variant_internal
 | 
					}  // namespace variant_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_VARIANT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdexcept>
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/base/config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STD_VARIANT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <variant>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					using std::bad_variant_access;
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else  // ABSL_HAVE_STD_VARIANT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace absl {
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -61,4 +73,6 @@ namespace variant_internal {
 | 
				
			||||||
}  // namespace variant_internal
 | 
					}  // namespace variant_internal
 | 
				
			||||||
}  // namespace absl
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_VARIANT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // ABSL_TYPES_BAD_VARIANT_ACCESS_H_
 | 
					#endif  // ABSL_TYPES_BAD_VARIANT_ACCESS_H_
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue