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 these after __execution_fwd.hpp 21 #include "__basic_sender.hpp" 22 #include "__concepts.hpp" 23 #include "__domain.hpp" 24 #include "__meta.hpp" 25 #include "__sender_adaptor_closure.hpp" 26 #include "__senders.hpp" // IWYU pragma: keep for __well_formed_sender 27 #include "__transform_completion_signatures.hpp" 28 #include "__transform_sender.hpp" 29 #include "__utility.hpp" 30 31 #include <exception> 32 #include <tuple> 33 #include <variant> // IWYU pragma: keep 34 35 namespace stdexec { 36 ///////////////////////////////////////////////////////////////////////////// 37 // [execution.senders.adaptors.into_variant] 38 namespace __into_variant { 39 template <class _Sender, class _Env> 40 requires sender_in<_Sender, _Env> 41 using __into_variant_result_t = value_types_of_t<_Sender, _Env>; 42 43 template <class _Sender, class... _Env> 44 using __variant_t = __value_types_t<__completion_signatures_of_t<_Sender, _Env...>>; 45 46 template <class _Variant> 47 using __variant_completions = 48 completion_signatures<set_value_t(_Variant), set_error_t(std::exception_ptr)>; 49 50 template <class _Sender, class... _Env> 51 using __completions = transform_completion_signatures< 52 __completion_signatures_of_t<_Sender, _Env...>, 53 __meval<__variant_completions, __variant_t<_Sender, _Env...>>, 54 __mconst<completion_signatures<>>::__f 55 >; 56 57 struct into_variant_t { 58 template <sender _Sender> operator ()stdexec::__into_variant::into_variant_t59 auto operator()(_Sender&& __sndr) const -> __well_formed_sender auto { 60 auto __domain = __get_early_domain(__sndr); 61 return stdexec::transform_sender( 62 __domain, __make_sexpr<into_variant_t>(__(), static_cast<_Sender&&>(__sndr))); 63 } 64 STDEXEC_ATTRIBUTEstdexec::__into_variant::into_variant_t65 STDEXEC_ATTRIBUTE(always_inline) 66 auto operator()() const noexcept -> __binder_back<into_variant_t> { 67 return {{}, {}, {}}; 68 } 69 }; 70 71 struct __into_variant_impl : __sexpr_defaults { 72 static constexpr auto get_state = 73 []<class _Self, class _Receiver>(_Self&&, _Receiver&) noexcept { 74 using __variant_t = value_types_of_t<__child_of<_Self>, env_of_t<_Receiver>>; 75 return __mtype<__variant_t>(); 76 }; 77 78 static constexpr auto complete = 79 []<class _State, class _Receiver, class _Tag, class... _Args>( 80 __ignore, 81 _State, 82 _Receiver& __rcvr, 83 _Tag, 84 _Args&&... __args) noexcept -> void { 85 if constexpr (__same_as<_Tag, set_value_t>) { 86 using __variant_t = __t<_State>; 87 STDEXEC_TRY { 88 set_value( 89 static_cast<_Receiver&&>(__rcvr), 90 __variant_t{std::tuple<_Args&&...>{static_cast<_Args&&>(__args)...}}); 91 } 92 STDEXEC_CATCH_ALL { 93 stdexec::set_error(static_cast<_Receiver&&>(__rcvr), std::current_exception()); 94 } 95 } else { 96 _Tag()(static_cast<_Receiver&&>(__rcvr), static_cast<_Args&&>(__args)...); 97 } 98 }; 99 100 static constexpr auto get_completion_signatures = 101 []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept 102 -> __completions<__child_of<_Self>, _Env...> { 103 static_assert(sender_expr_for<_Self, into_variant_t>); 104 return {}; 105 }; 106 }; 107 } // namespace __into_variant 108 109 using __into_variant::into_variant_t; 110 inline constexpr into_variant_t into_variant{}; 111 112 template <> 113 struct __sexpr_impl<into_variant_t> : __into_variant::__into_variant_impl { }; 114 } // namespace stdexec 115