summaryrefslogtreecommitdiffhomepage
path: root/test/bptr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/bptr.cpp')
-rw-r--r--test/bptr.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/test/bptr.cpp b/test/bptr.cpp
index 6f823344..55b10fe0 100644
--- a/test/bptr.cpp
+++ b/test/bptr.cpp
@@ -1,6 +1,7 @@
#include "app.hpp"
#include "compat/assert.hpp"
#include "compat/borrowed-ptr.inl"
+#include <array>
namespace floormat {
@@ -94,12 +95,203 @@ void test2()
fm_assert(A_alive == 0);
}
+void test3()
+{
+ A_total = 0; A_alive = 0;
+
+ auto p1 = bptr<A>{InPlace, 3};
+ (void)p1;
+ auto p2 = p1;
+ auto p3 = p2;
+
+ fm_assert(p1.use_count() == 3);
+ fm_assert(p1.get());
+ fm_assert(p1.get() == p2.get());
+ fm_assert(p1.get() == p3.get());
+ fm_assert(A_total == 1);
+ fm_assert(A_alive == 1);
+
+ p3 = nullptr; (void)p3;
+ fm_assert(p1.use_count() == 2);
+ p3 = p2;
+ fm_assert(p1.use_count() == 3 && p3->val == 3 && p3->serial == 1 && p2 == p3 && p1 == p3);
+}
+
+void check_empty(const bptr<A>& p)
+{
+ fm_assert(!p);
+ fm_assert(p.use_count() == 0);
+ fm_assert(!p.get());
+}
+
+void check_nonempty(const bptr<A>& p)
+{
+ fm_assert(p);
+ fm_assert(p.use_count() > 0);
+ fm_assert(p.get());
+}
+
+void test4()
+{
+ A_total = 0; A_alive = 0;
+
+ fm_assert(bptr<A>{} == bptr<A>{nullptr});
+ fm_assert(bptr<A>{} == bptr<A>{(A*)nullptr});
+ fm_assert(A_total == 0 && A_alive == 0);
+
+ {
+ auto p1 = bptr<A>{InPlace, 42};
+ auto p2 = bptr<A>{InPlace, 41};
+ auto p3 = bptr<A>{};
+ check_empty(p3);
+ (void)p1.operator=(p1);
+ (void)p2.operator=(p2);
+ fm_assert(p1->val == 42 && p1->serial == 1);
+ fm_assert(p2->val == 41 && p2->serial == 2);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 2);
+ check_nonempty(p1);
+ check_nonempty(p2);
+
+ p1.swap(p2);
+ fm_assert(p1->val == 41 && p1->serial == 2);
+ fm_assert(p2->val == 42 && p2->serial == 1);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 2);
+ check_nonempty(p1);
+ check_nonempty(p2);
+
+ p1 = nullptr;
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 1);
+ check_empty(p1);
+ check_nonempty(p2);
+
+ (void)p2;
+ p1 = p2;
+ fm_assert(p1 == p2);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 1);
+ check_nonempty(p1);
+ check_nonempty(p2);
+
+ p2 = bptr<A>{(A*)nullptr};
+ check_empty(p2);
+ check_nonempty(p1);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 1);
+ p1.reset();
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 0);
+
+ p1 = p2;
+ p2 = p1;
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 0);
+ }
+}
+
+void test5()
+{
+ A_total = 0; A_alive = 0;
+ auto p1 = bptr<A>{InPlace, -1};
+ auto p2 = bptr<A>{InPlace, -2};
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 2);
+ (void)p1;
+
+ auto p3 = p1;
+ fm_assert(p1.use_count() == 2);
+ fm_assert(p2.use_count() == 1);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 2);
+ fm_assert(p1->serial == 1 && p1->val == -1);
+ fm_assert(p2->serial == 2 && p2->val == -2);
+ fm_assert(p3->serial == 1 && p3->val == -1);
+
+ p1 = nullptr;
+ fm_assert(!p1.get());
+ fm_assert(p2->serial == 2 && p2->val == -2);
+ fm_assert(p3->serial == 1 && p3->val == -1);
+ fm_assert(A_total == 2);
+ fm_assert(A_alive == 2);
+
+ p2 = nullptr;
+ fm_assert(!p1.get());
+ fm_assert(!p2.get());
+ fm_assert(p3->serial == 1 && p3->val == -1);
+}
+
+void test6()
+{
+ constexpr size_t size = 5;
+ std::array<bptr<A>, size> array;
+ for (auto n = 0u; n < size; n++)
+ {
+ A_total = 0; A_alive = 0;
+ bptr<A> p0;
+ array[0] = bptr<A>{InPlace, 6};
+ for (auto i = 1u; i < size; i++)
+ array[i] = array[i-1];
+ fm_assert(array[0].use_count() == size);
+ fm_assert(A_total == 1 && A_alive == 1);
+ array[(n + 1) % size].reset();
+ array[(n + 2) % size] = bptr<A>((A*)nullptr);
+ array[(n + 3) % size] = move(p0);
+ array[(n + 4) % size].swap(p0);
+ array[(n + 0) % size] = nullptr;
+ p0 = nullptr;
+ for (auto k = 0u; k < size; k++)
+ {
+ for (auto i = 1u; i < size; i++)
+ array[i-1] = array[(i+k) % size];
+ for (auto i = 1u; i < size; i++)
+ check_empty(array[i]);
+ }
+ fm_assert(A_total == 1);
+ fm_assert(A_alive == 0);
+ fm_assert(array == std::array<bptr<A>, size>{});
+ }
+}
+
+void test7()
+{
+ A_total = 0; A_alive = 0;
+ auto p1 = bptr<A>{InPlace, 7};
+ auto p2 = bptr<A>{};
+ p2 = move(p1);
+ fm_assert(A_total == 1 && A_alive == 1);
+ check_empty(p1);
+ check_nonempty(p2);
+
+ p1.reset();
+ check_empty(p1);
+ check_nonempty(p2);
+
+ p1 = move(p2);
+ fm_assert(A_total == 1 && A_alive == 1);
+ check_nonempty(p1);
+ check_empty(p2);
+
+ p1 = move(p2);
+ check_empty(p1);
+ check_empty(p2);
+ fm_assert(A_total == 1 && A_alive == 0);
+
+ A_total = 0; A_alive = 0;
+}
+
} // namespace
void test_app::test_bptr()
{
test1();
test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
}
} // namespace floormat