diff --git a/docs_source/sphinx/http/server.md b/docs_source/sphinx/http/server.md index 17a3284a..4b215ff1 100644 --- a/docs_source/sphinx/http/server.md +++ b/docs_source/sphinx/http/server.md @@ -43,7 +43,7 @@ int main() // stop the thread_pool on scope exit to guarantee that all asynchronous tasks are finished before the server is // destroyed. - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; @@ -141,7 +141,7 @@ int main() // stop the thread_pool on scope exit to guarantee that all asynchronous tasks are finished before the server is // destroyed. - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; diff --git a/examples/100_continue/main.cpp b/examples/100_continue/main.cpp index 3b1ece6b..923f00f8 100644 --- a/examples/100_continue/main.cpp +++ b/examples/100_continue/main.cpp @@ -21,7 +21,7 @@ int main() // Create server. Roar::Server server{{.executor = pool.executor()}}; - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; diff --git a/examples/most_minimal/main.cpp b/examples/most_minimal/main.cpp index 4d250c89..d750798b 100644 --- a/examples/most_minimal/main.cpp +++ b/examples/most_minimal/main.cpp @@ -16,7 +16,7 @@ int main() // stop the thread_pool on scope exit to guarantee that all asynchronous tasks are finished before the server is // destroyed. - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; diff --git a/examples/serve_directory/main.cpp b/examples/serve_directory/main.cpp index c4e6a20b..abe50e9c 100644 --- a/examples/serve_directory/main.cpp +++ b/examples/serve_directory/main.cpp @@ -22,7 +22,7 @@ int main() // Create server. Roar::Server server{{.executor = pool.executor()}}; - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; diff --git a/examples/simple_server/main.cpp b/examples/simple_server/main.cpp index 62686594..ca3ef418 100644 --- a/examples/simple_server/main.cpp +++ b/examples/simple_server/main.cpp @@ -34,7 +34,7 @@ int main() .executor = pool.executor(), .onError = onAsynchronousError, }}; - const auto shutdownPool = Roar::ScopeExit{[&pool]() { + const auto shutdownPool = Roar::ScopeExit{[&pool]() noexcept { pool.stop(); pool.join(); }}; diff --git a/include/roar/utility/scope_exit.hpp b/include/roar/utility/scope_exit.hpp index 667632e4..55c8cd6a 100644 --- a/include/roar/utility/scope_exit.hpp +++ b/include/roar/utility/scope_exit.hpp @@ -1,25 +1,52 @@ #pragma once +#include + #include +#include #include +#define ROAR_SE_UNIQUE_IDENTIFIER BOOST_PP_CAT(roar_se_unique_identifier_, __COUNTER__) + namespace Roar { - template class ScopeExit { public: - ScopeExit(EF&& func) - : onExit_(std::forward(func)) + template + requires std::is_nothrow_invocable_v + explicit ScopeExit(FunctionT&& func) + : onExit_(std::forward(func)) {} ~ScopeExit() { - onExit_(); + if (onExit_) + onExit_(); + } + ScopeExit(ScopeExit&& other) = delete; + ScopeExit& operator=(ScopeExit&& other) = delete; + ScopeExit(const ScopeExit&) = delete; + ScopeExit& operator=(const ScopeExit&) = delete; + void disarm() + { + onExit_ = {}; } private: std::function onExit_; }; - template - ScopeExit(T) -> ScopeExit; + + namespace Detail + { + struct MakeScopeExitImpl + { + template + auto operator->*(FunctionT&& fn) const + { + return ScopeExit{std::forward(fn)}; + } + }; + } + +#define ROAR_ON_SCOPE_EXIT auto ROAR_SE_UNIQUE_IDENTIFIER = ::Roar::Detail::MakeScopeExitImpl{}->*[&]() noexcept } \ No newline at end of file