-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathget_completion_behaviour.hpp
More file actions
72 lines (61 loc) · 3.44 KB
/
Copy pathget_completion_behaviour.hpp
File metadata and controls
72 lines (61 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// include/beman/execution26/detail/get_completion_behaviour.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_COMPLETION_BEHAVIOUR
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_COMPLETION_BEHAVIOUR
#include <beman/execution26/detail/completion_behaviour.hpp>
#include <beman/execution26/detail/forward_like.hpp>
#include <beman/execution26/detail/is_awaitable.hpp>
#include <beman/execution26/detail/get_domain_late.hpp>
#include <beman/execution26/detail/transform_sender.hpp>
#include <type_traits>
namespace beman::execution26 {
struct get_completion_behaviour_t {
template <class Sender>
constexpr auto operator()(Sender&& sender) const noexcept {
if constexpr (requires { typename ::std::remove_cvref_t<Sender>::completion_behaviour; }) {
return typename ::std::remove_cvref_t<Sender>::completion_behaviour{};
} else if constexpr (requires { ::std::forward<Sender>(sender).get_completion_behaviour(); }) {
return ::std::forward<Sender>(sender).get_completion_behaviour();
} else if constexpr (::beman::execution26::detail::is_awaitable<
::std::remove_cvref_t<Sender>,
::beman::execution26::detail::env_promise<::beman::execution26::empty_env>>) {
return sender.await_ready() ? ::beman::execution26::completion_behaviour::inline_completion
: ::beman::execution26::completion_behaviour::unknown;
} else {
return ::beman::execution26::completion_behaviour::unknown;
}
}
template <class Sender, class Env>
constexpr auto operator()(Sender&& sender, Env&& env) const noexcept {
auto new_sender{[](auto&& sndr, auto&& e) -> decltype(auto) {
auto domain{::beman::execution26::detail::get_domain_late(sndr, e)};
return ::beman::execution26::transform_sender(
domain, ::std::forward<Sender>(sndr), ::std::forward<Env>(e));
}};
using new_sender_type =
::std::remove_cvref_t<decltype(new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env)))>;
using decayed_env = ::std::remove_cvref_t<Env>;
if constexpr (requires { typename new_sender_type::completion_behaviour; }) {
return typename new_sender_type::completion_behaviour{};
} else if constexpr (requires {
new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env))
.get_completion_behaviour(std::forward<Env>(env));
}) {
return new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env))
.get_completion_behaviour(std::forward<Env>(env));
} else if constexpr (::beman::execution26::detail::is_awaitable<
new_sender_type,
::beman::execution26::detail::env_promise<decayed_env>>) {
if (new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env)).await_ready()) {
return completion_behaviour::inline_completion;
} else {
return completion_behaviour::unknown;
}
} else {
return completion_behaviour::unknown;
}
}
};
inline constexpr get_completion_behaviour_t get_completion_behaviour{};
} // namespace beman::execution26
#endif