1 /* 2 * Copyright (c) 2021-2024 NVIDIA Corporation 3 * 4 * Licensed under the Apache License Version 2.0 with LLVM Exceptions 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * https://llvm.org/LICENSE.txt 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "__execution_fwd.hpp" 19 20 #include "__basic_sender.hpp" 21 #include "__diagnostics.hpp" 22 #include "__domain.hpp" 23 #include "__meta.hpp" 24 #include "__senders_core.hpp" 25 #include "__sender_adaptor_closure.hpp" 26 #include "__transform_completion_signatures.hpp" 27 #include "__transform_sender.hpp" 28 #include "__senders.hpp" // IWYU pragma: keep for __well_formed_sender 29 30 // include these after __execution_fwd.hpp 31 namespace stdexec { 32 ///////////////////////////////////////////////////////////////////////////// 33 // [execution.senders.adaptors.upon_stopped] 34 namespace __upon_stopped { 35 inline constexpr __mstring __upon_stopped_context = 36 "In stdexec::upon_stopped(Sender, Function)..."_mstr; 37 using __on_not_callable = __callable_error<__upon_stopped_context>; 38 39 template <class _Fun, class _CvrefSender, class... _Env> 40 using __completion_signatures_t = transform_completion_signatures< 41 __completion_signatures_of_t<_CvrefSender, _Env...>, 42 __with_error_invoke_t<__on_not_callable, set_stopped_t, _Fun, _CvrefSender, _Env...>, 43 __sigs::__default_set_value, 44 __sigs::__default_set_error, 45 __set_value_invoke_t<_Fun> 46 >; 47 48 //////////////////////////////////////////////////////////////////////////////////////////////// 49 struct upon_stopped_t { 50 template <sender _Sender, __movable_value _Fun> 51 requires __callable<_Fun> operator ()stdexec::__upon_stopped::upon_stopped_t52 auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender auto { 53 auto __domain = __get_early_domain(__sndr); 54 return stdexec::transform_sender( 55 __domain, 56 __make_sexpr<upon_stopped_t>(static_cast<_Fun&&>(__fun), static_cast<_Sender&&>(__sndr))); 57 } 58 59 template <__movable_value _Fun> 60 requires __callable<_Fun> STDEXEC_ATTRIBUTEstdexec::__upon_stopped::upon_stopped_t61 STDEXEC_ATTRIBUTE(always_inline) 62 auto operator()(_Fun __fun) const -> __binder_back<upon_stopped_t, _Fun> { 63 return {{static_cast<_Fun&&>(__fun)}, {}, {}}; 64 } 65 }; 66 67 struct __upon_stopped_impl : __sexpr_defaults { 68 static constexpr auto get_completion_signatures = 69 []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept 70 -> __completion_signatures_t<__decay_t<__data_of<_Sender>>, __child_of<_Sender>, _Env...> { 71 static_assert(sender_expr_for<_Sender, upon_stopped_t>); 72 return {}; 73 }; 74 75 static constexpr auto complete = 76 []<class _Tag, class _State, class _Receiver, class... _Args>( 77 __ignore, 78 _State& __state, 79 _Receiver& __rcvr, 80 _Tag, 81 _Args&&... __args) noexcept -> void { 82 if constexpr (__same_as<_Tag, set_stopped_t>) { 83 stdexec::__set_value_invoke( 84 static_cast<_Receiver&&>(__rcvr), 85 static_cast<_State&&>(__state), 86 static_cast<_Args&&>(__args)...); 87 } else { 88 _Tag()(static_cast<_Receiver&&>(__rcvr), static_cast<_Args&&>(__args)...); 89 } 90 }; 91 }; 92 } // namespace __upon_stopped 93 94 using __upon_stopped::upon_stopped_t; 95 inline constexpr upon_stopped_t upon_stopped{}; 96 97 template <> 98 struct __sexpr_impl<upon_stopped_t> : __upon_stopped::__upon_stopped_impl { }; 99 100 } // namespace stdexec 101