105 lines
2.6 KiB
C++
105 lines
2.6 KiB
C++
#include <doctest/doctest.h>
|
|
|
|
#include <memory>
|
|
|
|
#include <hdk/grid/SharedPtrWrapper.hpp>
|
|
|
|
namespace {
|
|
class IntWrapper final : public hdk::grid::SharedPtrWrapper<int> {
|
|
public:
|
|
using hdk::grid::SharedPtrWrapper<int>::DeleteFunc;
|
|
using hdk::grid::SharedPtrWrapper<int>::SharedPtr;
|
|
using hdk::grid::SharedPtrWrapper<int>::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<bool>(wrapped));
|
|
|
|
int* value = new int(11);
|
|
int deletes = 0;
|
|
IntWrapper owned(value, [&deletes](int* ptr) {
|
|
++deletes;
|
|
delete ptr;
|
|
});
|
|
|
|
CHECK(static_cast<bool>(owned));
|
|
CHECK(static_cast<int*>(owned) == value);
|
|
|
|
owned = nullptr;
|
|
CHECK_FALSE(static_cast<bool>(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<int*>(copied) == static_cast<int*>(first));
|
|
|
|
IntWrapper moved(std::move(copied));
|
|
CHECK(static_cast<int*>(moved) == static_cast<int*>(first));
|
|
|
|
IntWrapper assigned(nullptr);
|
|
assigned = first;
|
|
CHECK(static_cast<int*>(assigned) == static_cast<int*>(first));
|
|
|
|
IntWrapper moveAssigned(nullptr);
|
|
moveAssigned = std::move(assigned);
|
|
CHECK(static_cast<int*>(moveAssigned) == static_cast<int*>(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);
|
|
}
|