- ed0ba496fe01eb8edfa86beade8a37768e7c12ef Updates the API for Exception Safety testing to use build... by Abseil Team <absl-team@google.com>
- c4b7a4e517c9404932c45f2f9f92eb7dc694e45d Internal change by Abseil Team <absl-team@google.com> - 76c78ed9385f65d881511645446e0bb8ababf6ec Add missing ABSL_PREDICT_FALSE to one of FixedArray::at()... by Abseil Team <absl-team@google.com> - 1204fb1c46f007dd9dfb7d9abf3e96c58835d193 Internal change. by Greg Falcon <gfalcon@google.com> - f1f47c98a026bc5e425ae83ff4a2eb391bbd3d9b Add internal-only functionality to examine the stack, to ... by Derek Mauro <dmauro@google.com> - 30d63097cd268d912f917526f6511005580465c4 fix typo by Abseil Team <absl-team@google.com> - 942d7efa6cf54cd248ca57dcaf3c245188b52a76 Remove unnecessary semicolons from comment examples. by Abseil Team <absl-team@google.com> - 7db0669cf23a06d934d3ed8c76aee4e4e23b7e04 Remove malloc_hook and malloc_extension from our internal... by Greg Falcon <gfalcon@google.com> - 0190f1063d101b1ded355019df2e1d325931f6c7 Make the maximum length of a string view equal difference... by Abseil Team <absl-team@google.com> - c8ae37cbce29449b02115a0ebd435ddc3d7ab062 Add namespace qualification. by Shaindel Schwartz <shaindel@google.com> - ff70afe2e6e3dd39f51ce9829e3e1f18231bf4d7 Fix internal/direct_mmap.h for non-linux builds. by Greg Falcon <gfalcon@google.com> GitOrigin-RevId: ed0ba496fe01eb8edfa86beade8a37768e7c12ef Change-Id: I7595ee3480d1d6724fd3797c15ba9d9be0d17e62
This commit is contained in:
parent
a7e522daf1
commit
5b53540166
35 changed files with 831 additions and 2601 deletions
|
|
@ -21,15 +21,21 @@
|
|||
#include "absl/base/internal/exception_safety_testing.h"
|
||||
|
||||
using Thrower = absl::ThrowingValue<>;
|
||||
using NoThrowMoveThrower =
|
||||
absl::ThrowingValue<absl::NoThrow::kMoveCtor | absl::NoThrow::kMoveAssign>;
|
||||
using ThrowerList = std::initializer_list<Thrower>;
|
||||
using ThrowerVec = std::vector<Thrower>;
|
||||
using ThrowingAlloc = absl::ThrowingAllocator<Thrower>;
|
||||
using ThrowingThrowerVec = std::vector<Thrower, ThrowingAlloc>;
|
||||
|
||||
namespace absl {
|
||||
namespace {
|
||||
|
||||
testing::AssertionResult AbslCheckInvariants(absl::any* a,
|
||||
InternalAbslNamespaceFinder) {
|
||||
class AnyExceptionSafety : public ::testing::Test {
|
||||
private:
|
||||
absl::ConstructorTracker inspector_;
|
||||
};
|
||||
|
||||
testing::AssertionResult AnyInvariants(absl::any* a) {
|
||||
using testing::AssertionFailure;
|
||||
using testing::AssertionSuccess;
|
||||
|
||||
|
|
@ -69,17 +75,10 @@ testing::AssertionResult AbslCheckInvariants(absl::any* a,
|
|||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
} // namespace absl
|
||||
|
||||
namespace {
|
||||
|
||||
class AnyExceptionSafety : public ::testing::Test {
|
||||
private:
|
||||
absl::ConstructorTracker inspector_;
|
||||
};
|
||||
|
||||
testing::AssertionResult AnyIsEmpty(absl::any* a) {
|
||||
if (!a->has_value()) return testing::AssertionSuccess();
|
||||
if (!a->has_value()) {
|
||||
return testing::AssertionSuccess();
|
||||
}
|
||||
return testing::AssertionFailure()
|
||||
<< "a should be empty, but instead has value "
|
||||
<< absl::any_cast<Thrower>(*a).Get();
|
||||
|
|
@ -100,101 +99,70 @@ TEST_F(AnyExceptionSafety, Ctors) {
|
|||
absl::in_place_type_t<ThrowingThrowerVec>(), {val}, ThrowingAlloc());
|
||||
}
|
||||
|
||||
struct OneFactory {
|
||||
std::unique_ptr<absl::any> operator()() const {
|
||||
return absl::make_unique<absl::any>(absl::in_place_type_t<Thrower>(), 1,
|
||||
absl::no_throw_ctor);
|
||||
}
|
||||
};
|
||||
|
||||
struct EmptyFactory {
|
||||
std::unique_ptr<absl::any> operator()() const {
|
||||
return absl::make_unique<absl::any>();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AnyExceptionSafety, Assignment) {
|
||||
auto thrower_comp = [](const absl::any& l, const absl::any& r) {
|
||||
return absl::any_cast<Thrower>(l) == absl::any_cast<Thrower>(r);
|
||||
auto original =
|
||||
absl::any(absl::in_place_type_t<Thrower>(), 1, absl::no_throw_ctor);
|
||||
auto any_is_strong = [original](absl::any* ap) {
|
||||
return testing::AssertionResult(ap->has_value() &&
|
||||
absl::any_cast<Thrower>(original) ==
|
||||
absl::any_cast<Thrower>(*ap));
|
||||
};
|
||||
auto any_strong_tester = absl::MakeExceptionSafetyTester()
|
||||
.WithInitialValue(original)
|
||||
.WithInvariants(AnyInvariants, any_is_strong);
|
||||
|
||||
OneFactory one_factory;
|
||||
|
||||
absl::ThrowingValue<absl::NoThrow::kMoveCtor | absl::NoThrow::kMoveAssign>
|
||||
moveable_val(2);
|
||||
Thrower val(2);
|
||||
absl::any any_val(val);
|
||||
NoThrowMoveThrower mv_val(2);
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory, [&any_val](absl::any* ap) { *ap = any_val; },
|
||||
absl::StrongGuarantee(one_factory, thrower_comp)));
|
||||
auto assign_any = [&any_val](absl::any* ap) { *ap = any_val; };
|
||||
auto assign_val = [&val](absl::any* ap) { *ap = val; };
|
||||
auto move = [&val](absl::any* ap) { *ap = std::move(val); };
|
||||
auto move_movable = [&mv_val](absl::any* ap) { *ap = std::move(mv_val); };
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory, [&val](absl::any* ap) { *ap = val; },
|
||||
absl::StrongGuarantee(one_factory, thrower_comp)));
|
||||
EXPECT_TRUE(any_strong_tester.Test(assign_any));
|
||||
EXPECT_TRUE(any_strong_tester.Test(assign_val));
|
||||
EXPECT_TRUE(any_strong_tester.Test(move));
|
||||
EXPECT_TRUE(any_strong_tester.Test(move_movable));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory, [&val](absl::any* ap) { *ap = std::move(val); },
|
||||
absl::StrongGuarantee(one_factory, thrower_comp)));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory,
|
||||
[&moveable_val](absl::any* ap) { *ap = std::move(moveable_val); },
|
||||
absl::StrongGuarantee(one_factory, thrower_comp)));
|
||||
|
||||
EmptyFactory empty_factory;
|
||||
auto empty_comp = [](const absl::any& l, const absl::any& r) {
|
||||
return !(l.has_value() || r.has_value());
|
||||
auto empty_any_is_strong = [](absl::any* ap) {
|
||||
return testing::AssertionResult{!ap->has_value()};
|
||||
};
|
||||
auto strong_empty_any_tester =
|
||||
absl::MakeExceptionSafetyTester()
|
||||
.WithInitialValue(absl::any{})
|
||||
.WithInvariants(AnyInvariants, empty_any_is_strong);
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
empty_factory, [&any_val](absl::any* ap) { *ap = any_val; },
|
||||
absl::StrongGuarantee(empty_factory, empty_comp)));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
empty_factory, [&val](absl::any* ap) { *ap = val; },
|
||||
absl::StrongGuarantee(empty_factory, empty_comp)));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
empty_factory, [&val](absl::any* ap) { *ap = std::move(val); },
|
||||
absl::StrongGuarantee(empty_factory, empty_comp)));
|
||||
EXPECT_TRUE(strong_empty_any_tester.Test(assign_any));
|
||||
EXPECT_TRUE(strong_empty_any_tester.Test(assign_val));
|
||||
EXPECT_TRUE(strong_empty_any_tester.Test(move));
|
||||
}
|
||||
// libstdc++ std::any fails this test
|
||||
#if !defined(ABSL_HAVE_STD_ANY)
|
||||
TEST_F(AnyExceptionSafety, Emplace) {
|
||||
OneFactory one_factory;
|
||||
auto initial_val =
|
||||
absl::any{absl::in_place_type_t<Thrower>(), 1, absl::no_throw_ctor};
|
||||
auto one_tester = absl::MakeExceptionSafetyTester()
|
||||
.WithInitialValue(initial_val)
|
||||
.WithInvariants(AnyInvariants, AnyIsEmpty);
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory, [](absl::any* ap) { ap->emplace<Thrower>(2); }, AnyIsEmpty));
|
||||
auto emp_thrower = [](absl::any* ap) { ap->emplace<Thrower>(2); };
|
||||
auto emp_throwervec = [](absl::any* ap) {
|
||||
std::initializer_list<Thrower> il{Thrower(2, absl::no_throw_ctor)};
|
||||
ap->emplace<ThrowerVec>(il);
|
||||
};
|
||||
auto emp_movethrower = [](absl::any* ap) {
|
||||
ap->emplace<NoThrowMoveThrower>(2);
|
||||
};
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
one_factory,
|
||||
[](absl::any* ap) {
|
||||
ap->emplace<absl::ThrowingValue<absl::NoThrow::kMoveCtor |
|
||||
absl::NoThrow::kMoveAssign>>(2);
|
||||
},
|
||||
AnyIsEmpty));
|
||||
EXPECT_TRUE(one_tester.Test(emp_thrower));
|
||||
EXPECT_TRUE(one_tester.Test(emp_throwervec));
|
||||
EXPECT_TRUE(one_tester.Test(emp_movethrower));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(one_factory,
|
||||
[](absl::any* ap) {
|
||||
std::initializer_list<Thrower> il{
|
||||
Thrower(2, absl::no_throw_ctor)};
|
||||
ap->emplace<ThrowerVec>(il);
|
||||
},
|
||||
AnyIsEmpty));
|
||||
auto empty_tester = one_tester.WithInitialValue(absl::any{});
|
||||
|
||||
EmptyFactory empty_factory;
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(
|
||||
empty_factory, [](absl::any* ap) { ap->emplace<Thrower>(2); },
|
||||
AnyIsEmpty));
|
||||
|
||||
EXPECT_TRUE(absl::TestExceptionSafety(empty_factory,
|
||||
[](absl::any* ap) {
|
||||
std::initializer_list<Thrower> il{
|
||||
Thrower(2, absl::no_throw_ctor)};
|
||||
ap->emplace<ThrowerVec>(il);
|
||||
},
|
||||
AnyIsEmpty));
|
||||
EXPECT_TRUE(empty_tester.Test(emp_thrower));
|
||||
EXPECT_TRUE(empty_tester.Test(emp_throwervec));
|
||||
}
|
||||
#endif // ABSL_HAVE_STD_ANY
|
||||
|
||||
|
|
|
|||
|
|
@ -553,7 +553,7 @@ TEST(AnyTest, Move) {
|
|||
absl::any tmp4(4);
|
||||
absl::any o4(std::move(tmp4)); // move construct
|
||||
EXPECT_EQ(4, absl::any_cast<int>(o4));
|
||||
o4 = o4; // self assign
|
||||
o4 = *&o4; // self assign
|
||||
EXPECT_EQ(4, absl::any_cast<int>(o4));
|
||||
EXPECT_TRUE(o4.has_value());
|
||||
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ using EnableIfConvertibleToSpanConst =
|
|||
// // Construct a Span implicitly from a container
|
||||
// void MyRoutine(absl::Span<const int> a) {
|
||||
// ...
|
||||
// };
|
||||
// }
|
||||
// std::vector v = {1,2,3,4,5};
|
||||
// MyRoutine(v) // convert to Span<const T>
|
||||
//
|
||||
|
|
@ -235,7 +235,7 @@ using EnableIfConvertibleToSpanConst =
|
|||
//
|
||||
// void MyRoutine(absl::Span<const int> a) {
|
||||
// ...
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// std::vector v = {1,2,3,4,5};
|
||||
// MyRoutine(v);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue