6namespace asyncpp::detail {
9 struct is_coroutine_handle : std::false_type {};
12 template<
typename TPromise>
13 struct is_coroutine_handle<coroutine_handle<TPromise>> : std::true_type {};
17 inline constexpr bool is_coroutine_handle_v = is_coroutine_handle<T>::value;
21 concept is_valid_await_suspend_return_value =
22 std::is_void_v<T> || std::is_same_v<T, bool> || is_coroutine_handle_v<T>;
26 concept is_awaiter =
requires(T&& await) {
27 { await.await_ready() } -> std::convertible_to<bool>;
28 { await.await_suspend(std::declval<coroutine_handle<>>()) } -> is_valid_await_suspend_return_value<>;
29 { await.await_resume() };
37 struct await_return_type;
38 template<
bool b,
typename T>
39 struct await_return_type_impl;
42 struct await_return_type_impl<true, T> {
43 using type =
decltype(std::declval<T>().await_resume());
47 struct await_return_type_impl<false, T> {
48 using type =
typename await_return_type<decltype(std::declval<T>().operator
co_await())>::type;
52 struct await_return_type {
53 using type =
typename await_return_type_impl<is_awaiter<T>, T>::type;
62 { disp.push(std::declval<std::function<
void()>>) };
66 template<
class Allocator>
68 { std::allocator_traits<Allocator>::allocate(alloc, 0) } -> std::convertible_to<std::byte*>;
69 { std::allocator_traits<Allocator>::deallocate(alloc, std::declval<std::byte*>(), 0) };
Check if a type is a valid allocator providing std::byte allocations.
Definition concepts.h:67
Check if T implements the dispatcher interface.
Definition concepts.h:61
Provides a consistent import interface for coroutine, experimental/coroutine or a best effort fallbac...