/* * 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 #if UNIFEX_NO_COROUTINES # error "Coroutine support is required to use " #endif #include #include namespace unifex { namespace detail { template constexpr bool has_member_operator_co_await_v = false; template constexpr bool has_member_operator_co_await_v< Awaitable, std::void_t().operator co_await())>> = true; template constexpr bool has_free_operator_co_await_v = false; template constexpr bool has_free_operator_co_await_v< Awaitable, std::void_t()))>> = true; template struct await_result_impl {}; template struct await_result_impl< Awaiter, std::void_t< decltype(std::declval().await_ready() ? (void)0 : (void)0), decltype(std::declval().await_resume())>> { using type = decltype(std::declval().await_resume()); }; } // namespace detail inline const struct _get_awaiter_fn { template constexpr decltype(auto) operator()(Awaitable&& awaitable) const noexcept { if constexpr (detail::has_member_operator_co_await_v) { return static_cast(awaitable).operator co_await(); } else if constexpr (detail::has_free_operator_co_await_v) { return operator co_await(static_cast(awaitable)); } else { return static_cast(awaitable); } } } get_awaiter {}; template using awaiter_type_t = decltype(get_awaiter(std::declval())); template using await_result_t = typename detail::await_result_impl>::type; namespace detail { template UNIFEX_CONCEPT_FRAGMENT( // _awaitable_impl, // requires() ( // typename(await_result_t) )); template UNIFEX_CONCEPT // _awaitable = // UNIFEX_FRAGMENT(detail::_awaitable_impl, Awaitable); } // namespace detail } // namespace unifex #include