| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 | // 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_BEGINnamespace {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());}}  // namespaceABSL_NAMESPACE_END}  // namespace absl#endif  // ABSL_HAVE_EXCEPTIONS
 |