Просмотр исходного кода

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

to scope_exit (fixes #42, fixes #29).
main
offa 7 лет назад
Родитель
Сommit
9850626679
2 измененных файлов: 51 добавлений и 2 удалений
  1. +13
    -2
      include/scope_exit.h
  2. +38
    -0
      test/ScopeExitTest.cpp

+ 13
- 2
include/scope_exit.h Просмотреть файл

@@ -55,11 +55,22 @@ namespace sr
throw;
}


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)),
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();
}

+ 38
- 0
test/ScopeExitTest.cpp Просмотреть файл

@@ -54,6 +54,35 @@ namespace
}
};


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;


@@ -104,6 +133,15 @@ TEST_CASE("move releases moved-from object", "[ScopeExit]")
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]")
{
REQUIRE_CALL(m, deleter());

Загрузка…
Отмена
Сохранить