Export of internal Abseil changes
-- 3f913305d6582ac0c66c25f71275d89232dc97bf by CJ Johnson <johnsoncj@google.com>: Internal change PiperOrigin-RevId: 276081163 -- 19c65f15e8b67e4677ebed9f815f934091368f41 by CJ Johnson <johnsoncj@google.com>: Internal change PiperOrigin-RevId: 275964906 -- a40557fe4575a6bc9bed4fd83ed8c748bc3f15ff by Derek Mauro <dmauro@google.com>: Always enable symbolization on Windows. This doesn't require debug builds, only PDB files. https://github.com/abseil/abseil-cpp/pull/257 PiperOrigin-RevId: 275961084 -- 953bec0e67d2495e901b940b67b6330291871998 by CJ Johnson <johnsoncj@google.com>: Test FixedArray exception safety for OOM using ThrowingAllocator PiperOrigin-RevId: 275921366 -- 13211ea447af1daf1701ccb1c7c6b2cbaa68eb93 by CJ Johnson <johnsoncj@google.com>: Internal change PiperOrigin-RevId: 275913105 -- 09dccef0c829cfab5847137ead6866c511e9ce51 by CJ Johnson <johnsoncj@google.com>: Internal change PiperOrigin-RevId: 275912911 -- 65db8fc06f50e0989aee2d264f8f7a348ff95c17 by Samuel Benzaquen <sbenza@google.com>: Move FormatPack to bind.cc. We do not get any benefit from inlining this function, but it creates unnecessary bloat at the call site. Moving it to the .cc file moves the initialization of the string out of the caller code. PiperOrigin-RevId: 275889073 GitOrigin-RevId: 3f913305d6582ac0c66c25f71275d89232dc97bf Change-Id: Ia471eebba7322a6ea4edc954e50b30a060a45e39
This commit is contained in:
parent
ecc0033b54
commit
19b021cb3f
5 changed files with 116 additions and 24 deletions
|
@ -12,9 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "absl/container/fixed_array.h"
|
|
||||||
|
|
||||||
#include "absl/base/config.h"
|
#include "absl/base/config.h"
|
||||||
|
#include "absl/container/fixed_array.h"
|
||||||
|
|
||||||
#ifdef ABSL_HAVE_EXCEPTIONS
|
#ifdef ABSL_HAVE_EXCEPTIONS
|
||||||
|
|
||||||
|
@ -37,10 +36,19 @@ constexpr int kUpdatedValue = 10;
|
||||||
using ::testing::TestThrowingCtor;
|
using ::testing::TestThrowingCtor;
|
||||||
|
|
||||||
using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
|
using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
|
||||||
using FixedArr = absl::FixedArray<Thrower, kInlined>;
|
using ThrowAlloc =
|
||||||
|
testing::ThrowingAllocator<Thrower, testing::AllocSpec::kEverythingThrows>;
|
||||||
using MoveThrower = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
|
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 MoveFixedArr = absl::FixedArray<MoveThrower, kInlined>;
|
||||||
|
using MoveFixedArrWithAlloc =
|
||||||
|
absl::FixedArray<MoveThrower, kInlined, MoveThrowAlloc>;
|
||||||
|
|
||||||
TEST(FixedArrayExceptionSafety, CopyConstructor) {
|
TEST(FixedArrayExceptionSafety, CopyConstructor) {
|
||||||
auto small = FixedArr(kSmallSize);
|
auto small = FixedArr(kSmallSize);
|
||||||
|
@ -50,6 +58,14 @@ TEST(FixedArrayExceptionSafety, CopyConstructor) {
|
||||||
TestThrowingCtor<FixedArr>(large);
|
TestThrowingCtor<FixedArr>(large);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FixedArrayExceptionSafety, CopyConstructorWithAlloc) {
|
||||||
|
auto small = FixedArrWithAlloc(kSmallSize);
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(small);
|
||||||
|
|
||||||
|
auto large = FixedArrWithAlloc(kLargeSize);
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(large);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FixedArrayExceptionSafety, MoveConstructor) {
|
TEST(FixedArrayExceptionSafety, MoveConstructor) {
|
||||||
TestThrowingCtor<FixedArr>(FixedArr(kSmallSize));
|
TestThrowingCtor<FixedArr>(FixedArr(kSmallSize));
|
||||||
TestThrowingCtor<FixedArr>(FixedArr(kLargeSize));
|
TestThrowingCtor<FixedArr>(FixedArr(kLargeSize));
|
||||||
|
@ -59,16 +75,35 @@ TEST(FixedArrayExceptionSafety, MoveConstructor) {
|
||||||
TestThrowingCtor<MoveFixedArr>(MoveFixedArr(kLargeSize));
|
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) {
|
TEST(FixedArrayExceptionSafety, SizeConstructor) {
|
||||||
TestThrowingCtor<FixedArr>(kSmallSize);
|
TestThrowingCtor<FixedArr>(kSmallSize);
|
||||||
TestThrowingCtor<FixedArr>(kLargeSize);
|
TestThrowingCtor<FixedArr>(kLargeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FixedArrayExceptionSafety, SizeConstructorWithAlloc) {
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(kSmallSize);
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(kLargeSize);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FixedArrayExceptionSafety, SizeValueConstructor) {
|
TEST(FixedArrayExceptionSafety, SizeValueConstructor) {
|
||||||
TestThrowingCtor<FixedArr>(kSmallSize, Thrower());
|
TestThrowingCtor<FixedArr>(kSmallSize, Thrower());
|
||||||
TestThrowingCtor<FixedArr>(kLargeSize, Thrower());
|
TestThrowingCtor<FixedArr>(kLargeSize, Thrower());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FixedArrayExceptionSafety, SizeValueConstructorWithAlloc) {
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(kSmallSize, Thrower());
|
||||||
|
TestThrowingCtor<FixedArrWithAlloc>(kLargeSize, Thrower());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FixedArrayExceptionSafety, IteratorConstructor) {
|
TEST(FixedArrayExceptionSafety, IteratorConstructor) {
|
||||||
auto small = FixedArr(kSmallSize);
|
auto small = FixedArr(kSmallSize);
|
||||||
TestThrowingCtor<FixedArr>(small.begin(), small.end());
|
TestThrowingCtor<FixedArr>(small.begin(), small.end());
|
||||||
|
@ -77,6 +112,14 @@ TEST(FixedArrayExceptionSafety, IteratorConstructor) {
|
||||||
TestThrowingCtor<FixedArr>(large.begin(), large.end());
|
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) {
|
TEST(FixedArrayExceptionSafety, InitListConstructor) {
|
||||||
constexpr int small_inlined = 3;
|
constexpr int small_inlined = 3;
|
||||||
using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>;
|
using SmallFixedArr = absl::FixedArray<Thrower, small_inlined>;
|
||||||
|
@ -90,7 +133,22 @@ TEST(FixedArrayExceptionSafety, InitListConstructor) {
|
||||||
Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}});
|
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.
|
// Marked volatile to prevent optimization. Used for running asan tests.
|
||||||
volatile int sum = 0;
|
volatile int sum = 0;
|
||||||
for (const auto& thrower : *fixed_arr) {
|
for (const auto& thrower : *fixed_arr) {
|
||||||
|
@ -101,7 +159,7 @@ testing::AssertionResult ReadMemory(FixedArr* fixed_arr) {
|
||||||
|
|
||||||
TEST(FixedArrayExceptionSafety, Fill) {
|
TEST(FixedArrayExceptionSafety, Fill) {
|
||||||
auto test_fill = testing::MakeExceptionSafetyTester()
|
auto test_fill = testing::MakeExceptionSafetyTester()
|
||||||
.WithContracts(ReadMemory)
|
.WithContracts(ReadMemory<FixedArr>)
|
||||||
.WithOperation([&](FixedArr* fixed_arr_ptr) {
|
.WithOperation([&](FixedArr* fixed_arr_ptr) {
|
||||||
auto thrower =
|
auto thrower =
|
||||||
Thrower(kUpdatedValue, testing::nothrow_ctor);
|
Thrower(kUpdatedValue, testing::nothrow_ctor);
|
||||||
|
@ -116,6 +174,25 @@ TEST(FixedArrayExceptionSafety, Fill) {
|
||||||
.Test());
|
.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
|
||||||
|
|
||||||
} // namespace absl
|
} // namespace absl
|
||||||
|
|
|
@ -364,9 +364,11 @@ TYPED_TEST(OneSizeTest, EmplaceBack) {
|
||||||
using VecT = typename TypeParam::VecT;
|
using VecT = typename TypeParam::VecT;
|
||||||
constexpr static auto size = TypeParam::GetSizeAt(0);
|
constexpr static auto size = TypeParam::GetSizeAt(0);
|
||||||
|
|
||||||
|
// For testing calls to `emplace_back(...)` that reallocate.
|
||||||
VecT full_vec{size};
|
VecT full_vec{size};
|
||||||
full_vec.resize(full_vec.capacity());
|
full_vec.resize(full_vec.capacity());
|
||||||
|
|
||||||
|
// For testing calls to `emplace_back(...)` that don't reallocate.
|
||||||
VecT nonfull_vec{size};
|
VecT nonfull_vec{size};
|
||||||
nonfull_vec.reserve(size + 1);
|
nonfull_vec.reserve(size + 1);
|
||||||
|
|
||||||
|
@ -374,12 +376,11 @@ TYPED_TEST(OneSizeTest, EmplaceBack) {
|
||||||
InlinedVectorInvariants<VecT>);
|
InlinedVectorInvariants<VecT>);
|
||||||
|
|
||||||
EXPECT_TRUE(tester.WithInitialValue(nonfull_vec).Test([](VecT* vec) {
|
EXPECT_TRUE(tester.WithInitialValue(nonfull_vec).Test([](VecT* vec) {
|
||||||
vec->emplace_back(); //
|
vec->emplace_back();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
EXPECT_TRUE(tester.WithInitialValue(full_vec).Test([](VecT* vec) {
|
EXPECT_TRUE(tester.WithInitialValue(full_vec).Test(
|
||||||
vec->emplace_back(); //
|
[](VecT* vec) { vec->emplace_back(); }));
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(OneSizeTest, PopBack) {
|
TYPED_TEST(OneSizeTest, PopBack) {
|
||||||
|
@ -416,6 +417,19 @@ TYPED_TEST(OneSizeTest, Erase) {
|
||||||
vec->erase(it);
|
vec->erase(it);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
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) {
|
EXPECT_TRUE(tester.Test([](VecT* vec) {
|
||||||
auto it = vec->begin();
|
auto it = vec->begin();
|
||||||
vec->erase(it, it + 1);
|
vec->erase(it, it + 1);
|
||||||
|
@ -452,9 +466,7 @@ TYPED_TEST(TwoSizeTest, Reserve) {
|
||||||
.WithInitialValue(VecT{from_size})
|
.WithInitialValue(VecT{from_size})
|
||||||
.WithContracts(InlinedVectorInvariants<VecT>);
|
.WithContracts(InlinedVectorInvariants<VecT>);
|
||||||
|
|
||||||
EXPECT_TRUE(tester.Test([](VecT* vec) {
|
EXPECT_TRUE(tester.Test([](VecT* vec) { vec->reserve(to_capacity); }));
|
||||||
vec->reserve(to_capacity); //
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(OneSizeTest, ShrinkToFit) {
|
TYPED_TEST(OneSizeTest, ShrinkToFit) {
|
||||||
|
|
|
@ -539,12 +539,12 @@ template <typename ValueAdapter>
|
||||||
auto Storage<T, N, A>::Resize(ValueAdapter values, size_type new_size) -> void {
|
auto Storage<T, N, A>::Resize(ValueAdapter values, size_type new_size) -> void {
|
||||||
StorageView storage_view = MakeStorageView();
|
StorageView storage_view = MakeStorageView();
|
||||||
|
|
||||||
AllocationTransaction allocation_tx(GetAllocPtr());
|
|
||||||
ConstructionTransaction construction_tx(GetAllocPtr());
|
|
||||||
|
|
||||||
IteratorValueAdapter<MoveIterator> move_values(
|
IteratorValueAdapter<MoveIterator> move_values(
|
||||||
MoveIterator(storage_view.data));
|
MoveIterator(storage_view.data));
|
||||||
|
|
||||||
|
AllocationTransaction allocation_tx(GetAllocPtr());
|
||||||
|
ConstructionTransaction construction_tx(GetAllocPtr());
|
||||||
|
|
||||||
absl::Span<value_type> construct_loop;
|
absl::Span<value_type> construct_loop;
|
||||||
absl::Span<value_type> move_construct_loop;
|
absl::Span<value_type> move_construct_loop;
|
||||||
absl::Span<value_type> destroy_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>
|
template <typename T, size_t N, typename A>
|
||||||
auto Storage<T, N, A>::Erase(const_iterator from, const_iterator to)
|
auto Storage<T, N, A>::Erase(const_iterator from, const_iterator to)
|
||||||
-> iterator {
|
-> iterator {
|
||||||
assert(from != to);
|
|
||||||
|
|
||||||
StorageView storage_view = MakeStorageView();
|
StorageView storage_view = MakeStorageView();
|
||||||
|
|
||||||
size_type erase_size = std::distance(from, to);
|
size_type erase_size = std::distance(from, to);
|
||||||
|
|
|
@ -196,6 +196,15 @@ std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format,
|
||||||
return *out;
|
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,
|
int FprintF(std::FILE* output, const UntypedFormatSpecImpl format,
|
||||||
absl::Span<const FormatArgImpl> args) {
|
absl::Span<const FormatArgImpl> args) {
|
||||||
FILERawSink sink(output);
|
FILERawSink sink(output);
|
||||||
|
|
|
@ -178,12 +178,8 @@ bool FormatUntyped(FormatRawSinkImpl raw_sink,
|
||||||
std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
|
std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
|
||||||
absl::Span<const FormatArgImpl> args);
|
absl::Span<const FormatArgImpl> args);
|
||||||
|
|
||||||
inline std::string FormatPack(const UntypedFormatSpecImpl format,
|
std::string FormatPack(const UntypedFormatSpecImpl format,
|
||||||
absl::Span<const FormatArgImpl> args) {
|
absl::Span<const FormatArgImpl> args);
|
||||||
std::string out;
|
|
||||||
AppendPack(&out, format, args);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
|
int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
|
||||||
absl::Span<const FormatArgImpl> args);
|
absl::Span<const FormatArgImpl> args);
|
||||||
|
|
Loading…
Reference in a new issue