-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathbasic_sender.hpp
131 lines (118 loc) · 5.87 KB
/
basic_sender.hpp
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// include/beman/execution26/detail/basic_sender.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_BASIC_SENDER
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_BASIC_SENDER
#include <beman/execution26/detail/basic_operation.hpp>
#include <beman/execution26/detail/completion_signatures_for.hpp>
#include <beman/execution26/detail/decays_to.hpp>
#include <beman/execution26/detail/impls_for.hpp>
#include <beman/execution26/detail/product_type.hpp>
#include <beman/execution26/detail/sender.hpp>
#include <beman/execution26/detail/sender_decompose.hpp>
#include <beman/execution26/detail/connect.hpp>
#include <beman/execution26/detail/get_completion_signatures.hpp>
#include <utility>
#include <beman/execution26/detail/suppress_push.hpp>
// ----------------------------------------------------------------------------
namespace beman::execution26::detail {
/*!
* \brief Class template used to factor out common sender implementation for library senders.
* \headerfile beman/execution26/execution.hpp <beman/execution26/execution.hpp>
* \internal
*/
template <typename Tag, typename Data, typename... Child>
struct basic_sender : ::beman::execution26::detail::product_type<Tag, Data, Child...> {
friend struct ::beman::execution26::connect_t;
friend struct ::beman::execution26::get_completion_signatures_t;
using sender_concept = ::beman::execution26::sender_t;
using indices_for = ::std::index_sequence_for<Child...>;
auto get_env() const noexcept -> decltype(auto) {
auto data{::beman::execution26::detail::get_sender_data(*this)};
return ::std::apply(
[&data](auto&&... c) { return ::beman::execution26::detail::impls_for<Tag>::get_attrs(data.data, c...); },
data.children);
}
template <class Self, class Env>
constexpr auto get_completion_behaviour(this Self&& self, Env&& env) noexcept -> decltype(auto) {
auto data{::beman::execution26::detail::get_sender_data(self)};
return ::std::apply(
[&data, &env](auto&&... cs) {
return ::beman::execution26::detail::impls_for<Tag>::get_completion_behaviour(
::std::forward<Env>(env),
::beman::execution26::detail::forward_like<Self>(data.data),
::beman::execution26::detail::forward_like<Self>(cs)...);
},
::beman::execution26::detail::forward_like<Self>(data.children));
}
template <typename Receiver>
requires(not ::beman::execution26::receiver<Receiver>)
auto connect(Receiver receiver) = BEMAN_EXECUTION26_DELETE("the passed receiver doesn't model receiver");
private:
#if __cpp_explicit_this_parameter < 302110L //-dk:TODO need to figure out how to use explicit this with forwarding
template <::beman::execution26::receiver Receiver>
auto connect(Receiver receiver) & noexcept(
noexcept(::beman::execution26::detail::basic_operation<basic_sender&, Receiver>{
*this, ::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation<basic_sender&, Receiver> {
return {*this, ::std::move(receiver)};
}
template <::beman::execution26::receiver Receiver>
auto connect(Receiver receiver) const& noexcept(noexcept(
::beman::execution26::detail::basic_operation<const basic_sender&, Receiver>{*this, ::std::move(receiver)}))
-> ::beman::execution26::detail::basic_operation<const basic_sender&, Receiver> {
return {*this, ::std::move(receiver)};
}
template <::beman::execution26::receiver Receiver>
auto connect(Receiver receiver) && noexcept(
noexcept(::beman::execution26::detail::basic_operation<basic_sender, Receiver>{
::std::move(*this),
::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation<basic_sender, Receiver> {
return {::std::move(*this), ::std::move(receiver)};
}
#else
template <::beman::execution26::detail::decays_to<basic_sender> Self, ::beman::execution26::receiver Receiver>
auto
connect(this Self&& self,
Receiver receiver) noexcept(noexcept(::beman::execution26::detail::basic_operation<basic_sender, Receiver>{
::std::forward<Self>(self),
::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation<Self, Receiver> {
return {::std::forward<Self>(self), ::std::move(receiver)};
}
#endif
#if __cpp_explicit_this_parameter < 302110L
template <typename Env>
auto
get_completion_signatures(Env&&) && -> ::beman::execution26::detail::completion_signatures_for<basic_sender, Env> {
return {};
}
template <typename Env>
auto get_completion_signatures(
Env&&) const&& -> ::beman::execution26::detail::completion_signatures_for<const basic_sender, Env> {
return {};
}
template <typename Env>
auto
get_completion_signatures(Env&&) & -> ::beman::execution26::detail::completion_signatures_for<basic_sender, Env> {
return {};
}
template <typename Env>
auto get_completion_signatures(
Env&&) const& -> ::beman::execution26::detail::completion_signatures_for<const basic_sender, Env> {
return {};
}
#else
template <::beman::execution26::detail::decays_to<basic_sender> Self, typename Env>
auto get_completion_signatures(this Self&&, Env&&) noexcept
-> ::beman::execution26::detail::completion_signatures_for<Self, Env> {
return {};
}
template <::beman::execution26::detail::decays_to<basic_sender> Self, typename Env>
auto get_completion_behaviour(this Self&&, Env&&) noexcept
-> ::beman::execution26::detail::completion_signatures_for<Self, Env> {
return {};
}
#endif
};
} // namespace beman::execution26::detail
// ----------------------------------------------------------------------------
#include <beman/execution26/detail/suppress_pop.hpp>
#endif