2323
2424namespace experimental ::execution
2525{
26+ struct fork_join_t ;
27+
2628 struct PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE
2729 {};
2830
29- struct fork_join_impl_t
31+ struct INVALID_ARGUMENTS_TO_FORK_JOIN
32+ {};
33+
34+ namespace _fork_join
3035 {
3136 struct _mk_when_all_fn
3237 {
@@ -51,6 +56,10 @@ namespace experimental::execution
5156 }
5257 };
5358
59+ template <>
60+ struct _env_t <STDEXEC::indeterminate_domain<>>
61+ {};
62+
5463 template <class Tag , class ... Args>
5564 using _cref_sig_t = Tag(Args const &...);
5665
@@ -94,7 +103,8 @@ namespace experimental::execution
94103 return _opstate_t <Rcvr>{static_cast <Rcvr&&>(rcvr), _results_};
95104 }
96105
97- STDEXEC_ATTRIBUTE (host, device) static constexpr auto get_env () noexcept -> _env_t<Domain>
106+ STDEXEC_ATTRIBUTE (host, device)
107+ static constexpr auto get_env () noexcept -> _env_t<Domain>
98108 {
99109 return {};
100110 }
@@ -116,13 +126,12 @@ namespace experimental::execution
116126 using _child_completions_t = STDEXEC::__completion_signatures_of_t <Sndr, _env_t >;
117127 using _domain_t = STDEXEC::__completion_domain_of_t <STDEXEC::set_value_t , Sndr, _env_t >;
118128 using _when_all_sndr_t =
119- fork_join_impl_t ::_when_all_sndr_t <_child_completions_t , Closures, _domain_t >;
129+ _fork_join ::_when_all_sndr_t <_child_completions_t , Closures, _domain_t >;
120130 using _child_opstate_t =
121131 STDEXEC::connect_result_t <Sndr, STDEXEC::__receiver_ref<_opstate_t , _env_t >>;
122132 using _fork_opstate_t =
123133 STDEXEC::connect_result_t <_when_all_sndr_t , STDEXEC::__receiver_ref<Rcvr>>;
124- using _cache_sndr_t =
125- fork_join_impl_t ::_cache_sndr_t <_variant_t <_child_completions_t >, _domain_t >;
134+ using _cache_sndr_t = _fork_join::_cache_sndr_t <_variant_t <_child_completions_t >, _domain_t >;
126135
127136 STDEXEC_ATTRIBUTE (host, device)
128137 constexpr explicit _opstate_t (Sndr&& sndr, Closures&& closures, Rcvr rcvr) noexcept
@@ -139,7 +148,8 @@ namespace experimental::execution
139148
140149 STDEXEC_IMMOVABLE (_opstate_t );
141150
142- STDEXEC_ATTRIBUTE (host, device) constexpr ~_opstate_t ()
151+ STDEXEC_ATTRIBUTE (host, device)
152+ constexpr ~_opstate_t ()
143153 {
144154 // If this opstate was never started, we must explicitly destroy the _child_opstate_.
145155 if (_cache_.__is_valueless ())
@@ -148,7 +158,8 @@ namespace experimental::execution
148158 }
149159 }
150160
151- STDEXEC_ATTRIBUTE (host, device) constexpr void start () noexcept
161+ STDEXEC_ATTRIBUTE (host, device)
162+ constexpr void start () noexcept
152163 {
153164 STDEXEC::start (_child_opstate_.__get ());
154165 }
@@ -189,7 +200,8 @@ namespace experimental::execution
189200 this ->_complete (STDEXEC::set_error, static_cast <Error&&>(err));
190201 }
191202
192- STDEXEC_ATTRIBUTE (always_inline, host, device) void set_stopped () noexcept
203+ STDEXEC_ATTRIBUTE (always_inline, host, device)
204+ constexpr void set_stopped () noexcept
193205 {
194206 this ->_complete (STDEXEC::set_stopped);
195207 }
@@ -205,114 +217,103 @@ namespace experimental::execution
205217 STDEXEC::__manual_lifetime<_child_opstate_t > _child_opstate_{};
206218 _fork_opstate_t _fork_opstate_;
207219 };
208- };
220+
221+ template <class Sndr , class Closures , class Rcvr >
222+ STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE
223+ _opstate_t (Sndr&& sndr, Closures&& closures, Rcvr rcvr) -> _opstate_t <Sndr, Closures, Rcvr>;
224+
225+ struct __impls : STDEXEC::__sexpr_defaults
226+ {
227+ template <class Self , class ... Env>
228+ STDEXEC_ATTRIBUTE (host, device)
229+ static consteval auto __get_completion_signatures ()
230+ {
231+ using namespace STDEXEC ;
232+
233+ using _closures_t = __data_of<Self>;
234+ using _child_sndr_t = __child_of<Self>;
235+
236+ if constexpr (__minvocable_q<__completion_domain_of_t , set_value_t , _child_sndr_t , Env...>)
237+ {
238+ using _domain_t = __completion_domain_of_t <set_value_t , _child_sndr_t , Env...>;
239+ using _child_t = __copy_cvref_t <Self, _child_sndr_t >;
240+ using _child_completions_t = __completion_signatures_of_t <_child_t , __fwd_env_t <Env>...>;
241+ using __decay_copyable_results_t = __decay_copyable_results_t <_child_completions_t >;
242+
243+ if constexpr (!__valid_completion_signatures<_child_completions_t >)
244+ {
245+ return _child_completions_t {};
246+ }
247+ else if constexpr (!__decay_copyable_results_t ::value)
248+ {
249+ return STDEXEC::__throw_compile_time_error< //
250+ _WHAT_ (PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE),
251+ _IN_ALGORITHM_ (exec::fork_join_t )>();
252+ }
253+ else
254+ {
255+ using _sndr_t =
256+ _fork_join::_when_all_sndr_t <_child_completions_t , _closures_t , _domain_t >;
257+ return __completion_signatures_of_t <_sndr_t , __fwd_env_t <Env>...>{};
258+ }
259+ }
260+ else if constexpr (sizeof ...(Env) == 0 )
261+ {
262+ return STDEXEC::__throw_dependent_sender_error<Self>();
263+ }
264+ else
265+ {
266+ return STDEXEC::__throw_compile_time_error<
267+ INVALID_ARGUMENTS_TO_FORK_JOIN,
268+ __children_of<Self, __qq<_WITH_PRETTY_SENDERS_>>,
269+ __fn_t <_WITH_ENVIRONMENT_, Env>...>();
270+ }
271+ }
272+
273+ static constexpr auto __connect =
274+ []<class _Receiver , class _Sender >(_Sender&& __sndr, _Receiver __rcvr) noexcept
275+ -> _fork_join::_opstate_t <STDEXEC::__child_of<_Sender>,
276+ STDEXEC::__data_of<_Sender>,
277+ _Receiver>
278+ {
279+ auto & [tag, closures, child] = __sndr;
280+ return _fork_join::_opstate_t {STDEXEC::__forward_like<_Sender>(child),
281+ STDEXEC::__forward_like<_Sender>(closures),
282+ static_cast <_Receiver&&>(__rcvr)};
283+ };
284+ };
285+ } // namespace _fork_join
209286
210287 struct fork_join_t
211288 {
212- template <class Sndr , class ... Closures>
213- requires STDEXEC::sender<Sndr>
289+ template <STDEXEC::sender Sndr, class ... Closures>
214290 STDEXEC_ATTRIBUTE (host, device)
215- constexpr auto
216- operator ()(Sndr&& sndr, Closures&&... closures) const -> STDEXEC::__well_formed_sender auto
291+ constexpr auto operator ()(Sndr&& sndr, Closures&&... closures) const //
292+ -> STDEXEC::__well_formed_sender auto
217293 {
218- return STDEXEC::__make_sexpr<fork_join_t >(STDEXEC::__tuple{std::forward <Closures>(
294+ return STDEXEC::__make_sexpr<fork_join_t >(STDEXEC::__tuple{static_cast <Closures&& >(
219295 closures)...},
220- std::forward <Sndr>(sndr));
296+ static_cast <Sndr&& >(sndr));
221297 }
222298
223299 template <class ... Closures>
224300 requires ((!STDEXEC::sender<Closures>) && ...)
225301 STDEXEC_ATTRIBUTE (host, device)
226302 constexpr auto operator ()(Closures&&... closures) const
227303 {
228- return STDEXEC::__closure{*this , std::forward <Closures>(closures)...};
304+ return STDEXEC::__closure{*this , static_cast <Closures&& >(closures)...};
229305 }
230306 };
231307
232- template <>
233- struct fork_join_impl_t ::_env_t <STDEXEC::indeterminate_domain<>>
234- {};
235-
236308 inline constexpr fork_join_t fork_join{};
237309
238310} // namespace experimental::execution
239311
240312namespace exec = experimental::execution;
241313
242- namespace experimental ::execution::__fork_join
243- {
244- struct _INVALID_ARGUMENTS_TO_FORK_JOIN_
245- {};
246-
247- struct __impls : STDEXEC::__sexpr_defaults
248- {
249- template <class Self , class ... Env>
250- STDEXEC_ATTRIBUTE (host, device)
251- static consteval auto __get_completion_signatures ()
252- {
253- using namespace STDEXEC ;
254-
255- using _closures_t = STDEXEC::__data_of<Self>;
256- using _child_sndr_t = STDEXEC::__child_of<Self>;
257-
258- if constexpr (__minvocable_q<__completion_domain_of_t , set_value_t , _child_sndr_t , Env...>)
259- {
260- using _domain_t = __completion_domain_of_t <set_value_t , _child_sndr_t , Env...>;
261- using _child_t = __copy_cvref_t <Self, _child_sndr_t >;
262- using _child_completions_t = __completion_signatures_of_t <_child_t , __fwd_env_t <Env>...>;
263- using __decay_copyable_results_t =
264- STDEXEC::__decay_copyable_results_t <_child_completions_t >;
265-
266- if constexpr (!STDEXEC::__valid_completion_signatures<_child_completions_t >)
267- {
268- return _child_completions_t {};
269- }
270- else if constexpr (!__decay_copyable_results_t ::value)
271- {
272- return _ERROR_<_WHAT_ (PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE),
273- _IN_ALGORITHM_ (exec::fork_join_t )>();
274- }
275- else
276- {
277- using _sndr_t =
278- fork_join_impl_t ::_when_all_sndr_t <_child_completions_t , _closures_t , _domain_t >;
279- return __completion_signatures_of_t <_sndr_t , __fwd_env_t <Env>...>{};
280- }
281- }
282- else if constexpr (sizeof ...(Env) == 0 )
283- {
284- return STDEXEC::__throw_dependent_sender_error<Self>();
285- }
286- else
287- {
288- return STDEXEC::__throw_compile_time_error<_INVALID_ARGUMENTS_TO_FORK_JOIN_,
289- __children_of<Self, __qq<_WITH_PRETTY_SENDERS_>>,
290- __fn_t <_WITH_ENVIRONMENT_, Env>...>();
291- }
292- }
293-
294- static constexpr auto __connect = []<class _Receiver , class _Sender >(_Sender&& __sndr,
295- _Receiver __rcvr) noexcept
296- -> fork_join_impl_t ::_opstate_t <STDEXEC::__child_of<_Sender>,
297- STDEXEC::__data_of<_Sender>,
298- _Receiver>
299- {
300- using _closures_t = STDEXEC::__data_of<_Sender>;
301- using _sndr_t = STDEXEC::__child_of<_Sender>;
302-
303- return fork_join_impl_t ::_opstate_t <_sndr_t , _closures_t , _Receiver>{
304- STDEXEC::__get<2 >(static_cast <_Sender&&>(__sndr)),
305- STDEXEC::__get<1 >(static_cast <_Sender&&>(__sndr)),
306- static_cast <_Receiver&&>(__rcvr)};
307- };
308- };
309- } // namespace experimental::execution::__fork_join
310-
311- namespace exec = experimental::execution;
312-
313314namespace STDEXEC
314315{
315316 template <>
316- struct __sexpr_impl <exec::fork_join_t > : exec::__fork_join ::__impls
317+ struct __sexpr_impl <exec::fork_join_t > : exec::_fork_join ::__impls
317318 {};
318319} // namespace STDEXEC
0 commit comments