open62541pp 0.17.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
async_transform.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <functional> // invoke
4#include <type_traits>
5#include <utility>
6
8
9namespace opcua::services::detail {
10
11template <typename CompletionHandler, typename Transform>
12auto asyncTransform(CompletionHandler&& handler, Transform&& transform) {
13 return [innerHandler = std::forward<CompletionHandler>(handler),
14 innerTransform = std::forward<Transform>(transform)](auto&& result) mutable {
15 auto transformed = std::invoke(innerTransform, std::forward<decltype(result)>(result));
16 std::invoke(innerHandler, transformed);
17 };
18}
19
20/**
21 * Special token to transform async results within the completion handler.
22 * The TransformToken wraps a transform function (object) and the original completion token.
23 */
24template <typename TransformFunction, typename CompletionToken>
25struct TransformToken {
26 TransformToken(TransformFunction&& transformFunction, CompletionToken&& completionToken)
27 : transform(std::move(transformFunction)),
28 token(std::move(completionToken)) {}
29
30 std::decay_t<TransformFunction> transform;
31 std::decay_t<CompletionToken> token;
32};
33
34template <typename TransformFunction, typename CompletionToken>
35TransformToken(TransformFunction&&, CompletionToken&&)
36 -> TransformToken<TransformFunction, CompletionToken>;
37
38} // namespace opcua::services::detail
39
40namespace opcua {
41
42template <typename TransformFunction, typename CompletionToken, typename T>
43struct AsyncResult<services::detail::TransformToken<TransformFunction, CompletionToken>, T> {
44 using Token = services::detail::TransformToken<TransformFunction, CompletionToken>;
45
46 template <typename Initiation, typename... Args>
47 static auto initiate(
48 Initiation&& initiation,
49 Token&& token, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
50 Args&&... args
51 ) {
52 using TransformResult = std::invoke_result_t<TransformFunction, T&>;
54 [innerInitiation = std::forward<Initiation>(initiation),
55 innerTransform = std::forward<Token>(token).transform](
56 auto&& handler, auto&&... innerArgs
57 ) mutable {
58 std::invoke(
59 innerInitiation,
60 services::detail::asyncTransform(
61 std::forward<decltype(handler)>(handler), std::move(innerTransform)
62 ),
63 std::forward<decltype(innerArgs)>(innerArgs)...
64 );
65 },
66 std::forward<Token>(token).token,
67 std::forward<Args>(args)...
68 );
69 }
70};
71
72} // namespace opcua
auto asyncInitiate(Initiation &&initiation, CompletionToken &&token, Args &&... args)
Definition async.hpp:40
static void initiate(Initiation &&initiation, CompletionHandler &&handler, Args &&... args)
Definition async.hpp:29