Changes imported from Abseil "staging" branch:
- 0a519d9a4507158267cc515e0c7c83959d94fc78 Fix missing header include when compiling with _GLIBCXX_D... by Alex Strelnikov <strel@google.com> - d089af70781d92af9a5de2d84c417ddf2c87689a Internal change by Gennadiy Rozental <rogeeff@google.com> - 0d3afc89d3907923ede964d58c6bcca579e8ad65 Test absl::any for exception safety. This test is tempor... by Jon Cohen <cohenjon@google.com> - 29af424b8a3174a7b3e657e478aa30a8a425aee2 Tweak the ABSL type trait library and expand its tests. by Abseil Team <absl-team@google.com> - 99ab42b2ebbe466cc3730fb6b16b5fad848f95af Rollback GLIBCXX_DEBUG fix due to internal breakage. by Alex Strelnikov <strel@google.com> - 1a5bcb93ee16d4dd2170254e54c4b62b38fbf17b Internal change. by Abseil Team <absl-team@google.com> - 46de7d09c7d4aef5b7b5389ce9b4f96b654aac02 absl::string_view::rfind: doc fix. by Abseil Team <absl-team@google.com> - edda4c7ddd2d76fbb5b3fd5226b95082083c57d9 Fix string_view_test with c++17/clang/libc++ to address by Xiaoyi Zhang <zhangxy@google.com> GitOrigin-RevId: 0a519d9a4507158267cc515e0c7c83959d94fc78 Change-Id: Ie27de1be3e79bba011f05e924d34e8fcc62d8de5
This commit is contained in:
		
							parent
							
								
									0271cd3557
								
							
						
					
					
						commit
						4132ce2595
					
				
					 14 changed files with 724 additions and 191 deletions
				
			
		| 
						 | 
					@ -235,6 +235,7 @@ cc_library(
 | 
				
			||||||
    hdrs = ["internal/exception_safety_testing.h"],
 | 
					    hdrs = ["internal/exception_safety_testing.h"],
 | 
				
			||||||
    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
					    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":base",
 | 
				
			||||||
        ":config",
 | 
					        ":config",
 | 
				
			||||||
        ":pretty_function",
 | 
					        ":pretty_function",
 | 
				
			||||||
        "//absl/memory",
 | 
					        "//absl/memory",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@ list(APPEND BASE_INTERNAL_HEADERS
 | 
				
			||||||
  "internal/cycleclock.h"
 | 
					  "internal/cycleclock.h"
 | 
				
			||||||
  "internal/endian.h"
 | 
					  "internal/endian.h"
 | 
				
			||||||
  "internal/exception_testing.h"
 | 
					  "internal/exception_testing.h"
 | 
				
			||||||
 | 
					  "internal/exception_safety_testing.h"
 | 
				
			||||||
  "internal/identity.h"
 | 
					  "internal/identity.h"
 | 
				
			||||||
  "internal/invoke.h"
 | 
					  "internal/invoke.h"
 | 
				
			||||||
  "internal/log_severity.h"
 | 
					  "internal/log_severity.h"
 | 
				
			||||||
| 
						 | 
					@ -43,6 +44,7 @@ list(APPEND BASE_INTERNAL_HEADERS
 | 
				
			||||||
  "internal/malloc_hook.h"
 | 
					  "internal/malloc_hook.h"
 | 
				
			||||||
  "internal/malloc_hook_invoke.h"
 | 
					  "internal/malloc_hook_invoke.h"
 | 
				
			||||||
  "internal/per_thread_tls.h"
 | 
					  "internal/per_thread_tls.h"
 | 
				
			||||||
 | 
					  "internal/pretty_function.h"
 | 
				
			||||||
  "internal/raw_logging.h"
 | 
					  "internal/raw_logging.h"
 | 
				
			||||||
  "internal/scheduling_mode.h"
 | 
					  "internal/scheduling_mode.h"
 | 
				
			||||||
  "internal/spinlock.h"
 | 
					  "internal/spinlock.h"
 | 
				
			||||||
| 
						 | 
					@ -57,8 +59,9 @@ list(APPEND BASE_INTERNAL_HEADERS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# absl_base main library
 | 
					# absl_base main library
 | 
				
			||||||
list(APPEND BASE_SRC 
 | 
					list(APPEND BASE_SRC
 | 
				
			||||||
  "internal/cycleclock.cc"
 | 
					  "internal/cycleclock.cc"
 | 
				
			||||||
 | 
					  "internal/exception_safety_testing.cc"
 | 
				
			||||||
  "internal/raw_logging.cc"
 | 
					  "internal/raw_logging.cc"
 | 
				
			||||||
  "internal/spinlock.cc"
 | 
					  "internal/spinlock.cc"
 | 
				
			||||||
  "internal/sysinfo.cc"
 | 
					  "internal/sysinfo.cc"
 | 
				
			||||||
| 
						 | 
					@ -318,6 +321,20 @@ absl_test(
 | 
				
			||||||
    ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES}
 | 
					    ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#test exceptions_safety_testing_test
 | 
				
			||||||
 | 
					set(EXCEPTION_SAFETY_TESTING_TEST_SRC "exception_safety_testing_test.cc")
 | 
				
			||||||
 | 
					set(EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES absl::base absl::memory absl::meta absl::strings absl::optional)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_test(
 | 
				
			||||||
 | 
					  TARGET
 | 
				
			||||||
 | 
					    absl_exception_safety_testing_test
 | 
				
			||||||
 | 
					  SOURCES
 | 
				
			||||||
 | 
					    ${EXCEPTION_SAFETY_TESTING_TEST_SRC}
 | 
				
			||||||
 | 
					  PUBLIC_LIBRARIES
 | 
				
			||||||
 | 
					    ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES}
 | 
				
			||||||
 | 
					  PRIVATE_COMPILE_FLAGS
 | 
				
			||||||
 | 
					    ${ABSL_EXCEPTIONS_FLAG}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test absl_malloc_extension_system_malloc_test
 | 
					# test absl_malloc_extension_system_malloc_test
 | 
				
			||||||
set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc")
 | 
					set(MALLOC_EXTENSION_SYSTEM_MALLOC_TEST_SRC "internal/malloc_extension_test.cc")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ TEST_F(ThrowingValueTest, Throws) {
 | 
				
			||||||
// the countdown doesn't hit 0, and doesn't modify the state of the
 | 
					// the countdown doesn't hit 0, and doesn't modify the state of the
 | 
				
			||||||
// ThrowingValue if it throws
 | 
					// ThrowingValue if it throws
 | 
				
			||||||
template <typename F>
 | 
					template <typename F>
 | 
				
			||||||
void TestOp(F&& f) {
 | 
					void TestOp(const F& f) {
 | 
				
			||||||
  UnsetCountdown();
 | 
					  UnsetCountdown();
 | 
				
			||||||
  ExpectNoThrow(f);
 | 
					  ExpectNoThrow(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,11 +153,21 @@ TEST_F(ThrowingValueTest, ThrowingStreamOps) {
 | 
				
			||||||
  TestOp([&]() { std::cout << bomb; });
 | 
					  TestOp([&]() { std::cout << bomb; });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename F>
 | 
				
			||||||
 | 
					void TestAllocatingOp(const F& f) {
 | 
				
			||||||
 | 
					  UnsetCountdown();
 | 
				
			||||||
 | 
					  ExpectNoThrow(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SetCountdown();
 | 
				
			||||||
 | 
					  EXPECT_THROW(f(), exceptions_internal::TestBadAllocException);
 | 
				
			||||||
 | 
					  UnsetCountdown();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_F(ThrowingValueTest, ThrowingAllocatingOps) {
 | 
					TEST_F(ThrowingValueTest, ThrowingAllocatingOps) {
 | 
				
			||||||
  // make_unique calls unqualified operator new, so these exercise the
 | 
					  // make_unique calls unqualified operator new, so these exercise the
 | 
				
			||||||
  // ThrowingValue overloads.
 | 
					  // ThrowingValue overloads.
 | 
				
			||||||
  TestOp([]() { return absl::make_unique<ThrowingValue<>>(1); });
 | 
					  TestAllocatingOp([]() { return absl::make_unique<ThrowingValue<>>(1); });
 | 
				
			||||||
  TestOp([]() { return absl::make_unique<ThrowingValue<>[]>(2); });
 | 
					  TestAllocatingOp([]() { return absl::make_unique<ThrowingValue<>[]>(2); });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_F(ThrowingValueTest, NonThrowingMoveCtor) {
 | 
					TEST_F(ThrowingValueTest, NonThrowingMoveCtor) {
 | 
				
			||||||
| 
						 | 
					@ -399,7 +409,8 @@ struct CallOperator {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct NonNegative {
 | 
					struct NonNegative {
 | 
				
			||||||
  friend testing::AssertionResult AbslCheckInvariants(NonNegative* g) {
 | 
					  friend testing::AssertionResult AbslCheckInvariants(
 | 
				
			||||||
 | 
					      NonNegative* g, absl::InternalAbslNamespaceFinder) {
 | 
				
			||||||
    if (g->i >= 0) return testing::AssertionSuccess();
 | 
					    if (g->i >= 0) return testing::AssertionSuccess();
 | 
				
			||||||
    return testing::AssertionFailure()
 | 
					    return testing::AssertionFailure()
 | 
				
			||||||
           << "i should be non-negative but is " << g->i;
 | 
					           << "i should be non-negative but is " << g->i;
 | 
				
			||||||
| 
						 | 
					@ -503,7 +514,8 @@ struct HasReset : public NonNegative {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void reset() { i = 0; }
 | 
					  void reset() { i = 0; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  friend bool AbslCheckInvariants(HasReset* h) {
 | 
					  friend bool AbslCheckInvariants(HasReset* h,
 | 
				
			||||||
 | 
					                                  absl::InternalAbslNamespaceFinder) {
 | 
				
			||||||
    h->reset();
 | 
					    h->reset();
 | 
				
			||||||
    return h->i == 0;
 | 
					    return h->i == 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -591,7 +603,8 @@ struct ExhaustivenessTester {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  friend testing::AssertionResult AbslCheckInvariants(ExhaustivenessTester*) {
 | 
					  friend testing::AssertionResult AbslCheckInvariants(
 | 
				
			||||||
 | 
					      ExhaustivenessTester*, absl::InternalAbslNamespaceFinder) {
 | 
				
			||||||
    return testing::AssertionSuccess();
 | 
					    return testing::AssertionSuccess();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,8 +23,11 @@ namespace exceptions_internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int countdown = -1;
 | 
					int countdown = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MaybeThrow(absl::string_view msg) {
 | 
					void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) {
 | 
				
			||||||
  if (countdown-- == 0) throw TestException(msg);
 | 
					  if (countdown-- == 0) {
 | 
				
			||||||
 | 
					    if (throw_bad_alloc) throw TestBadAllocException(msg);
 | 
				
			||||||
 | 
					    throw TestException(msg);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
testing::AssertionResult FailureMessage(const TestException& e,
 | 
					testing::AssertionResult FailureMessage(const TestException& e,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,8 @@
 | 
				
			||||||
#include "absl/types/optional.h"
 | 
					#include "absl/types/optional.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace absl {
 | 
					namespace absl {
 | 
				
			||||||
 | 
					struct InternalAbslNamespaceFinder {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct AllocInspector;
 | 
					struct AllocInspector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A configuration enum for Throwing*.  Operations whose flags are set will
 | 
					// A configuration enum for Throwing*.  Operations whose flags are set will
 | 
				
			||||||
| 
						 | 
					@ -71,31 +73,45 @@ constexpr bool ThrowingAllowed(NoThrow flags, NoThrow flag) {
 | 
				
			||||||
class TestException {
 | 
					class TestException {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  explicit TestException(absl::string_view msg) : msg_(msg) {}
 | 
					  explicit TestException(absl::string_view msg) : msg_(msg) {}
 | 
				
			||||||
  absl::string_view what() const { return msg_; }
 | 
					  virtual ~TestException() {}
 | 
				
			||||||
 | 
					  virtual const char* what() const noexcept { return msg_.c_str(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  std::string msg_;
 | 
					  std::string msg_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestBadAllocException exists because allocation functions must throw an
 | 
				
			||||||
 | 
					// exception which can be caught by a handler of std::bad_alloc.  We use a child
 | 
				
			||||||
 | 
					// class of std::bad_alloc so we can customise the error message, and also
 | 
				
			||||||
 | 
					// derive from TestException so we don't accidentally end up catching an actual
 | 
				
			||||||
 | 
					// bad_alloc exception in TestExceptionSafety.
 | 
				
			||||||
 | 
					class TestBadAllocException : public std::bad_alloc, public TestException {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit TestBadAllocException(absl::string_view msg)
 | 
				
			||||||
 | 
					      : TestException(msg) {}
 | 
				
			||||||
 | 
					  using TestException::what;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int countdown;
 | 
					extern int countdown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MaybeThrow(absl::string_view msg);
 | 
					void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
testing::AssertionResult FailureMessage(const TestException& e,
 | 
					testing::AssertionResult FailureMessage(const TestException& e,
 | 
				
			||||||
                                        int countdown) noexcept;
 | 
					                                        int countdown) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TrackedObject {
 | 
					class TrackedObject {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  TrackedObject(const TrackedObject&) = delete;
 | 
				
			||||||
 | 
					  TrackedObject(TrackedObject&&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  explicit TrackedObject(absl::string_view child_ctor) {
 | 
					  explicit TrackedObject(const char* child_ctor) {
 | 
				
			||||||
    if (!GetAllocs().emplace(this, child_ctor).second) {
 | 
					    if (!GetAllocs().emplace(this, child_ctor).second) {
 | 
				
			||||||
      ADD_FAILURE() << "Object at address " << static_cast<void*>(this)
 | 
					      ADD_FAILURE() << "Object at address " << static_cast<void*>(this)
 | 
				
			||||||
                    << " re-constructed in ctor " << child_ctor;
 | 
					                    << " re-constructed in ctor " << child_ctor;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TrackedObject(const TrackedObject&) = delete;
 | 
					 | 
				
			||||||
  TrackedObject(TrackedObject&&) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static std::unordered_map<TrackedObject*, absl::string_view>& GetAllocs() {
 | 
					  static std::unordered_map<TrackedObject*, absl::string_view>& GetAllocs() {
 | 
				
			||||||
    static auto* m =
 | 
					    static auto* m =
 | 
				
			||||||
        new std::unordered_map<TrackedObject*, absl::string_view>();
 | 
					        new std::unordered_map<TrackedObject*, absl::string_view>();
 | 
				
			||||||
| 
						 | 
					@ -120,10 +136,10 @@ using FactoryType = typename absl::result_of_t<Factory()>::element_type;
 | 
				
			||||||
template <typename Factory, typename Op, typename Checker>
 | 
					template <typename Factory, typename Op, typename Checker>
 | 
				
			||||||
absl::optional<testing::AssertionResult> TestCheckerAtCountdown(
 | 
					absl::optional<testing::AssertionResult> TestCheckerAtCountdown(
 | 
				
			||||||
    Factory factory, const Op& op, int count, const Checker& check) {
 | 
					    Factory factory, const Op& op, int count, const Checker& check) {
 | 
				
			||||||
  exceptions_internal::countdown = count;
 | 
					 | 
				
			||||||
  auto t_ptr = factory();
 | 
					  auto t_ptr = factory();
 | 
				
			||||||
  absl::optional<testing::AssertionResult> out;
 | 
					  absl::optional<testing::AssertionResult> out;
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
 | 
					    exceptions_internal::countdown = count;
 | 
				
			||||||
    op(t_ptr.get());
 | 
					    op(t_ptr.get());
 | 
				
			||||||
  } catch (const exceptions_internal::TestException& e) {
 | 
					  } catch (const exceptions_internal::TestException& e) {
 | 
				
			||||||
    out.emplace(check(t_ptr.get()));
 | 
					    out.emplace(check(t_ptr.get()));
 | 
				
			||||||
| 
						 | 
					@ -141,6 +157,10 @@ int UpdateOut(Factory factory, const Op& op, int count, const Checker& checker,
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Declare AbslCheckInvariants so that it can be found eventually via ADL.
 | 
				
			||||||
 | 
					// Taking `...` gives it the lowest possible precedence.
 | 
				
			||||||
 | 
					void AbslCheckInvariants(...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns an optional with the result of the check if op fails, or an empty
 | 
					// Returns an optional with the result of the check if op fails, or an empty
 | 
				
			||||||
// optional if op passes
 | 
					// optional if op passes
 | 
				
			||||||
template <typename Factory, typename Op, typename... Checkers>
 | 
					template <typename Factory, typename Op, typename... Checkers>
 | 
				
			||||||
| 
						 | 
					@ -148,8 +168,9 @@ absl::optional<testing::AssertionResult> TestAtCountdown(
 | 
				
			||||||
    Factory factory, const Op& op, int count, const Checkers&... checkers) {
 | 
					    Factory factory, const Op& op, int count, const Checkers&... checkers) {
 | 
				
			||||||
  // Don't bother with the checkers if the class invariants are already broken.
 | 
					  // Don't bother with the checkers if the class invariants are already broken.
 | 
				
			||||||
  auto out = TestCheckerAtCountdown(
 | 
					  auto out = TestCheckerAtCountdown(
 | 
				
			||||||
      factory, op, count,
 | 
					      factory, op, count, [](FactoryType<Factory>* t_ptr) {
 | 
				
			||||||
      [](FactoryType<Factory>* t_ptr) { return AbslCheckInvariants(t_ptr); });
 | 
					        return AbslCheckInvariants(t_ptr, InternalAbslNamespaceFinder());
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
  if (!out.has_value()) return out;
 | 
					  if (!out.has_value()) return out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Run each checker, short circuiting after the first failure
 | 
					  // Run each checker, short circuiting after the first failure
 | 
				
			||||||
| 
						 | 
					@ -483,7 +504,7 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
 | 
				
			||||||
  static void* operator new(size_t s, Args&&... args) noexcept(
 | 
					  static void* operator new(size_t s, Args&&... args) noexcept(
 | 
				
			||||||
      !exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
					      !exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
				
			||||||
    if (exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
					    if (exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
				
			||||||
      exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
 | 
					      exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ::operator new(s, std::forward<Args>(args)...);
 | 
					    return ::operator new(s, std::forward<Args>(args)...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -492,7 +513,7 @@ class ThrowingValue : private exceptions_internal::TrackedObject {
 | 
				
			||||||
  static void* operator new[](size_t s, Args&&... args) noexcept(
 | 
					  static void* operator new[](size_t s, Args&&... args) noexcept(
 | 
				
			||||||
      !exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
					      !exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
				
			||||||
    if (exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
					    if (exceptions_internal::ThrowingAllowed(Flags, NoThrow::kAllocation)) {
 | 
				
			||||||
      exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION);
 | 
					      exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ::operator new[](s, std::forward<Args>(args)...);
 | 
					    return ::operator new[](s, std::forward<Args>(args)...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -630,10 +651,7 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject {
 | 
				
			||||||
    p->~U();
 | 
					    p->~U();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  size_type max_size() const
 | 
					  size_type max_size() const noexcept {
 | 
				
			||||||
      noexcept(!exceptions_internal::ThrowingAllowed(Flags,
 | 
					 | 
				
			||||||
                                                     NoThrow::kNoThrow)) {
 | 
					 | 
				
			||||||
    ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION);
 | 
					 | 
				
			||||||
    return std::numeric_limits<difference_type>::max() / sizeof(value_type);
 | 
					    return std::numeric_limits<difference_type>::max() / sizeof(value_type);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -720,9 +738,12 @@ T TestThrowingCtor(Args&&... args) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that performing operation Op on a T follows exception safety
 | 
					// Tests that performing operation Op on a T follows exception safety
 | 
				
			||||||
// guarantees.  By default only tests the basic guarantee. There must be a
 | 
					// guarantees.  By default only tests the basic guarantee. There must be a
 | 
				
			||||||
// function, AbslCheckInvariants(T*) which returns
 | 
					// function, AbslCheckInvariants(T*, absl::InternalAbslNamespaceFinder) which
 | 
				
			||||||
// anything convertible to bool and which makes sure the invariants of the type
 | 
					// returns anything convertible to bool and which makes sure the invariants of
 | 
				
			||||||
// are upheld.  This is called before any of the checkers.
 | 
					// the type are upheld.  This is called before any of the checkers.  The
 | 
				
			||||||
 | 
					// InternalAbslNamespaceFinder is unused, and just helps find
 | 
				
			||||||
 | 
					// AbslCheckInvariants for absl types which become aliases to std::types in
 | 
				
			||||||
 | 
					// C++17.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Parameters:
 | 
					// Parameters:
 | 
				
			||||||
//   * TFactory: operator() returns a unique_ptr to the type under test (T).  It
 | 
					//   * TFactory: operator() returns a unique_ptr to the type under test (T).  It
 | 
				
			||||||
| 
						 | 
					@ -740,11 +761,13 @@ template <typename TFactory, typename FunctionFromTPtrToVoid,
 | 
				
			||||||
testing::AssertionResult TestExceptionSafety(TFactory factory,
 | 
					testing::AssertionResult TestExceptionSafety(TFactory factory,
 | 
				
			||||||
                                             FunctionFromTPtrToVoid&& op,
 | 
					                                             FunctionFromTPtrToVoid&& op,
 | 
				
			||||||
                                             const Checkers&... checkers) {
 | 
					                                             const Checkers&... checkers) {
 | 
				
			||||||
 | 
					  struct Cleanup {
 | 
				
			||||||
 | 
					    ~Cleanup() { UnsetCountdown(); }
 | 
				
			||||||
 | 
					  } c;
 | 
				
			||||||
  for (int countdown = 0;; ++countdown) {
 | 
					  for (int countdown = 0;; ++countdown) {
 | 
				
			||||||
    auto out = exceptions_internal::TestAtCountdown(factory, op, countdown,
 | 
					    auto out = exceptions_internal::TestAtCountdown(factory, op, countdown,
 | 
				
			||||||
                                                    checkers...);
 | 
					                                                    checkers...);
 | 
				
			||||||
    if (!out.has_value()) {
 | 
					    if (!out.has_value()) {
 | 
				
			||||||
      UnsetCountdown();
 | 
					 | 
				
			||||||
      return testing::AssertionSuccess();
 | 
					      return testing::AssertionSuccess();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!*out) return *out;
 | 
					    if (!*out) return *out;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,11 +148,16 @@ struct negation : std::integral_constant<bool, !T::value> {};
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct is_trivially_destructible
 | 
					struct is_trivially_destructible
 | 
				
			||||||
    : std::integral_constant<bool, __has_trivial_destructor(T) &&
 | 
					    : std::integral_constant<bool, __has_trivial_destructor(T) &&
 | 
				
			||||||
                                       std::is_destructible<T>::value> {
 | 
					                                   std::is_destructible<T>::value> {
 | 
				
			||||||
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
 | 
					#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
 | 
				
			||||||
  static_assert(std::is_trivially_destructible<T>::value ==
 | 
					  static constexpr bool compliant = std::is_trivially_destructible<T>::value ==
 | 
				
			||||||
                    is_trivially_destructible::value,
 | 
					                                    is_trivially_destructible::value;
 | 
				
			||||||
                "Not compliant with std::is_trivially_destructible");
 | 
					  static_assert(compliant || std::is_trivially_destructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_destructible; "
 | 
				
			||||||
 | 
					                "Standard: false, Implementation: true");
 | 
				
			||||||
 | 
					  static_assert(compliant || !std::is_trivially_destructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_destructible; "
 | 
				
			||||||
 | 
					                "Standard: true, Implementation: false");
 | 
				
			||||||
#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
 | 
					#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,18 +191,23 @@ struct is_trivially_destructible
 | 
				
			||||||
// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
 | 
					// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
 | 
				
			||||||
// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116.
 | 
					// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// "T obj();" need to be well-formed and not call any non-trivial operation.
 | 
					// "T obj();" need to be well-formed and not call any nontrivial operation.
 | 
				
			||||||
// Nontrivally destructible types will cause the expression to be nontrivial.
 | 
					// Nontrivally destructible types will cause the expression to be nontrivial.
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct is_trivially_default_constructible
 | 
					struct is_trivially_default_constructible
 | 
				
			||||||
    : std::integral_constant<bool,
 | 
					    : std::integral_constant<bool, __has_trivial_constructor(T) &&
 | 
				
			||||||
                             __has_trivial_constructor(T) &&
 | 
					                                   std::is_default_constructible<T>::value &&
 | 
				
			||||||
                                 std::is_default_constructible<T>::value &&
 | 
					                                   is_trivially_destructible<T>::value> {
 | 
				
			||||||
                                 is_trivially_destructible<T>::value> {
 | 
					 | 
				
			||||||
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
					#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
				
			||||||
  static_assert(std::is_trivially_default_constructible<T>::value ==
 | 
					  static constexpr bool compliant =
 | 
				
			||||||
                    is_trivially_default_constructible::value,
 | 
					      std::is_trivially_default_constructible<T>::value ==
 | 
				
			||||||
                "Not compliant with std::is_trivially_default_constructible");
 | 
					      is_trivially_default_constructible::value;
 | 
				
			||||||
 | 
					  static_assert(compliant || std::is_trivially_default_constructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_default_constructible; "
 | 
				
			||||||
 | 
					                "Standard: false, Implementation: true");
 | 
				
			||||||
 | 
					  static_assert(compliant || !std::is_trivially_default_constructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_default_constructible; "
 | 
				
			||||||
 | 
					                "Standard: true, Implementation: false");
 | 
				
			||||||
#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
					#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,12 +227,18 @@ struct is_trivially_default_constructible
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct is_trivially_copy_constructible
 | 
					struct is_trivially_copy_constructible
 | 
				
			||||||
    : std::integral_constant<bool, __has_trivial_copy(T) &&
 | 
					    : std::integral_constant<bool, __has_trivial_copy(T) &&
 | 
				
			||||||
                                       std::is_copy_constructible<T>::value &&
 | 
					                                   std::is_copy_constructible<T>::value &&
 | 
				
			||||||
                                       is_trivially_destructible<T>::value> {
 | 
					                                   is_trivially_destructible<T>::value> {
 | 
				
			||||||
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
					#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
				
			||||||
  static_assert(std::is_trivially_copy_constructible<T>::value ==
 | 
					  static constexpr bool compliant =
 | 
				
			||||||
                    is_trivially_copy_constructible::value,
 | 
					      std::is_trivially_copy_constructible<T>::value ==
 | 
				
			||||||
                "Not compliant with std::is_trivially_copy_constructible");
 | 
					      is_trivially_copy_constructible::value;
 | 
				
			||||||
 | 
					  static_assert(compliant || std::is_trivially_copy_constructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_copy_constructible; "
 | 
				
			||||||
 | 
					                "Standard: false, Implementation: true");
 | 
				
			||||||
 | 
					  static_assert(compliant || !std::is_trivially_copy_constructible<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_copy_constructible; "
 | 
				
			||||||
 | 
					                "Standard: true, Implementation: false");
 | 
				
			||||||
#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
					#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,15 +256,21 @@ struct is_trivially_copy_constructible
 | 
				
			||||||
// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
 | 
					// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
 | 
				
			||||||
// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
 | 
					// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
 | 
				
			||||||
// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
 | 
					// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
 | 
				
			||||||
// `is_trivially_assignable<T, const T&>`.
 | 
					// `is_trivially_assignable<T&, const T&>`.
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct is_trivially_copy_assignable
 | 
					struct is_trivially_copy_assignable
 | 
				
			||||||
    : std::integral_constant<bool, __has_trivial_assign(T) &&
 | 
					    : std::integral_constant<bool, __has_trivial_assign(T) &&
 | 
				
			||||||
                                       std::is_copy_assignable<T>::value> {
 | 
					                                   std::is_copy_assignable<T>::value> {
 | 
				
			||||||
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 | 
					#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 | 
				
			||||||
  static_assert(std::is_trivially_copy_assignable<T>::value ==
 | 
					  static constexpr bool compliant =
 | 
				
			||||||
                    is_trivially_copy_assignable::value,
 | 
					      std::is_trivially_copy_assignable<T>::value ==
 | 
				
			||||||
                "Not compliant with std::is_trivially_copy_assignable");
 | 
					      is_trivially_copy_assignable::value;
 | 
				
			||||||
 | 
					  static_assert(compliant || std::is_trivially_copy_assignable<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_copy_assignable; "
 | 
				
			||||||
 | 
					                "Standard: false, Implementation: true");
 | 
				
			||||||
 | 
					  static_assert(compliant || !std::is_trivially_copy_assignable<T>::value,
 | 
				
			||||||
 | 
					                "Not compliant with std::is_trivially_copy_assignable; "
 | 
				
			||||||
 | 
					                "Standard: true, Implementation: false");
 | 
				
			||||||
#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 | 
					#endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,18 @@ class Trivial {
 | 
				
			||||||
  int n_;
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct TrivialDestructor {
 | 
				
			||||||
 | 
					  ~TrivialDestructor() = default;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct NontrivialDestructor {
 | 
				
			||||||
 | 
					  ~NontrivialDestructor() {}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct DeletedDestructor {
 | 
				
			||||||
 | 
					  ~DeletedDestructor() = delete;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TrivialDefaultCtor {
 | 
					class TrivialDefaultCtor {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  TrivialDefaultCtor() = default;
 | 
					  TrivialDefaultCtor() = default;
 | 
				
			||||||
| 
						 | 
					@ -108,6 +120,23 @@ class TrivialDefaultCtor {
 | 
				
			||||||
  int n_;
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NontrivialDefaultCtor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  NontrivialDefaultCtor() : n_(1) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DeletedDefaultCtor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  DeletedDefaultCtor() = delete;
 | 
				
			||||||
 | 
					  explicit DeletedDefaultCtor(int n) : n_(n) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TrivialCopyCtor {
 | 
					class TrivialCopyCtor {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  explicit TrivialCopyCtor(int n) : n_(n) {}
 | 
					  explicit TrivialCopyCtor(int n) : n_(n) {}
 | 
				
			||||||
| 
						 | 
					@ -121,22 +150,57 @@ class TrivialCopyCtor {
 | 
				
			||||||
  int n_;
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NontrivialCopyCtor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit NontrivialCopyCtor(int n) : n_(n) {}
 | 
				
			||||||
 | 
					  NontrivialCopyCtor(const NontrivialCopyCtor& t) : n_(t.n_) {}
 | 
				
			||||||
 | 
					  NontrivialCopyCtor& operator=(const NontrivialCopyCtor&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DeletedCopyCtor {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit DeletedCopyCtor(int n) : n_(n) {}
 | 
				
			||||||
 | 
					  DeletedCopyCtor(const DeletedCopyCtor&) = delete;
 | 
				
			||||||
 | 
					  DeletedCopyCtor& operator=(const DeletedCopyCtor&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TrivialCopyAssign {
 | 
					class TrivialCopyAssign {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  explicit TrivialCopyAssign(int n) : n_(n) {}
 | 
					  explicit TrivialCopyAssign(int n) : n_(n) {}
 | 
				
			||||||
  TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {}
 | 
					  TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {}
 | 
				
			||||||
  TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default;
 | 
					  TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default;
 | 
				
			||||||
  ~TrivialCopyAssign() {}  // can have non trivial destructor
 | 
					  ~TrivialCopyAssign() {}  // can have nontrivial destructor
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  int n_;
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct NonTrivialDestructor {
 | 
					class NontrivialCopyAssign {
 | 
				
			||||||
  ~NonTrivialDestructor() {}
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit NontrivialCopyAssign(int n) : n_(n) {}
 | 
				
			||||||
 | 
					  NontrivialCopyAssign(const NontrivialCopyAssign&) = default;
 | 
				
			||||||
 | 
					  NontrivialCopyAssign& operator=(const NontrivialCopyAssign& t) {
 | 
				
			||||||
 | 
					    n_ = t.n_;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TrivialDestructor {
 | 
					class DeletedCopyAssign {
 | 
				
			||||||
  ~TrivialDestructor() = default;
 | 
					 public:
 | 
				
			||||||
 | 
					  explicit DeletedCopyAssign(int n) : n_(n) {}
 | 
				
			||||||
 | 
					  DeletedCopyAssign(const DeletedCopyAssign&) = default;
 | 
				
			||||||
 | 
					  DeletedCopyAssign& operator=(const DeletedCopyAssign&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  int n_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct NonCopyable {
 | 
					struct NonCopyable {
 | 
				
			||||||
| 
						 | 
					@ -152,19 +216,105 @@ class Base {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// In GCC/Clang, std::is_trivially_constructible requires that the destructor is
 | 
					// In GCC/Clang, std::is_trivially_constructible requires that the destructor is
 | 
				
			||||||
// trivial. However, MSVC doesn't require that. This results in different
 | 
					// trivial. However, MSVC doesn't require that. This results in different
 | 
				
			||||||
// behavior when checking is_trivially_constructible on any type with nontrivial
 | 
					// behavior when checking is_trivially_constructible on any type with
 | 
				
			||||||
// destructor. Since absl::is_trivially_default_constructible and
 | 
					// nontrivial destructor. Since absl::is_trivially_default_constructible and
 | 
				
			||||||
// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation
 | 
					// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation
 | 
				
			||||||
// and check is_trivially_destructible, it results in inconsistency with
 | 
					// and check is_trivially_destructible, it results in inconsistency with
 | 
				
			||||||
// std::is_trivially_xxx_constructible on MSVC. This macro is used to work
 | 
					// std::is_trivially_xxx_constructible on MSVC. This macro is used to work
 | 
				
			||||||
// around this issue in test. In practice, a trivially constructible type
 | 
					// around this issue in test. In practice, a trivially constructible type
 | 
				
			||||||
// should also be trivially destructible.
 | 
					// should also be trivially destructible.
 | 
				
			||||||
// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
 | 
					// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452
 | 
				
			||||||
// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116.
 | 
					// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116
 | 
				
			||||||
#ifdef _MSC_VER
 | 
					#ifndef _MSC_VER
 | 
				
			||||||
#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
 | 
					#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors
 | 
				
			||||||
 | 
					// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this
 | 
				
			||||||
 | 
					// is no longer considered true and has thus been amended.
 | 
				
			||||||
 | 
					// Compiler Explorer: https://godbolt.org/g/zT59ZL
 | 
				
			||||||
 | 
					// CWG issue 1734: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1734
 | 
				
			||||||
 | 
					// CWG issue 1928: http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1928
 | 
				
			||||||
 | 
					#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 3700
 | 
				
			||||||
 | 
					#define ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// As of the moment, GCC versions >5.1 have a problem compiling for
 | 
				
			||||||
 | 
					// std::is_trivially_default_constructible<NontrivialDestructor[10]>, where
 | 
				
			||||||
 | 
					// NontrivialDestructor is a struct with a custom nontrivial destructor. Note
 | 
				
			||||||
 | 
					// that this problem only occurs for arrays of a known size, so something like
 | 
				
			||||||
 | 
					// std::is_trivially_default_constructible<NontrivialDestructor[]> does not
 | 
				
			||||||
 | 
					// have any problems.
 | 
				
			||||||
 | 
					// Compiler Explorer: https://godbolt.org/g/dXRbdK
 | 
				
			||||||
 | 
					// GCC bug 83689: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689
 | 
				
			||||||
 | 
					#if defined(__clang__) || defined(_MSC_VER) || \
 | 
				
			||||||
 | 
					    (defined(__GNUC__) && __GNUC__ < 5)
 | 
				
			||||||
 | 
					#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TypeTraitsTest, TestTrivialDestructor) {
 | 
				
			||||||
 | 
					  // Verify that arithmetic types and pointers have trivial destructors.
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<bool>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<char>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<int>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<float>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<double>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<long double>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<const std::string*>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<const Trivial*>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<std::string**>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<Trivial**>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // classes with destructors
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that types with a nontrivial or deleted destructor
 | 
				
			||||||
 | 
					  // are marked as such.
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor>::value);
 | 
				
			||||||
 | 
					#ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_destructible<DeletedDestructor>::value);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // simple_pair of such types is trivial
 | 
				
			||||||
 | 
					  EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value));
 | 
				
			||||||
 | 
					  EXPECT_TRUE((absl::is_trivially_destructible<
 | 
				
			||||||
 | 
					               simple_pair<Trivial, TrivialDestructor>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that types without trivial destructors are correctly marked as such.
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_destructible<std::string>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_destructible<std::vector<int>>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that simple_pairs of types without trivial destructors
 | 
				
			||||||
 | 
					  // are not marked as trivial.
 | 
				
			||||||
 | 
					  EXPECT_FALSE((absl::is_trivially_destructible<
 | 
				
			||||||
 | 
					                simple_pair<int, std::string>>::value));
 | 
				
			||||||
 | 
					  EXPECT_FALSE((absl::is_trivially_destructible<
 | 
				
			||||||
 | 
					                simple_pair<std::string, int>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // array of such types is trivial
 | 
				
			||||||
 | 
					  using int10 = int[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<int10>::value);
 | 
				
			||||||
 | 
					  using Trivial10 = Trivial[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<Trivial10>::value);
 | 
				
			||||||
 | 
					  using TrivialDestructor10 = TrivialDestructor[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Conversely, the opposite also holds.
 | 
				
			||||||
 | 
					  using NontrivialDestructor10 = NontrivialDestructor[10];
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor10>::value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
 | 
					TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
 | 
				
			||||||
  // arithmetic types and pointers have trivial default constructors.
 | 
					  // arithmetic types and pointers have trivial default constructors.
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value);
 | 
				
			||||||
| 
						 | 
					@ -184,42 +334,67 @@ TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value);
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
      absl::is_trivially_default_constructible<const TrivialCopyCtor*>::value);
 | 
					      absl::is_trivially_default_constructible<const std::string*>::value);
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<const Trivial*>::value);
 | 
				
			||||||
      absl::is_trivially_default_constructible<TrivialCopyCtor**>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<std::string**>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial**>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with compiler generated default ctors
 | 
					  // types with compiler generated default ctors
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value);
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
      absl::is_trivially_default_constructible<TrivialDefaultCtor>::value);
 | 
					      absl::is_trivially_default_constructible<TrivialDefaultCtor>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
 | 
					  // Verify that types without them are not.
 | 
				
			||||||
  // types with non trivial destructor are non trivial
 | 
					 | 
				
			||||||
  EXPECT_FALSE(
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
      absl::is_trivially_default_constructible<NonTrivialDestructor>::value);
 | 
					      absl::is_trivially_default_constructible<NontrivialDefaultCtor>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      absl::is_trivially_default_constructible<DeletedDefaultCtor>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
 | 
				
			||||||
 | 
					  // types with nontrivial destructor are nontrivial
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      absl::is_trivially_default_constructible<NontrivialDestructor>::value);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with vtables
 | 
					  // types with vtables
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that arrays of such types are trivially default constructible
 | 
					 | 
				
			||||||
  typedef int int10[10];
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value);
 | 
					 | 
				
			||||||
  typedef Trivial Trivial10[10];
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value);
 | 
					 | 
				
			||||||
  typedef Trivial TrivialDefaultCtor10[10];
 | 
					 | 
				
			||||||
  EXPECT_TRUE(
 | 
					 | 
				
			||||||
      absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Verify that simple_pair has trivial constructors where applicable.
 | 
					  // Verify that simple_pair has trivial constructors where applicable.
 | 
				
			||||||
  EXPECT_TRUE((absl::is_trivially_default_constructible<
 | 
					  EXPECT_TRUE((absl::is_trivially_default_constructible<
 | 
				
			||||||
               simple_pair<int, char*>>::value));
 | 
					               simple_pair<int, char*>>::value));
 | 
				
			||||||
 | 
					  EXPECT_TRUE((absl::is_trivially_default_constructible<
 | 
				
			||||||
 | 
					               simple_pair<int, Trivial>>::value));
 | 
				
			||||||
 | 
					  EXPECT_TRUE((absl::is_trivially_default_constructible<
 | 
				
			||||||
 | 
					               simple_pair<int, TrivialDefaultCtor>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that types without trivial constructors are
 | 
					  // Verify that types without trivial constructors are
 | 
				
			||||||
  // correctly marked as such.
 | 
					  // correctly marked as such.
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value);
 | 
				
			||||||
  EXPECT_FALSE(
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
      absl::is_trivially_default_constructible<std::vector<int>>::value);
 | 
					      absl::is_trivially_default_constructible<std::vector<int>>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that simple_pairs of types without trivial constructors
 | 
				
			||||||
 | 
					  // are not marked as trivial.
 | 
				
			||||||
 | 
					  EXPECT_FALSE((absl::is_trivially_default_constructible<
 | 
				
			||||||
 | 
					                simple_pair<int, std::string>>::value));
 | 
				
			||||||
 | 
					  EXPECT_FALSE((absl::is_trivially_default_constructible<
 | 
				
			||||||
 | 
					                simple_pair<std::string, int>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that arrays of such types are trivially default constructible
 | 
				
			||||||
 | 
					  using int10 = int[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value);
 | 
				
			||||||
 | 
					  using Trivial10 = Trivial[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value);
 | 
				
			||||||
 | 
					  using TrivialDefaultCtor10 = TrivialDefaultCtor[10];
 | 
				
			||||||
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
 | 
					      absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Conversely, the opposite also holds.
 | 
				
			||||||
 | 
					#ifdef ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL
 | 
				
			||||||
 | 
					  using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10];
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      absl::is_trivially_default_constructible<NontrivialDefaultCtor10>::value);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TypeTraitsTest, TestTrivialCopyCtor) {
 | 
					TEST(TypeTraitsTest, TestTrivialCopyCtor) {
 | 
				
			||||||
| 
						 | 
					@ -241,18 +416,26 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value);
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<const std::string*>::value);
 | 
				
			||||||
      absl::is_trivially_copy_constructible<const TrivialCopyCtor*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<const Trivial*>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor**>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with compiler generated copy ctors
 | 
					  // types with compiler generated copy ctors
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
 | 
					  // Verify that types without them (i.e. nontrivial or deleted) are not.
 | 
				
			||||||
  // type with non-trivial destructor are non-trivial copy construbtible
 | 
					 | 
				
			||||||
  EXPECT_FALSE(
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
      absl::is_trivially_copy_constructible<NonTrivialDestructor>::value);
 | 
					      absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      absl::is_trivially_copy_constructible<NonCopyable>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
 | 
				
			||||||
 | 
					  // type with nontrivial destructor are nontrivial copy construbtible
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      absl::is_trivially_copy_constructible<NontrivialDestructor>::value);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with vtables
 | 
					  // types with vtables
 | 
				
			||||||
| 
						 | 
					@ -266,9 +449,10 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
 | 
				
			||||||
  EXPECT_TRUE((absl::is_trivially_copy_constructible<
 | 
					  EXPECT_TRUE((absl::is_trivially_copy_constructible<
 | 
				
			||||||
               simple_pair<int, TrivialCopyCtor>>::value));
 | 
					               simple_pair<int, TrivialCopyCtor>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that arrays are not
 | 
					  // Verify that types without trivial copy constructors are
 | 
				
			||||||
  typedef int int10[10];
 | 
					  // correctly marked as such.
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that simple_pairs of types without trivial copy constructors
 | 
					  // Verify that simple_pairs of types without trivial copy constructors
 | 
				
			||||||
  // are not marked as trivial.
 | 
					  // are not marked as trivial.
 | 
				
			||||||
| 
						 | 
					@ -277,18 +461,14 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
 | 
				
			||||||
  EXPECT_FALSE((absl::is_trivially_copy_constructible<
 | 
					  EXPECT_FALSE((absl::is_trivially_copy_constructible<
 | 
				
			||||||
                simple_pair<std::string, int>>::value));
 | 
					                simple_pair<std::string, int>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that types without trivial copy constructors are
 | 
					  // Verify that arrays are not
 | 
				
			||||||
  // correctly marked as such.
 | 
					  using int10 = int[10];
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value);
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // types with deleted copy constructors are not copy constructible
 | 
					 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_constructible<NonCopyable>::value);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TypeTraitsTest, TestTrivialCopyAssign) {
 | 
					TEST(TypeTraitsTest, TestTrivialCopyAssign) {
 | 
				
			||||||
  // Verify that arithmetic types and pointers have trivial copy
 | 
					  // Verify that arithmetic types and pointers have trivial copy
 | 
				
			||||||
  // constructors.
 | 
					  // assignment operators.
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value);
 | 
				
			||||||
| 
						 | 
					@ -305,9 +485,10 @@ TEST(TypeTraitsTest, TestTrivialCopyAssign) {
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value);
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<const std::string*>::value);
 | 
				
			||||||
      absl::is_trivially_copy_assignable<const TrivialCopyCtor*>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<const Trivial*>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyCtor**>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string**>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial**>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // const qualified types are not assignable
 | 
					  // const qualified types are not assignable
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value);
 | 
				
			||||||
| 
						 | 
					@ -316,65 +497,37 @@ TEST(TypeTraitsTest, TestTrivialCopyAssign) {
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Verify that types without them (i.e. nontrivial or deleted) are not.
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with vtables
 | 
					  // types with vtables
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that arrays are not trivially copy assignable
 | 
					 | 
				
			||||||
  typedef int int10[10];
 | 
					 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Verify that simple_pair is trivially assignable
 | 
					  // Verify that simple_pair is trivially assignable
 | 
				
			||||||
  EXPECT_TRUE(
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
      (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value));
 | 
					      (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value));
 | 
				
			||||||
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
 | 
					      (absl::is_trivially_copy_assignable<simple_pair<int, Trivial>>::value));
 | 
				
			||||||
 | 
					  EXPECT_TRUE((absl::is_trivially_copy_assignable<
 | 
				
			||||||
 | 
					               simple_pair<int, TrivialCopyAssign>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that types without trivial copy constructors are
 | 
					  // Verify that types not trivially copy assignable are
 | 
				
			||||||
  // correctly marked as such.
 | 
					  // correctly marked as such.
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value);
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value);
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // types with deleted copy assignment are not copy assignable
 | 
					  // Verify that simple_pairs of types not trivially copy assignable
 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value);
 | 
					  // are not marked as trivial.
 | 
				
			||||||
}
 | 
					  EXPECT_FALSE((absl::is_trivially_copy_assignable<
 | 
				
			||||||
 | 
					                simple_pair<int, std::string>>::value));
 | 
				
			||||||
 | 
					  EXPECT_FALSE((absl::is_trivially_copy_assignable<
 | 
				
			||||||
 | 
					                simple_pair<std::string, int>>::value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TypeTraitsTest, TestTrivialDestructor) {
 | 
					  // Verify that arrays are not trivially copy assignable
 | 
				
			||||||
  // Verify that arithmetic types and pointers have trivial copy
 | 
					  using int10 = int[10];
 | 
				
			||||||
  // constructors.
 | 
					  EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value);
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<bool>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<char>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<int>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<float>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<double>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<long double>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<const TrivialCopyCtor*>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<TrivialCopyCtor**>::value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // classes with destructors
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value);
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value);
 | 
					 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_destructible<NonTrivialDestructor>::value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // simple_pair of such types is trivial
 | 
					 | 
				
			||||||
  EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value));
 | 
					 | 
				
			||||||
  EXPECT_TRUE((absl::is_trivially_destructible<
 | 
					 | 
				
			||||||
               simple_pair<Trivial, TrivialDestructor>>::value));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // array of such types is trivial
 | 
					 | 
				
			||||||
  typedef int int10[10];
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<int10>::value);
 | 
					 | 
				
			||||||
  typedef TrivialDestructor TrivialDestructor10[10];
 | 
					 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value);
 | 
					 | 
				
			||||||
  typedef NonTrivialDestructor NonTrivialDestructor10[10];
 | 
					 | 
				
			||||||
  EXPECT_FALSE(absl::is_trivially_destructible<NonTrivialDestructor10>::value);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...)          \
 | 
					#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...)          \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,31 +79,48 @@ struct IsSTLContainer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename C, template <typename...> class T, typename = void>
 | 
					template <typename C, template <typename...> class T, typename = void>
 | 
				
			||||||
struct IsBaseOfSpecializationImpl : std::false_type {};
 | 
					struct IsBaseOfSpecializationImpl : std::false_type {};
 | 
				
			||||||
// IsBaseOfSpecializationImpl must have three partial specializations,
 | 
					// IsBaseOfSpecializationImpl needs multiple partial specializations to SFINAE
 | 
				
			||||||
// because we must only compare templates that take the same number of
 | 
					// on the existence of container dependent types and plug them into the STL
 | 
				
			||||||
// arguments. Otherwise, for example, std::vector can be compared with std::map,
 | 
					// template.
 | 
				
			||||||
// and fail to compile because of too few or too many template arguments.
 | 
					template <typename C, template <typename, typename> class T>
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// We must also SFINAE on the existence of an allocator_type. Otherwise, we may
 | 
					 | 
				
			||||||
// try to compare, for example, a std::pair<std::string, std::string> with a
 | 
					 | 
				
			||||||
// std::vector<std::string, std:std::string>. This would fail to compile, because
 | 
					 | 
				
			||||||
// of expected properties of the type passed in as the allocator.
 | 
					 | 
				
			||||||
template <template <typename, typename> class U,
 | 
					 | 
				
			||||||
          template <typename, typename> class T, typename... Args>
 | 
					 | 
				
			||||||
struct IsBaseOfSpecializationImpl<
 | 
					struct IsBaseOfSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T, absl::void_t<typename C::value_type, typename C::allocator_type>>
 | 
				
			||||||
    : std::is_base_of<U<Args...>, T<Args...>> {};
 | 
					    : std::is_base_of<C,
 | 
				
			||||||
template <template <typename, typename, typename> class U,
 | 
					                      T<typename C::value_type, typename C::allocator_type>> {};
 | 
				
			||||||
          template <typename, typename, typename> class T, typename... Args>
 | 
					template <typename C, template <typename, typename, typename> class T>
 | 
				
			||||||
struct IsBaseOfSpecializationImpl<
 | 
					struct IsBaseOfSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T,
 | 
				
			||||||
    : std::is_base_of<U<Args...>, T<Args...>> {};
 | 
					    absl::void_t<typename C::key_type, typename C::key_compare,
 | 
				
			||||||
template <template <typename, typename, typename, typename> class U,
 | 
					                 typename C::allocator_type>>
 | 
				
			||||||
          template <typename, typename, typename, typename> class T,
 | 
					    : std::is_base_of<C, T<typename C::key_type, typename C::key_compare,
 | 
				
			||||||
          typename... Args>
 | 
					                           typename C::allocator_type>> {};
 | 
				
			||||||
 | 
					template <typename C, template <typename, typename, typename, typename> class T>
 | 
				
			||||||
struct IsBaseOfSpecializationImpl<
 | 
					struct IsBaseOfSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T,
 | 
				
			||||||
    : std::is_base_of<U<Args...>, T<Args...>> {};
 | 
					    absl::void_t<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                 typename C::key_compare, typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_base_of<C,
 | 
				
			||||||
 | 
					                      T<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                        typename C::key_compare, typename C::allocator_type>> {
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template <typename C, template <typename, typename, typename, typename> class T>
 | 
				
			||||||
 | 
					struct IsBaseOfSpecializationImpl<
 | 
				
			||||||
 | 
					    C, T,
 | 
				
			||||||
 | 
					    absl::void_t<typename C::key_type, typename C::hasher,
 | 
				
			||||||
 | 
					                 typename C::key_equal, typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_base_of<C, T<typename C::key_type, typename C::hasher,
 | 
				
			||||||
 | 
					                           typename C::key_equal, typename C::allocator_type>> {
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template <typename C,
 | 
				
			||||||
 | 
					          template <typename, typename, typename, typename, typename> class T>
 | 
				
			||||||
 | 
					struct IsBaseOfSpecializationImpl<
 | 
				
			||||||
 | 
					    C, T,
 | 
				
			||||||
 | 
					    absl::void_t<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                 typename C::hasher, typename C::key_equal,
 | 
				
			||||||
 | 
					                 typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_base_of<C, T<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                           typename C::hasher, typename C::key_equal,
 | 
				
			||||||
 | 
					                           typename C::allocator_type>> {};
 | 
				
			||||||
template <typename C, template <typename...> class T>
 | 
					template <typename C, template <typename...> class T>
 | 
				
			||||||
using IsBaseOfSpecialization = IsBaseOfSpecializationImpl<absl::decay_t<C>, T>;
 | 
					using IsBaseOfSpecialization = IsBaseOfSpecializationImpl<absl::decay_t<C>, T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,31 +157,47 @@ struct IsBaseOfSTLContainer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename C, template <typename...> class T, typename = void>
 | 
					template <typename C, template <typename...> class T, typename = void>
 | 
				
			||||||
struct IsConvertibleToSpecializationImpl : std::false_type {};
 | 
					struct IsConvertibleToSpecializationImpl : std::false_type {};
 | 
				
			||||||
// IsConvertibleToSpecializationImpl must have three partial specializations,
 | 
					// IsConvertibleToSpecializationImpl needs multiple partial specializations to
 | 
				
			||||||
// because we must only compare templates that take the same number of
 | 
					// SFINAE on the existence of container dependent types and plug them into the
 | 
				
			||||||
// arguments. Otherwise, for example, std::vector can be compared with std::map,
 | 
					// STL template.
 | 
				
			||||||
// and fail to compile because of too few or too many template arguments.
 | 
					template <typename C, template <typename, typename> class T>
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// We must also SFINAE on the existence of an allocator_type. Otherwise, we may
 | 
					 | 
				
			||||||
// try to compare, for example, a std::pair<std::string, std::string> with a
 | 
					 | 
				
			||||||
// std::vector<std::string, std:std::string>. This would fail to compile, because
 | 
					 | 
				
			||||||
// of expected properties of the type passed in as the allocator.
 | 
					 | 
				
			||||||
template <template <typename, typename> class U,
 | 
					 | 
				
			||||||
          template <typename, typename> class T, typename... Args>
 | 
					 | 
				
			||||||
struct IsConvertibleToSpecializationImpl<
 | 
					struct IsConvertibleToSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T, absl::void_t<typename C::value_type, typename C::allocator_type>>
 | 
				
			||||||
    : std::is_convertible<U<Args...>, T<Args...>> {};
 | 
					    : std::is_convertible<
 | 
				
			||||||
template <template <typename, typename, typename> class U,
 | 
					          C, T<typename C::value_type, typename C::allocator_type>> {};
 | 
				
			||||||
          template <typename, typename, typename> class T, typename... Args>
 | 
					template <typename C, template <typename, typename, typename> class T>
 | 
				
			||||||
struct IsConvertibleToSpecializationImpl<
 | 
					struct IsConvertibleToSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T,
 | 
				
			||||||
    : std::is_convertible<U<Args...>, T<Args...>> {};
 | 
					    absl::void_t<typename C::key_type, typename C::key_compare,
 | 
				
			||||||
template <template <typename, typename, typename, typename> class U,
 | 
					                 typename C::allocator_type>>
 | 
				
			||||||
          template <typename, typename, typename, typename> class T,
 | 
					    : std::is_convertible<C, T<typename C::key_type, typename C::key_compare,
 | 
				
			||||||
          typename... Args>
 | 
					                               typename C::allocator_type>> {};
 | 
				
			||||||
 | 
					template <typename C, template <typename, typename, typename, typename> class T>
 | 
				
			||||||
struct IsConvertibleToSpecializationImpl<
 | 
					struct IsConvertibleToSpecializationImpl<
 | 
				
			||||||
    U<Args...>, T, absl::void_t<typename U<Args...>::allocator_type>>
 | 
					    C, T,
 | 
				
			||||||
    : std::is_convertible<U<Args...>, T<Args...>> {};
 | 
					    absl::void_t<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                 typename C::key_compare, typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_convertible<
 | 
				
			||||||
 | 
					          C, T<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					               typename C::key_compare, typename C::allocator_type>> {};
 | 
				
			||||||
 | 
					template <typename C, template <typename, typename, typename, typename> class T>
 | 
				
			||||||
 | 
					struct IsConvertibleToSpecializationImpl<
 | 
				
			||||||
 | 
					    C, T,
 | 
				
			||||||
 | 
					    absl::void_t<typename C::key_type, typename C::hasher,
 | 
				
			||||||
 | 
					                 typename C::key_equal, typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_convertible<
 | 
				
			||||||
 | 
					          C, T<typename C::key_type, typename C::hasher, typename C::key_equal,
 | 
				
			||||||
 | 
					               typename C::allocator_type>> {};
 | 
				
			||||||
 | 
					template <typename C,
 | 
				
			||||||
 | 
					          template <typename, typename, typename, typename, typename> class T>
 | 
				
			||||||
 | 
					struct IsConvertibleToSpecializationImpl<
 | 
				
			||||||
 | 
					    C, T,
 | 
				
			||||||
 | 
					    absl::void_t<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                 typename C::hasher, typename C::key_equal,
 | 
				
			||||||
 | 
					                 typename C::allocator_type>>
 | 
				
			||||||
 | 
					    : std::is_convertible<C, T<typename C::key_type, typename C::mapped_type,
 | 
				
			||||||
 | 
					                               typename C::hasher, typename C::key_equal,
 | 
				
			||||||
 | 
					                               typename C::allocator_type>> {};
 | 
				
			||||||
template <typename C, template <typename...> class T>
 | 
					template <typename C, template <typename...> class T>
 | 
				
			||||||
using IsConvertibleToSpecialization =
 | 
					using IsConvertibleToSpecialization =
 | 
				
			||||||
    IsConvertibleToSpecializationImpl<absl::decay_t<C>, T>;
 | 
					    IsConvertibleToSpecializationImpl<absl::decay_t<C>, T>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -419,7 +419,7 @@ class string_view {
 | 
				
			||||||
  size_type rfind(string_view s, size_type pos = npos) const
 | 
					  size_type rfind(string_view s, size_type pos = npos) const
 | 
				
			||||||
      noexcept;
 | 
					      noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Overload of `string_view::rfind()` for finding the given character `c`
 | 
					  // Overload of `string_view::rfind()` for finding the last given character `c`
 | 
				
			||||||
  // within the `string_view`.
 | 
					  // within the `string_view`.
 | 
				
			||||||
  size_type rfind(char c, size_type pos = npos) const noexcept;
 | 
					  size_type rfind(char c, size_type pos = npos) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -796,11 +796,25 @@ TEST(StringViewTest, FrontBackSingleChar) {
 | 
				
			||||||
  EXPECT_EQ(&c, &csp.back());
 | 
					  EXPECT_EQ(&c, &csp.back());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// `std::string_view::string_view(const char*)` calls
 | 
				
			||||||
 | 
					// `std::char_traits<char>::length(const char*)` to get the std::string length. In
 | 
				
			||||||
 | 
					// libc++, it doesn't allow `nullptr` in the constexpr context, with the error
 | 
				
			||||||
 | 
					// "read of dereferenced null pointer is not allowed in a constant expression".
 | 
				
			||||||
 | 
					// At run time, the behavior of `std::char_traits::length()` on `nullptr` is
 | 
				
			||||||
 | 
					// undefined by the standard and usually results in crash with libc++. This
 | 
				
			||||||
 | 
					// conforms to the standard, but `absl::string_view` implements a different
 | 
				
			||||||
 | 
					// behavior for historical reasons. We work around tests that construct
 | 
				
			||||||
 | 
					// `string_view` from `nullptr` when using libc++.
 | 
				
			||||||
 | 
					#if !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION)
 | 
				
			||||||
 | 
					#define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1
 | 
				
			||||||
 | 
					#endif  // !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(StringViewTest, NULLInput) {
 | 
					TEST(StringViewTest, NULLInput) {
 | 
				
			||||||
  absl::string_view s;
 | 
					  absl::string_view s;
 | 
				
			||||||
  EXPECT_EQ(s.data(), nullptr);
 | 
					  EXPECT_EQ(s.data(), nullptr);
 | 
				
			||||||
  EXPECT_EQ(s.size(), 0);
 | 
					  EXPECT_EQ(s.size(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR
 | 
				
			||||||
  s = absl::string_view(nullptr);
 | 
					  s = absl::string_view(nullptr);
 | 
				
			||||||
  EXPECT_EQ(s.data(), nullptr);
 | 
					  EXPECT_EQ(s.data(), nullptr);
 | 
				
			||||||
  EXPECT_EQ(s.size(), 0);
 | 
					  EXPECT_EQ(s.size(), 0);
 | 
				
			||||||
| 
						 | 
					@ -808,6 +822,7 @@ TEST(StringViewTest, NULLInput) {
 | 
				
			||||||
  // .ToString() on a absl::string_view with nullptr should produce the empty
 | 
					  // .ToString() on a absl::string_view with nullptr should produce the empty
 | 
				
			||||||
  // std::string.
 | 
					  // std::string.
 | 
				
			||||||
  EXPECT_EQ("", std::string(s));
 | 
					  EXPECT_EQ("", std::string(s));
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(StringViewTest, Comparisons2) {
 | 
					TEST(StringViewTest, Comparisons2) {
 | 
				
			||||||
| 
						 | 
					@ -879,7 +894,9 @@ TEST(StringViewTest, NullSafeStringView) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(StringViewTest, ConstexprCompiles) {
 | 
					TEST(StringViewTest, ConstexprCompiles) {
 | 
				
			||||||
  constexpr absl::string_view sp;
 | 
					  constexpr absl::string_view sp;
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR
 | 
				
			||||||
  constexpr absl::string_view cstr(nullptr);
 | 
					  constexpr absl::string_view cstr(nullptr);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  constexpr absl::string_view cstr_len("cstr", 4);
 | 
					  constexpr absl::string_view cstr_len("cstr", 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(ABSL_HAVE_STD_STRING_VIEW)
 | 
					#if defined(ABSL_HAVE_STD_STRING_VIEW)
 | 
				
			||||||
| 
						 | 
					@ -923,10 +940,12 @@ TEST(StringViewTest, ConstexprCompiles) {
 | 
				
			||||||
  constexpr absl::string_view::iterator const_end_empty = sp.end();
 | 
					  constexpr absl::string_view::iterator const_end_empty = sp.end();
 | 
				
			||||||
  EXPECT_EQ(const_begin_empty, const_end_empty);
 | 
					  EXPECT_EQ(const_begin_empty, const_end_empty);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR
 | 
				
			||||||
  constexpr absl::string_view::iterator const_begin_nullptr = cstr.begin();
 | 
					  constexpr absl::string_view::iterator const_begin_nullptr = cstr.begin();
 | 
				
			||||||
  constexpr absl::string_view::iterator const_end_nullptr = cstr.end();
 | 
					  constexpr absl::string_view::iterator const_end_nullptr = cstr.end();
 | 
				
			||||||
  EXPECT_EQ(const_begin_nullptr, const_end_nullptr);
 | 
					  EXPECT_EQ(const_begin_nullptr, const_end_nullptr);
 | 
				
			||||||
#endif
 | 
					#endif  // ABSL_HAVE_STRING_VIEW_FROM_NULLPTR
 | 
				
			||||||
 | 
					#endif  // !defined(__clang__) || ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constexpr absl::string_view::iterator const_begin = cstr_len.begin();
 | 
					  constexpr absl::string_view::iterator const_begin = cstr_len.begin();
 | 
				
			||||||
  constexpr absl::string_view::iterator const_end = cstr_len.end();
 | 
					  constexpr absl::string_view::iterator const_end = cstr_len.end();
 | 
				
			||||||
| 
						 | 
					@ -1042,11 +1061,11 @@ TEST(HugeStringView, TwoPointTwoGB) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif  // THREAD_SANITIZER
 | 
					#endif  // THREAD_SANITIZER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef NDEBUG
 | 
					#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
 | 
				
			||||||
TEST(NonNegativeLenTest, NonNegativeLen) {
 | 
					TEST(NonNegativeLenTest, NonNegativeLen) {
 | 
				
			||||||
  EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize");
 | 
					  EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif  // NDEBUG
 | 
					#endif  // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StringViewStreamTest : public ::testing::Test {
 | 
					class StringViewStreamTest : public ::testing::Test {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,4 +178,24 @@ TEST(String, StripLeadingAsciiWhitespace) {
 | 
				
			||||||
  EXPECT_EQ(absl::string_view(), absl::StripLeadingAsciiWhitespace(orig));
 | 
					  EXPECT_EQ(absl::string_view(), absl::StripLeadingAsciiWhitespace(orig));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Strip, StripAsciiWhitespace) {
 | 
				
			||||||
 | 
					  std::string test2 = "\t  \f\r\n\vfoo \t\f\r\v\n";
 | 
				
			||||||
 | 
					  absl::StripAsciiWhitespace(&test2);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test2, "foo");
 | 
				
			||||||
 | 
					  std::string test3 = "bar";
 | 
				
			||||||
 | 
					  absl::StripAsciiWhitespace(&test3);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test3, "bar");
 | 
				
			||||||
 | 
					  std::string test4 = "\t  \f\r\n\vfoo";
 | 
				
			||||||
 | 
					  absl::StripAsciiWhitespace(&test4);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test4, "foo");
 | 
				
			||||||
 | 
					  std::string test5 = "foo \t\f\r\v\n";
 | 
				
			||||||
 | 
					  absl::StripAsciiWhitespace(&test5);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test5, "foo");
 | 
				
			||||||
 | 
					  absl::string_view test6("\t  \f\r\n\vfoo \t\f\r\v\n");
 | 
				
			||||||
 | 
					  test6 = absl::StripAsciiWhitespace(test6);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test6, "foo");
 | 
				
			||||||
 | 
					  test6 = absl::StripAsciiWhitespace(test6);
 | 
				
			||||||
 | 
					  EXPECT_EQ(test6, "foo");  // already stripped
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ licenses(["notice"])  # Apache 2.0
 | 
				
			||||||
cc_library(
 | 
					cc_library(
 | 
				
			||||||
    name = "any",
 | 
					    name = "any",
 | 
				
			||||||
    hdrs = ["any.h"],
 | 
					    hdrs = ["any.h"],
 | 
				
			||||||
    copts = ABSL_DEFAULT_COPTS,
 | 
					    copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
				
			||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        ":bad_any_cast",
 | 
					        ":bad_any_cast",
 | 
				
			||||||
        "//absl/base:config",
 | 
					        "//absl/base:config",
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,17 @@ cc_test(
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cc_test(
 | 
				
			||||||
 | 
					    name = "any_exception_safety_test",
 | 
				
			||||||
 | 
					    srcs = ["any_exception_safety_test.cc"],
 | 
				
			||||||
 | 
					    copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        ":any",
 | 
				
			||||||
 | 
					        "//absl/base:exception_safety_testing",
 | 
				
			||||||
 | 
					        "@com_google_googletest//:gtest_main",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_library(
 | 
					cc_library(
 | 
				
			||||||
    name = "span",
 | 
					    name = "span",
 | 
				
			||||||
    hdrs = ["span.h"],
 | 
					    hdrs = ["span.h"],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,8 @@ absl_header_library(
 | 
				
			||||||
    absl_any
 | 
					    absl_any
 | 
				
			||||||
  PUBLIC_LIBRARIES
 | 
					  PUBLIC_LIBRARIES
 | 
				
			||||||
    absl::utility
 | 
					    absl::utility
 | 
				
			||||||
 | 
					  PRIVATE_COMPILE_FLAGS
 | 
				
			||||||
 | 
					    ${ABSL_EXCEPTIONS_FLAG}
 | 
				
			||||||
  EXPORT_NAME
 | 
					  EXPORT_NAME
 | 
				
			||||||
    any
 | 
					    any
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -126,6 +128,21 @@ absl_test(
 | 
				
			||||||
    ${ANY_TEST_PUBLIC_LIBRARIES}
 | 
					    ${ANY_TEST_PUBLIC_LIBRARIES}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# test any_exception_safety_test
 | 
				
			||||||
 | 
					set(ANY_EXCEPTION_SAFETY_TEST_SRC "any_exception_safety_test.cc")
 | 
				
			||||||
 | 
					set(ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES absl::any absl::base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					absl_test(
 | 
				
			||||||
 | 
					  TARGET
 | 
				
			||||||
 | 
					    any_exception_safety_test
 | 
				
			||||||
 | 
					  SOURCES
 | 
				
			||||||
 | 
					    ${ANY_EXCEPTION_SAFETY_TEST_SRC}
 | 
				
			||||||
 | 
					  PUBLIC_LIBRARIES
 | 
				
			||||||
 | 
					    ${ANY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES}
 | 
				
			||||||
 | 
					  PRIVATE_COMPILE_FLAGS
 | 
				
			||||||
 | 
					    ${ABSL_EXCEPTIONS_FLAG}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# test span_test
 | 
					# test span_test
 | 
				
			||||||
set(SPAN_TEST_SRC "span_test.cc")
 | 
					set(SPAN_TEST_SRC "span_test.cc")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										201
									
								
								absl/types/any_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								absl/types/any_exception_safety_test.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,201 @@
 | 
				
			||||||
 | 
					// 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 "absl/types/any.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <typeinfo>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gtest/gtest.h"
 | 
				
			||||||
 | 
					#include "absl/base/internal/exception_safety_testing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Thrower = absl::ThrowingValue<>;
 | 
				
			||||||
 | 
					using ThrowerList = std::initializer_list<Thrower>;
 | 
				
			||||||
 | 
					using ThrowerVec = std::vector<Thrower>;
 | 
				
			||||||
 | 
					using ThrowingAlloc = absl::ThrowingAllocator<Thrower>;
 | 
				
			||||||
 | 
					using ThrowingThrowerVec = std::vector<Thrower, ThrowingAlloc>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace absl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					testing::AssertionResult AbslCheckInvariants(absl::any* a,
 | 
				
			||||||
 | 
					                                             InternalAbslNamespaceFinder) {
 | 
				
			||||||
 | 
					  using testing::AssertionFailure;
 | 
				
			||||||
 | 
					  using testing::AssertionSuccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (a->has_value()) {
 | 
				
			||||||
 | 
					    if (a->type() == typeid(void)) {
 | 
				
			||||||
 | 
					      return AssertionFailure()
 | 
				
			||||||
 | 
					             << "A non-empty any should not have type `void`";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if (a->type() != typeid(void)) {
 | 
				
			||||||
 | 
					      return AssertionFailure()
 | 
				
			||||||
 | 
					             << "An empty any should have type void, but has type "
 | 
				
			||||||
 | 
					             << a->type().name();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  Make sure that reset() changes any to a valid state.
 | 
				
			||||||
 | 
					  a->reset();
 | 
				
			||||||
 | 
					  if (a->has_value()) {
 | 
				
			||||||
 | 
					    return AssertionFailure() << "A reset `any` should be valueless";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (a->type() != typeid(void)) {
 | 
				
			||||||
 | 
					    return AssertionFailure() << "A reset `any` should have type() of `void`, "
 | 
				
			||||||
 | 
					                                 "but instead has type "
 | 
				
			||||||
 | 
					                              << a->type().name();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    auto unused = absl::any_cast<Thrower>(*a);
 | 
				
			||||||
 | 
					    static_cast<void>(unused);
 | 
				
			||||||
 | 
					    return AssertionFailure()
 | 
				
			||||||
 | 
					           << "A reset `any` should not be able to be any_cast";
 | 
				
			||||||
 | 
					  } catch (absl::bad_any_cast) {
 | 
				
			||||||
 | 
					  } catch (...) {
 | 
				
			||||||
 | 
					    return AssertionFailure()
 | 
				
			||||||
 | 
					           << "Unexpected exception thrown from absl::any_cast";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return AssertionSuccess();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace absl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AnyExceptionSafety : public ::testing::Test {
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  absl::AllocInspector inspector_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					testing::AssertionResult AnyIsEmpty(absl::any* a) {
 | 
				
			||||||
 | 
					  if (!a->has_value()) return testing::AssertionSuccess();
 | 
				
			||||||
 | 
					  return testing::AssertionFailure()
 | 
				
			||||||
 | 
					         << "a should be empty, but instead has value "
 | 
				
			||||||
 | 
					         << absl::any_cast<Thrower>(*a).Get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_F(AnyExceptionSafety, Ctors) {
 | 
				
			||||||
 | 
					  Thrower val(1);
 | 
				
			||||||
 | 
					  auto with_val = absl::TestThrowingCtor<absl::any>(val);
 | 
				
			||||||
 | 
					  auto copy = absl::TestThrowingCtor<absl::any>(with_val);
 | 
				
			||||||
 | 
					  auto in_place =
 | 
				
			||||||
 | 
					      absl::TestThrowingCtor<absl::any>(absl::in_place_type_t<Thrower>(), 1);
 | 
				
			||||||
 | 
					  auto in_place_list = absl::TestThrowingCtor<absl::any>(
 | 
				
			||||||
 | 
					      absl::in_place_type_t<ThrowerVec>(), ThrowerList{val});
 | 
				
			||||||
 | 
					  auto in_place_list_again =
 | 
				
			||||||
 | 
					      absl::TestThrowingCtor<absl::any,
 | 
				
			||||||
 | 
					                             absl::in_place_type_t<ThrowingThrowerVec>,
 | 
				
			||||||
 | 
					                             ThrowerList, ThrowingAlloc>(
 | 
				
			||||||
 | 
					          absl::in_place_type_t<ThrowingThrowerVec>(), {val}, ThrowingAlloc());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct OneFactory {
 | 
				
			||||||
 | 
					  std::unique_ptr<absl::any> operator()() const {
 | 
				
			||||||
 | 
					    return absl::make_unique<absl::any>(absl::in_place_type_t<Thrower>(), 1,
 | 
				
			||||||
 | 
					                                        absl::no_throw_ctor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct EmptyFactory {
 | 
				
			||||||
 | 
					  std::unique_ptr<absl::any> operator()() const {
 | 
				
			||||||
 | 
					    return absl::make_unique<absl::any>();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_F(AnyExceptionSafety, Assignment) {
 | 
				
			||||||
 | 
					  auto thrower_comp = [](const absl::any& l, const absl::any& r) {
 | 
				
			||||||
 | 
					    return absl::any_cast<Thrower>(l) == absl::any_cast<Thrower>(r);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  OneFactory one_factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  absl::ThrowingValue<absl::NoThrow::kMoveCtor | absl::NoThrow::kMoveAssign>
 | 
				
			||||||
 | 
					      moveable_val(2);
 | 
				
			||||||
 | 
					  Thrower val(2);
 | 
				
			||||||
 | 
					  absl::any any_val(val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory, [&any_val](absl::any* ap) { *ap = any_val; },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(one_factory, thrower_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory, [&val](absl::any* ap) { *ap = val; },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(one_factory, thrower_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory, [&val](absl::any* ap) { *ap = std::move(val); },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(one_factory, thrower_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory,
 | 
				
			||||||
 | 
					      [&moveable_val](absl::any* ap) { *ap = std::move(moveable_val); },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(one_factory, thrower_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EmptyFactory empty_factory;
 | 
				
			||||||
 | 
					  auto empty_comp = [](const absl::any& l, const absl::any& r) {
 | 
				
			||||||
 | 
					    return !(l.has_value() || r.has_value());
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      empty_factory, [&any_val](absl::any* ap) { *ap = any_val; },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(empty_factory, empty_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      empty_factory, [&val](absl::any* ap) { *ap = val; },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(empty_factory, empty_comp)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      empty_factory, [&val](absl::any* ap) { *ap = std::move(val); },
 | 
				
			||||||
 | 
					      absl::StrongGuarantee(empty_factory, empty_comp)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// libstdc++ std::any fails this test
 | 
				
			||||||
 | 
					#if !defined(ABSL_HAVE_STD_ANY)
 | 
				
			||||||
 | 
					TEST_F(AnyExceptionSafety, Emplace) {
 | 
				
			||||||
 | 
					  OneFactory one_factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory, [](absl::any* ap) { ap->emplace<Thrower>(2); }, AnyIsEmpty));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      one_factory,
 | 
				
			||||||
 | 
					      [](absl::any* ap) {
 | 
				
			||||||
 | 
					        ap->emplace<absl::ThrowingValue<absl::NoThrow::kMoveCtor |
 | 
				
			||||||
 | 
					                                        absl::NoThrow::kMoveAssign>>(2);
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      AnyIsEmpty));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(one_factory,
 | 
				
			||||||
 | 
					                                        [](absl::any* ap) {
 | 
				
			||||||
 | 
					                                          std::initializer_list<Thrower> il{
 | 
				
			||||||
 | 
					                                              Thrower(2, absl::no_throw_ctor)};
 | 
				
			||||||
 | 
					                                          ap->emplace<ThrowerVec>(il);
 | 
				
			||||||
 | 
					                                        },
 | 
				
			||||||
 | 
					                                        AnyIsEmpty));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EmptyFactory empty_factory;
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(
 | 
				
			||||||
 | 
					      empty_factory, [](absl::any* ap) { ap->emplace<Thrower>(2); },
 | 
				
			||||||
 | 
					      AnyIsEmpty));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::TestExceptionSafety(empty_factory,
 | 
				
			||||||
 | 
					                                        [](absl::any* ap) {
 | 
				
			||||||
 | 
					                                          std::initializer_list<Thrower> il{
 | 
				
			||||||
 | 
					                                              Thrower(2, absl::no_throw_ctor)};
 | 
				
			||||||
 | 
					                                          ap->emplace<ThrowerVec>(il);
 | 
				
			||||||
 | 
					                                        },
 | 
				
			||||||
 | 
					                                        AnyIsEmpty));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif  // ABSL_HAVE_STD_ANY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue