open62541pp 0.16.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
async.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <functional> // invoke
4#include <future>
5#include <tuple>
6#include <type_traits>
7#include <utility> // forward, move
8
9#include "open62541pp/types.hpp" // StatusCode
10
11namespace opcua {
12
13/**
14 * @defgroup Async Asynchronous operations
15 * The asynchronous model is based on (Boost) Asio's universal model for asynchronous operations.
16 * Each async function takes a `CompletionToken` as it's last parameter.
17 * The completion token can be a callable with the signature `void(T)` or `void(T&)` where `T` is a
18 * function-specific result type.
19 *
20 * @see https://think-async.com/asio/asio-1.28.0/doc/asio/overview/model/async_ops.html
21 * @see https://think-async.com/asio/asio-1.28.0/doc/asio/overview/model/completion_tokens.html
22 * @see https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf
23 * @{
24 */
25
26template <class CompletionToken, typename T>
28 template <typename Initiation, typename CompletionHandler, typename... Args>
29 static void initiate(Initiation&& initiation, CompletionHandler&& handler, Args&&... args) {
30 static_assert(std::is_invocable_v<CompletionHandler, T> || std::is_invocable_v<CompletionHandler, T&>);
31 std::invoke(
32 std::forward<Initiation>(initiation),
33 std::forward<CompletionHandler>(handler),
34 std::forward<Args>(args)...
35 );
36 }
37};
38
39template <typename T, typename Initiation, typename CompletionToken, typename... Args>
40auto asyncInitiate(Initiation&& initiation, CompletionToken&& token, Args&&... args) {
42 std::forward<Initiation>(initiation),
43 std::forward<CompletionToken>(token),
44 std::forward<Args>(args)...
45 );
46}
47
48/* ------------------------------------------- Future ------------------------------------------- */
49
50/**
51 * Future completion token type.
52 * A completion token that causes an asynchronous operation to return a future.
53 */
55
56/**
57 * Future completion token object.
58 * @see UseFutureToken
59 */
61
62template <typename T>
64 template <typename Initiation, typename... Args>
65 static auto initiate(Initiation&& initiation, UseFutureToken /*unused*/, Args&&... args) {
66 std::promise<T> promise;
67 auto future = promise.get_future();
68 std::invoke(
69 std::forward<Initiation>(initiation),
70 [p = std::move(promise)](T& result) mutable { p.set_value(std::move(result)); },
71 std::forward<Args>(args)...
72 );
73 return future;
74 }
75};
76
77/* ------------------------------------------ Deferred ------------------------------------------ */
78
79/**
80 * Deferred completion token type.
81 * The token is used to indicate that an asynchronous operation should return a function object to
82 * lazily launch the operation.
83 */
85
86/**
87 * Deferred completion token object.
88 * @see UseDeferredToken
89 */
91
92template <typename T>
94 template <typename Initiation, typename... Args>
95 static auto initiate(Initiation&& initiation, UseDeferredToken /*unused*/, Args&&... args) {
96 return [initiation = std::forward<Initiation>(initiation),
97 argsPack = std::make_tuple(std::forward<Args>(args)...)](auto&& token) mutable {
98 return std::apply(
99 [&](auto&&... argsInner) {
100 return AsyncResult<std::decay_t<decltype(token)>, T>::initiate(
101 std::move(initiation),
102 std::forward<decltype(token)>(token),
103 std::forward<decltype(argsInner)>(argsInner)...
104 );
105 },
106 std::move(argsPack)
107 );
108 };
109 }
110};
111
112/* ------------------------------------------ Detached ------------------------------------------ */
113
114/**
115 * Detached completion token type.
116 * The token is used to indicate that an asynchronous operation is detached. That is, there is no
117 * completion handler waiting for the operation's result.
118 */
120
121/**
122 * Detached completion token object.
123 * @see UseDetachedToken
124 */
126
127template <typename T>
129 template <typename Initiation, typename... Args>
130 static auto initiate(Initiation&& initiation, UseDetachedToken /*unused*/, Args&&... args) {
131 std::invoke(
132 std::forward<Initiation>(initiation),
133 [](auto&&...) {
134 // ...
135 },
136 std::forward<Args>(args)...
137 );
138 }
139};
140
141/* ------------------------------------------ Defaults ------------------------------------------ */
142
143/**
144 * Default completion token for async operations.
145 * @see UseFutureToken
146 */
148
149/**
150 * @}
151 */
152
153} // namespace opcua
constexpr UseDetachedToken useDetached
Detached completion token object.
Definition async.hpp:125
constexpr UseDeferredToken useDeferred
Deferred completion token object.
Definition async.hpp:90
auto asyncInitiate(Initiation &&initiation, CompletionToken &&token, Args &&... args)
Definition async.hpp:40
constexpr UseFutureToken useFuture
Future completion token object.
Definition async.hpp:60
static UA_LogCategory const char va_list args
static auto initiate(Initiation &&initiation, UseDeferredToken, Args &&... args)
Definition async.hpp:95
static auto initiate(Initiation &&initiation, UseDetachedToken, Args &&... args)
Definition async.hpp:130
static auto initiate(Initiation &&initiation, UseFutureToken, Args &&... args)
Definition async.hpp:65
static void initiate(Initiation &&initiation, CompletionHandler &&handler, Args &&... args)
Definition async.hpp:29
Deferred completion token type.
Definition async.hpp:84
Detached completion token type.
Definition async.hpp:119
Future completion token type.
Definition async.hpp:54