Procházet zdrojové kódy

Move-Assignment implemented.

main
offa před 7 roky
rodič
revize
061d16e478
2 změnil soubory, kde provedl 66 přidání a 18 odebrání
  1. +11
    -1
      include/unique_resource.h
  2. +55
    -17
      test/UniqueResourceTest.cpp

+ 11
- 1
include/unique_resource.h Zobrazit soubor

} }




unique_resource_t& operator=(unique_resource_t&&) = default;
unique_resource_t& operator=(unique_resource_t&& other) noexcept
{
m_deleter();
m_resource = std::move(other.m_resource);
m_deleter = std::move(other.m_deleter);
m_execute_on_destruction = other.m_execute_on_destruction;
other.release();

return *this;
}

unique_resource_t& operator=(const unique_resource_t&) = delete; unique_resource_t& operator=(const unique_resource_t&) = delete;





+ 55
- 17
test/UniqueResourceTest.cpp Zobrazit soubor

*/ */


#include "unique_resource.h" #include "unique_resource.h"
#include <functional>
#include <catch.hpp> #include <catch.hpp>


using Handle = int; using Handle = int;
TEST_CASE("deleter called on destruction", "[UniqueResource]") TEST_CASE("deleter called on destruction", "[UniqueResource]")
{ {
std::size_t calls{0}; std::size_t calls{0};
constexpr Handle handle{3};


{ {
auto guard = sr::unique_resource(handle, [&calls] { ++calls; });
auto guard = sr::unique_resource(Handle{3}, [&calls] { ++calls; });
static_cast<void>(guard); static_cast<void>(guard);
} }


TEST_CASE("deleter is not called if released", "[UniqueResource]") TEST_CASE("deleter is not called if released", "[UniqueResource]")
{ {
std::size_t calls{0}; std::size_t calls{0};
constexpr Handle handle{3};


{ {
auto guard = sr::unique_resource(handle, [&calls] { ++calls; });
auto guard = sr::unique_resource(Handle{3}, [&calls] { ++calls; });
guard.release(); guard.release();
} }




TEST_CASE("release returns reference to resource", "[UniqueResource]") TEST_CASE("release returns reference to resource", "[UniqueResource]")
{ {
constexpr Handle handle{3};

auto guard = sr::unique_resource(handle, [] { });
auto guard = sr::unique_resource(Handle{3}, [] { });
const auto result = guard.release(); const auto result = guard.release();


REQUIRE(handle == result);
REQUIRE(3 == result);
} }


TEST_CASE("move releases moved-from object", "[UniqueResource]") TEST_CASE("move releases moved-from object", "[UniqueResource]")
{ {
std::size_t calls{0}; std::size_t calls{0};
constexpr Handle handle{3};


{ {
auto movedFrom = sr::unique_resource(handle, [&calls] { ++calls; });
auto movedFrom = sr::unique_resource(Handle{3}, [&calls] { ++calls; });
auto guard = std::move(movedFrom); auto guard = std::move(movedFrom);
static_cast<void>(guard); static_cast<void>(guard);
} }
TEST_CASE("move transfers state", "[UniqueResource]") TEST_CASE("move transfers state", "[UniqueResource]")
{ {
std::size_t calls{0}; std::size_t calls{0};
constexpr Handle handle{3};


{ {
auto movedFrom = sr::unique_resource(handle, [&calls] { ++calls; });
auto movedFrom = sr::unique_resource(Handle{3}, [&calls] { ++calls; });
auto guard = std::move(movedFrom); auto guard = std::move(movedFrom);
static_cast<void>(guard); static_cast<void>(guard);
} }
TEST_CASE("move transfers state if released", "[UniqueResource]") TEST_CASE("move transfers state if released", "[UniqueResource]")
{ {
std::size_t calls{0}; std::size_t calls{0};
constexpr Handle handle{3};


{ {
auto movedFrom = sr::unique_resource(handle, [&calls] { ++calls; });
auto movedFrom = sr::unique_resource(Handle{3}, [&calls] { ++calls; });
movedFrom.release(); movedFrom.release();
auto guard = std::move(movedFrom); auto guard = std::move(movedFrom);
static_cast<void>(guard); static_cast<void>(guard);
REQUIRE(calls == 0); REQUIRE(calls == 0);
} }


TEST_CASE("no exception propagation from deleter", "[UniqueResource]")
TEST_CASE("move assignment releases moved-from object", "[UniqueResource]")
{
std::size_t calls{0};
std::function<void()> del = [&calls] { ++calls; };

{
auto movedFrom = sr::unique_resource(Handle{3}, del);
auto guard = sr::unique_resource(Handle{3}, del);
guard = std::move(movedFrom);
static_cast<void>(guard);
}

REQUIRE(calls == 2);
}

TEST_CASE("move assignment transfers state", "[UniqueResource]")
{ {
constexpr Handle handle{3};
std::size_t calls{0};
std::function<void()> del = [&calls] { ++calls; };

{
auto movedFrom = sr::unique_resource(Handle{3}, del);
auto guard = sr::unique_resource(Handle{3}, del);
guard = std::move(movedFrom);
static_cast<void>(guard);
}


REQUIRE(calls == 2);
}

TEST_CASE("move assignment transfers state if released", "[UniqueResource]")
{
std::size_t calls{0};
std::function<void()> del = [&calls] { ++calls; };

{
auto movedFrom = sr::unique_resource(Handle{3}, del);
movedFrom.release();
auto guard = sr::unique_resource(Handle{3}, del);
guard = std::move(movedFrom);
static_cast<void>(guard);
}

REQUIRE(calls == 1);
}

TEST_CASE("no exception propagation from deleter", "[UniqueResource]")
{
REQUIRE_NOTHROW([] { REQUIRE_NOTHROW([] {
auto guard = sr::unique_resource(handle, [] { throw "Don't propagate this!"; });
auto guard = sr::unique_resource(Handle{3}, [] { throw "Don't propagate this!"; });
static_cast<void>(guard); static_cast<void>(guard);
}()); }());
} }

Načítá se…
Zrušit
Uložit