The member
impls-for<when_all_t>::complete
is initialized with a callable object
equivalent to the following lambda expression:
[]<class Index, class State, class Rcvr, class Set, class... Args>(
this auto& complete, Index, State& state, Rcvr& rcvr, Set, Args&&... args) noexcept -> void {
if constexpr (same_as<Set, set_error_t>) {
if (disposition::error != state.disp.exchange(disposition::error)) {
state.stop_src.request_stop();
TRY-EMPLACE-ERROR(state.errors, std::forward<Args>(args)...);
}
} else if constexpr (same_as<Set, set_stopped_t>) {
auto expected = disposition::started;
if (state.disp.compare_exchange_strong(expected, disposition::stopped)) {
state.stop_src.request_stop();
}
} else if constexpr (!same_as<decltype(State::values), tuple<>>) {
if (state.disp == disposition::started) {
auto& opt = get<Index::value>(state.values);
TRY-EMPLACE-VALUE(complete, opt, std::forward<Args>(args)...);
}
}
state.arrive(rcvr);
}
where
TRY-EMPLACE-ERROR(v, e),
for subexpressions
v and
e, is equivalent to:
try {
v.template emplace<decltype(auto(e))>(e);
} catch (...) {
v.template emplace<exception_ptr>(current_exception());
}
if the expression
decltype(auto(e))(e) is potentially throwing;
otherwise,
v.template emplace<decltype(auto(e))>(e);
and where
TRY-EMPLACE-VALUE(c, o, as...),
for subexpressions
c,
o, and pack of subexpressions
as,
is equivalent to:
try {
o.emplace(as...);
} catch (...) {
c(Index(), state, rcvr, set_error, current_exception());
return;
}
if the expression
decayed-tuple<decltype(as)...>{as...}
is potentially throwing;
otherwise,
o.emplace(as...).