Move is_awaiter<T> into cppcoro::detail namespace.
It is just an implementation detail of is_awaitable<T> and shouldn't form part of the public API.
This commit is contained in:
parent
d0383c1cb3
commit
2f8469bd96
|
@ -5,7 +5,7 @@
|
||||||
#ifndef CPPCORO_DETAIL_GET_AWAITER_HPP_INCLUDED
|
#ifndef CPPCORO_DETAIL_GET_AWAITER_HPP_INCLUDED
|
||||||
#define CPPCORO_DETAIL_GET_AWAITER_HPP_INCLUDED
|
#define CPPCORO_DETAIL_GET_AWAITER_HPP_INCLUDED
|
||||||
|
|
||||||
#include <cppcoro/is_awaiter.hpp>
|
#include <cppcoro/detail/is_awaiter.hpp>
|
||||||
#include <cppcoro/detail/any.hpp>
|
#include <cppcoro/detail/any.hpp>
|
||||||
|
|
||||||
namespace cppcoro
|
namespace cppcoro
|
||||||
|
@ -28,7 +28,9 @@ namespace cppcoro
|
||||||
return operator co_await(static_cast<T&&>(value));
|
return operator co_await(static_cast<T&&>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::enable_if_t<cppcoro::is_awaiter<T&&>::value, int> = 0>
|
template<
|
||||||
|
typename T,
|
||||||
|
std::enable_if_t<cppcoro::detail::is_awaiter<T&&>::value, int> = 0>
|
||||||
T&& get_awaiter_impl(T&& value, cppcoro::detail::any) noexcept
|
T&& get_awaiter_impl(T&& value, cppcoro::detail::any) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<T&&>(value);
|
return static_cast<T&&>(value);
|
||||||
|
|
55
include/cppcoro/detail/is_awaiter.hpp
Normal file
55
include/cppcoro/detail/is_awaiter.hpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (c) Lewis Baker
|
||||||
|
// Licenced under MIT license. See LICENSE.txt for details.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef CPPCORO_DETAIL_IS_AWAITER_HPP_INCLUDED
|
||||||
|
#define CPPCORO_DETAIL_IS_AWAITER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <experimental/coroutine>
|
||||||
|
|
||||||
|
namespace cppcoro
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct is_coroutine_handle
|
||||||
|
: std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename PROMISE>
|
||||||
|
struct is_coroutine_handle<std::experimental::coroutine_handle<PROMISE>>
|
||||||
|
: std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
// NOTE: We're accepting a return value of coroutine_handle<P> here
|
||||||
|
// which is an extension supported by Clang which is not yet part of
|
||||||
|
// the C++ coroutines TS.
|
||||||
|
template<typename T>
|
||||||
|
struct is_valid_await_suspend_return_value : std::disjunction<
|
||||||
|
std::is_void<T>,
|
||||||
|
std::is_same<T, bool>,
|
||||||
|
is_coroutine_handle<T>>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename T, typename = std::void_t<>>
|
||||||
|
struct is_awaiter : std::false_type {};
|
||||||
|
|
||||||
|
// NOTE: We're testing whether await_suspend() will be callable using an
|
||||||
|
// arbitrary coroutine_handle here by checking if it supports being passed
|
||||||
|
// a coroutine_handle<void>. This may result in a false-result for some
|
||||||
|
// types which are only awaitable within a certain context.
|
||||||
|
template<typename T>
|
||||||
|
struct is_awaiter<T, std::void_t<
|
||||||
|
decltype(std::declval<T>().await_ready()),
|
||||||
|
decltype(std::declval<T>().await_suspend(std::declval<std::experimental::coroutine_handle<>>())),
|
||||||
|
decltype(std::declval<T>().await_resume())>> :
|
||||||
|
std::conjunction<
|
||||||
|
std::is_constructible<bool, decltype(std::declval<T>().await_ready())>,
|
||||||
|
detail::is_valid_await_suspend_return_value<
|
||||||
|
decltype(std::declval<T>().await_suspend(std::declval<std::experimental::coroutine_handle<>>()))>>
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,55 +0,0 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Copyright (c) Lewis Baker
|
|
||||||
// Licenced under MIT license. See LICENSE.txt for details.
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifndef CPPCORO_IS_AWAITER_HPP_INCLUDED
|
|
||||||
#define CPPCORO_IS_AWAITER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <experimental/coroutine>
|
|
||||||
|
|
||||||
namespace cppcoro
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
struct is_coroutine_handle
|
|
||||||
: std::false_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename PROMISE>
|
|
||||||
struct is_coroutine_handle<std::experimental::coroutine_handle<PROMISE>>
|
|
||||||
: std::true_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
// NOTE: We're accepting a return value of coroutine_handle<P> here
|
|
||||||
// which is an extension supported by Clang which is not yet part of
|
|
||||||
// the C++ coroutines TS.
|
|
||||||
template<typename T>
|
|
||||||
struct is_valid_await_suspend_return_value : std::disjunction<
|
|
||||||
std::is_void<T>,
|
|
||||||
std::is_same<T, bool>,
|
|
||||||
is_coroutine_handle<T>>
|
|
||||||
{};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename = std::void_t<>>
|
|
||||||
struct is_awaiter : std::false_type {};
|
|
||||||
|
|
||||||
// NOTE: We're testing whether await_suspend() will be callable using an
|
|
||||||
// arbitrary coroutine_handle here by checking if it supports being passed
|
|
||||||
// a coroutine_handle<void>. This may result in a false-result for some
|
|
||||||
// types which are only awaitable within a certain context.
|
|
||||||
template<typename T>
|
|
||||||
struct is_awaiter<T, std::void_t<
|
|
||||||
decltype(std::declval<T>().await_ready()),
|
|
||||||
decltype(std::declval<T>().await_suspend(std::declval<std::experimental::coroutine_handle<>>())),
|
|
||||||
decltype(std::declval<T>().await_resume())>> :
|
|
||||||
std::conjunction<
|
|
||||||
std::is_constructible<bool, decltype(std::declval<T>().await_ready())>,
|
|
||||||
detail::is_valid_await_suspend_return_value<
|
|
||||||
decltype(std::declval<T>().await_suspend(std::declval<std::experimental::coroutine_handle<>>()))>>
|
|
||||||
{};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -10,7 +10,6 @@ from cake.tools import compiler, script, env, project, variant
|
||||||
includes = cake.path.join(env.expand('${CPPCORO}'), 'include', 'cppcoro', [
|
includes = cake.path.join(env.expand('${CPPCORO}'), 'include', 'cppcoro', [
|
||||||
'awaitable_traits.hpp',
|
'awaitable_traits.hpp',
|
||||||
'is_awaitable.hpp',
|
'is_awaitable.hpp',
|
||||||
'is_awaiter.hpp',
|
|
||||||
'async_auto_reset_event.hpp',
|
'async_auto_reset_event.hpp',
|
||||||
'async_manual_reset_event.hpp',
|
'async_manual_reset_event.hpp',
|
||||||
'async_generator.hpp',
|
'async_generator.hpp',
|
||||||
|
@ -56,6 +55,7 @@ detailIncludes = cake.path.join(env.expand('${CPPCORO}'), 'include', 'cppcoro',
|
||||||
'when_all_counter.hpp',
|
'when_all_counter.hpp',
|
||||||
'when_all_task.hpp',
|
'when_all_task.hpp',
|
||||||
'get_awaiter.hpp',
|
'get_awaiter.hpp',
|
||||||
|
'is_awaiter.hpp',
|
||||||
'any.hpp',
|
'any.hpp',
|
||||||
'sync_wait_task.hpp',
|
'sync_wait_task.hpp',
|
||||||
'unwrap_reference.hpp',
|
'unwrap_reference.hpp',
|
||||||
|
|
Loading…
Reference in a new issue