#include #include #include namespace { class IntWrapper final : public hdk::grid::SharedPtrWrapper { public: using hdk::grid::SharedPtrWrapper::DeleteFunc; using hdk::grid::SharedPtrWrapper::SharedPtr; using hdk::grid::SharedPtrWrapper::SharedPtrWrapper; static SharedPtr View(int* ptr) { return get_or_view(ptr); } static SharedPtr Cache(int* ptr, DeleteFunc deleteFunc) { return get_or_cache(ptr, deleteFunc); } }; } // namespace TEST_CASE("SharedPtrWrapper supports null and bool conversion") { IntWrapper wrapped(nullptr); CHECK_FALSE(static_cast(wrapped)); int* value = new int(11); int deletes = 0; IntWrapper owned(value, [&deletes](int* ptr) { ++deletes; delete ptr; }); CHECK(static_cast(owned)); CHECK(static_cast(owned) == value); owned = nullptr; CHECK_FALSE(static_cast(owned)); CHECK(deletes == 1); } TEST_CASE("SharedPtrWrapper copy and move preserve pointed object") { int deletes = 0; IntWrapper first(new int(8), [&deletes](int* ptr) { ++deletes; delete ptr; }); IntWrapper copied(first); CHECK(static_cast(copied) == static_cast(first)); IntWrapper moved(std::move(copied)); CHECK(static_cast(moved) == static_cast(first)); IntWrapper assigned(nullptr); assigned = first; CHECK(static_cast(assigned) == static_cast(first)); IntWrapper moveAssigned(nullptr); moveAssigned = std::move(assigned); CHECK(static_cast(moveAssigned) == static_cast(first)); } TEST_CASE("SharedPtrWrapper cache returns same control block") { int deletes = 0; int* raw = new int(3); auto deleter = [&deletes](int* ptr) { ++deletes; delete ptr; }; auto cachedA = IntWrapper::Cache(raw, deleter); auto cachedB = IntWrapper::Cache(raw, deleter); CHECK(cachedA.get() == raw); CHECK(cachedB.get() == raw); CHECK(cachedA.use_count() >= 2); cachedA.reset(); CHECK(deletes == 0); cachedB.reset(); CHECK(deletes == 1); } TEST_CASE("SharedPtrWrapper view wraps pointers without ownership") { int stackValue = 5; auto viewA = IntWrapper::View(&stackValue); auto viewB = IntWrapper::View(&stackValue); CHECK(viewA.get() == &stackValue); CHECK(viewB.get() == &stackValue); int deletes = 0; int* raw = new int(13); IntWrapper owner(raw, [&deletes](int* ptr) { ++deletes; delete ptr; }); auto cachedView = IntWrapper::View(raw); CHECK(cachedView.get() == raw); CHECK(cachedView.use_count() >= 2); owner = nullptr; CHECK(deletes == 0); cachedView.reset(); CHECK(deletes == 1); }