| TEST_CASE("construction with move", "[UniqueResource]") | TEST_CASE("construction with move", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| const Handle h{3}; | const Handle h{3}; | ||||
| const auto d = [](auto v) { m.deleter(v); }; | const auto d = [](auto v) { m.deleter(v); }; | ||||
| auto guard = sr::make_unique_resource(h, d); | |||||
| auto guard = sr::unique_resource{h, d}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||
| const auto d = [](const auto&) { m.deleter(3); }; | const auto d = [](const auto&) { m.deleter(3); }; | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| sr::unique_resource<decltype(noMove), decltype(d)> guard{noMove, d}; | |||||
| sr::unique_resource guard{noMove, d}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| }()); | }()); | ||||
| } | } | ||||
| TEST_CASE("move-construction with move", "[UniqueResource]") | TEST_CASE("move-construction with move", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto movedFrom = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto movedFrom = sr::unique_resource{Handle{3}, deleter}; | |||||
| auto guard = std::move(movedFrom); | auto guard = std::move(movedFrom); | ||||
| CHECK(guard.get() == 3); | CHECK(guard.get() == 3); | ||||
| } | } | ||||
| auto d = [](auto) { deleter(7); }; | auto d = [](auto) { deleter(7); }; | ||||
| const CopyMock copyMock; | const CopyMock copyMock; | ||||
| sr::unique_resource<CopyMock, decltype(d)> movedFrom{copyMock, d}; | |||||
| sr::unique_resource movedFrom{copyMock, d}; | |||||
| auto guard = std::move(movedFrom); | auto guard = std::move(movedFrom); | ||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||
| TEST_CASE("move assignment calls deleter", "[UniqueResource]") | TEST_CASE("move assignment calls deleter", "[UniqueResource]") | ||||
| { | { | ||||
| auto moveFrom = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto moveFrom = sr::unique_resource{Handle{3}, deleter}; | |||||
| REQUIRE_CALL(m, deleter(4)); | REQUIRE_CALL(m, deleter(4)); | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto guard = sr::make_unique_resource(Handle{4}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{4}, deleter}; | |||||
| guard = std::move(moveFrom); | guard = std::move(moveFrom); | ||||
| } | } | ||||
| } | } | ||||
| TEST_CASE("deleter called on destruction", "[UniqueResource]") | TEST_CASE("deleter called on destruction", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||
| TEST_CASE("reset calls deleter", "[UniqueResource]") | TEST_CASE("reset calls deleter", "[UniqueResource]") | ||||
| { | { | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| TEST_CASE("reset does not call deleter if released", "[UniqueResource]") | TEST_CASE("reset does not call deleter if released", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)).TIMES(0); | REQUIRE_CALL(m, deleter(3)).TIMES(0); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| guard.release(); | guard.release(); | ||||
| guard.reset(); | guard.reset(); | ||||
| } | } | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| REQUIRE_CALL(m, deleter(7)); | REQUIRE_CALL(m, deleter(7)); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| guard.reset(Handle{7}); | guard.reset(Handle{7}); | ||||
| } | } | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| REQUIRE_CALL(m, deleter(7)); | REQUIRE_CALL(m, deleter(7)); | ||||
| auto d = [](const auto& v) { deleter(v.m_handle); }; | auto d = [](const auto& v) { deleter(v.m_handle); }; | ||||
| auto guard = sr::make_unique_resource(ConditialThrowOnCopyMock{3, false}, d); | |||||
| auto guard = sr::unique_resource{ConditialThrowOnCopyMock{3, false}, d}; | |||||
| guard.reset(ConditialThrowOnCopyMock{7, true}); | guard.reset(ConditialThrowOnCopyMock{7, true}); | ||||
| } | } | ||||
| TEST_CASE("release disables deleter", "[UniqueResource]") | TEST_CASE("release disables deleter", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)).TIMES(0); | REQUIRE_CALL(m, deleter(3)).TIMES(0); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| guard.release(); | guard.release(); | ||||
| } | } | ||||
| TEST_CASE("get returns resource", "[UniqueResource]") | TEST_CASE("get returns resource", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| CHECK(guard.get() == 3); | CHECK(guard.get() == 3); | ||||
| } | } | ||||
| TEST_CASE("pointer access returns resource" "[UniqueResource]") | TEST_CASE("pointer access returns resource" "[UniqueResource]") | ||||
| { | { | ||||
| const auto p = std::make_pair(3, 4); | const auto p = std::make_pair(3, 4); | ||||
| auto guard = sr::make_unique_resource(&p, [](auto*) { }); | |||||
| auto guard = sr::unique_resource{&p, [](auto*) { }}; | |||||
| REQUIRE(guard->first == 3); | REQUIRE(guard->first == 3); | ||||
| REQUIRE(guard->second == 4); | REQUIRE(guard->second == 4); | ||||
| } | } | ||||
| TEST_CASE("pointer dereference returns resource" "[UniqueResource]") | TEST_CASE("pointer dereference returns resource" "[UniqueResource]") | ||||
| { | { | ||||
| Handle h{5}; | Handle h{5}; | ||||
| auto guard = sr::make_unique_resource(PtrHandle{&h}, [](auto*) { }); | |||||
| auto guard = sr::unique_resource{PtrHandle{&h}, [](auto*) { }}; | |||||
| REQUIRE(*guard == 5); | REQUIRE(*guard == 5); | ||||
| } | } | ||||
| TEST_CASE("deleter access", "[UniqueResource]") | TEST_CASE("deleter access", "[UniqueResource]") | ||||
| { | { | ||||
| auto guard = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{3}, deleter}; | |||||
| guard.release(); | guard.release(); | ||||
| { | { | ||||
| TEST_CASE("swap", "[UniqueResource]") | TEST_CASE("swap", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(7)); | REQUIRE_CALL(m, deleter(7)); | ||||
| auto guard1 = sr::make_unique_resource(Handle{3}, deleter); | |||||
| auto guard1 = sr::unique_resource(Handle{3}, deleter); | |||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| auto guard2 = sr::make_unique_resource(Handle{7}, deleter); | |||||
| auto guard2 = sr::unique_resource{Handle{7}, deleter}; | |||||
| guard2.swap(guard1); | guard2.swap(guard1); | ||||
| REQUIRE(guard1.get() == 7); | REQUIRE(guard1.get() == 7); | ||||
| REQUIRE(guard2.get() == 3); | REQUIRE(guard2.get() == 3); | ||||
| TEST_CASE("make unique resource", "[UniqueResource]") | TEST_CASE("make unique resource", "[UniqueResource]") | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(7)); | REQUIRE_CALL(m, deleter(7)); | ||||
| auto guard = sr::make_unique_resource(Handle{7}, deleter); | |||||
| auto guard = sr::unique_resource{Handle{7}, deleter}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||
| { | { | ||||
| REQUIRE_CALL(m, deleter(3)); | REQUIRE_CALL(m, deleter(3)); | ||||
| Handle h{3}; | Handle h{3}; | ||||
| auto guard = sr::make_unique_resource(std::ref(h), deleter); | |||||
| auto guard = sr::unique_resource{std::ref(h), deleter}; | |||||
| static_cast<void>(guard); | static_cast<void>(guard); | ||||
| } | } | ||||