diff --git a/autotests/shared/CMakeLists.txt b/autotests/shared/CMakeLists.txt --- a/autotests/shared/CMakeLists.txt +++ b/autotests/shared/CMakeLists.txt @@ -19,3 +19,4 @@ endmacro() add_unit_test(akrangestest.cpp) +add_unit_test(akscopeguardtest.cpp) diff --git a/autotests/shared/akscopeguardtest.cpp b/autotests/shared/akscopeguardtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/shared/akscopeguardtest.cpp @@ -0,0 +1,98 @@ +/* + Copyright (C) 2019 Daniel Vrátil + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include +#include + +#include "shared/akscopeguard.h" + +using namespace Akonadi; + +class AkScopeGuardTest : public QObject +{ + Q_OBJECT + +private: + static void staticMethod() noexcept + { + Q_ASSERT(!mCalled); + mCalled = true; + } + + void regularMethod() noexcept + { + Q_ASSERT(!mCalled); + mCalled = true; + } + +private Q_SLOTS: + + void testLambda() + { + mCalled = false; + { + AkScopeGuard guard([&]() noexcept { + Q_ASSERT(!mCalled); + mCalled = true; + }); + } + QVERIFY(mCalled); + } + + void testStaticMethod() + { + mCalled = false; + { + AkScopeGuard guard(&AkScopeGuardTest::staticMethod); + } + QVERIFY(mCalled); + } + + void testBindExpr() + { + mCalled = false; + { + AkScopeGuard guard(std::bind(&AkScopeGuardTest::regularMethod, this)); + } + QVERIFY(mCalled); + } + + void testStdFunction() + { + mCalled = false; + std::function func = [&]() noexcept { + Q_ASSERT(!mCalled); + mCalled = true; + }; + { + AkScopeGuard guard(func); + } + QVERIFY(mCalled); + } + +private: + static bool mCalled; +}; + +bool AkScopeGuardTest::mCalled = false; + +QTEST_GUILESS_MAIN(AkScopeGuardTest) + +#include "akscopeguardtest.moc" + diff --git a/src/shared/akscopeguard.h b/src/shared/akscopeguard.h new file mode 100644 --- /dev/null +++ b/src/shared/akscopeguard.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2019 Daniel Vrátil + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef AKONADI_AKSCOPEGUARD_H_ +#define AKONADI_AKSCOPEGUARD_H_ + +#include +#include + +namespace Akonadi { + +class AkScopeGuard +{ +public: + template + AkScopeGuard(U &&fun) + : mFun(std::move(fun)) + {} + + AkScopeGuard(const AkScopeGuard &) = delete; + AkScopeGuard(AkScopeGuard &&) = default; + AkScopeGuard &operator=(const AkScopeGuard &) = delete; + AkScopeGuard &operator=(AkScopeGuard &&) = delete; + + ~AkScopeGuard() noexcept + { + mFun(); + } + +private: + std::function mFun; +}; + +} // namespace Akonadi + +#endif