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