- 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:
Abseil Team 2018-04-18 05:56:39 -07:00 committed by Jon Cohen
parent a7e522daf1
commit 5b53540166
35 changed files with 831 additions and 2601 deletions

View file

@ -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

View file

@ -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());

View file

@ -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);