Explorar el Código

LValue handling of the scope guard move ctor implemented (fixes #41).

main
offa hace 7 años
padre
commit
5e610e63e4
Se han modificado 2 ficheros con 42 adiciones y 3 borrados
  1. +8
    -3
      include/scope_guard.h
  2. +34
    -0
      test/ScopeGuardTest.cpp

+ 8
- 3
include/scope_guard.h Ver fichero

@@ -45,10 +45,15 @@ namespace sr
std::enable_if_t<std::is_constructible<Deleter, D>::value, int> = 0,
std::enable_if_t<std::is_lvalue_reference<D>::value, int> = 0
>
explicit scope_guard_t(D&& deleter) : m_deleter(deleter),
explicit scope_guard_t(D&& deleter) try : m_deleter(deleter),
m_execute_on_destruction(true)
{
}
catch( ... )
{
deleter();
throw;
}


scope_guard_t(const scope_guard_t&) = delete;
@@ -96,9 +101,9 @@ namespace sr


template<class Deleter>
scope_guard_t<Deleter> scope_guard(Deleter&& deleter) noexcept
scope_guard_t<std::decay_t<Deleter>> scope_guard(Deleter&& deleter) noexcept
{
return scope_guard_t<Deleter>{std::move(deleter)};
return scope_guard_t<std::decay_t<Deleter>>{std::forward<Deleter>(deleter)};
}

}

+ 34
- 0
test/ScopeGuardTest.cpp Ver fichero

@@ -31,8 +31,32 @@ namespace
MAKE_MOCK0(deleter, void());
};


struct ThrowOnCopyMock
{
ThrowOnCopyMock() = default;

ThrowOnCopyMock(const ThrowOnCopyMock&)
{
throw std::exception{};
}

MAKE_CONST_MOCK0(deleter, void());

void operator()() const
{
this->deleter();
}

ThrowOnCopyMock& operator=(const ThrowOnCopyMock&)
{
throw std::exception{};
}
};

CallMock m;


void deleter()
{
m.deleter();
@@ -55,6 +79,16 @@ TEST_CASE("deleter lambda called on destruction", "[ScopeGuard]")
static_cast<void>(guard);
}

TEST_CASE("deleter called and rethrow on copy exception", "[ScopeGuard]")
{
REQUIRE_THROWS([] {
const ThrowOnCopyMock noMove;
REQUIRE_CALL(noMove, deleter());

sr::scope_guard_t<decltype(noMove)> guard{noMove};
}());
}

TEST_CASE("deleter is not called if released", "[ScopeGuard]")
{
REQUIRE_CALL(m, deleter()).TIMES(0);

Cargando…
Cancelar
Guardar