Parcourir la source

Move-Assignment implemented.

main
offa il y a 7 ans
Parent
révision
061d16e478
2 fichiers modifiés avec 66 ajouts et 18 suppressions
  1. +11
    -1
      include/unique_resource.h
  2. +55
    -17
      test/UniqueResourceTest.cpp

+ 11
- 1
include/unique_resource.h Voir le fichier

@@ -64,7 +64,17 @@ namespace sr
}


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;



+ 55
- 17
test/UniqueResourceTest.cpp Voir le fichier

@@ -19,6 +19,7 @@
*/

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

using Handle = int;
@@ -26,10 +27,9 @@ using Handle = int;
TEST_CASE("deleter called on destruction", "[UniqueResource]")
{
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);
}

@@ -39,10 +39,9 @@ TEST_CASE("deleter called on destruction", "[UniqueResource]")
TEST_CASE("deleter is not called if released", "[UniqueResource]")
{
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();
}

@@ -51,21 +50,18 @@ TEST_CASE("deleter is not called if released", "[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();

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

TEST_CASE("move releases moved-from object", "[UniqueResource]")
{
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);
static_cast<void>(guard);
}
@@ -76,10 +72,9 @@ TEST_CASE("move releases moved-from object", "[UniqueResource]")
TEST_CASE("move transfers state", "[UniqueResource]")
{
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);
static_cast<void>(guard);
}
@@ -90,10 +85,9 @@ TEST_CASE("move transfers state", "[UniqueResource]")
TEST_CASE("move transfers state if released", "[UniqueResource]")
{
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();
auto guard = std::move(movedFrom);
static_cast<void>(guard);
@@ -102,12 +96,56 @@ TEST_CASE("move transfers state if released", "[UniqueResource]")
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([] {
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);
}());
}

Chargement…
Annuler
Enregistrer