userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
get_all.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/engine/get_all.hpp
4
/// @brief Provides engine::GetAll
5
6
#
include
<
type_traits
>
7
#
include
<
vector
>
8
9
#
include
<
userver
/
engine
/
wait_all_checked
.
hpp
>
10
#
include
<
userver
/
utils
/
meta
.
hpp
>
11
12
USERVER_NAMESPACE_BEGIN
13
14
namespace
engine {
15
16
/// @ingroup userver_concurrency
17
///
18
/// @brief Waits for the successful completion of all of the specified tasks
19
/// or the cancellation of the caller.
20
///
21
/// Effectively performs `for (auto& task : tasks) task.Get();` with a twist:
22
/// task.Get() is called in tasks completion order rather than in provided
23
/// order, thus exceptions are rethrown ASAP.
24
///
25
/// After successful return from this method the tasks are invalid,
26
/// in case of an exception being thrown some of the tasks might be invalid.
27
///
28
/// @param tasks either a single container, or a pack of future-like elements.
29
/// @returns `std::vector<Result>` or `void`, depending on the tasks result type
30
/// (which must be the same for all `tasks`).
31
/// @throws WaitInterruptedException when `current_task::IsCancelRequested()`
32
/// and no TaskCancellationBlockers are present.
33
/// @throws std::exception rethrows one of specified tasks exception, if any, in
34
/// no particular order.
35
///
36
/// @note Has overall computational complexity of O(N^2),
37
/// where N is the number of tasks.
38
/// @note Prefer engine::WaitAllChecked for tasks with a result, unless you
39
/// specifically need the results stored in a `std::vector` or when storing the
40
/// results long-term.
41
template
<
typename
... Tasks>
42
auto
GetAll
(Tasks&... tasks);
43
44
namespace
impl
{
45
46
template
<
typename
Container>
47
auto
GetAllResultsFromContainer(Container& tasks) {
48
using
Result =
decltype
(std::begin(tasks)->Get());
49
50
if
constexpr
(std::is_void_v<Result>) {
51
for
(
auto
& task : tasks) {
52
task.Get();
53
}
54
return
;
55
}
else
{
56
std::vector<Result> results;
57
results.reserve(std::size(tasks));
58
for
(
auto
& task : tasks) {
59
results.push_back(task.Get());
60
}
61
return
results;
62
}
63
}
64
65
template
<
typename
... Tasks>
66
auto
GetAllResultsFromTasks(Tasks&... tasks) {
67
using
Result =
decltype
((
void
(), ..., tasks.Get()));
68
69
if
constexpr
(std::is_void_v<Result>) {
70
static_assert
((
true
&& ... && std::is_void_v<
decltype
(tasks.Get())>));
71
(tasks.Get(), ...);
72
return
;
73
}
else
{
74
std::vector<Result> results;
75
results.reserve(
sizeof
...(tasks));
76
(results.push_back(tasks.Get()), ...);
77
return
results;
78
}
79
}
80
81
}
// namespace impl
82
83
template
<
typename
... Tasks>
84
auto
GetAll
(Tasks&... tasks) {
85
engine::WaitAllChecked(tasks...);
86
if
constexpr
(meta::impl::IsSingleRange<Tasks...>) {
87
return
impl
::GetAllResultsFromContainer(tasks...);
88
}
else
{
89
return
impl
::GetAllResultsFromTasks(tasks...);
90
}
91
}
92
93
}
// namespace engine
94
95
USERVER_NAMESPACE_END
userver
engine
get_all.hpp
Generated on
for userver by
Doxygen
1.17.0