diff options
-rw-r--r-- | absl/container/fixed_array_exception_safety_test.cc | 87 | ||||
-rw-r--r-- | absl/container/inlined_vector_exception_safety_test.cc | 26 | ||||
-rw-r--r-- | absl/container/internal/inlined_vector.h | 8 | ||||
-rw-r--r-- | absl/strings/internal/str_format/bind.cc | 9 | ||||
-rw-r--r-- | absl/strings/internal/str_format/bind.h | 8 |
5 files changed, 115 insertions, 23 deletions
diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc index 9aabfd5c..5ebeac05 100644 --- a/absl/container/fixed_array_exception_safety_test.cc +++ b/absl/container/fixed_array_exception_safety_test.cc @@ -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 diff --git a/absl/container/inlined_vector_exception_safety_test.cc b/absl/container/inlined_vector_exception_safety_test.cc index 937e43a5..0e6a05b5 100644 --- a/absl/container/inlined_vector_exception_safety_test.cc +++ b/absl/container/inlined_vector_exception_safety_test.cc @@ -364,9 +364,11 @@ TYPED_TEST(OneSizeTest, EmplaceBack) { using VecT = typename TypeParam::VecT; constexpr static auto size = TypeParam::GetSizeAt(0); + // For testing calls to `emplace_back(...)` that reallocate. VecT full_vec{size}; full_vec.resize(full_vec.capacity()); + // For testing calls to `emplace_back(...)` that don't reallocate. VecT nonfull_vec{size}; nonfull_vec.reserve(size + 1); @@ -374,12 +376,11 @@ TYPED_TEST(OneSizeTest, EmplaceBack) { InlinedVectorInvariants<VecT>); EXPECT_TRUE(tester.WithInitialValue(nonfull_vec).Test([](VecT* vec) { - vec->emplace_back(); // + vec->emplace_back(); })); - EXPECT_TRUE(tester.WithInitialValue(full_vec).Test([](VecT* vec) { - vec->emplace_back(); // - })); + EXPECT_TRUE(tester.WithInitialValue(full_vec).Test( + [](VecT* vec) { vec->emplace_back(); })); } TYPED_TEST(OneSizeTest, PopBack) { @@ -418,6 +419,19 @@ TYPED_TEST(OneSizeTest, Erase) { EXPECT_TRUE(tester.Test([](VecT* vec) { auto it = vec->begin(); + vec->erase(it, it); + })); + EXPECT_TRUE(tester.Test([](VecT* vec) { + auto it = vec->begin() + (vec->size() / 2); + vec->erase(it, it); + })); + EXPECT_TRUE(tester.Test([](VecT* vec) { + auto it = vec->begin() + (vec->size() - 1); + vec->erase(it, it); + })); + + EXPECT_TRUE(tester.Test([](VecT* vec) { + auto it = vec->begin(); vec->erase(it, it + 1); })); EXPECT_TRUE(tester.Test([](VecT* vec) { @@ -452,9 +466,7 @@ TYPED_TEST(TwoSizeTest, Reserve) { .WithInitialValue(VecT{from_size}) .WithContracts(InlinedVectorInvariants<VecT>); - EXPECT_TRUE(tester.Test([](VecT* vec) { - vec->reserve(to_capacity); // - })); + EXPECT_TRUE(tester.Test([](VecT* vec) { vec->reserve(to_capacity); })); } TYPED_TEST(OneSizeTest, ShrinkToFit) { diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 54369c85..7d08f7e3 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -539,12 +539,12 @@ template <typename ValueAdapter> auto Storage<T, N, A>::Resize(ValueAdapter values, size_type new_size) -> void { StorageView storage_view = MakeStorageView(); - AllocationTransaction allocation_tx(GetAllocPtr()); - ConstructionTransaction construction_tx(GetAllocPtr()); - IteratorValueAdapter<MoveIterator> move_values( MoveIterator(storage_view.data)); + AllocationTransaction allocation_tx(GetAllocPtr()); + ConstructionTransaction construction_tx(GetAllocPtr()); + absl::Span<value_type> construct_loop; absl::Span<value_type> move_construct_loop; absl::Span<value_type> destroy_loop; @@ -727,8 +727,6 @@ auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> reference { template <typename T, size_t N, typename A> auto Storage<T, N, A>::Erase(const_iterator from, const_iterator to) -> iterator { - assert(from != to); - StorageView storage_view = MakeStorageView(); size_type erase_size = std::distance(from, to); diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index a31859ec..45e335a3 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -196,6 +196,15 @@ std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format, return *out; } +std::string FormatPack(const UntypedFormatSpecImpl format, + absl::Span<const FormatArgImpl> args) { + std::string out; + if (ABSL_PREDICT_FALSE(!FormatUntyped(&out, format, args))) { + out.clear(); + } + return out; +} + int FprintF(std::FILE* output, const UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args) { FILERawSink sink(output); diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 7df140a4..7f460351 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -178,12 +178,8 @@ bool FormatUntyped(FormatRawSinkImpl raw_sink, std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); -inline std::string FormatPack(const UntypedFormatSpecImpl format, - absl::Span<const FormatArgImpl> args) { - std::string out; - AppendPack(&out, format, args); - return out; -} +std::string FormatPack(const UntypedFormatSpecImpl format, + absl::Span<const FormatArgImpl> args); int FprintF(std::FILE* output, UntypedFormatSpecImpl format, absl::Span<const FormatArgImpl> args); |