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 "__basic_sender.hpp" 195cee9157SPatrick Williams #include "__diagnostics.hpp" 205cee9157SPatrick Williams #include "__domain.hpp" 215cee9157SPatrick Williams #include "__execution_fwd.hpp" 225cee9157SPatrick Williams #include "__meta.hpp" 235cee9157SPatrick Williams #include "__sender_adaptor_closure.hpp" 245cee9157SPatrick Williams #include "__senders.hpp" 255cee9157SPatrick Williams #include "__senders_core.hpp" 265cee9157SPatrick Williams #include "__transform_completion_signatures.hpp" 275cee9157SPatrick Williams #include "__transform_sender.hpp" 285cee9157SPatrick Williams 295cee9157SPatrick Williams // include these after __execution_fwd.hpp 305cee9157SPatrick Williams namespace stdexec 315cee9157SPatrick Williams { 325cee9157SPatrick Williams ///////////////////////////////////////////////////////////////////////////// 335cee9157SPatrick Williams // [execution.senders.adaptors.upon_stopped] 345cee9157SPatrick Williams namespace __upon_stopped 355cee9157SPatrick Williams { 365cee9157SPatrick Williams inline constexpr __mstring __upon_stopped_context = 375cee9157SPatrick Williams "In stdexec::upon_stopped(Sender, Function)..."_mstr; 385cee9157SPatrick Williams using __on_not_callable = __callable_error<__upon_stopped_context>; 395cee9157SPatrick Williams 405cee9157SPatrick Williams template <class _Fun, class _CvrefSender, class... _Env> 415cee9157SPatrick Williams using __completion_signatures_t = // 425cee9157SPatrick Williams transform_completion_signatures< 435cee9157SPatrick Williams __completion_signatures_of_t<_CvrefSender, _Env...>, 445cee9157SPatrick Williams __with_error_invoke_t<__on_not_callable, set_stopped_t, _Fun, 455cee9157SPatrick Williams _CvrefSender, _Env...>, 465cee9157SPatrick Williams __sigs::__default_set_value, __sigs::__default_set_error, 475cee9157SPatrick Williams __set_value_invoke_t<_Fun>>; 485cee9157SPatrick Williams 495cee9157SPatrick Williams //////////////////////////////////////////////////////////////////////////////////////////////// 505cee9157SPatrick Williams struct upon_stopped_t 515cee9157SPatrick Williams { 525cee9157SPatrick Williams template <sender _Sender, __movable_value _Fun> 535cee9157SPatrick Williams requires __callable<_Fun> operator ()stdexec::__upon_stopped::upon_stopped_t545cee9157SPatrick Williams auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender 555cee9157SPatrick Williams auto 565cee9157SPatrick Williams { 575cee9157SPatrick Williams auto __domain = __get_early_domain(__sndr); 585cee9157SPatrick Williams return stdexec::transform_sender( 595cee9157SPatrick Williams __domain, 605cee9157SPatrick Williams __make_sexpr<upon_stopped_t>(static_cast<_Fun&&>(__fun), 615cee9157SPatrick Williams static_cast<_Sender&&>(__sndr))); 625cee9157SPatrick Williams } 635cee9157SPatrick Williams 645cee9157SPatrick Williams template <__movable_value _Fun> 655cee9157SPatrick Williams requires __callable<_Fun> 66*06f265f6SPatrick Williams STDEXEC_ATTRIBUTE((always_inline)) operator ()stdexec::__upon_stopped::upon_stopped_t67*06f265f6SPatrick Williams auto operator()(_Fun __fun) const -> __binder_back<upon_stopped_t, _Fun> 685cee9157SPatrick Williams { 695cee9157SPatrick Williams return {{static_cast<_Fun&&>(__fun)}, {}, {}}; 705cee9157SPatrick Williams } 715cee9157SPatrick Williams 725cee9157SPatrick Williams using _Sender = __1; 735cee9157SPatrick Williams using _Fun = __0; 745cee9157SPatrick Williams using __legacy_customizations_t = 755cee9157SPatrick Williams __types<tag_invoke_t(upon_stopped_t, 765cee9157SPatrick Williams get_completion_scheduler_t<set_value_t>( 775cee9157SPatrick Williams get_env_t(_Sender&)), 785cee9157SPatrick Williams _Sender, _Fun), 795cee9157SPatrick Williams tag_invoke_t(upon_stopped_t, _Sender, _Fun)>; 805cee9157SPatrick Williams }; 815cee9157SPatrick Williams 825cee9157SPatrick Williams struct __upon_stopped_impl : __sexpr_defaults 835cee9157SPatrick Williams { 845cee9157SPatrick Williams static constexpr auto get_completion_signatures = // 855cee9157SPatrick Williams []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept 865cee9157SPatrick Williams -> __completion_signatures_t<__decay_t<__data_of<_Sender>>, 875cee9157SPatrick Williams __child_of<_Sender>, _Env...> { 885cee9157SPatrick Williams static_assert(sender_expr_for<_Sender, upon_stopped_t>); 895cee9157SPatrick Williams return {}; 905cee9157SPatrick Williams }; 915cee9157SPatrick Williams 925cee9157SPatrick Williams static constexpr auto complete = // 935cee9157SPatrick Williams []<class _Tag, class _State, class _Receiver, class... _Args>( 945cee9157SPatrick Williams __ignore, _State& __state, _Receiver& __rcvr, _Tag, 955cee9157SPatrick Williams _Args&&... __args) noexcept -> void { 965cee9157SPatrick Williams if constexpr (__same_as<_Tag, set_stopped_t>) 975cee9157SPatrick Williams { 985cee9157SPatrick Williams stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr), 995cee9157SPatrick Williams static_cast<_State&&>(__state), 1005cee9157SPatrick Williams static_cast<_Args&&>(__args)...); 1015cee9157SPatrick Williams } 1025cee9157SPatrick Williams else 1035cee9157SPatrick Williams { 1045cee9157SPatrick Williams _Tag()(static_cast<_Receiver&&>(__rcvr), 1055cee9157SPatrick Williams static_cast<_Args&&>(__args)...); 1065cee9157SPatrick Williams } 1075cee9157SPatrick Williams }; 1085cee9157SPatrick Williams }; 1095cee9157SPatrick Williams } // namespace __upon_stopped 1105cee9157SPatrick Williams 1115cee9157SPatrick Williams using __upon_stopped::upon_stopped_t; 1125cee9157SPatrick Williams inline constexpr upon_stopped_t upon_stopped{}; 1135cee9157SPatrick Williams 1145cee9157SPatrick Williams template <> 1155cee9157SPatrick Williams struct __sexpr_impl<upon_stopped_t> : __upon_stopped::__upon_stopped_impl 1165cee9157SPatrick Williams {}; 1175cee9157SPatrick Williams 1185cee9157SPatrick Williams } // namespace stdexec 119