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:
Lewis Baker 2017-09-11 21:16:59 +09:30
parent d0383c1cb3
commit 2f8469bd96
4 changed files with 60 additions and 58 deletions

View file

@ -5,7 +5,7 @@
#ifndef 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>
namespace cppcoro
@ -28,7 +28,9 @@ namespace cppcoro
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
{
return static_cast<T&&>(value);

View 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

View file

@ -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

View file

@ -10,7 +10,6 @@ from cake.tools import compiler, script, env, project, variant
includes = cake.path.join(env.expand('${CPPCORO}'), 'include', 'cppcoro', [
'awaitable_traits.hpp',
'is_awaitable.hpp',
'is_awaiter.hpp',
'async_auto_reset_event.hpp',
'async_manual_reset_event.hpp',
'async_generator.hpp',
@ -56,6 +55,7 @@ detailIncludes = cake.path.join(env.expand('${CPPCORO}'), 'include', 'cppcoro',
'when_all_counter.hpp',
'when_all_task.hpp',
'get_awaiter.hpp',
'is_awaiter.hpp',
'any.hpp',
'sync_wait_task.hpp',
'unwrap_reference.hpp',