33 Execution control library [exec]

33.9 Senders [exec.snd]

33.9.12 Sender adaptors [exec.adapt]

33.9.12.9 execution​::​bulk [exec.bulk]

bulk runs a task repeatedly for every index in an index space.
The name bulk denotes a pipeable sender adaptor object.
For subexpressions sndr, shape, and f, let Shape be decltype(auto(shape)).
If bulk(sndr, shape, f) is ill-formed.
Otherwise, the expression bulk(sndr, shape, f) is expression-equivalent to:
transform_sender(get-domain-early(sndr), make-sender(bulk, product-type{shape, f}, sndr)) except that sndr is evaluated only once.
The exposition-only class template impls-for ([exec.snd.general]) is specialized for bulk_t as follows: namespace std::execution { template<> struct impls-for<bulk_t> : default-impls { static constexpr auto complete = see below; }; }
The member impls-for<bulk_t>​::​complete is initialized with a callable object equivalent to the following lambda: []<class Index, class State, class Rcvr, class Tag, class... Args> (Index, State& state, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void requires see below { if constexpr (same_as<Tag, set_value_t>) { auto& [shape, f] = state; constexpr bool nothrow = noexcept(f(auto(shape), args...)); TRY-EVAL(rcvr, [&]() noexcept(nothrow) { for (decltype(auto(shape)) i = 0; i < shape; ++i) { f(auto(i), args...); } Tag()(std::move(rcvr), std::forward<Args>(args)...); }()); } else { Tag()(std::move(rcvr), std::forward<Args>(args)...); } }
The expression in the requires-clause of the lambda above is true if and only if Tag denotes a type other than set_value_t or if the expression f(auto(shape), args...) is well-formed.
Let the subexpression out_sndr denote the result of the invocation bulk(sndr, shape, f) or an object equal to such, and let the subexpression rcvr denote a receiver such that the expression connect(out_sndr, rcvr) is well-formed.
The expression connect(out_sndr, rcvr) has undefined behavior unless it creates an asynchronous operation ([exec.async.ops]) that, when started,
  • on a value completion operation, invokes f(i, args...) for every i of type Shape from 0 to shape, where args is a pack of lvalue subexpressions referring to the value completion result datums of the input sender, and
  • propagates all completion operations sent by sndr.