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 "__basic_sender.hpp" 19 #include "__diagnostics.hpp" 20 #include "__domain.hpp" 21 #include "__execution_fwd.hpp" 22 #include "__meta.hpp" 23 #include "__sender_adaptor_closure.hpp" 24 #include "__senders.hpp" 25 #include "__senders_core.hpp" 26 #include "__transform_completion_signatures.hpp" 27 #include "__transform_sender.hpp" 28 29 // include these after __execution_fwd.hpp 30 namespace stdexec 31 { 32 ///////////////////////////////////////////////////////////////////////////// 33 // [execution.senders.adaptors.then] 34 namespace __then 35 { 36 inline constexpr __mstring __then_context = 37 "In stdexec::then(Sender, Function)..."_mstr; 38 using __on_not_callable = __callable_error<__then_context>; 39 40 template <class _Fun, class _CvrefSender, class... _Env> 41 using __completions_t = // 42 transform_completion_signatures< 43 __completion_signatures_of_t<_CvrefSender, _Env...>, 44 __with_error_invoke_t<__on_not_callable, set_value_t, _Fun, 45 _CvrefSender, _Env...>, 46 __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>, 47 _Fun>::template __f>; 48 49 //////////////////////////////////////////////////////////////////////////////////////////////// 50 struct then_t 51 { 52 template <sender _Sender, __movable_value _Fun> operator ()stdexec::__then::then_t53 auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender 54 auto 55 { 56 auto __domain = __get_early_domain(__sndr); 57 return stdexec::transform_sender( 58 __domain, __make_sexpr<then_t>(static_cast<_Fun&&>(__fun), 59 static_cast<_Sender&&>(__sndr))); 60 } 61 62 template <__movable_value _Fun> 63 STDEXEC_ATTRIBUTE((always_inline)) operator ()stdexec::__then::then_t64 auto operator()(_Fun __fun) const -> __binder_back<then_t, _Fun> 65 { 66 return {{static_cast<_Fun&&>(__fun)}, {}, {}}; 67 } 68 69 using _Sender = __1; 70 using _Fun = __0; 71 using __legacy_customizations_t = 72 __types<tag_invoke_t(then_t, 73 get_completion_scheduler_t<set_value_t>( 74 get_env_t(_Sender&)), 75 _Sender, _Fun), 76 tag_invoke_t(then_t, _Sender, _Fun)>; 77 }; 78 79 struct __then_impl : __sexpr_defaults 80 { 81 static constexpr auto get_completion_signatures = // 82 []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept 83 -> __completions_t<__decay_t<__data_of<_Sender>>, __child_of<_Sender>, 84 _Env...> { 85 static_assert(sender_expr_for<_Sender, then_t>); 86 return {}; 87 }; 88 89 static constexpr auto complete = // 90 []<class _Tag, class _State, class _Receiver, class... _Args>( 91 __ignore, _State& __state, _Receiver& __rcvr, _Tag, 92 _Args&&... __args) noexcept -> void { 93 if constexpr (__same_as<_Tag, set_value_t>) 94 { 95 stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr), 96 static_cast<_State&&>(__state), 97 static_cast<_Args&&>(__args)...); 98 } 99 else 100 { 101 _Tag()(static_cast<_Receiver&&>(__rcvr), 102 static_cast<_Args&&>(__args)...); 103 } 104 }; 105 }; 106 } // namespace __then 107 108 using __then::then_t; 109 110 /// @brief The then sender adaptor, which invokes a function with the result of 111 /// a sender, making the result available to the next receiver. 112 /// @hideinitializer 113 inline constexpr then_t then{}; 114 115 template <> 116 struct __sexpr_impl<then_t> : __then::__then_impl 117 {}; 118 } // namespace stdexec 119