Files
TL/test/test_ptr.cpp
T
jeanlemotan 8297b0b45f First
2024-07-02 18:06:33 +02:00

2559 lines
74 KiB
C++

#include "stdafx.h"
#include "tl/ptr.h"
#include <compare>
// each test module could contain no more then one 'main' file with init function defined
// alternatively you could define init function yourself
#include <boost/test/unit_test.hpp>
// These are sample tests that show the different features of the framework
struct ExpectedAssertGuard
{
ExpectedAssertGuard(tl::string msg)
{
s_msgs.push_back(std::move(msg));
s_oldHandlers.push_back(tl::assert::set_handler(assertHandler));
}
~ExpectedAssertGuard()
{
tl::assert::set_handler(s_oldHandlers.back());
s_oldHandlers.pop_back();
s_msgs.pop_back();
}
private:
static tl::assert::response assertHandler(const char* condition, const char* file, int line, const char* msg)
{
BOOST_CHECK(s_msgs.back() == msg);
return tl::assert::response::CONTINUE;
}
static tl::vector<tl::string> s_msgs;
static tl::vector<tl::assert::handler> s_oldHandlers;
};
tl::vector<tl::string> ExpectedAssertGuard::s_msgs;
tl::vector<tl::assert::handler> ExpectedAssertGuard::s_oldHandlers;
struct NoAssertsGuard
{
NoAssertsGuard()
{
s_oldHandlers.push_back(tl::assert::set_handler(assertHandler));
}
~NoAssertsGuard()
{
tl::assert::set_handler(s_oldHandlers.back());
s_oldHandlers.pop_back();
}
private:
static tl::assert::response assertHandler(const char* condition, const char* file, int line, const char* msg)
{
BOOST_FAIL(tl::format("Unexpected assert: [{}] {}({}): {}", condition ? condition : "", file ? file : "", line, msg ? msg : "").c_str());
return tl::assert::response::CONTINUE;
}
static tl::vector<tl::assert::handler> s_oldHandlers;
};
tl::vector<tl::assert::handler> NoAssertsGuard::s_oldHandlers;
struct ExpectedCrashGuard
{
ExpectedCrashGuard(tl::string msg)
{
s_msgs.push_back(std::move(msg));
s_oldHandlers.push_back(tl::crash::set_handler(crashHandler));
}
~ExpectedCrashGuard()
{
tl::crash::set_handler(s_oldHandlers.back());
s_oldHandlers.pop_back();
s_msgs.pop_back();
}
private:
static tl::crash::response crashHandler(const char* file, int line, const char* msg)
{
BOOST_CHECK(s_msgs.back() == msg);
return tl::crash::response::CONTINUE;
}
static tl::vector<tl::string> s_msgs;
static tl::vector<tl::crash::handler> s_oldHandlers;
};
tl::vector<tl::string> ExpectedCrashGuard::s_msgs;
tl::vector<tl::crash::handler> ExpectedCrashGuard::s_oldHandlers;
struct NoCrashesGuard
{
NoCrashesGuard()
{
s_oldHandlers.push_back(tl::crash::set_handler(crashHandler));
}
~NoCrashesGuard()
{
tl::crash::set_handler(s_oldHandlers.back());
s_oldHandlers.pop_back();
}
private:
static tl::crash::response crashHandler(const char* file, int line, const char* msg)
{
BOOST_FAIL(tl::format("Unexpected crash: {}({}): {}", file ? file : "", line, msg ? msg : "").c_str());
return tl::crash::response::CONTINUE;
}
static tl::vector<tl::crash::handler> s_oldHandlers;
};
tl::vector<tl::crash::handler> NoCrashesGuard::s_oldHandlers;
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;
BOOST_AUTO_TEST_CASE(lent_ptr_ctor)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::lent_ptr<Test> lptr;
BOOST_CHECK(lptr.get() == nullptr);
BOOST_CHECK(Test::s_counters == Counters{});
}
BOOST_AUTO_TEST_CASE(lent_ptr_ctor_ptr)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ptr<Test> lptr(tl::lend(t));
BOOST_CHECK(lptr.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
BOOST_AUTO_TEST_CASE(lent_ptr_copy_ctor)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lent_ptr<Test> lptr1;
tl::lent_ptr<Test> lptr2(lptr1);
BOOST_CHECK(lptr2.get() == nullptr);
BOOST_CHECK(Test::s_counters == Counters{});
}
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ptr<Test> lptr1(tl::lend(t));
tl::lent_ptr<Test> lptr2(lptr1);
BOOST_CHECK(lptr1.get() == &t.get());
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_move_ctor)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lent_ptr<Test> lptr1;
tl::lent_ptr<Test> lptr2(std::move(lptr1));
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK(lptr2.get() == nullptr);
BOOST_CHECK(Test::s_counters == Counters{});
}
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ptr<Test> lptr1(tl::lend(t));
tl::lent_ptr<Test> lptr2(std::move(lptr1));
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_copy_ass)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lent_ptr<Test> lptr1;
tl::lent_ptr<Test> lptr2;
lptr2 = lptr1;
BOOST_CHECK(lptr2.get() == nullptr);
BOOST_CHECK(Test::s_counters == Counters{});
}
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ptr<Test> lptr1(tl::lend(t));
tl::lent_ptr<Test> lptr2;
lptr2 = lptr1;
BOOST_CHECK(lptr1.get() == &t.get());
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_move_ass)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lent_ptr<Test> lptr1;
tl::lent_ptr<Test> lptr2;
lptr2 = std::move(lptr1);
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK(lptr2.get() == nullptr);
BOOST_CHECK(Test::s_counters == Counters{});
}
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ptr<Test> lptr1(tl::lend(t));
tl::lent_ptr<Test> lptr2;
lptr2 = std::move(lptr1);
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
BOOST_CHECK(lptr1.get() == uptr.get());
BOOST_CHECK((bool)lptr1 != false);
BOOST_CHECK(lptr1 == uptr);
BOOST_CHECK(lptr1 == uptr.get());
BOOST_CHECK(lptr1.get() == uptr);
BOOST_CHECK(lptr1->data = 1234);
lptr1 = nullptr;
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK((bool)lptr1 == false);
BOOST_CHECK(lptr1 == nullptr);
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref)
{
Test::resetCounters();
tl::unique_ref<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
BOOST_CHECK(lptr1.get() == uptr.get());
BOOST_CHECK(lptr1 == uptr);
BOOST_CHECK(lptr1 == uptr.get());
BOOST_CHECK(lptr1.get() == uptr);
BOOST_CHECK(lptr1->data = 1234);
lptr1 = nullptr;
BOOST_CHECK(lptr1.get() == nullptr);
BOOST_CHECK((bool)lptr1 == false);
BOOST_CHECK(lptr1 == nullptr);
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_no_dangling)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
lptr = nullptr;
uptr = nullptr; //no dangling here!
lptr = uptr; //no dangling here!
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_move_no_dangling)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2;
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
uptr2 = std::move(uptr); //no dangling here!
lptr = uptr2; //no dangling here!
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_assign_nullptr_dangling)
{
{
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
tl::lent_ptr<Test> lptr2 = uptr;
tl::lent_ptr<Test> lptr3 = uptr;
tl::lent_ptr<Test> lptr4 = uptr;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
tl::lent_ptr<Test> lptr2 = std::move(lptr1);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
NoAssertsGuard eassert;
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_assign_new_dangling)
{
{
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
tl::lent_ptr<Test> lptr2 = uptr;
tl::lent_ptr<Test> lptr3 = uptr;
tl::lent_ptr<Test> lptr4 = uptr;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_reset_dangling)
{
{
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uptr;
tl::lent_ptr<Test> lptr2 = uptr;
tl::lent_ptr<Test> lptr3 = uptr;
tl::lent_ptr<Test> lptr4 = uptr;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ptr_assign_move_dangling)
{
{
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uptr;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
tl::unique_ptr<Test> uptr3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = std::move(uptr3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
tl::unique_ptr<Test> uptr3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ptr<Test> lptr1 = uptr1;
tl::lent_ptr<Test> lptr2 = uptr2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = std::move(uptr3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uptr;
tl::lent_ptr<Test> lptr2 = uptr;
tl::lent_ptr<Test> lptr3 = uptr;
tl::lent_ptr<Test> lptr4 = uptr;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref_no_dangling)
{
NoAssertsGuard eassert;
tl::lent_ptr<Test> lptr;
{
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
lptr = uref;
lptr = nullptr;
}
lptr = {}; //no dangling here!
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref_move_no_dangling)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
tl::unique_ref<Test> 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
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref_assign_nullptr_dangling)
{
{
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uref;
tl::lent_ptr<Test> lptr2 = uref;
tl::lent_ptr<Test> lptr3 = uref;
tl::lent_ptr<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref_reset_dangling)
{
{
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ptr<Test> lptr1 = uref;
tl::lent_ptr<Test> lptr2 = uref;
tl::lent_ptr<Test> lptr3 = uref;
tl::lent_ptr<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ptr_unique_ref_assign_move_dangling)
{
{
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = {}; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
tl::unique_ref<Test> uref3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = std::move(uref3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
tl::unique_ref<Test> uref3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ptr<Test> lptr1 = uref1;
tl::lent_ptr<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = std::move(uref3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ptr<Test> lptr1 = uref;
tl::lent_ptr<Test> lptr2 = uref;
tl::lent_ptr<Test> lptr3 = uref;
tl::lent_ptr<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = {}; //dangling here!
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE(lent_ref_ctor_ptr)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ref<Test> lptr(tl::lend(t));
BOOST_CHECK(lptr.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
BOOST_AUTO_TEST_CASE(lent_ref_copy_ctor)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ref<Test> lptr1(tl::lend(t));
tl::lent_ref<Test> lptr2(lptr1);
BOOST_CHECK(lptr1.get() == &t.get());
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ref_move_ctor)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lendable<Test> t;
tl::lent_ref<Test> lptr1(tl::lend(t));
tl::lent_ref<Test> lptr2(std::move(lptr1));
{
ExpectedCrashGuard ecrash("nullptr");
BOOST_CHECK(lptr1.get() == nullptr);
}
BOOST_CHECK(lptr2.get() == &t.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
}
}
BOOST_AUTO_TEST_CASE(lent_ref_copy_ass)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lendable<Test> t1;
tl::lendable<Test> t2;
tl::lent_ref<Test> lptr1(tl::lend(t1));
tl::lent_ref<Test> lptr2(tl::lend(t2));
lptr2 = lptr1;
BOOST_CHECK(lptr1.get() == &t1.get());
BOOST_CHECK(lptr2.get() == &t1.get());
BOOST_CHECK(t1->s_counters == Counters{.ctor = 2});
}
}
BOOST_AUTO_TEST_CASE(lent_ref_move_ass)
{
NoAssertsGuard eassert;
{
Test::resetCounters();
tl::lendable<Test> t1;
tl::lendable<Test> t2;
tl::lent_ref<Test> lptr1(tl::lend(t1));
tl::lent_ref<Test> lptr2(tl::lend(t2));
lptr2 = std::move(lptr1);
{
ExpectedCrashGuard ecrash("nullptr");
BOOST_CHECK(lptr1.get() == nullptr);
}
BOOST_CHECK(lptr2.get() == &t1.get());
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ref<Test> lptr1 = tl::promote(uptr);
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
BOOST_CHECK(lptr1.get() == uptr.get());
BOOST_CHECK(lptr1 == uptr);
BOOST_CHECK(lptr1 == uptr.get());
BOOST_CHECK(lptr1.get() == uptr);
BOOST_CHECK(lptr1->data = 1234);
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ref)
{
Test::resetCounters();
tl::unique_ref<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ref<Test> lptr1 = uptr;
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
BOOST_CHECK(lptr1.get() == uptr.get());
BOOST_CHECK(lptr1 == uptr);
BOOST_CHECK(lptr1 == uptr.get());
BOOST_CHECK(lptr1.get() == uptr);
BOOST_CHECK(lptr1->data = 1234);
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_no_dangling)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
tl::lent_ref<Test> lptr = tl::promote(uptr);
} //no dangling here!
uptr = nullptr;
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_move_no_dangling)
{
NoAssertsGuard eassert;
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2;
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lent_ref<Test> lptr = tl::promote(uptr);
uptr2 = std::move(uptr); //no dangling here!
lptr = tl::promote(uptr2); //no dangling here!
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_assign_nullptr_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr);
tl::lent_ref<Test> lptr2 = tl::promote(uptr);
tl::lent_ref<Test> lptr3 = tl::promote(uptr);
tl::lent_ref<Test> lptr4 = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = nullptr; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_assign_new_dangling)
{
{
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
tl::lendable<Test> t;
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr);
tl::lent_ref<Test> lptr2 = tl::promote(uptr);
tl::lent_ref<Test> lptr3 = tl::promote(uptr);
tl::lent_ref<Test> lptr4 = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = {}; //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_reset_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = tl::promote(uptr);
tl::lent_ref<Test> lptr2 = tl::promote(uptr);
tl::lent_ref<Test> lptr3 = tl::promote(uptr);
tl::lent_ref<Test> lptr4 = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr.reset(); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ptr_assign_move_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
tl::unique_ptr<Test> uptr3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = std::move(uptr3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ptr<Test> uptr1(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
tl::unique_ptr<Test> uptr3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = tl::promote(uptr1);
tl::lent_ref<Test> lptr2 = tl::promote(uptr2);
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uptr1 = std::move(uptr3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ptr<Test> uptr(new Test(1234));
tl::unique_ptr<Test> uptr2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = tl::promote(uptr);
tl::lent_ref<Test> lptr2 = tl::promote(uptr);
tl::lent_ref<Test> lptr3 = tl::promote(uptr);
tl::lent_ref<Test> lptr4 = tl::promote(uptr);
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uptr = std::move(uptr2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE(lent_ref_unique_ref_assign_nullptr_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref;
tl::lent_ref<Test> lptr2 = uref;
tl::lent_ref<Test> lptr3 = uref;
tl::lent_ref<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref = tl::unique_ref<Test>(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ref_reset_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 1});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
tl::lent_ref<Test> lptr1 = uref;
tl::lent_ref<Test> lptr2 = uref;
tl::lent_ref<Test> lptr3 = uref;
tl::lent_ref<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref.reset(new Test(1234)); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}
BOOST_AUTO_TEST_CASE(lent_ref_unique_ref_assign_move_dangling)
{
{
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//destructor
Test::resetCounters();
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 2});
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
} //dangling here!
}
{
//reset
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to empty ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr = uref;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr = tl::lend(t); //dangling here!
}
}
{
//copy assignment to another valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
tl::unique_ref<Test> uref3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = std::move(uref3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = lptr2; //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::unique_ref<Test> uref1(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
tl::unique_ref<Test> uref3(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = uref1;
tl::lent_ref<Test> lptr2 = uref2;
{
ExpectedAssertGuard eassert("unique: 1 dangling lent ptrs detected");
uref1 = std::move(uref3); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr1 = std::move(lptr2); //dangling here!
}
}
{
//move assignment to a valid ptr
Test::resetCounters();
tl::lendable<Test> t;
tl::unique_ref<Test> uref(new Test(1234));
tl::unique_ref<Test> uref2(new Test(1234));
BOOST_CHECK(Test::s_counters == Counters{.ctor = 3});
tl::lent_ref<Test> lptr1 = uref;
tl::lent_ref<Test> lptr2 = uref;
tl::lent_ref<Test> lptr3 = uref;
tl::lent_ref<Test> lptr4 = uref;
{
ExpectedAssertGuard eassert("unique: 4 dangling lent ptrs detected");
uref = std::move(uref2); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 4 dangling lent ptrs detected");
lptr1 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 3 dangling lent ptrs detected");
lptr2 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 2 dangling lent ptrs detected");
lptr3 = tl::lend(t); //dangling here!
}
{
ExpectedAssertGuard eassert("lent: 1 dangling lent ptrs detected");
lptr4 = tl::lend(t); //dangling here!
}
}
}