1f083bc1aSPatrick Williams /* 2f083bc1aSPatrick Williams * Copyright (c) 2021-2024 NVIDIA Corporation 3f083bc1aSPatrick Williams * 4f083bc1aSPatrick Williams * Licensed under the Apache License Version 2.0 with LLVM Exceptions 5f083bc1aSPatrick Williams * (the "License"); you may not use this file except in compliance with 6f083bc1aSPatrick Williams * the License. You may obtain a copy of the License at 7f083bc1aSPatrick Williams * 8f083bc1aSPatrick Williams * https://llvm.org/LICENSE.txt 9f083bc1aSPatrick Williams * 10f083bc1aSPatrick Williams * Unless required by applicable law or agreed to in writing, software 11f083bc1aSPatrick Williams * distributed under the License is distributed on an "AS IS" BASIS, 12f083bc1aSPatrick Williams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f083bc1aSPatrick Williams * See the License for the specific language governing permissions and 14f083bc1aSPatrick Williams * limitations under the License. 15f083bc1aSPatrick Williams */ 16f083bc1aSPatrick Williams #pragma once 17f083bc1aSPatrick Williams 18f083bc1aSPatrick Williams #include "__execution_fwd.hpp" 19f083bc1aSPatrick Williams 20f083bc1aSPatrick Williams // include these after __execution_fwd.hpp 21f083bc1aSPatrick Williams #include "__basic_sender.hpp" 22f083bc1aSPatrick Williams #include "__concepts.hpp" 23f083bc1aSPatrick Williams #include "__env.hpp" 24f083bc1aSPatrick Williams #include "__meta.hpp" 25f083bc1aSPatrick Williams #include "__schedule_from.hpp" 26f083bc1aSPatrick Williams #include "__schedulers.hpp" 27f083bc1aSPatrick Williams #include "__sender_adaptor_closure.hpp" 28f083bc1aSPatrick Williams #include "__sender_introspection.hpp" 29f083bc1aSPatrick Williams #include "__senders.hpp" 30f083bc1aSPatrick Williams #include "__tag_invoke.hpp" 31f083bc1aSPatrick Williams #include "__transform_sender.hpp" 32f083bc1aSPatrick Williams #include "__type_traits.hpp" 33f083bc1aSPatrick Williams 34f083bc1aSPatrick Williams #include <utility> 35f083bc1aSPatrick Williams 36f083bc1aSPatrick Williams namespace stdexec 37f083bc1aSPatrick Williams { 38f083bc1aSPatrick Williams ///////////////////////////////////////////////////////////////////////////// 39f083bc1aSPatrick Williams // [execution.senders.adaptors.continues_on] 40f083bc1aSPatrick Williams namespace __continues_on 41f083bc1aSPatrick Williams { 42f083bc1aSPatrick Williams using __schfr::__environ; 43f083bc1aSPatrick Williams 44f083bc1aSPatrick Williams template <class _Env> 45f083bc1aSPatrick Williams using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>; 46f083bc1aSPatrick Williams 47f083bc1aSPatrick Williams template <class _Sender> 48f083bc1aSPatrick Williams using __lowered_t = // 49f083bc1aSPatrick Williams __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>, 50f083bc1aSPatrick Williams __child_of<_Sender>>; 51f083bc1aSPatrick Williams 52f083bc1aSPatrick Williams struct continues_on_t 53f083bc1aSPatrick Williams { 54f083bc1aSPatrick Williams template <sender _Sender, scheduler _Scheduler> operator ()stdexec::__continues_on::continues_on_t55*36137e09SPatrick Williams auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const 56*36137e09SPatrick Williams -> __well_formed_sender auto 57f083bc1aSPatrick Williams { 58f083bc1aSPatrick Williams auto __domain = __get_early_domain(__sndr); 59f083bc1aSPatrick Williams using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>; 60f083bc1aSPatrick Williams return stdexec::transform_sender( 61f083bc1aSPatrick Williams __domain, __make_sexpr<continues_on_t>( 62f083bc1aSPatrick Williams _Env{{static_cast<_Scheduler&&>(__sched)}}, 63f083bc1aSPatrick Williams static_cast<_Sender&&>(__sndr))); 64f083bc1aSPatrick Williams } 65f083bc1aSPatrick Williams 66f083bc1aSPatrick Williams template <scheduler _Scheduler> 67f083bc1aSPatrick Williams STDEXEC_ATTRIBUTE((always_inline)) operator ()stdexec::__continues_on::continues_on_t68f083bc1aSPatrick Williams auto operator()(_Scheduler&& __sched) const 69f083bc1aSPatrick Williams -> __binder_back<continues_on_t, __decay_t<_Scheduler>> 70f083bc1aSPatrick Williams { 71f083bc1aSPatrick Williams return {{static_cast<_Scheduler&&>(__sched)}, {}, {}}; 72f083bc1aSPatrick Williams } 73f083bc1aSPatrick Williams 74f083bc1aSPatrick Williams ////////////////////////////////////////////////////////////////////////////////////////////// 75f083bc1aSPatrick Williams using _Env = __0; 76f083bc1aSPatrick Williams using _Sender = __1; 77f083bc1aSPatrick Williams using __legacy_customizations_t = // 78f083bc1aSPatrick Williams __types<tag_invoke_t(continues_on_t, 79f083bc1aSPatrick Williams get_completion_scheduler_t<set_value_t>( 80f083bc1aSPatrick Williams get_env_t(const _Sender&)), 81f083bc1aSPatrick Williams _Sender, 82f083bc1aSPatrick Williams get_completion_scheduler_t<set_value_t>(_Env)), 83f083bc1aSPatrick Williams tag_invoke_t(continues_on_t, _Sender, 84f083bc1aSPatrick Williams get_completion_scheduler_t<set_value_t>(_Env))>; 85f083bc1aSPatrick Williams 86f083bc1aSPatrick Williams template <class _Env> __transform_sender_fnstdexec::__continues_on::continues_on_t87f083bc1aSPatrick Williams static auto __transform_sender_fn(const _Env&) 88f083bc1aSPatrick Williams { 89f083bc1aSPatrick Williams return [&]<class _Data, class _Child>(__ignore, _Data&& __data, 90f083bc1aSPatrick Williams _Child&& __child) { 91f083bc1aSPatrick Williams auto __sched = get_completion_scheduler<set_value_t>(__data); 92f083bc1aSPatrick Williams return schedule_from(std::move(__sched), 93f083bc1aSPatrick Williams static_cast<_Child&&>(__child)); 94f083bc1aSPatrick Williams }; 95f083bc1aSPatrick Williams } 96f083bc1aSPatrick Williams 97f083bc1aSPatrick Williams template <class _Sender, class _Env> transform_senderstdexec::__continues_on::continues_on_t98f083bc1aSPatrick Williams static auto transform_sender(_Sender&& __sndr, const _Env& __env) 99f083bc1aSPatrick Williams { 100f083bc1aSPatrick Williams return __sexpr_apply(static_cast<_Sender&&>(__sndr), 101f083bc1aSPatrick Williams __transform_sender_fn(__env)); 102f083bc1aSPatrick Williams } 103f083bc1aSPatrick Williams }; 104f083bc1aSPatrick Williams 105f083bc1aSPatrick Williams struct __continues_on_impl : __sexpr_defaults 106f083bc1aSPatrick Williams { 107f083bc1aSPatrick Williams static constexpr auto get_attrs = // 108f083bc1aSPatrick Williams []<class _Data, class _Child>( 109f083bc1aSPatrick Williams const _Data& __data, 110f083bc1aSPatrick Williams const _Child& __child) noexcept -> decltype(auto) { 111f083bc1aSPatrick Williams return __env::__join(__data, stdexec::get_env(__child)); 112f083bc1aSPatrick Williams }; 113f083bc1aSPatrick Williams 114f083bc1aSPatrick Williams static constexpr auto get_completion_signatures = // 115f083bc1aSPatrick Williams []<class _Sender>(_Sender&&) noexcept // 116f083bc1aSPatrick Williams -> __completion_signatures_of_t< // 117f083bc1aSPatrick Williams transform_sender_result_t<default_domain, _Sender, empty_env>> {}; 118f083bc1aSPatrick Williams }; 119f083bc1aSPatrick Williams } // namespace __continues_on 120f083bc1aSPatrick Williams 121f083bc1aSPatrick Williams using __continues_on::continues_on_t; 122f083bc1aSPatrick Williams inline constexpr continues_on_t continues_on{}; 123f083bc1aSPatrick Williams 124f083bc1aSPatrick Williams using transfer_t = continues_on_t; 125f083bc1aSPatrick Williams inline constexpr continues_on_t transfer{}; 126f083bc1aSPatrick Williams 127f083bc1aSPatrick Williams using continue_on_t = continues_on_t; 128f083bc1aSPatrick Williams inline constexpr continues_on_t continue_on{}; 129f083bc1aSPatrick Williams 130f083bc1aSPatrick Williams template <> 131f083bc1aSPatrick Williams struct __sexpr_impl<continues_on_t> : __continues_on::__continues_on_impl 132f083bc1aSPatrick Williams {}; 133f083bc1aSPatrick Williams } // namespace stdexec 134