From 7c00dc1860ac5c05c3a9d7c3baae832af6b9e420 Mon Sep 17 00:00:00 2001 From: sha512sum Date: Wed, 3 Jul 2024 17:58:27 +0000 Subject: [PATCH] Add clang-tidy, clang-format and fixes --- .clang-format | 13 + .clang-tidy | 1 + include/cserver/clients/http/component.hpp | 52 +-- include/cserver/clients/http/request.hpp | 38 +-- include/cserver/clients/http/response.hpp | 24 +- include/cserver/components/cli/manager.hpp | 24 +- include/cserver/components/cli/struct.hpp | 49 ++- .../components/loggable_component_base.hpp | 29 +- include/cserver/components/logger.hpp | 25 +- include/cserver/components/work_guard.hpp | 6 +- .../cserver/engine/basic/task_processor.hpp | 13 +- include/cserver/engine/components.hpp | 309 ++++++++---------- include/cserver/engine/coroutine.hpp | 125 ++++--- include/cserver/engine/network.hpp | 80 +++-- include/cserver/engine/not_implemented.hpp | 2 +- include/cserver/engine/use_streaming.hpp | 2 +- .../server/handlers/http_handler_base.hpp | 34 +- include/cserver/server/http/http_request.hpp | 9 +- .../server/http/http_request_parser.hpp | 21 +- include/cserver/server/http/http_response.hpp | 9 +- include/cserver/server/http/http_stream.hpp | 21 +- include/cserver/server/server/server.hpp | 72 ++-- 22 files changed, 459 insertions(+), 499 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6a358db --- /dev/null +++ b/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: Google +IndentWidth: 2 +ColumnLimit: 140 +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +BreakConstructorInitializers: AfterColon +AlwaysBreakAfterReturnType: None +SpaceBeforeParens: Never +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: Empty +BinPackArguments: false +BinPackParameters: false +AlwaysBreakTemplateDeclarations: true diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..1d4ba70 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +Checks: '-*,google-*,cppcoreguidelines-*,-cppcoreguidelines-c-copy-assignment-signature,-cppcoreguidelines-special-member-functions,-cppcoreguidelines-avoid-const-or-ref-data-members,modernize-*' diff --git a/include/cserver/clients/http/component.hpp b/include/cserver/clients/http/component.hpp index 30858f7..d8e99e0 100644 --- a/include/cserver/clients/http/component.hpp +++ b/include/cserver/clients/http/component.hpp @@ -1,12 +1,11 @@ #pragma once +#include +#include #include #include #include #include -#include #include -#include -#include #include namespace cserver::server::http { @@ -16,9 +15,8 @@ inline constexpr auto ParseHttpHeader(std::string header) -> std::pair struct HttpClient { @@ -30,20 +28,20 @@ struct HttpClient { return clients::http::Request{*this}; }; inline constexpr HttpClient(auto, auto& context) : - taskProcessor(context.template FindComponent<"basicTaskProcessor">()), - ctx(boost::asio::ssl::context::method::sslv23_client), - resolver(this->taskProcessor.ioContext) {} - + taskProcessor(context.template FindComponent<"basicTaskProcessor">()), + ctx(boost::asio::ssl::context::method::sslv23_client), + resolver(this->taskProcessor.ioContext) {}; + template - static consteval auto Adder(const T& context) { + static consteval auto Adder(const T& context) { using Type = std::remove_cvref_t())>; return context.TransformComponents( - [&](const ComponentConfig, Options>&) -> ComponentConfig, Options> { - return {}; - }); + [&](const ComponentConfig, Options>&) -> ComponentConfig, Options> { + return {}; + }); }; -private: + private: template static consteval auto GetPerformReturnType(Flags...) { constexpr auto kUseStreaming = utempl::Find(utempl::kTypeList) != sizeof...(Flags); @@ -54,7 +52,7 @@ private: } else { return [] -> server::http::HttpResponse { std::unreachable(); - }(); + }(); }; }; template @@ -76,14 +74,18 @@ private: inline auto ReadBody(Socket&& socket, std::size_t length, auto&&...) const -> cserver::Task { std::string response; response.reserve(length); - co_await boost::asio::async_read(socket, boost::asio::dynamic_buffer(response), boost::asio::transfer_at_least(length), boost::asio::use_awaitable); + co_await boost::asio::async_read( + socket, boost::asio::dynamic_buffer(response), boost::asio::transfer_at_least(length), boost::asio::use_awaitable); co_return response; }; template inline auto ReadBody(Socket&& socket, auto&&...) const -> cserver::Task { std::string response; for(;;) { - auto [ec, n] = co_await boost::asio::async_read(socket, boost::asio::dynamic_buffer(response), boost::asio::transfer_at_least(1), boost::asio::as_tuple(boost::asio::use_awaitable)); + auto [ec, n] = co_await boost::asio::async_read(socket, + boost::asio::dynamic_buffer(response), + boost::asio::transfer_at_least(1), + boost::asio::as_tuple(boost::asio::use_awaitable)); if(ec && ec == boost::asio::error::eof) { break; }; @@ -93,19 +95,23 @@ private: }; co_return response; }; -public: + + public: template - inline auto PerformRequest(T&& request, Flags... flags) -> cserver::TaskGetPerformReturnType>(flags...))> { + inline auto PerformRequest(T&& request, Flags... flags) + -> cserver::TaskGetPerformReturnType>(flags...))> { constexpr bool kUseStreaming = utempl::Find(utempl::kTypeList) != sizeof...(Flags); boost::asio::ssl::stream socket(this->taskProcessor.ioContext, this->ctx); - boost::asio::ip::tcp::resolver::iterator endpoint = - co_await this->resolver.async_resolve({request.request.url.host(), request.request.url.has_port() ? request.request.url.port() : request.request.url.scheme()}, boost::asio::use_awaitable); + boost::asio::ip::tcp::resolver::iterator endpoint = co_await this->resolver.async_resolve( + {request.request.url.host(), request.request.url.has_port() ? request.request.url.port() : request.request.url.scheme()}, + boost::asio::use_awaitable); co_await boost::asio::async_connect(socket.lowest_layer(), endpoint, boost::asio::use_awaitable); co_await socket.async_handshake(boost::asio::ssl::stream_base::client, boost::asio::use_awaitable); std::string req(request.request.ToString()); - co_await boost::asio::async_write(socket, boost::asio::buffer(req.data(), req.size()), boost::asio::transfer_all(), boost::asio::use_awaitable); + co_await boost::asio::async_write( + socket, boost::asio::buffer(req.data(), req.size()), boost::asio::transfer_all(), boost::asio::use_awaitable); auto response = co_await this->ReadHeaders(socket, flags...); if constexpr(kUseStreaming) { co_return clients::http::Response, decltype(socket)>{*this, std::move(socket), std::move(response)}; @@ -120,4 +126,4 @@ public: }; }; -} // namespace cserver::clients::http +} // namespace cserver::components diff --git a/include/cserver/clients/http/request.hpp b/include/cserver/clients/http/request.hpp index 51319d1..290fd70 100644 --- a/include/cserver/clients/http/request.hpp +++ b/include/cserver/clients/http/request.hpp @@ -1,69 +1,67 @@ #pragma once +#include #include #include -#include namespace cserver::clients::http { template struct Request { HttpClient& client; server::http::HttpRequest request; - Request(HttpClient& client) : - client(client) { + explicit Request(HttpClient& client) : client(client) { this->AddHeader("User-Agent", "cserver/1"); }; - inline constexpr auto Post(this auto&& self) -> decltype(auto) { + constexpr auto Post(this auto&& self) -> decltype(auto) { self.request.method = "POST"; return self; }; - inline constexpr auto Get(this auto&& self) -> decltype(auto) { + constexpr auto Get(this auto&& self) -> decltype(auto) { self.request.method = "GET"; return self; }; - inline constexpr auto Put(this auto&& self) -> decltype(auto) { + constexpr auto Put(this auto&& self) -> decltype(auto) { self.request.method = "PUT"; return self; }; - inline constexpr auto SetCustomMethod(this auto&& self, std::string method) -> decltype(auto) { + constexpr auto SetCustomMethod(this auto&& self, std::string method) -> decltype(auto) { self.request.method = std::move(method); return self; }; - inline constexpr auto AddHeader(this auto&& self, std::string first, std::string second) -> decltype(auto) { + constexpr auto AddHeader(this auto&& self, std::string first, std::string second) -> decltype(auto) { self.request.headers.emplace(std::move(first), std::move(second)); return self; }; template - inline constexpr auto AddHeaderIfNotExists(this Self&& self, - std::string check, - std::string first, - std::string second) -> decltype(auto) { + constexpr auto AddHeaderIfNotExists(this Self&& self, std::string check, std::string first, std::string second) -> decltype(auto) { if(!self.request.headers.contains(std::move(check))) { return std::forward(self).AddHeader(std::move(first), std::move(second)); }; return self; }; template - inline constexpr auto Url(this Self&& self, - std::string url) -> auto&& { + constexpr auto Url(this Self&& self, std::string url) -> auto&& { self.request.url = boost::urls::url{std::move(url)}; auto authority = self.request.url.authority(); return std::forward(self).AddHeader("Host", std::string{authority.data(), authority.size()}); }; - inline constexpr auto Data(this auto&& self, std::string data) -> decltype(auto) { + constexpr auto Data(this auto&& self, std::string data) -> decltype(auto) { self.request.body = std::move(data); return self; }; - inline constexpr auto ToString() const -> std::string { + [[nodiscard]] constexpr auto ToString() const -> std::string { return this->request.ToString(); }; template inline auto Perform(this Self&& self, Flags&&... flags) - -> decltype(self.client.PerformRequest(std::forward(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(self.request.body.size())), std::forward(flags)...)) { + -> decltype(self.client.PerformRequest( + std::forward(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(self.request.body.size())), + std::forward(flags)...)) { HttpClient& client = self.client; std::string size = std::to_string(self.request.body.size()); - co_return co_await client.PerformRequest(std::forward(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::move(size)), std::forward(flags)...); + co_return co_await client.PerformRequest( + std::forward(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::move(size)), + std::forward(flags)...); }; - }; -}; +} // namespace cserver::clients::http diff --git a/include/cserver/clients/http/response.hpp b/include/cserver/clients/http/response.hpp index 3bbc07a..68fb1e8 100644 --- a/include/cserver/clients/http/response.hpp +++ b/include/cserver/clients/http/response.hpp @@ -1,7 +1,7 @@ #pragma once -#include -#include #include +#include +#include namespace cserver::clients::http { @@ -10,10 +10,12 @@ class Response : public server::http::HttpResponse { HttpClient& client; Socket socket; -public: + public: inline auto ReadChunk() -> cserver::Task { - this->body.resize(4479); - auto [ec, n] = co_await this->socket.async_read_some(boost::asio::buffer(this->body.data(), 4479), boost::asio::as_tuple(boost::asio::use_awaitable)); + this->body.resize(4479); // NOLINT + + auto [ec, n] = co_await this->socket.async_read_some(boost::asio::buffer(this->body.data(), 4479), // NOLINT + boost::asio::as_tuple(boost::asio::use_awaitable)); if(ec == boost::asio::error::eof || ec == boost::asio::error::operation_aborted || ec == boost::asio::ssl::error::stream_truncated) { co_return false; }; @@ -23,12 +25,10 @@ public: this->body.resize(n); co_return true; }; - inline constexpr Response(Response&&) = default; - inline constexpr Response(const Response&) = default; - inline constexpr Response(HttpClient& client, Socket socket, server::http::HttpResponse response) : - client(client), - socket(std::move(socket)), - HttpResponse(std::move(response)) {}; + constexpr Response(Response&&) = default; + constexpr Response(const Response&) = default; + inline Response(HttpClient& client, Socket socket, server::http::HttpResponse response) : + client(client), socket(std::move(socket)), HttpResponse(std::move(response)) {}; }; -} // namespace cserver::clients::http +} // namespace cserver::clients::http diff --git a/include/cserver/components/cli/manager.hpp b/include/cserver/components/cli/manager.hpp index 7a96db5..7680d63 100644 --- a/include/cserver/components/cli/manager.hpp +++ b/include/cserver/components/cli/manager.hpp @@ -1,10 +1,10 @@ #pragma once -#include -#include -#include #include -#include +#include +#include #include +#include +#include namespace cserver::cli { @@ -22,25 +22,19 @@ struct StructConfig { static constexpr auto kValue = utempl::Tuple{Configs...}; }; - - - template -consteval auto CreateOptionConfig(utempl::ConstexprString name, - utempl::ConstexprString description) -> OptionConfig { +consteval auto CreateOptionConfig(utempl::ConstexprString name, utempl::ConstexprString description) -> OptionConfig { return {name, description}; }; - - template struct Manager { boost::program_options::variables_map variableMap; static constexpr utempl::ConstexprString kName = "cliManager"; - constexpr Manager(auto& context) { + explicit constexpr Manager(auto& context) { boost::program_options::options_description general("General options"); - general.add_options() - ("help,h", "Show help"); + general.add_options()("help,h", "Show help"); + // clang-format off ([&]{ using Current = decltype(Configs)::Type; boost::program_options::options_description desc(fmt::format("{} options", @@ -48,7 +42,6 @@ struct Manager { utempl::Unpack(utempl::PackConstexprWrapper(), [&](auto... vs) { auto&& add = desc.add_options(); ([&]{ - //static_assert((std::ignore = utempl::kWrapper<*vs>, false)); if constexpr((*vs).description.size() == 0) { add((*vs).name.data.begin(), boost::program_options::value()); @@ -61,6 +54,7 @@ struct Manager { }); general.add(desc); }(), ...); + // clang-format-on boost::program_options::store(boost::program_options::parse_command_line(context.argc, context.argv, general), this->variableMap); boost::program_options::notify(this->variableMap); if(this->variableMap.count("help")) { diff --git a/include/cserver/components/cli/struct.hpp b/include/cserver/components/cli/struct.hpp index e1b5212..5f961d3 100644 --- a/include/cserver/components/cli/struct.hpp +++ b/include/cserver/components/cli/struct.hpp @@ -1,9 +1,9 @@ #pragma once -#include -#include -#include -#include #include +#include +#include +#include +#include namespace cserver::cli { @@ -17,32 +17,28 @@ struct Description { static constexpr utempl::ConstexprString kValue = Value; }; - template struct IsNameM { static constexpr bool value = utempl::Overloaded( - [](utempl::TypeList>) { - return true; - }, - [](auto) {return false;} - )(utempl::kType); + [](utempl::TypeList>) { + return true; + }, + [](auto) { + return false; + })(utempl::kType); }; template struct IsDescriptionM { static constexpr bool value = utempl::Overloaded( - [](utempl::TypeList>) { - return true; - }, - [](auto) {return false;} - )(utempl::kType); + [](utempl::TypeList>) { + return true; + }, + [](auto) { + return false; + })(utempl::kType); }; - - - - - template struct Struct : T { static constexpr utempl::ConstexprString kCliManagerName = "cliManager"; @@ -61,23 +57,18 @@ struct Struct : T { }; }; - static consteval auto GetConfig() { static constexpr auto names = boost::pfr::names_as_array(); return [&](auto... is) { return StructConfig(std::declval()))>>( - GetFirstOrDefault(utempl::ConstexprString(names[is].data())), - GetFirstOrDefault(utempl::ConstexprString<0>{})); + GetFirstOrDefault(utempl::ConstexprString(names[is].data())), + GetFirstOrDefault(utempl::ConstexprString<0>{})); }()...>{}; } | utempl::kSeq>; }; - - constexpr Struct(auto& context) : - T(context.template FindComponent().template Get()) {}; - - + explicit constexpr Struct(auto& context) : T(context.template FindComponent().template Get()) {}; template static consteval auto CliStructAdder(const auto& context) { @@ -96,4 +87,4 @@ struct StructWithAdder : Struct { }; }; -} // namespace cserver::cli +} // namespace cserver::cli diff --git a/include/cserver/components/loggable_component_base.hpp b/include/cserver/components/loggable_component_base.hpp index 93d3569..10d3e42 100644 --- a/include/cserver/components/loggable_component_base.hpp +++ b/include/cserver/components/loggable_component_base.hpp @@ -7,18 +7,23 @@ namespace cserver { struct ComponentBase { Logging& logging; template - constexpr ComponentBase(T& context) : - logging(context.template FindComponent<"logging">()) {}; + explicit constexpr ComponentBase(T& context) : logging(context.template FindComponent<"logging">()){}; }; +#define LOG_TRACE \ + if(this->logging.level == ::cserver::LoggingLevel::kTrace) \ + this->logging.Trace +#define LOG_DEBUG \ + if(this->logging.level <= ::cserver::LoggingLevel::kDebug) \ + this->logging.Debug +#define LOG_INFO \ + if(this->logging.level <= ::cserver::LoggingLevel::kInfo) \ + this->logging.Info +#define LOG_WARNING \ + if(this->logging.level <= ::cserver::LoggingLevel::kWarning) \ + this->logging.Warning +#define LOG_ERROR \ + if(this->logging.level <= ::cserver::LoggingLevel::kError) \ + this->logging.Error -#define LOG_TRACE if(this->logging.level == ::cserver::LoggingLevel::kTrace) this->logging.Trace -#define LOG_DEBUG if(this->logging.level <= ::cserver::LoggingLevel::kDebug) this->logging.Debug -#define LOG_INFO if(this->logging.level <= ::cserver::LoggingLevel::kInfo) this->logging.Info -#define LOG_WARNING if(this->logging.level <= ::cserver::LoggingLevel::kWarning) this->logging.Warning -#define LOG_ERROR if(this->logging.level <= ::cserver::LoggingLevel::kError) this->logging.Error - - - - -} // namespace cserver +} // namespace cserver diff --git a/include/cserver/components/logger.hpp b/include/cserver/components/logger.hpp index 03f0c7b..d270a65 100644 --- a/include/cserver/components/logger.hpp +++ b/include/cserver/components/logger.hpp @@ -1,26 +1,20 @@ #pragma once -#include -#include #include #include + +#include #include +#include namespace cserver { - -enum class LoggingLevel { - kTrace, - kDebug, - kInfo, - kWarning, - kError -}; +enum class LoggingLevel { kTrace, kDebug, kInfo, kWarning, kError }; struct Logging { static constexpr utempl::ConstexprString kName = "logging"; LoggingLevel level; template - constexpr Logging(T&) : level(T::kConfig.template Get().template Get<"level">()) { + explicit constexpr Logging(T&) : level(T::kConfig.template Get().template Get<"level">()) { std::ios::sync_with_stdio(false); }; @@ -28,13 +22,12 @@ struct Logging { this->level = level; }; - template static consteval auto GetFormatStringFor(utempl::ConstexprString fmt, utempl::ConstexprString level) { constexpr auto f = FMT_COMPILE("[{}]: {}\n"); constexpr auto size = N + NN + 6; - char data[size]{}; - fmt::format_to(data, f, static_cast(level), static_cast(fmt)); + std::array data{}; + fmt::format_to(data.begin(), f, static_cast(level), static_cast(fmt)); return utempl::ConstexprString(data); }; @@ -42,7 +35,6 @@ struct Logging { std::cout << data; }; - template constexpr auto Debug(Ts&&... args) { static constexpr auto fmt = GetFormatStringFor(Fmt, utempl::ConstexprString{"DEBUG"}); @@ -74,5 +66,4 @@ struct Logging { }; }; - -} // namespace cserver +} // namespace cserver diff --git a/include/cserver/components/work_guard.hpp b/include/cserver/components/work_guard.hpp index 6325c7d..79936a6 100644 --- a/include/cserver/components/work_guard.hpp +++ b/include/cserver/components/work_guard.hpp @@ -3,11 +3,9 @@ namespace cserver { - struct StopBlocker { boost::asio::io_context::work guard; - inline constexpr StopBlocker(auto& context) : - guard(context.template FindComponent().ioContext) {}; + explicit constexpr StopBlocker(auto& context) : guard(context.template FindComponent().ioContext) {}; }; -} // namespace cserver +} // namespace cserver diff --git a/include/cserver/engine/basic/task_processor.hpp b/include/cserver/engine/basic/task_processor.hpp index c19864d..6ec9eb5 100644 --- a/include/cserver/engine/basic/task_processor.hpp +++ b/include/cserver/engine/basic/task_processor.hpp @@ -1,19 +1,16 @@ #pragma once -#include #include #include +#include namespace cserver::engine::basic { template struct TaskProcessor { boost::asio::io_context ioContext; - std::array, Size> pool; + std::array, Size> pool{}; static constexpr utempl::ConstexprString kName = "basicTaskProcessor"; - inline constexpr TaskProcessor(auto, auto&) : - ioContext{}, - pool{} { - }; + inline constexpr TaskProcessor(auto, auto&) : ioContext{} {}; inline ~TaskProcessor() { for(auto& thread : this->pool) { @@ -28,7 +25,7 @@ struct TaskProcessor { if(this->ioContext.stopped()) { return; }; - thread = std::thread([&]{ + thread = std::thread([&] { if(this->ioContext.stopped()) { return; }; @@ -38,4 +35,4 @@ struct TaskProcessor { }; }; -} +} // namespace cserver::engine::basic diff --git a/include/cserver/engine/components.hpp b/include/cserver/engine/components.hpp index 9de8b8d..0ae291e 100644 --- a/include/cserver/engine/components.hpp +++ b/include/cserver/engine/components.hpp @@ -1,10 +1,11 @@ #pragma once +#include + +#include #include #include -#include #include -#include -#include +#include namespace cserver { @@ -29,34 +30,32 @@ struct NamedValue { }; template -using GetTypeFromComponentConfig = decltype( - [](const ComponentConfig&) -> TT { - }(std::declval())); +using GetTypeFromComponentConfig = decltype([]( + const ComponentConfig&) -> TT {}(std::declval())); template -inline constexpr utempl::ConstexprString kNameFromComponentConfig = - decltype([](const ComponentConfig&) { - return utempl::Wrapper{}; - }(std::declval()))::kValue; +inline constexpr utempl::ConstexprString kNameFromComponentConfig = + decltype([](const ComponentConfig&) { + return utempl::Wrapper{}; + }(std::declval()))::kValue; template inline constexpr auto TransformIfOk(T&& value, auto&& f) { - if constexpr(requires{f(std::forward(value));}) { + if constexpr(requires { f(std::forward(value)); }) { return f(std::forward(value)); } else { return value; }; }; - -} // namespace impl +} // namespace impl template struct ConstexprConfig { utempl::Tuple data; template inline constexpr auto Get() const -> auto { - return [&](const ConstexprConfig...>&){ + return [&](const ConstexprConfig...>&) { constexpr auto list = utempl::TypeList...>{}; constexpr std::size_t I = Find>(list); if constexpr(I < sizeof...(Ts)) { @@ -81,30 +80,30 @@ inline constexpr auto GetInitFlagFor(auto&... args) -> InitFlag& { template constexpr auto TransformDependencyGraphToTupleWithDependenciesToInitedFlagChanges(auto&&... args) { return utempl::Map(utempl::PackConstexprWrapper(), [&](utempl::Wrapper) { - return utempl::Map(utempl::PackConstexprWrapper>(), [&](auto elem) { - return &GetInitFlagFor(elem)>(args...); - }, utempl::kType>); + return utempl::Map( + utempl::PackConstexprWrapper>(), + [&](auto elem) { + return &GetInitFlagFor(elem)>(args...); + }, + utempl::kType>); }); }; struct AsyncConditionVariable { - inline AsyncConditionVariable(boost::asio::io_context& ioContext) : - mtx{}, - deadlineTimer(ioContext), - flag{} {}; + explicit inline AsyncConditionVariable(boost::asio::io_context& ioContext) : mtx{}, deadlineTimer(ioContext) {}; template > inline auto AsyncWait(Token&& token = {}) -> Task<> { - return boost::asio::async_initiate< - Token, - void(void)>([this](Handler&& handler) -> void { - std::unique_lock lc(this->mtx); - if(this->flag) { - return handler(); - }; - this->deadlineTimer.async_wait([h = std::make_unique(std::forward(handler))](const boost::system::error_code&){ - return (*h)(); - }); - }, token); + return boost::asio::async_initiate( + [this](Handler&& handler) -> void { + std::unique_lock lc(this->mtx); + if(this->flag) { + return handler(); + }; + this->deadlineTimer.async_wait([h = std::make_unique(std::forward(handler))](const boost::system::error_code&) { + return (*h)(); + }); + }, + token); }; inline auto Wait() -> void { this->deadlineTimer.wait(); @@ -120,7 +119,7 @@ struct AsyncConditionVariable { }; std::mutex mtx; boost::asio::deadline_timer deadlineTimer; - bool flag; + bool flag{}; }; template @@ -136,8 +135,8 @@ struct ServiceContextForComponent { }; template - constexpr auto FindComponent() -> auto& - requires (Name == kBasicTaskProcessorName || requires {this->FindComponent();}) { + constexpr auto FindComponent() -> auto& requires(Name == kBasicTaskProcessorName || + requires { this->FindComponent(); }) { if constexpr(Name == kBasicTaskProcessorName) { return this->context.taskProcessor; } else { @@ -155,7 +154,7 @@ struct ServiceContextForComponent { }; template