15cee9157SPatrick Williams /*
25cee9157SPatrick Williams  * Copyright (c) 2021-2024 NVIDIA Corporation
35cee9157SPatrick Williams  *
45cee9157SPatrick Williams  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
55cee9157SPatrick Williams  * (the "License"); you may not use this file except in compliance with
65cee9157SPatrick Williams  * the License. You may obtain a copy of the License at
75cee9157SPatrick Williams  *
85cee9157SPatrick Williams  *   https://llvm.org/LICENSE.txt
95cee9157SPatrick Williams  *
105cee9157SPatrick Williams  * Unless required by applicable law or agreed to in writing, software
115cee9157SPatrick Williams  * distributed under the License is distributed on an "AS IS" BASIS,
125cee9157SPatrick Williams  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135cee9157SPatrick Williams  * See the License for the specific language governing permissions and
145cee9157SPatrick Williams  * limitations under the License.
155cee9157SPatrick Williams  */
165cee9157SPatrick Williams #pragma once
175cee9157SPatrick Williams 
185cee9157SPatrick Williams #include "__execution_fwd.hpp"
195cee9157SPatrick Williams 
205cee9157SPatrick Williams // include these after __execution_fwd.hpp
215cee9157SPatrick Williams #include "__basic_sender.hpp"
225cee9157SPatrick Williams #include "__concepts.hpp"
235cee9157SPatrick Williams #include "__env.hpp"
245cee9157SPatrick Williams #include "__meta.hpp"
255cee9157SPatrick Williams #include "__schedule_from.hpp"
265cee9157SPatrick Williams #include "__schedulers.hpp"
275cee9157SPatrick Williams #include "__sender_adaptor_closure.hpp"
285cee9157SPatrick Williams #include "__sender_introspection.hpp"
295cee9157SPatrick Williams #include "__senders.hpp"
305cee9157SPatrick Williams #include "__tag_invoke.hpp"
315cee9157SPatrick Williams #include "__transform_sender.hpp"
325cee9157SPatrick Williams #include "__type_traits.hpp"
335cee9157SPatrick Williams 
345cee9157SPatrick Williams #include <utility>
355cee9157SPatrick Williams 
365cee9157SPatrick Williams namespace stdexec
375cee9157SPatrick Williams {
385cee9157SPatrick Williams /////////////////////////////////////////////////////////////////////////////
395cee9157SPatrick Williams // [execution.senders.adaptors.continue_on]
405cee9157SPatrick Williams namespace __continue_on
415cee9157SPatrick Williams {
425cee9157SPatrick Williams using __schfr::__environ;
435cee9157SPatrick Williams 
445cee9157SPatrick Williams template <class _Env>
455cee9157SPatrick Williams using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>;
465cee9157SPatrick Williams 
475cee9157SPatrick Williams template <class _Sender>
485cee9157SPatrick Williams using __lowered_t = //
495cee9157SPatrick Williams     __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>,
505cee9157SPatrick Williams                 __child_of<_Sender>>;
515cee9157SPatrick Williams 
525cee9157SPatrick Williams struct continue_on_t
535cee9157SPatrick Williams {
545cee9157SPatrick Williams     template <sender _Sender, scheduler _Scheduler>
operator ()stdexec::__continue_on::continue_on_t55*06f265f6SPatrick Williams     auto operator()(_Sender&& __sndr,
56*06f265f6SPatrick Williams                     _Scheduler&& __sched) const -> __well_formed_sender auto
575cee9157SPatrick Williams     {
585cee9157SPatrick Williams         auto __domain = __get_early_domain(__sndr);
595cee9157SPatrick Williams         using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
605cee9157SPatrick Williams         return stdexec::transform_sender(
615cee9157SPatrick Williams             __domain, __make_sexpr<continue_on_t>(
625cee9157SPatrick Williams                           _Env{{static_cast<_Scheduler&&>(__sched)}},
635cee9157SPatrick Williams                           static_cast<_Sender&&>(__sndr)));
645cee9157SPatrick Williams     }
655cee9157SPatrick Williams 
665cee9157SPatrick Williams     template <scheduler _Scheduler>
675cee9157SPatrick Williams     STDEXEC_ATTRIBUTE((always_inline))
operator ()stdexec::__continue_on::continue_on_t685cee9157SPatrick Williams     auto operator()(_Scheduler&& __sched) const
695cee9157SPatrick Williams         -> __binder_back<continue_on_t, __decay_t<_Scheduler>>
705cee9157SPatrick Williams     {
715cee9157SPatrick Williams         return {{static_cast<_Scheduler&&>(__sched)}, {}, {}};
725cee9157SPatrick Williams     }
735cee9157SPatrick Williams 
745cee9157SPatrick Williams     //////////////////////////////////////////////////////////////////////////////////////////////
755cee9157SPatrick Williams     using _Env = __0;
765cee9157SPatrick Williams     using _Sender = __1;
775cee9157SPatrick Williams     using __legacy_customizations_t = //
785cee9157SPatrick Williams         __types<tag_invoke_t(continue_on_t,
795cee9157SPatrick Williams                              get_completion_scheduler_t<set_value_t>(
805cee9157SPatrick Williams                                  get_env_t(const _Sender&)),
815cee9157SPatrick Williams                              _Sender,
825cee9157SPatrick Williams                              get_completion_scheduler_t<set_value_t>(_Env)),
835cee9157SPatrick Williams                 tag_invoke_t(continue_on_t, _Sender,
845cee9157SPatrick Williams                              get_completion_scheduler_t<set_value_t>(_Env))>;
855cee9157SPatrick Williams 
865cee9157SPatrick Williams     template <class _Env>
__transform_sender_fnstdexec::__continue_on::continue_on_t875cee9157SPatrick Williams     static auto __transform_sender_fn(const _Env&)
885cee9157SPatrick Williams     {
895cee9157SPatrick Williams         return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
905cee9157SPatrick Williams                                               _Child&& __child) {
915cee9157SPatrick Williams             auto __sched = get_completion_scheduler<set_value_t>(__data);
925cee9157SPatrick Williams             return schedule_from(std::move(__sched),
935cee9157SPatrick Williams                                  static_cast<_Child&&>(__child));
945cee9157SPatrick Williams         };
955cee9157SPatrick Williams     }
965cee9157SPatrick Williams 
975cee9157SPatrick Williams     template <class _Sender, class _Env>
transform_senderstdexec::__continue_on::continue_on_t985cee9157SPatrick Williams     static auto transform_sender(_Sender&& __sndr, const _Env& __env)
995cee9157SPatrick Williams     {
1005cee9157SPatrick Williams         return __sexpr_apply(static_cast<_Sender&&>(__sndr),
1015cee9157SPatrick Williams                              __transform_sender_fn(__env));
1025cee9157SPatrick Williams     }
1035cee9157SPatrick Williams };
1045cee9157SPatrick Williams 
1055cee9157SPatrick Williams struct __continue_on_impl : __sexpr_defaults
1065cee9157SPatrick Williams {
1075cee9157SPatrick Williams     static constexpr auto get_attrs = //
1085cee9157SPatrick Williams         []<class _Data, class _Child>(
1095cee9157SPatrick Williams             const _Data& __data,
1105cee9157SPatrick Williams             const _Child& __child) noexcept -> decltype(auto) {
1115cee9157SPatrick Williams         return __env::__join(__data, stdexec::get_env(__child));
1125cee9157SPatrick Williams     };
1135cee9157SPatrick Williams 
1145cee9157SPatrick Williams     static constexpr auto get_completion_signatures = //
1155cee9157SPatrick Williams         []<class _Sender>(_Sender&&) noexcept         //
1165cee9157SPatrick Williams         -> __completion_signatures_of_t<              //
1175cee9157SPatrick Williams             transform_sender_result_t<default_domain, _Sender, empty_env>> {};
1185cee9157SPatrick Williams };
1195cee9157SPatrick Williams } // namespace __continue_on
1205cee9157SPatrick Williams 
1215cee9157SPatrick Williams using __continue_on::continue_on_t;
1225cee9157SPatrick Williams inline constexpr continue_on_t continue_on{};
1235cee9157SPatrick Williams 
1245cee9157SPatrick Williams using transfer_t = continue_on_t;
1255cee9157SPatrick Williams inline constexpr transfer_t transfer{};
1265cee9157SPatrick Williams 
1275cee9157SPatrick Williams template <>
1285cee9157SPatrick Williams struct __sexpr_impl<continue_on_t> : __continue_on::__continue_on_impl
1295cee9157SPatrick Williams {};
1305cee9157SPatrick Williams } // namespace stdexec
131