From 489459d97087a3ad7c35a156f2bfa9660ca809e2 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 8 Feb 2024 20:57:30 +0200 Subject: [PATCH] Finish the assignment tests #verification #sonar #docs --- .../suites/unittest/test_pf17_optional.cpp | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/cetlvast/suites/unittest/test_pf17_optional.cpp b/cetlvast/suites/unittest/test_pf17_optional.cpp index 75795d4c..080469e7 100644 --- a/cetlvast/suites/unittest/test_pf17_optional.cpp +++ b/cetlvast/suites/unittest/test_pf17_optional.cpp @@ -1103,3 +1103,189 @@ TYPED_TEST(test_optional_combinations, assignment_4) EXPECT_FALSE(v1); EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, dtor); } + +/// ------------------------------------------------------------------------------------------------ + +TYPED_TEST(test_optional_combinations, assignment_5) +{ + struct From final : TypeParam + { + explicit From(const std::int64_t val) noexcept + : value{val} + { + } + std::int64_t value; + }; + struct To final : TypeParam + { + explicit To(const std::int64_t val) noexcept + : value{val} + { + } + explicit To(const From& val) noexcept + : value{val.value} + { + } + To& operator=(const From& val) noexcept + { + value = val.value; + return *this; + } + std::int64_t value; + }; + static_assert(std::is_assignable::value, ""); + static_assert(std::is_assignable, optional>::value, ""); + std::uint32_t a_dtor = 0; + std::uint32_t b_dtor = 0; + optional a; + optional b; + EXPECT_FALSE(a); + EXPECT_FALSE(b); + // Assign empty to empty. + a = b; + EXPECT_FALSE(a); + EXPECT_FALSE(b); + // Non-empty to empty. + b.emplace(12345).configure_destruction_counter(&b_dtor); + EXPECT_TRUE(b); + EXPECT_FALSE(a); + a = b; + EXPECT_TRUE(a); + EXPECT_TRUE(b); + a.value().configure_destruction_counter(&a_dtor); + EXPECT_EQ(12345, a.value().value); + EXPECT_EQ(12345, b.value().value); + EXPECT_EQ(0, a->get_copy_ctor_count()); + EXPECT_EQ(0, a->get_move_ctor_count()); + EXPECT_EQ(0, a->get_copy_assignment_count()); + EXPECT_EQ(0, a->get_move_assignment_count()); + EXPECT_EQ(0, a_dtor); + EXPECT_EQ(0, b->get_copy_ctor_count()); + EXPECT_EQ(0, b->get_move_ctor_count()); + EXPECT_EQ(0, b->get_copy_assignment_count()); + EXPECT_EQ(0, b->get_move_assignment_count()); + EXPECT_EQ(0, b_dtor); + // Non-empty to non-empty. + b.value().value = 23456; + EXPECT_EQ(12345, a.value().value); + EXPECT_EQ(23456, b.value().value); + a = b; + EXPECT_TRUE(a); + EXPECT_TRUE(b); + EXPECT_EQ(23456, a.value().value); + EXPECT_EQ(23456, b.value().value); + EXPECT_EQ(0, a->get_copy_ctor_count()); + EXPECT_EQ(0, a->get_move_ctor_count()); + EXPECT_EQ(0, a->get_copy_assignment_count()); + EXPECT_EQ(0, a->get_move_assignment_count()); + EXPECT_EQ(0, a_dtor); + EXPECT_EQ(0, b->get_copy_ctor_count()); + EXPECT_EQ(0, b->get_move_ctor_count()); + EXPECT_EQ(0, b->get_copy_assignment_count()); + EXPECT_EQ(0, b->get_move_assignment_count()); + EXPECT_EQ(0, b_dtor); + // Empty to non-empty. + b = nullopt; + EXPECT_TRUE(a); + EXPECT_FALSE(b); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, b_dtor); + a = b; + EXPECT_FALSE(a); + EXPECT_FALSE(b); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, a_dtor); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, b_dtor); +} + +/// ------------------------------------------------------------------------------------------------ + +TYPED_TEST(test_optional_combinations, assignment_6) +{ + struct From final : TypeParam + { + explicit From(const std::int64_t val) noexcept + : value{val} + { + } + std::int64_t value; + }; + struct To final : TypeParam + { + explicit To(const std::int64_t val) noexcept + : value{val} + { + } + explicit To(const From& other) noexcept; // Intentionally not implemented. + explicit To(From&& other) noexcept + : value{other.value} + { + other.value = 0; + } + To& operator=(const From&) noexcept; // Intentionally not implemented. + To& operator=(From&& other) noexcept + { + value = other.value; + other.value = 0; + return *this; + } + std::int64_t value; + }; + std::uint32_t a_dtor = 0; + std::uint32_t b_dtor = 0; + optional a; + optional b; + EXPECT_FALSE(a); + EXPECT_FALSE(b); + // Assign empty to empty. + a = std::move(b); + EXPECT_FALSE(a); + EXPECT_FALSE(b); + // Non-empty to empty. + b.emplace(12345).configure_destruction_counter(&b_dtor); + EXPECT_TRUE(b); + EXPECT_FALSE(a); + a = std::move(b); + EXPECT_TRUE(a); + EXPECT_TRUE(b); + a.value().configure_destruction_counter(&a_dtor); + EXPECT_EQ(12345, a.value().value); + EXPECT_EQ(0, b.value().value); // Moving zeroes the source. + EXPECT_EQ(0, a->get_copy_ctor_count()); + EXPECT_EQ(0, a->get_move_ctor_count()); + EXPECT_EQ(0, a->get_copy_assignment_count()); + EXPECT_EQ(0, a->get_move_assignment_count()); + EXPECT_EQ(0, a_dtor); + EXPECT_EQ(0, b->get_copy_ctor_count()); + EXPECT_EQ(0, b->get_move_ctor_count()); + EXPECT_EQ(0, b->get_copy_assignment_count()); + EXPECT_EQ(0, b->get_move_assignment_count()); + EXPECT_EQ(0, b_dtor); + // Non-empty to non-empty. + b.value().value = 23456; + EXPECT_EQ(12345, a.value().value); + EXPECT_EQ(23456, b.value().value); + a = std::move(b); + EXPECT_TRUE(a); + EXPECT_TRUE(b); + EXPECT_EQ(23456, a.value().value); + EXPECT_EQ(0, b.value().value); // Moving zeroes the source. + EXPECT_EQ(0, a->get_copy_ctor_count()); + EXPECT_EQ(0, a->get_move_ctor_count()); + EXPECT_EQ(0, a->get_copy_assignment_count()); + EXPECT_EQ(0, a->get_move_assignment_count()); + EXPECT_EQ(0, a_dtor); + EXPECT_EQ(0, b->get_copy_ctor_count()); + EXPECT_EQ(0, b->get_move_ctor_count()); + EXPECT_EQ(0, b->get_copy_assignment_count()); + EXPECT_EQ(0, b->get_move_assignment_count()); + EXPECT_EQ(0, b_dtor); + // Empty to non-empty. + b = nullopt; + EXPECT_TRUE(a); + EXPECT_FALSE(b); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, b_dtor); + a = std::move(b); + EXPECT_FALSE(a); + EXPECT_FALSE(b); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, a_dtor); + EXPECT_EQ((TypeParam::dtor_policy_value == policy_nontrivial) ? 1 : 0, b_dtor); +}