diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/tests/include/kstd/tests/test_types.hpp | 71 | ||||
| -rw-r--r-- | libs/kstd/tests/src/vector.cpp | 119 |
2 files changed, 128 insertions, 62 deletions
diff --git a/libs/kstd/tests/include/kstd/tests/test_types.hpp b/libs/kstd/tests/include/kstd/tests/test_types.hpp index 6a06311..9207ee9 100644 --- a/libs/kstd/tests/include/kstd/tests/test_types.hpp +++ b/libs/kstd/tests/include/kstd/tests/test_types.hpp @@ -11,44 +11,43 @@ namespace kstd::tests //! A type tracking copy and move operations //! //! This type is designed to test move and copy semantics of standard library containers implemented in kstd. - struct move_tracker + struct special_member_tracker { //! A value indicating that the object was moved from. constexpr auto static moved_from_v = -1; - //! A simple value to be able to track the move-from state. - int value{}; - //! A flag to track if an instance of this type was either copy constructed or copy assigned. - bool was_copied{false}; - //! A flag to track if an instance of this type was either move constructed or move assigned. - bool was_moved{false}; + constexpr special_member_tracker() + : default_constructed_count{1} + {} //! Construct a new move tracker with the given value, if any. - constexpr move_tracker(int v = 0) + constexpr special_member_tracker(int v = 0) : value{v} + , value_constructed_count{1} {} //! Construct a new move tracker by copying an existing one. - constexpr move_tracker(move_tracker const & other) + constexpr special_member_tracker(special_member_tracker const & other) : value{other.value} - , was_copied{true} + , copy_constructed_count{1} {} //! Construct a new move tracker by moving from an existing one. - constexpr move_tracker(move_tracker && other) noexcept + constexpr special_member_tracker(special_member_tracker && other) noexcept : value{other.value} - , was_moved{true} + , move_constructed_count{1} { other.value = moved_from_v; } //! Copy assign a new move tracker from an existing one. - constexpr auto operator=(move_tracker const & other) -> move_tracker & + constexpr auto operator=(special_member_tracker const & other) -> special_member_tracker & { if (this != &other) { value = other.value; - was_copied = true; + ++copy_assigned_count; + ++other.copied_from_count; } return *this; } @@ -56,16 +55,56 @@ namespace kstd::tests //! Move assign a new move tracker from an existing one. //! //! This function ensures that the moved-from state is marked. - constexpr auto operator=(move_tracker && other) noexcept -> move_tracker & + constexpr auto operator=(special_member_tracker && other) noexcept -> special_member_tracker & { if (this != &other) { value = other.value; - was_moved = true; + ++move_assigned_count; other.value = moved_from_v; + ++other.moved_from_count; } return *this; } + + ~special_member_tracker() + { + ++destroyed_count; + } + + auto reset_counts() -> void + { + default_constructed_count = 0; + copy_constructed_count = 0; + move_constructed_count = 0; + value_constructed_count = 0; + copy_assigned_count = 0; + move_assigned_count = 0; + destroyed_count = 0; + copied_from_count = 0; + moved_from_count = 0; + } + + //! A simple value to be able to track the move-from state. + int value{}; + //! A counter to track how many times an instance of this type was default constructed. + std::size_t default_constructed_count{0}; + //! A counter to track how many times an instance of this type was copy constructed. + std::size_t copy_constructed_count{0}; + //! A counter to track how many times an instance of this type was move constructed. + std::size_t move_constructed_count{0}; + //! A counter to track how many times an instance of this type was value constructed. + std::size_t value_constructed_count{0}; + //! A counter to track how many times an instance of this type was copy assigned. + std::size_t copy_assigned_count{0}; + //! A counter to track how many times an instance of this type was move assigned. + std::size_t move_assigned_count{0}; + //! A counter to track how many times an instance of this type was destroyed. + std::size_t destroyed_count{0}; + //! A counter to track how many times an instance of this type was copied from another instance. + mutable std::size_t copied_from_count{0}; + //! A counter to track how many times an instance of this type was moved from another instance. + std::size_t moved_from_count{0}; }; //! A type that is not default constructible. diff --git a/libs/kstd/tests/src/vector.cpp b/libs/kstd/tests/src/vector.cpp index b7971f4..81bf32f 100644 --- a/libs/kstd/tests/src/vector.cpp +++ b/libs/kstd/tests/src/vector.cpp @@ -919,8 +919,8 @@ SCENARIO("Vector modifier move semantics", "[vector]") { GIVEN("An empty vector and a move tracker element") { - auto v = kstd::vector<kstd::tests::move_tracker>{}; - auto tracker = kstd::tests::move_tracker{42}; + auto v = kstd::vector<kstd::tests::special_member_tracker>{}; + auto tracker = kstd::tests::special_member_tracker{42}; WHEN("push_back is called with the move tracker") { @@ -929,8 +929,8 @@ SCENARIO("Vector modifier move semantics", "[vector]") THEN("the element is added and the size and capacity increase") { REQUIRE(v.size() == 1); - REQUIRE(v.back().was_moved); - REQUIRE_FALSE(v.back().was_copied); + REQUIRE(v.back().move_constructed_count == 1); + REQUIRE(v.back().copy_constructed_count == 0); REQUIRE(v.back().value == 42); } @@ -943,7 +943,7 @@ SCENARIO("Vector modifier move semantics", "[vector]") GIVEN("An empty vector") { - auto v = kstd::vector<kstd::tests::move_tracker>{}; + auto v = kstd::vector<kstd::tests::special_member_tracker>{}; WHEN("emplace_back is called with constructor arguments") { @@ -952,8 +952,8 @@ SCENARIO("Vector modifier move semantics", "[vector]") THEN("the element is constructed directly, without moves or copies") { REQUIRE(v.size() == 1); - REQUIRE_FALSE(v.back().was_moved); - REQUIRE_FALSE(v.back().was_copied); + REQUIRE(v.back().move_constructed_count == 0); + REQUIRE(v.back().copy_constructed_count == 0); REQUIRE(v.back().value == 42); } } @@ -961,7 +961,7 @@ SCENARIO("Vector modifier move semantics", "[vector]") GIVEN("A populated vector of move trackers") { - auto v = kstd::vector<kstd::tests::move_tracker>{}; + auto v = kstd::vector<kstd::tests::special_member_tracker>{}; v.reserve(10); v.emplace_back(10); v.emplace_back(20); @@ -969,41 +969,46 @@ SCENARIO("Vector modifier move semantics", "[vector]") WHEN("inserting an element in the middle with sufficient capacity") { - auto const tracker = kstd::tests::move_tracker{15}; + auto const tracker = kstd::tests::special_member_tracker{15}; v.insert(v.cbegin() + 1, tracker); THEN("the shifted elements are move-assigned and the new element is copy-assigned") { REQUIRE(v.size() == 4); REQUIRE(v[0].value == 10); - REQUIRE_FALSE(v[0].was_moved); + REQUIRE(v[0].move_assigned_count == 0); + REQUIRE(v[0].copy_assigned_count == 0); REQUIRE(v[1].value == 15); - REQUIRE(v[1].was_copied); - REQUIRE_FALSE(v[1].was_moved); + REQUIRE(v[1].move_assigned_count == 0); + REQUIRE(v[1].copy_assigned_count == 1); + REQUIRE(tracker.copied_from_count == 1); REQUIRE(v[2].value == 20); - REQUIRE(v[2].was_moved); + REQUIRE(v[2].move_assigned_count == 1); + REQUIRE(v[2].copy_assigned_count == 0); REQUIRE(v[3].value == 30); - REQUIRE(v[3].was_moved); + REQUIRE(v[3].move_constructed_count == 1); } } WHEN("inserting an rvalue element in the middle with sufficient capacity") { - auto tracker = kstd::tests::move_tracker{15}; + auto tracker = kstd::tests::special_member_tracker{15}; v.insert(v.cbegin() + 1, std::move(tracker)); THEN("the shifted elements are move-assigned and the new element is move-assigned") { REQUIRE(v.size() == 4); REQUIRE(v[0].value == 10); - REQUIRE_FALSE(v[0].was_moved); + REQUIRE(v[0].move_assigned_count == 0); + REQUIRE(v[0].copy_assigned_count == 0); REQUIRE(v[1].value == 15); - REQUIRE_FALSE(v[1].was_copied); - REQUIRE(v[1].was_moved); + REQUIRE(v[1].move_assigned_count == 1); + REQUIRE(v[1].copy_assigned_count == 0); + REQUIRE(tracker.moved_from_count == 1); REQUIRE(v[2].value == 20); - REQUIRE(v[2].was_moved); + REQUIRE(v[2].move_assigned_count == 1); REQUIRE(v[3].value == 30); - REQUIRE(v[3].was_moved); + REQUIRE(v[3].move_constructed_count == 1); } } @@ -1011,8 +1016,7 @@ SCENARIO("Vector modifier move semantics", "[vector]") { for (auto & elem : v) { - elem.was_copied = false; - elem.was_moved = false; + elem.reset_counts(); } auto it = v.erase(v.cbegin() + 1); @@ -1022,12 +1026,15 @@ SCENARIO("Vector modifier move semantics", "[vector]") REQUIRE(v.size() == 2); REQUIRE(v[0].value == 10); - REQUIRE_FALSE(v[0].was_moved); - REQUIRE_FALSE(v[0].was_copied); + REQUIRE(v[0].move_assigned_count == 0); + REQUIRE(v[0].copy_assigned_count == 0); REQUIRE(v[1].value == 30); - REQUIRE(v[1].was_moved); - REQUIRE_FALSE(v[1].was_copied); + REQUIRE(v[1].move_assigned_count == 1); + REQUIRE(v[1].copy_assigned_count == 0); + + REQUIRE(v.data()[2].destroyed_count == 1); + REQUIRE(v.data()[2].moved_from_count == 1); REQUIRE(it == v.begin() + 1); } @@ -1037,8 +1044,7 @@ SCENARIO("Vector modifier move semantics", "[vector]") { for (auto & elem : v) { - elem.was_copied = false; - elem.was_moved = false; + elem.reset_counts(); } auto it = v.erase(v.cend() - 1); @@ -1048,12 +1054,20 @@ SCENARIO("Vector modifier move semantics", "[vector]") REQUIRE(v.size() == 2); REQUIRE(v[0].value == 10); - REQUIRE_FALSE(v[0].was_moved); - REQUIRE_FALSE(v[0].was_copied); + REQUIRE(v[0].move_constructed_count == 0); + REQUIRE(v[0].copy_constructed_count == 0); + REQUIRE(v[0].move_assigned_count == 0); + REQUIRE(v[0].copy_assigned_count == 0); REQUIRE(v[1].value == 20); - REQUIRE_FALSE(v[1].was_moved); - REQUIRE_FALSE(v[1].was_copied); + REQUIRE(v[1].move_constructed_count == 0); + REQUIRE(v[1].copy_constructed_count == 0); + REQUIRE(v[1].move_assigned_count == 0); + REQUIRE(v[1].copy_assigned_count == 0); + + REQUIRE(v.data()[2].destroyed_count == 1); + REQUIRE(v.data()[2].moved_from_count == 0); + REQUIRE(v.data()[2].copied_from_count == 0); REQUIRE(it == v.end()); } @@ -1066,8 +1080,7 @@ SCENARIO("Vector modifier move semantics", "[vector]") for (auto & elem : v) { - elem.was_copied = false; - elem.was_moved = false; + elem.reset_counts(); } auto it = v.erase(v.cbegin() + 1, v.cbegin() + 3); @@ -1077,16 +1090,30 @@ SCENARIO("Vector modifier move semantics", "[vector]") REQUIRE(v.size() == 3); REQUIRE(v[0].value == 10); - REQUIRE_FALSE(v[0].was_moved); - REQUIRE_FALSE(v[0].was_copied); + REQUIRE(v[0].move_constructed_count == 0); + REQUIRE(v[0].copy_constructed_count == 0); + REQUIRE(v[0].move_assigned_count == 0); + REQUIRE(v[0].copy_assigned_count == 0); REQUIRE(v[1].value == 40); - REQUIRE(v[1].was_moved); - REQUIRE_FALSE(v[1].was_copied); + REQUIRE(v[1].move_constructed_count == 0); + REQUIRE(v[1].copy_constructed_count == 0); + REQUIRE(v[1].move_assigned_count == 1); + REQUIRE(v[1].copy_assigned_count == 0); REQUIRE(v[2].value == 50); - REQUIRE(v[2].was_moved); - REQUIRE_FALSE(v[2].was_copied); + REQUIRE(v[2].move_constructed_count == 0); + REQUIRE(v[2].copy_constructed_count == 0); + REQUIRE(v[2].move_assigned_count == 1); + REQUIRE(v[2].copy_assigned_count == 0); + + REQUIRE(v.data()[3].destroyed_count == 1); + REQUIRE(v.data()[3].moved_from_count == 1); + REQUIRE(v.data()[3].copied_from_count == 0); + + REQUIRE(v.data()[4].destroyed_count == 1); + REQUIRE(v.data()[4].moved_from_count == 1); + REQUIRE(v.data()[4].copied_from_count == 0); REQUIRE(it == v.begin() + 1); } @@ -1417,8 +1444,8 @@ SCENARIO("Vector const accessors and copy insertion", "[vector]") GIVEN("An empty vector and a const lvalue tracker") { - auto v = kstd::vector<kstd::tests::move_tracker>{}; - auto const tracker = kstd::tests::move_tracker{42}; + auto v = kstd::vector<kstd::tests::special_member_tracker>{}; + auto const tracker = kstd::tests::special_member_tracker{42}; WHEN("push_back is called with the const lvalue") { @@ -1428,8 +1455,8 @@ SCENARIO("Vector const accessors and copy insertion", "[vector]") { REQUIRE(v.size() == 1); REQUIRE(v.back().value == 42); - REQUIRE(v.back().was_copied); - REQUIRE_FALSE(v.back().was_moved); + REQUIRE(v.back().copy_constructed_count == 1); + REQUIRE(v.back().move_constructed_count == 0); } } @@ -1444,8 +1471,8 @@ SCENARIO("Vector const accessors and copy insertion", "[vector]") REQUIRE(v.size() == 1); REQUIRE(v.capacity() == current_capacity); REQUIRE(v.back().value == 42); - REQUIRE(v.back().was_copied); - REQUIRE_FALSE(v.back().was_moved); + REQUIRE(v.back().copy_constructed_count == 1); + REQUIRE(v.back().move_constructed_count == 0); } } } |
