#include "stdafx.h" #include "tl/ptr.h" #include #include "tl/utest.h" #include "TestHelpers.h" struct Counters { auto operator<=>(Counters const& other) const noexcept = default; bool operator==(Counters const& other) const noexcept = default; size_t ctor = 0; size_t dtor = 0; size_t copyCtor = 0; size_t moveCtor = 0; size_t copyAss = 0; size_t moveAss = 0; void resetCounters() { ctor = 0; dtor = 0; copyCtor = 0; moveCtor = 0; copyAss = 0; moveAss = 0; } }; struct Test { Test(size_t data = 0) : data(data) { s_counters.ctor++; } ~Test() { s_counters.dtor++; } Test(const Test&) { s_counters.copyCtor++; } Test(Test&&) { s_counters.moveCtor++; } Test& operator=(const Test&) { s_counters.copyAss++; return *this; } Test& operator=(Test&&) { s_counters.moveAss++; return *this; } static void resetCounters() { s_counters.resetCounters(); } size_t data = 0; static Counters s_counters; }; Counters Test::s_counters; #define SIMPLE_TEST(x) UTEST(x, ##x) SIMPLE_TEST(lent_ptr_ctor) { NO_ASSERT_GUARD; Test::resetCounters(); tl::lent_ptr lptr; ASSERT_EQ(lptr.get(), nullptr); ASSERT_EQ(Test::s_counters, Counters{}); } SIMPLE_TEST(lent_ptr_ctor_ptr) { NO_ASSERT_GUARD; Test::resetCounters(); tl::lendable t; tl::lent_ptr lptr(tl::lend(t)); ASSERT_EQ(lptr.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } SIMPLE_TEST(lent_ptr_copy_ctor) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lent_ptr lptr1; tl::lent_ptr lptr2(lptr1); ASSERT_EQ(lptr2.get(), nullptr); ASSERT_EQ(Test::s_counters, Counters{}); } { Test::resetCounters(); tl::lendable t; tl::lent_ptr lptr1(tl::lend(t)); tl::lent_ptr lptr2(lptr1); ASSERT_EQ(lptr1.get(), &t.get()); ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ptr_move_ctor) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lent_ptr lptr1; tl::lent_ptr lptr2(std::move(lptr1)); ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ(lptr2.get(), nullptr); ASSERT_EQ(Test::s_counters, Counters{}); } { Test::resetCounters(); tl::lendable t; tl::lent_ptr lptr1(tl::lend(t)); tl::lent_ptr lptr2(std::move(lptr1)); ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ptr_copy_ass) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lent_ptr lptr1; tl::lent_ptr lptr2; lptr2 = lptr1; ASSERT_EQ(lptr2.get(), nullptr); ASSERT_EQ(Test::s_counters, Counters{}); } { Test::resetCounters(); tl::lendable t; tl::lent_ptr lptr1(tl::lend(t)); tl::lent_ptr lptr2; lptr2 = lptr1; ASSERT_EQ(lptr1.get(), &t.get()); ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ptr_move_ass) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lent_ptr lptr1; tl::lent_ptr lptr2; lptr2 = std::move(lptr1); ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ(lptr2.get(), nullptr); ASSERT_EQ(Test::s_counters, Counters{}); } { Test::resetCounters(); tl::lendable t; tl::lent_ptr lptr1(tl::lend(t)); tl::lent_ptr lptr2; lptr2 = std::move(lptr1); ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ptr_unique_ptr) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); ASSERT_EQ(lptr1.get(), uptr.get()); ASSERT_NE((bool)lptr1, false); ASSERT_EQ(lptr1, uptr); ASSERT_EQ(lptr1, uptr.get()); ASSERT_EQ(lptr1.get(), uptr); ASSERT_EQ(lptr1->data, 1234); lptr1 = nullptr; ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ((bool)lptr1, false); ASSERT_EQ(lptr1, nullptr); } SIMPLE_TEST(lent_ptr_unique_ref) { Test::resetCounters(); tl::unique_ref uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); ASSERT_EQ(lptr1.get(), uptr.get()); ASSERT_EQ(lptr1, uptr); ASSERT_EQ(lptr1, uptr.get()); ASSERT_EQ(lptr1.get(), uptr); ASSERT_EQ(lptr1->data, 1234); lptr1 = nullptr; ASSERT_EQ(lptr1.get(), nullptr); ASSERT_EQ((bool)lptr1, false); ASSERT_EQ(lptr1, nullptr); } SIMPLE_TEST(lent_ptr_unique_ptr_no_dangling) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; lptr = nullptr; uptr = nullptr; //no dangling here! lptr = uptr; //no dangling here! } SIMPLE_TEST(lent_ptr_unique_ptr_move_no_dangling) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2; ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; uptr2 = std::move(uptr); //no dangling here! lptr = uptr2; //no dangling here! } SIMPLE_TEST(lent_ptr_unique_ptr_assign_nullptr_dangling) { { Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; tl::lent_ptr lptr2 = uptr; tl::lent_ptr lptr3 = uptr; tl::lent_ptr lptr4 = uptr; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; tl::lent_ptr lptr2 = std::move(lptr1); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { NO_ASSERT_GUARD; lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } } } SIMPLE_TEST(lent_ptr_unique_ptr_assign_new_dangling) { { Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; tl::lent_ptr lptr2 = uptr; tl::lent_ptr lptr3 = uptr; tl::lent_ptr lptr4 = uptr; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } SIMPLE_TEST(lent_ptr_unique_ptr_reset_dangling) { { Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uptr; tl::lent_ptr lptr2 = uptr; tl::lent_ptr lptr3 = uptr; tl::lent_ptr lptr4 = uptr; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } SIMPLE_TEST(lent_ptr_unique_ptr_assign_move_dangling) { { Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uptr; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); tl::unique_ptr uptr3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = std::move(uptr3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); tl::unique_ptr uptr3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ptr lptr1 = uptr1; tl::lent_ptr lptr2 = uptr2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = std::move(uptr3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uptr; tl::lent_ptr lptr2 = uptr; tl::lent_ptr lptr3 = uptr; tl::lent_ptr lptr4 = uptr; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SIMPLE_TEST(lent_ptr_unique_ref_no_dangling) { NO_ASSERT_GUARD; tl::lent_ptr lptr; { Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); lptr = uref; lptr = nullptr; } lptr = {}; //no dangling here! } SIMPLE_TEST(lent_ptr_unique_ref_move_no_dangling) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; tl::unique_ref uref2 = std::move(uref); //no dangling here! lptr = uref2; //no dangling here! lptr = nullptr; //to avoid a legit dangling when the uref2 goes out of scope } SIMPLE_TEST(lent_ptr_unique_ref_assign_nullptr_dangling) { { Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uref; tl::lent_ptr lptr2 = uref; tl::lent_ptr lptr3 = uref; tl::lent_ptr lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } SIMPLE_TEST(lent_ptr_unique_ref_reset_dangling) { { Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ptr lptr1 = uref; tl::lent_ptr lptr2 = uref; tl::lent_ptr lptr3 = uref; tl::lent_ptr lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } SIMPLE_TEST(lent_ptr_unique_ref_assign_move_dangling) { { Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = {}; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); tl::unique_ref uref3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = std::move(uref3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); tl::unique_ref uref3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ptr lptr1 = uref1; tl::lent_ptr lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = std::move(uref3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ptr lptr1 = uref; tl::lent_ptr lptr2 = uref; tl::lent_ptr lptr3 = uref; tl::lent_ptr lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = {}; //dangling here! } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SIMPLE_TEST(lent_ref_ctor_ptr) { NO_ASSERT_GUARD; Test::resetCounters(); tl::lendable t; tl::lent_ref lptr(tl::lend(t)); ASSERT_EQ(lptr.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } SIMPLE_TEST(lent_ref_copy_ctor) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lendable t; tl::lent_ref lptr1(tl::lend(t)); tl::lent_ref lptr2(lptr1); ASSERT_EQ(lptr1.get(), &t.get()); ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ref_move_ctor) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lendable t; tl::lent_ref lptr1(tl::lend(t)); tl::lent_ref lptr2(std::move(lptr1)); { EXPECTED_CRASH_GUARD("nullptr"); ASSERT_EQ(lptr1.get(), nullptr); } ASSERT_EQ(lptr2.get(), &t.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); } } SIMPLE_TEST(lent_ref_copy_ass) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lendable t1; tl::lendable t2; tl::lent_ref lptr1(tl::lend(t1)); tl::lent_ref lptr2(tl::lend(t2)); lptr2 = lptr1; ASSERT_EQ(lptr1.get(), &t1.get()); ASSERT_EQ(lptr2.get(), &t1.get()); ASSERT_EQ(t1->s_counters, Counters{.ctor = 2}); } } SIMPLE_TEST(lent_ref_move_ass) { NO_ASSERT_GUARD; { Test::resetCounters(); tl::lendable t1; tl::lendable t2; tl::lent_ref lptr1(tl::lend(t1)); tl::lent_ref lptr2(tl::lend(t2)); lptr2 = std::move(lptr1); { EXPECTED_CRASH_GUARD("nullptr"); ASSERT_EQ(lptr1.get(), nullptr); } ASSERT_EQ(lptr2.get(), &t1.get()); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); } } SIMPLE_TEST(lent_ref_unique_ptr) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ref lptr1 = tl::promote(uptr); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); ASSERT_EQ(lptr1.get(), uptr.get()); ASSERT_EQ(lptr1, uptr); ASSERT_EQ(lptr1, uptr.get()); ASSERT_EQ(lptr1.get(), uptr); ASSERT_EQ(lptr1->data, 1234); } SIMPLE_TEST(lent_ref_unique_ref) { Test::resetCounters(); tl::unique_ref uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ref lptr1 = uptr; ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); ASSERT_EQ(lptr1.get(), uptr.get()); ASSERT_EQ(lptr1, uptr); ASSERT_EQ(lptr1, uptr.get()); ASSERT_EQ(lptr1.get(), uptr); ASSERT_EQ(lptr1->data, 1234); } SIMPLE_TEST(lent_ref_unique_ptr_no_dangling) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { tl::lent_ref lptr = tl::promote(uptr); } //no dangling here! uptr = nullptr; } SIMPLE_TEST(lent_ref_unique_ptr_move_no_dangling) { NO_ASSERT_GUARD; Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2; ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lent_ref lptr = tl::promote(uptr); uptr2 = std::move(uptr); //no dangling here! lptr = tl::promote(uptr2); //no dangling here! } SIMPLE_TEST(lent_ref_unique_ptr_assign_nullptr_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr); tl::lent_ref lptr2 = tl::promote(uptr); tl::lent_ref lptr3 = tl::promote(uptr); tl::lent_ref lptr4 = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = nullptr; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } SIMPLE_TEST(lent_ref_unique_ptr_assign_new_dangling) { { Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); tl::lendable t; tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr); tl::lent_ref lptr2 = tl::promote(uptr); tl::lent_ref lptr3 = tl::promote(uptr); tl::lent_ref lptr4 = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = {}; //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } SIMPLE_TEST(lent_ref_unique_ptr_reset_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = tl::promote(uptr); tl::lent_ref lptr2 = tl::promote(uptr); tl::lent_ref lptr3 = tl::promote(uptr); tl::lent_ref lptr4 = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr.reset(); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } SIMPLE_TEST(lent_ref_unique_ptr_assign_move_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); tl::unique_ptr uptr3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = std::move(uptr3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ptr uptr1(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); tl::unique_ptr uptr3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = tl::promote(uptr1); tl::lent_ref lptr2 = tl::promote(uptr2); { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uptr1 = std::move(uptr3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ptr uptr(new Test(1234)); tl::unique_ptr uptr2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = tl::promote(uptr); tl::lent_ref lptr2 = tl::promote(uptr); tl::lent_ref lptr3 = tl::promote(uptr); tl::lent_ref lptr4 = tl::promote(uptr); { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uptr = std::move(uptr2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SIMPLE_TEST(lent_ref_unique_ref_assign_nullptr_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref; tl::lent_ref lptr2 = uref; tl::lent_ref lptr3 = uref; tl::lent_ref lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref = tl::unique_ref(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } SIMPLE_TEST(lent_ref_unique_ref_reset_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 1}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); tl::lent_ref lptr1 = uref; tl::lent_ref lptr2 = uref; tl::lent_ref lptr3 = uref; tl::lent_ref lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref.reset(new Test(1234)); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } } SIMPLE_TEST(lent_ref_unique_ref_assign_move_dangling) { { Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //destructor Test::resetCounters(); tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 2}); { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } } //dangling here! } { //reset Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to empty ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr = uref; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr = tl::lend(t); //dangling here! } } { //copy assignment to another valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); tl::unique_ref uref3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = std::move(uref3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = lptr2; //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::unique_ref uref1(new Test(1234)); tl::unique_ref uref2(new Test(1234)); tl::unique_ref uref3(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = uref1; tl::lent_ref lptr2 = uref2; { EXPECTED_ASSERT_GUARD("unique: 1 dangling lent ptrs detected"); uref1 = std::move(uref3); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr1 = std::move(lptr2); //dangling here! } } { //move assignment to a valid ptr Test::resetCounters(); tl::lendable t; tl::unique_ref uref(new Test(1234)); tl::unique_ref uref2(new Test(1234)); ASSERT_EQ(Test::s_counters, Counters{.ctor = 3}); tl::lent_ref lptr1 = uref; tl::lent_ref lptr2 = uref; tl::lent_ref lptr3 = uref; tl::lent_ref lptr4 = uref; { EXPECTED_ASSERT_GUARD("unique: 4 dangling lent ptrs detected"); uref = std::move(uref2); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 4 dangling lent ptrs detected"); lptr1 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 3 dangling lent ptrs detected"); lptr2 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 2 dangling lent ptrs detected"); lptr3 = tl::lend(t); //dangling here! } { EXPECTED_ASSERT_GUARD("lent: 1 dangling lent ptrs detected"); lptr4 = tl::lend(t); //dangling here! } } }