Selaa lähdekoodia

Handling of the not no-throw-constructible case of the move ctor added

to scope_exit (fixes #42, fixes #29).
main
offa 7 vuotta sitten
vanhempi
commit
9850626679
2 muutettua tiedostoa jossa 51 lisäystä ja 2 poistoa
  1. +13
    -2
      include/scope_exit.h
  2. +38
    -0
      test/ScopeExitTest.cpp

+ 13
- 2
include/scope_exit.h Näytä tiedosto

throw; throw;
} }



scope_exit(const scope_exit&) = delete; scope_exit(const scope_exit&) = delete;


template<class T = Deleter,
std::enable_if_t<std::is_nothrow_move_constructible<T>::value, int> = 0
>
scope_exit(scope_exit&& other) : m_deleter(std::move(other.m_deleter)), scope_exit(scope_exit&& other) : m_deleter(std::move(other.m_deleter)),
m_execute_on_destruction(other.m_execute_on_destruction)
m_execute_on_destruction(other.m_execute_on_destruction)
{
other.release();
}

template<class T = Deleter,
std::enable_if_t<!std::is_nothrow_move_constructible<T>::value, int> = 0
>
scope_exit(scope_exit&& other) : m_deleter(other.m_deleter),
m_execute_on_destruction(other.m_execute_on_destruction)
{ {
other.release(); other.release();
} }

+ 38
- 0
test/ScopeExitTest.cpp Näytä tiedosto

} }
}; };



struct NotNothrowMoveMock
{
NotNothrowMoveMock(CallMock* m) : m_mock(m) { }
NotNothrowMoveMock(const NotNothrowMoveMock& other) : m_mock(other.m_mock) { }
NotNothrowMoveMock(NotNothrowMoveMock&& other) noexcept(false) : m_mock(other.m_mock) { }

MAKE_CONST_MOCK0(deleter, void());

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

NotNothrowMoveMock& operator=(const NotNothrowMoveMock&)
{
throw "Not implemented";
}

NotNothrowMoveMock& operator=(NotNothrowMoveMock&&)
{
throw "Not implemented";
}

CallMock* m_mock;

};


CallMock m; CallMock m;




static_cast<void>(guard); static_cast<void>(guard);
} }


TEST_CASE("move with copy init releases moved-from object", "[ScopeExit]")
{
CallMock mock;
const NotNothrowMoveMock notNothrow{&mock};
REQUIRE_CALL(mock, deleter());
sr::scope_exit<decltype(notNothrow)> movedFrom{notNothrow};
auto guard = std::move(movedFrom);
}

TEST_CASE("move transfers state", "[ScopeExit]") TEST_CASE("move transfers state", "[ScopeExit]")
{ {
REQUIRE_CALL(m, deleter()); REQUIRE_CALL(m, deleter());

Loading…
Peruuta
Tallenna