aboutsummaryrefslogtreecommitdiff
path: root/src/test/util_tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/util_tests.cpp')
-rw-r--r--src/test/util_tests.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 3995a3c732..02303d0f65 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -13,6 +13,7 @@
#include <util/string.h>
#include <util/time.h>
#include <util/spanparsing.h>
+#include <util/vector.h>
#include <stdint.h>
#include <thread>
@@ -1714,4 +1715,109 @@ BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
}
+namespace {
+
+struct Tracker
+{
+ //! Points to the original object (possibly itself) we moved/copied from
+ const Tracker* origin;
+ //! How many copies where involved between the original object and this one (moves are not counted)
+ int copies;
+
+ Tracker() noexcept : origin(this), copies(0) {}
+ Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
+ Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
+ Tracker& operator=(const Tracker& t) noexcept
+ {
+ origin = t.origin;
+ copies = t.copies + 1;
+ return *this;
+ }
+ Tracker& operator=(Tracker&& t) noexcept
+ {
+ origin = t.origin;
+ copies = t.copies;
+ return *this;
+ }
+};
+
+}
+
+BOOST_AUTO_TEST_CASE(test_tracked_vector)
+{
+ Tracker t1;
+ Tracker t2;
+ Tracker t3;
+
+ BOOST_CHECK(t1.origin == &t1);
+ BOOST_CHECK(t2.origin == &t2);
+ BOOST_CHECK(t3.origin == &t3);
+
+ auto v1 = Vector(t1);
+ BOOST_CHECK_EQUAL(v1.size(), 1);
+ BOOST_CHECK(v1[0].origin == &t1);
+ BOOST_CHECK_EQUAL(v1[0].copies, 1);
+
+ auto v2 = Vector(std::move(t2));
+ BOOST_CHECK_EQUAL(v2.size(), 1);
+ BOOST_CHECK(v2[0].origin == &t2);
+ BOOST_CHECK_EQUAL(v2[0].copies, 0);
+
+ auto v3 = Vector(t1, std::move(t2));
+ BOOST_CHECK_EQUAL(v3.size(), 2);
+ BOOST_CHECK(v3[0].origin == &t1);
+ BOOST_CHECK(v3[1].origin == &t2);
+ BOOST_CHECK_EQUAL(v3[0].copies, 1);
+ BOOST_CHECK_EQUAL(v3[1].copies, 0);
+
+ auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
+ BOOST_CHECK_EQUAL(v4.size(), 3);
+ BOOST_CHECK(v4[0].origin == &t1);
+ BOOST_CHECK(v4[1].origin == &t2);
+ BOOST_CHECK(v4[2].origin == &t3);
+ BOOST_CHECK_EQUAL(v4[0].copies, 1);
+ BOOST_CHECK_EQUAL(v4[1].copies, 1);
+ BOOST_CHECK_EQUAL(v4[2].copies, 0);
+
+ auto v5 = Cat(v1, v4);
+ BOOST_CHECK_EQUAL(v5.size(), 4);
+ BOOST_CHECK(v5[0].origin == &t1);
+ BOOST_CHECK(v5[1].origin == &t1);
+ BOOST_CHECK(v5[2].origin == &t2);
+ BOOST_CHECK(v5[3].origin == &t3);
+ BOOST_CHECK_EQUAL(v5[0].copies, 2);
+ BOOST_CHECK_EQUAL(v5[1].copies, 2);
+ BOOST_CHECK_EQUAL(v5[2].copies, 2);
+ BOOST_CHECK_EQUAL(v5[3].copies, 1);
+
+ auto v6 = Cat(std::move(v1), v3);
+ BOOST_CHECK_EQUAL(v6.size(), 3);
+ BOOST_CHECK(v6[0].origin == &t1);
+ BOOST_CHECK(v6[1].origin == &t1);
+ BOOST_CHECK(v6[2].origin == &t2);
+ BOOST_CHECK_EQUAL(v6[0].copies, 1);
+ BOOST_CHECK_EQUAL(v6[1].copies, 2);
+ BOOST_CHECK_EQUAL(v6[2].copies, 1);
+
+ auto v7 = Cat(v2, std::move(v4));
+ BOOST_CHECK_EQUAL(v7.size(), 4);
+ BOOST_CHECK(v7[0].origin == &t2);
+ BOOST_CHECK(v7[1].origin == &t1);
+ BOOST_CHECK(v7[2].origin == &t2);
+ BOOST_CHECK(v7[3].origin == &t3);
+ BOOST_CHECK_EQUAL(v7[0].copies, 1);
+ BOOST_CHECK_EQUAL(v7[1].copies, 1);
+ BOOST_CHECK_EQUAL(v7[2].copies, 1);
+ BOOST_CHECK_EQUAL(v7[3].copies, 0);
+
+ auto v8 = Cat(std::move(v2), std::move(v3));
+ BOOST_CHECK_EQUAL(v8.size(), 3);
+ BOOST_CHECK(v8[0].origin == &t2);
+ BOOST_CHECK(v8[1].origin == &t1);
+ BOOST_CHECK(v8[2].origin == &t2);
+ BOOST_CHECK_EQUAL(v8[0].copies, 0);
+ BOOST_CHECK_EQUAL(v8[1].copies, 1);
+ BOOST_CHECK_EQUAL(v8[2].copies, 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()