about summary refs log tree commit diff
path: root/third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc')
-rw-r--r--third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc202
1 files changed, 202 insertions, 0 deletions
diff --git a/third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc b/third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc
new file mode 100644
index 0000000000..a5bb009d98
--- /dev/null
+++ b/third_party/abseil_cpp/absl/container/fixed_array_exception_safety_test.cc
@@ -0,0 +1,202 @@
+// Copyright 2019 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
+//
+//      https://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/base/config.h"
+#include "absl/container/fixed_array.h"
+
+#ifdef ABSL_HAVE_EXCEPTIONS
+
+#include <initializer_list>
+
+#include "gtest/gtest.h"
+#include "absl/base/internal/exception_safety_testing.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+namespace {
+
+constexpr size_t kInlined = 25;
+constexpr size_t kSmallSize = kInlined / 2;
+constexpr size_t kLargeSize = kInlined * 2;
+
+constexpr int kInitialValue = 5;
+constexpr int kUpdatedValue = 10;
+
+using ::testing::TestThrowingCtor;
+
+using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
+using ThrowAlloc =
+    testing::ThrowingAllocator<Thrower, testing::AllocSpec::kEverythingThrows>;
+using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
+using MoveThrowAlloc =
+    testing::ThrowingAllocator<MoveThrower,
+                               testing::AllocSpec::kEverythingThrows>;
+
+using FixedArr = absl::FixedArray<Thrower, kInlined>;
+using FixedArrWithAlloc = absl::FixedArray<Thrower, kInlined, ThrowAlloc>;
+
+using MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>;
+using MoveFixedArrWithAlloc =
+    absl::FixedArray<MoveThrower, kInlined, MoveThrowAlloc>;
+
+TEST(FixedArrayExceptionSafety, CopyConstructor) {
+  auto small = FixedArr(kSmallSize);
+  TestThrowingCtor<FixedArr>(small);
+
+  auto large = FixedArr(kLargeSize);
+  TestThrowingCtor<FixedArr>(large);
+}
+
+TEST(FixedArrayExceptionSafety, CopyConstructorWithAlloc) {
+  auto small = FixedArrWithAlloc(kSmallSize);
+  TestThrowingCtor<FixedArrWithAlloc>(small);
+
+  auto large = FixedArrWithAlloc(kLargeSize);
+  TestThrowingCtor<FixedArrWithAlloc>(large);
+}
+
+TEST(FixedArrayExceptionSafety, MoveConstructor) {
+  TestThrowingCtor<FixedArr>(FixedArr(kSmallSize));
+  TestThrowingCtor<FixedArr>(FixedArr(kLargeSize));
+
+  // TypeSpec::kNoThrowMove
+  TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kSmallSize));
+  TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kLargeSize));
+}
+
+TEST(FixedArrayExceptionSafety, MoveConstructorWithAlloc) {
+  TestThrowingCtor<FixedArrWithAlloc>(FixedArrWithAlloc(kSmallSize));
+  TestThrowingCtor<FixedArrWithAlloc>(FixedArrWithAlloc(kLargeSize));
+
+  // TypeSpec::kNoThrowMove
+  TestThrowingCtor<MoveFixedArrWithAlloc>(MoveFixedArrWithAlloc(kSmallSize));
+  TestThrowingCtor<MoveFixedArrWithAlloc>(MoveFixedArrWithAlloc(kLargeSize));
+}
+
+TEST(FixedArrayExceptionSafety, SizeConstructor) {
+  TestThrowingCtor<FixedArr>(kSmallSize);
+  TestThrowingCtor<FixedArr>(kLargeSize);
+}
+
+TEST(FixedArrayExceptionSafety, SizeConstructorWithAlloc) {
+  TestThrowingCtor<FixedArrWithAlloc>(kSmallSize);
+  TestThrowingCtor<FixedArrWithAlloc>(kLargeSize);
+}
+
+TEST(FixedArrayExceptionSafety, SizeValueConstructor) {
+  TestThrowingCtor<FixedArr>(kSmallSize, Thrower());
+  TestThrowingCtor<FixedArr>(kLargeSize, Thrower());
+}
+
+TEST(FixedArrayExceptionSafety, SizeValueConstructorWithAlloc) {
+  TestThrowingCtor<FixedArrWithAlloc>(kSmallSize, Thrower());
+  TestThrowingCtor<FixedArrWithAlloc>(kLargeSize, Thrower());
+}
+
+TEST(FixedArrayExceptionSafety, IteratorConstructor) {
+  auto small = FixedArr(kSmallSize);
+  TestThrowingCtor<FixedArr>(small.begin(), small.end());
+
+  auto large = FixedArr(kLargeSize);
+  TestThrowingCtor<FixedArr>(large.begin(), large.end());
+}
+
+TEST(FixedArrayExceptionSafety, IteratorConstructorWithAlloc) {
+  auto small = FixedArrWithAlloc(kSmallSize);
+  TestThrowingCtor<FixedArrWithAlloc>(small.begin(), small.end());
+
+  auto large = FixedArrWithAlloc(kLargeSize);
+  TestThrowingCtor<FixedArrWithAlloc>(large.begin(), large.end());
+}
+
+TEST(FixedArrayExceptionSafety, InitListConstructor) {
+  constexpr int small_inlined = 3;
+  using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>;
+
+  TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{});
+  // Test inlined allocation
+  TestThrowingCtor<SmallFixedArr>(
+      std::initializer_list<Thrower>{Thrower{}, Thrower{}});
+  // Test out of line allocation
+  TestThrowingCtor<SmallFixedArr>(std::initializer_list<Thrower>{
+      Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
+}
+
+TEST(FixedArrayExceptionSafety, InitListConstructorWithAlloc) {
+  constexpr int small_inlined = 3;
+  using SmallFixedArrWithAlloc =
+      absl::FixedArray<Thrower, small_inlined, ThrowAlloc>;
+
+  TestThrowingCtor<SmallFixedArrWithAlloc>(std::initializer_list<Thrower>{});
+  // Test inlined allocation
+  TestThrowingCtor<SmallFixedArrWithAlloc>(
+      std::initializer_list<Thrower>{Thrower{}, Thrower{}});
+  // Test out of line allocation
+  TestThrowingCtor<SmallFixedArrWithAlloc>(std::initializer_list<Thrower>{
+      Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
+}
+
+template <typename FixedArrT>
+testing::AssertionResult ReadMemory(FixedArrT* fixed_arr) {
+  // Marked volatile to prevent optimization. Used for running asan tests.
+  volatile int sum = 0;
+  for (const auto& thrower : *fixed_arr) {
+    sum += thrower.Get();
+  }
+  return testing::AssertionSuccess() << "Values sum to [" << sum << "]";
+}
+
+TEST(FixedArrayExceptionSafety, Fill) {
+  auto test_fill = testing::MakeExceptionSafetyTester()
+                       .WithContracts(ReadMemory<FixedArr>)
+                       .WithOperation([&](FixedArr* fixed_arr_ptr) {
+                         auto thrower =
+                             Thrower(kUpdatedValue, testing::nothrow_ctor);
+                         fixed_arr_ptr->fill(thrower);
+                       });
+
+  EXPECT_TRUE(
+      test_fill.WithInitialValue(FixedArr(kSmallSize, Thrower(kInitialValue)))
+          .Test());
+  EXPECT_TRUE(
+      test_fill.WithInitialValue(FixedArr(kLargeSize, Thrower(kInitialValue)))
+          .Test());
+}
+
+TEST(FixedArrayExceptionSafety, FillWithAlloc) {
+  auto test_fill = testing::MakeExceptionSafetyTester()
+                       .WithContracts(ReadMemory<FixedArrWithAlloc>)
+                       .WithOperation([&](FixedArrWithAlloc* fixed_arr_ptr) {
+                         auto thrower =
+                             Thrower(kUpdatedValue, testing::nothrow_ctor);
+                         fixed_arr_ptr->fill(thrower);
+                       });
+
+  EXPECT_TRUE(test_fill
+                  .WithInitialValue(
+                      FixedArrWithAlloc(kSmallSize, Thrower(kInitialValue)))
+                  .Test());
+  EXPECT_TRUE(test_fill
+                  .WithInitialValue(
+                      FixedArrWithAlloc(kLargeSize, Thrower(kInitialValue)))
+                  .Test());
+}
+
+}  // namespace
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_HAVE_EXCEPTIONS