/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License Version 2.0 with LLVM Exceptions * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * https://llvm.org/LICENSE.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include namespace unifex { namespace _let_v_w { template struct _operation { struct type; }; template using operation = typename _operation< StateFactory, InnerOp, Receiver>::type; template struct _sender { class type; }; template using let_with_sender = typename _sender::type; template class _sender::type { public: using InnerOp = std::invoke_result_t&>; template class Variant, template class Tuple> using value_types = sender_value_types_t; template class Variant> using error_types = sender_error_types_t; static constexpr bool sends_done = sender_traits::sends_done; template explicit type(StateFactory2&& stateFactory, SuccessorFactory2&& func) : stateFactory_((StateFactory2&&)stateFactory), func_((SuccessorFactory2&&)func) {} template(typename Self, typename Receiver) (requires same_as, type> AND receiver) friend auto tag_invoke(tag_t, Self&& self, Receiver&& r) noexcept( is_nothrow_callable_v> && std::is_nothrow_invocable_v< member_t, callable_result_t>&> && is_nothrow_connectable_v< callable_result_t< member_t, callable_result_t>&>, remove_cvref_t>) { return operation( static_cast(self).stateFactory_, static_cast(self).func_, static_cast(r)); } private: UNIFEX_NO_UNIQUE_ADDRESS StateFactory stateFactory_; UNIFEX_NO_UNIQUE_ADDRESS SuccessorFactory func_; }; template struct _operation::type { type(StateFactory&& stateFactory, SuccessorFactory&& func, Receiver&& r) : stateFactory_(static_cast(stateFactory)), func_(static_cast(func)), state_(static_cast(stateFactory_)()), innerOp_( unifex::connect( static_cast(func_)(state_), static_cast(r))) { } void start() & noexcept { unifex::start(innerOp_); } StateFactory stateFactory_; SuccessorFactory func_; callable_result_t state_; connect_result_t< callable_result_t&>, remove_cvref_t> innerOp_; }; namespace _cpo { struct _fn { template (typename StateFactory, typename SuccessorFactory) (requires callable> AND callable< std::decay_t, callable_result_t>&> AND sender< callable_result_t< std::decay_t, callable_result_t>&>>) auto operator()(StateFactory&& stateFactory, SuccessorFactory&& successor_factory) const noexcept(std::is_nothrow_constructible_v, SuccessorFactory> && std::is_nothrow_constructible_v, StateFactory>) -> _let_v_w::let_with_sender< std::decay_t, std::decay_t> { return _let_v_w::let_with_sender< std::decay_t, std::decay_t>{ (StateFactory&&)stateFactory, (SuccessorFactory&&)successor_factory}; } }; } // namespace _cpo } // namespace _let_v_w inline constexpr _let_v_w::_cpo::_fn let_value_with{}; } // namespace unifex #include