/* * 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 #include #include namespace unifex { namespace _single { template struct _next_op { struct type; }; template using next_operation = typename _next_op>::type; template struct _next_op::type { union { Receiver receiver_; manual_lifetime> innerOp_; }; bool done_; template(typename Receiver2) (requires constructible_from) explicit type(Receiver2&& receiver) : receiver_((Receiver2&&)receiver) , done_(true) {} explicit type(Sender&& sender, Receiver&& receiver) : done_(false) { unifex::activate_union_member_with(innerOp_, [&] { return unifex::connect( static_cast(sender), (Receiver&&)receiver); }); } ~type() { if (done_) { receiver_.~Receiver(); } else { unifex::deactivate_union_member(innerOp_); } } void start() noexcept { if (done_) { unifex::set_done(std::move(receiver_)); } else { unifex::start(innerOp_.get()); } } }; template struct _stream { struct type; }; template using stream = typename _stream>::type; template struct _stream::type { std::optional sender_; struct next_sender { std::optional sender_; template