|  | @@ -12,9 +12,8 @@
 | 
	
		
			
				|  |  |  // See the License for the specific language governing permissions and
 | 
	
		
			
				|  |  |  // limitations under the License.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#include "absl/container/fixed_array.h"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  #include "absl/base/config.h"
 | 
	
		
			
				|  |  | +#include "absl/container/fixed_array.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef ABSL_HAVE_EXCEPTIONS
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -37,10 +36,19 @@ 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 MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
 | 
	
		
			
				|  |  |  using MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>;
 | 
	
		
			
				|  |  | +using MoveFixedArrWithAlloc =
 | 
	
		
			
				|  |  | +    absl::FixedArray<MoveThrower, kInlined, MoveThrowAlloc>;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  TEST(FixedArrayExceptionSafety, CopyConstructor) {
 | 
	
		
			
				|  |  |    auto small = FixedArr(kSmallSize);
 | 
	
	
		
			
				|  | @@ -50,6 +58,14 @@ TEST(FixedArrayExceptionSafety, CopyConstructor) {
 | 
	
		
			
				|  |  |    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));
 | 
	
	
		
			
				|  | @@ -59,16 +75,35 @@ TEST(FixedArrayExceptionSafety, MoveConstructor) {
 | 
	
		
			
				|  |  |    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());
 | 
	
	
		
			
				|  | @@ -77,6 +112,14 @@ TEST(FixedArrayExceptionSafety, IteratorConstructor) {
 | 
	
		
			
				|  |  |    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>;
 | 
	
	
		
			
				|  | @@ -90,7 +133,22 @@ TEST(FixedArrayExceptionSafety, InitListConstructor) {
 | 
	
		
			
				|  |  |        Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -testing::AssertionResult ReadMemory(FixedArr* fixed_arr) {
 | 
	
		
			
				|  |  | +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) {
 | 
	
	
		
			
				|  | @@ -101,7 +159,7 @@ testing::AssertionResult ReadMemory(FixedArr* fixed_arr) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  TEST(FixedArrayExceptionSafety, Fill) {
 | 
	
		
			
				|  |  |    auto test_fill = testing::MakeExceptionSafetyTester()
 | 
	
		
			
				|  |  | -                       .WithContracts(ReadMemory)
 | 
	
		
			
				|  |  | +                       .WithContracts(ReadMemory<FixedArr>)
 | 
	
		
			
				|  |  |                         .WithOperation([&](FixedArr* fixed_arr_ptr) {
 | 
	
		
			
				|  |  |                           auto thrower =
 | 
	
		
			
				|  |  |                               Thrower(kUpdatedValue, testing::nothrow_ctor);
 | 
	
	
		
			
				|  | @@ -116,6 +174,25 @@ TEST(FixedArrayExceptionSafety, Fill) {
 | 
	
		
			
				|  |  |            .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
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  }  // namespace absl
 |