Skip to content

Commit 234a033

Browse files
committed
give just_from a custom submit member
1 parent 8c9bfeb commit 234a033

2 files changed

Lines changed: 63 additions & 48 deletions

File tree

include/exec/just_from.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ namespace exec {
134134
noexcept(stdexec::__nothrow_decay_copyable<Rcvr, Fn const &>) -> _opstate<Rcvr, Fn> {
135135
return _opstate<Rcvr, Fn>{static_cast<Rcvr&&>(rcvr), _fn};
136136
}
137+
138+
template <class Rcvr>
139+
STDEXEC_ATTRIBUTE((host, device)) auto submit(Rcvr rcvr) && noexcept -> void {
140+
auto op = static_cast<_sndr_base&&>(*this).connect(static_cast<Rcvr&&>(rcvr));
141+
stdexec::start(op);
142+
}
143+
144+
template <class Rcvr>
145+
STDEXEC_ATTRIBUTE((host, device)) auto submit(Rcvr rcvr) const & noexcept -> void {
146+
auto op = this->connect(static_cast<Rcvr&&>(rcvr));
147+
stdexec::start(op);
148+
}
137149
};
138150

139151
template <class Fn, class Tag = JustTag>

include/stdexec/__detail/__submit.hpp

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace stdexec {
4141
using __id = __data;
4242

4343
STDEXEC_IMMOVABLE(__t);
44+
4445
explicit __t(_CvSender&& __sndr, _Receiver __rcvr) noexcept(
4546
__nothrow_connectable<_CvSender, _Receiver>)
4647
: __op_(connect(static_cast<_CvSender&&>(__sndr), static_cast<_Receiver&&>(__rcvr))) {
@@ -53,57 +54,59 @@ namespace stdexec {
5354

5455
template <class _CvSender, class _Receiver>
5556
using __op_data = __t<__data<__cvref_id<_CvSender>, __id<_Receiver>>>;
56-
} // namespace __submit
5757

58-
// submit is a combination of connect and start. it is customizable for times when it
59-
// can be done more efficiently than by calling connect and start directly.
60-
struct __submit_t {
61-
struct __void { };
62-
63-
// The default implementation of submit is to call connect and start.
64-
template <class _Sender, class _Receiver, class _Default = __void>
65-
requires sender_to<_Sender, _Receiver>
66-
auto operator()(_Sender&& __sndr, _Receiver __rcvr, _Default = {}) const
67-
noexcept(__nothrow_connectable<_Sender, _Receiver>)
68-
-> __submit::__op_data<_Sender, _Receiver> {
69-
return __submit::__op_data<_Sender, _Receiver>{
70-
static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)};
71-
}
72-
73-
// This implementation is used if the sender has a non-static submit member function.
74-
template <class _Sender, class _Receiver, class _Default = __void>
75-
requires sender_to<_Sender, _Receiver> && __submit::__has_memfn<_Sender, _Receiver>
76-
auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
77-
noexcept(noexcept(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)))) {
78-
using __result_t =
79-
decltype(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)));
80-
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
81-
static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
82-
return __def;
83-
} else {
84-
return static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
58+
// submit is a combination of connect and start. it is customizable for times when it
59+
// can be done more efficiently than by calling connect and start directly.
60+
struct __submit_t {
61+
struct __void { };
62+
63+
// The default implementation of submit is to call connect and start.
64+
template <class _Sender, class _Receiver, class _Default = __void>
65+
requires sender_to<_Sender, _Receiver>
66+
auto operator()(_Sender&& __sndr, _Receiver __rcvr, _Default = {}) const
67+
noexcept(__nothrow_connectable<_Sender, _Receiver>)
68+
-> __submit::__op_data<_Sender, _Receiver> {
69+
return __submit::__op_data<_Sender, _Receiver>{
70+
static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)};
71+
}
72+
73+
// This implementation is used if the sender has a non-static submit member function.
74+
template <class _Sender, class _Receiver, class _Default = __void>
75+
requires sender_to<_Sender, _Receiver> && __submit::__has_memfn<_Sender, _Receiver>
76+
auto
77+
operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
78+
noexcept(noexcept(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)))) {
79+
using __result_t =
80+
decltype(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)));
81+
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
82+
static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
83+
return __def;
84+
} else {
85+
return static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
86+
}
8587
}
86-
}
87-
88-
// This implementation is used if the sender has a static submit member function.
89-
template <class _Sender, class _Receiver, class _Default = __void>
90-
requires sender_to<_Sender, _Receiver> && __submit::__has_static_memfn<_Sender, _Receiver>
91-
auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
92-
noexcept(
93-
noexcept(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)))) {
94-
using __result_t =
95-
decltype(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)));
96-
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
97-
__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
98-
return __def;
99-
} else {
100-
return __sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
88+
89+
// This implementation is used if the sender has a static submit member function.
90+
template <class _Sender, class _Receiver, class _Default = __void>
91+
requires sender_to<_Sender, _Receiver> && __submit::__has_static_memfn<_Sender, _Receiver>
92+
auto
93+
operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
94+
noexcept(noexcept(
95+
__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)))) {
96+
using __result_t =
97+
decltype(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)));
98+
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
99+
__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
100+
return __def;
101+
} else {
102+
return __sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
103+
}
101104
}
102-
}
103-
};
105+
};
106+
} // namespace __submit
104107

105-
inline constexpr __submit_t submit{};
108+
inline constexpr __submit::__submit_t submit{};
106109

107-
template <class _Sender, class _Receiver, class _Default = __submit_t::__void>
108-
using submit_result_t = __call_result_t<__submit_t, _Sender, _Receiver, _Default>;
110+
template <class _Sender, class _Receiver, class _Default = __submit::__submit_t::__void>
111+
using submit_result_t = __call_result_t<__submit::__submit_t, _Sender, _Receiver, _Default>;
109112
} // namespace stdexec

0 commit comments

Comments
 (0)