| && std::is_nothrow_move_constructible_v<D>) | && std::is_nothrow_move_constructible_v<D>) | ||||
| : resource(std::move_if_noexcept(other.resource.get()), scope_exit{[] { }}), | : resource(std::move_if_noexcept(other.resource.get()), scope_exit{[] { }}), | ||||
| deleter(std::move_if_noexcept(other.deleter.get()), scope_exit{[&other] { | deleter(std::move_if_noexcept(other.deleter.get()), scope_exit{[&other] { | ||||
| other.get_deleter()(other.resource.get()); | |||||
| if( other.execute_on_reset == true ) | |||||
| { | |||||
| other.get_deleter()(other.resource.get()); | |||||
| } | |||||
| other.release(); }}), | other.release(); }}), | ||||
| execute_on_reset(std::exchange(other.execute_on_reset, false)) | execute_on_reset(std::exchange(other.execute_on_reset, false)) | ||||
| { | { |
| CopyMock(const CopyMock&) { } | CopyMock(const CopyMock&) { } | ||||
| }; | }; | ||||
| struct ConditionalThrowOnCopyDeleter | |||||
| { | |||||
| ConditionalThrowOnCopyDeleter() { } | |||||
| ConditionalThrowOnCopyDeleter(const ConditionalThrowOnCopyDeleter&) | |||||
| { | |||||
| if( throwOnNextCopy == true ) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| throwOnNextCopy = false; | |||||
| } | |||||
| MAKE_CONST_MOCK1(deleter, void(Handle)); | |||||
| void operator()(Handle h) const | |||||
| { | |||||
| this->deleter(h); | |||||
| } | |||||
| static inline bool throwOnNextCopy{false}; | |||||
| }; | |||||
| } | } | ||||
| [[maybe_unused]] auto guard = std::move(movedFrom); | [[maybe_unused]] auto guard = std::move(movedFrom); | ||||
| } | } | ||||
| TEST_CASE("move-construction prevents double release", "[UniqueResource]") | |||||
| { | |||||
| auto movedFrom = sr::unique_resource{Handle{3}, ConditionalThrowOnCopyDeleter{}}; | |||||
| movedFrom.release(); | |||||
| ConditionalThrowOnCopyDeleter::throwOnNextCopy = true; | |||||
| REQUIRE_THROWS([&movedFrom] { [[maybe_unused]] auto guard = std::move(movedFrom); }()); | |||||
| } | |||||
| TEST_CASE("move assignment calls deleter", "[UniqueResource]") | TEST_CASE("move assignment calls deleter", "[UniqueResource]") | ||||
| { | { | ||||
| auto moveFrom = sr::unique_resource{Handle{3}, deleter}; | auto moveFrom = sr::unique_resource{Handle{3}, deleter}; |