1515 */
1616#pragma once
1717
18- #include < utility>
19-
2018#include " ../stdexec/execution.hpp"
2119#include " __detail/__system_context_replaceability_api.hpp"
2220
21+ #include < optional>
22+ #include < utility>
23+
2324#ifndef STDEXEC_SYSTEM_CONTEXT_SCHEDULE_OP_SIZE
2425# define STDEXEC_SYSTEM_CONTEXT_SCHEDULE_OP_SIZE 72
2526#endif
@@ -43,48 +44,61 @@ namespace exec {
4344 namespace detail {
4445 // / Allows a frontend receiver of type `_Rcvr` to be passed to the backend.
4546 template <class _Rcvr >
46- struct __receiver_adapter : system_context_replaceability::receiver {
47+ struct __receiver_adapter : STDEXEC:: system_context_replaceability::receiver_proxy {
4748 explicit __receiver_adapter (_Rcvr&& __rcvr)
48- : __rcvr_{std::forward<_Rcvr>(__rcvr)} {
49- }
50-
51- auto __query_env (__uuid __id, void * __dest) noexcept -> bool override {
52- using system_context_replaceability::__runtime_property_helper;
53- using __StopToken = decltype (STDEXEC::get_stop_token (STDEXEC::get_env (__rcvr_)));
54- if constexpr (std::is_same_v<STDEXEC::inplace_stop_token, __StopToken>) {
55- if (__id == __runtime_property_helper<STDEXEC::inplace_stop_token>::__property_identifier) {
56- *static_cast <STDEXEC::inplace_stop_token*>(__dest) = STDEXEC::get_stop_token (
57- STDEXEC::get_env (__rcvr_));
58- return true ;
59- }
60- }
61- return false ;
49+ : __rcvr_{static_cast <_Rcvr&&>(__rcvr)} {
6250 }
6351
6452 void set_value () noexcept override {
6553 STDEXEC::set_value (std::forward<_Rcvr>(__rcvr_));
6654 }
6755
68- void set_error (std::exception_ptr __ex) noexcept override {
56+ void set_error (std::exception_ptr&& __ex) noexcept override {
6957 STDEXEC::set_error (std::forward<_Rcvr>(__rcvr_), std::move (__ex));
7058 }
7159
7260 void set_stopped () noexcept override {
7361 STDEXEC::set_stopped (std::forward<_Rcvr>(__rcvr_));
7462 }
7563
64+ protected:
65+ void __query_env (
66+ STDEXEC::__type_index __query_type,
67+ STDEXEC::__type_index __value_type,
68+ void * __dest) const noexcept override {
69+ if (__query_type == STDEXEC::__mtypeid<STDEXEC::get_stop_token_t >) {
70+ __query (STDEXEC::get_stop_token, __value_type, __dest);
71+ }
72+ }
73+
74+ private:
75+ void __query (STDEXEC::get_stop_token_t , STDEXEC::__type_index __value_type, void * __dest)
76+ const noexcept {
77+ using __stop_token_t = STDEXEC::stop_token_of_t <STDEXEC::env_of_t <_Rcvr>>;
78+ if constexpr (std::is_same_v<STDEXEC::inplace_stop_token, __stop_token_t >) {
79+ if (__value_type == STDEXEC::__mtypeid<STDEXEC::inplace_stop_token>) {
80+ using __dest_t = std::optional<STDEXEC::inplace_stop_token>;
81+ *static_cast <__dest_t *>(__dest) = STDEXEC::get_stop_token (STDEXEC::get_env (__rcvr_));
82+ }
83+ }
84+ }
85+
86+ public:
7687 STDEXEC_ATTRIBUTE (no_unique_address)
7788 _Rcvr __rcvr_;
7889 };
7990
8091 // / The type large enough to store the data produced by a sender.
92+ // / BUGBUG: this seems wrong. i think this should be a variant of tuples of possible
93+ // / results.
8194 template <class _Sender >
8295 using __sender_data_t = decltype (STDEXEC::sync_wait(std::declval<_Sender>()).value());
8396
8497 } // namespace detail
8598
8699 class parallel_scheduler ;
87100 class __parallel_sender ;
101+
88102 template <bool , STDEXEC::sender _S, std::integral _Size, class _Fn , bool >
89103 class __parallel_bulk_sender ;
90104
@@ -106,7 +120,7 @@ namespace exec {
106120
107121 namespace detail {
108122 using __backend_ptr =
109- std::shared_ptr<system_context_replaceability::parallel_scheduler_backend>;
123+ std::shared_ptr<STDEXEC:: system_context_replaceability::parallel_scheduler_backend>;
110124
111125 template <class T >
112126 auto __make_parallel_scheduler_from (T, __backend_ptr) noexcept ;
@@ -199,7 +213,7 @@ namespace exec {
199213 auto & __scheduler_impl = __preallocated_.__as <__backend_ptr>();
200214 auto __impl = std::move (__scheduler_impl);
201215 std::destroy_at (&__scheduler_impl);
202- __impl->schedule (__preallocated_.__as_storage (), __rcvr_ );
216+ __impl->schedule (__rcvr_, __preallocated_.__as_storage ());
203217 }
204218
205219 // / Object that receives completion from the work described by the sender.
@@ -312,7 +326,8 @@ namespace exec {
312326 // / This represents the base class that abstracts the storage of the values sent by the previous sender.
313327 // / Derived class will properly implement the receiver methods.
314328 template <class _Previous >
315- struct __forward_args_receiver : system_context_replaceability::bulk_item_receiver {
329+ struct __forward_args_receiver
330+ : STDEXEC::system_context_replaceability::bulk_item_receiver_proxy {
316331 using __storage_t = detail::__sender_data_t <_Previous>;
317332
318333 // / Storage for the arguments received from the previous sender.
@@ -329,24 +344,11 @@ namespace exec {
329344 // / Stores `__as` in the base class storage, with the right types.
330345 explicit __typed_forward_args_receiver (_As&&... __as) {
331346 static_assert (sizeof (std::tuple<_As...>) <= sizeof (__base_t ::__arguments_data_));
347+ // BUGBUG: this seems wrong. we are not ever destroying this tuple.
332348 new (__base_t ::__arguments_data_)
333349 std::tuple<STDEXEC::__decay_t <_As>...>{std::move (__as)...};
334350 }
335351
336- auto __query_env (__uuid __id, void * __dest) noexcept -> bool override {
337- auto __state = reinterpret_cast <_BulkState*>(this );
338- using system_context_replaceability::__runtime_property_helper;
339- using __StopToken = decltype (STDEXEC::get_stop_token (STDEXEC::get_env (__state->__rcvr_ )));
340- if constexpr (std::is_same_v<STDEXEC::inplace_stop_token, __StopToken>) {
341- if (__id == __runtime_property_helper<STDEXEC::inplace_stop_token>::__property_identifier) {
342- *static_cast <STDEXEC::inplace_stop_token*>(__dest) = STDEXEC::get_stop_token (
343- STDEXEC::get_env (__state->__rcvr_ ));
344- return true ;
345- }
346- }
347- return false ;
348- }
349-
350352 // / Calls `set_value()` on the final receiver of the bulk operation, using the values from the previous sender.
351353 void set_value () noexcept override {
352354 auto __state = reinterpret_cast <_BulkState*>(this );
@@ -396,6 +398,30 @@ namespace exec {
396398 *reinterpret_cast <std::tuple<_As...>*>(__base_t ::__arguments_data_));
397399 }
398400 }
401+
402+ protected:
403+ void __query_env (
404+ STDEXEC::__type_index __query_type,
405+ STDEXEC::__type_index __value_type,
406+ void * __dest) const noexcept override {
407+ if (__query_type == STDEXEC::__mtypeid<STDEXEC::get_stop_token_t >) {
408+ __query (STDEXEC::get_stop_token, __value_type, __dest);
409+ }
410+ }
411+
412+ private:
413+ void __query (STDEXEC::get_stop_token_t , STDEXEC::__type_index __value_type, void * __dest)
414+ const noexcept {
415+ auto __state = reinterpret_cast <const _BulkState*>(this );
416+ using __stop_token_t = STDEXEC::stop_token_of_t <STDEXEC::env_of_t <__rcvr_t >>;
417+ if constexpr (std::is_same_v<STDEXEC::inplace_stop_token, __stop_token_t >) {
418+ using __dest_t = std::optional<STDEXEC::inplace_stop_token>;
419+ if (__value_type == STDEXEC::__mtypeid<STDEXEC::inplace_stop_token>) {
420+ *static_cast <__dest_t *>(__dest) = STDEXEC::get_stop_token (
421+ STDEXEC::get_env (__state->__rcvr_ ));
422+ }
423+ }
424+ }
399425 };
400426
401427 // / The state needed to execute the bulk sender created from system context, minus the preallocates space.
@@ -645,7 +671,7 @@ namespace exec {
645671 };
646672
647673 inline auto get_parallel_scheduler () -> parallel_scheduler {
648- auto __impl = system_context_replaceability::query_parallel_scheduler_backend ();
674+ auto __impl = STDEXEC:: system_context_replaceability::query_parallel_scheduler_backend ();
649675 if (!__impl) {
650676 STDEXEC_THROW (std::runtime_error{" No system context implementation found" });
651677 }
@@ -728,5 +754,5 @@ namespace exec {
728754
729755#if defined(STDEXEC_SYSTEM_CONTEXT_HEADER_ONLY)
730756# define STDEXEC_SYSTEM_CONTEXT_INLINE inline
731- # include " __detail/__system_context_default_impl_entry.hpp"
757+ # include " ../stdexec/ __detail/__system_context_default_impl_entry.hpp"
732758#endif
0 commit comments