Repository navigation
Expand file tree
/
Copy pathbasic_sequence.hpp
More file actions
138 lines (118 loc) · 4.73 KB
/
Copy pathbasic_sequence.hpp
File metadata and controls
138 lines (118 loc) · 4.73 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
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
132
133
134
135
136
137
138
/*
* Copyright (c) 2023 NVIDIA Corporation
* Copyright (c) 2023 Maikel Nadolski
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "../../stdexec/__detail/__config.hpp"
#if STDEXEC_USE_MODULES()
import stdexec;
#else
# include "../../stdexec/__detail/__basic_sender.hpp"
# include "../../stdexec/__detail/__meta.hpp"
#endif
#include "../../stdexec/__detail/__basic_sender_macros.hpp"
#include "../sequence_senders.hpp"
namespace experimental::execution
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// __seqexpr
template <class...>
struct __basic_sequence_sender
{};
namespace
{
template <auto _DescriptorFn>
struct __seqexpr
: STDEXEC::__minvoke<decltype(_DescriptorFn()), STDEXEC::__qq<STDEXEC::__tuple>>
{
using sender_concept = sequence_sender_tag;
using __desc_t = decltype(_DescriptorFn());
using __tag_t = __desc_t::__tag;
STDEXEC_ATTRIBUTE(always_inline)
static constexpr auto __tag() noexcept -> __tag_t
{
return {};
}
template <class _Self = __seqexpr>
auto get_env() const noexcept -> decltype(_Self::__tag().get_env(*this))
{
static_assert(noexcept(_Self::__tag().get_env(*this)));
return _Self::__tag().get_env(*this);
}
template <class _Self, class... _Env>
static consteval auto get_completion_signatures()
{
static_assert(STDEXEC::__decays_to_derived_from<_Self, __seqexpr>);
return __tag_t::template get_completion_signatures<_Self, _Env...>();
}
template <class _Self, class... _Env>
static consteval auto get_item_types()
{
static_assert(STDEXEC::__decays_to_derived_from<_Self, __seqexpr>);
return __tag_t::template get_item_types<_Self, _Env...>();
}
// clang-format off
template <class _Self, STDEXEC::receiver _Receiver>
static constexpr auto __static_subscribe(_Self&& __self, _Receiver __rcvr) STDEXEC_AUTO_RETURN
(
__tag_t::subscribe(static_cast<_Self&&>(__self), static_cast<_Receiver&&>(__rcvr))
)
template <STDEXEC::receiver _Receiver>
constexpr auto subscribe(_Receiver __rcvr) && STDEXEC_AUTO_RETURN
(
__tag_t::subscribe(static_cast<__seqexpr&&>(*this), static_cast<_Receiver&&>(__rcvr))
)
template <STDEXEC::receiver _Receiver>
constexpr auto subscribe(_Receiver __rcvr) const & STDEXEC_AUTO_RETURN
(
__tag_t::subscribe(*this, static_cast<_Receiver&&>(__rcvr))
)
// clang-format on
};
template <class _Tag, class _Data, class... _Child>
STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE __seqexpr(_Tag, _Data, _Child...)
-> __seqexpr<STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child...)>;
} // namespace
template <class _Tag, class _Data, class... _Child>
using __seqexpr_t = __seqexpr<STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child...)>;
namespace __mkseqexpr
{
template <class _Tag, class _Domain = STDEXEC::default_domain>
struct make_sequence_expr_t
{
template <class _Data = STDEXEC::__, class... _Children>
constexpr auto operator()(_Data __data = {}, _Children... __children) const
{
return __seqexpr_t<_Tag, _Data, _Children...>{_Tag(),
static_cast<_Data&&>(__data),
static_cast<_Children&&>(__children)...};
}
};
} // namespace __mkseqexpr
template <class _Tag, class _Data, class... _Child>
using __basic_sequence_sender_t =
__basic_sequence_sender<_Tag, _Data, STDEXEC::__demangle_t<_Child>...>;
template <class _Tag, class _Domain = STDEXEC::default_domain>
inline constexpr __mkseqexpr::make_sequence_expr_t<_Tag, _Domain> make_sequence_expr{};
} // namespace experimental::execution
namespace exec = experimental::execution;
namespace STDEXEC::__detail
{
template <auto _DescriptorFn>
extern decltype(_DescriptorFn()) __desc_of_v<exec::__seqexpr<_DescriptorFn>>;
template <auto _DescriptorFn>
extern __mtype<__minvoke<decltype(_DescriptorFn()), __q<exec::__basic_sequence_sender_t>>>
__demangle_v<exec::__seqexpr<_DescriptorFn>>;
} // namespace STDEXEC::__detail