/* * 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 _alloc { template struct _op { class type; }; template using operation = typename _op::type; template class _op::type { using operation = type; using allocator_t = typename std::allocator_traits< Allocator>::template rebind_alloc; public: template explicit type(Sender&& s, Receiver&& r) : allocator_(get_allocator(r)) { using allocator_traits = std::allocator_traits; Operation* op = allocator_traits::allocate(allocator_, 1); scope_guard freeOnError = [&]() noexcept { allocator_traits::deallocate(allocator_, op, 1); }; op_ = ::new (static_cast(op)) Operation(connect((Sender &&) s, (Receiver &&) r)); freeOnError.release(); } ~type() { op_->~Operation(); std::allocator_traits::deallocate(allocator_, op_, 1); } friend void tag_invoke(tag_t, operation& op) noexcept { start(*op.op_); } private: Operation* op_; UNIFEX_NO_UNIQUE_ADDRESS allocator_t allocator_; }; template struct _sender { class type; }; template using sender = typename _sender>::type; template class _sender::type { using sender = type; public: template < template class Variant, template class Tuple> using value_types = sender_value_types_t; template