Skip to content

Commit cd50ced

Browse files
committed
fixed the noexception specification for connect and connect_all
1 parent 734df0c commit cd50ced

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

include/beman/execution26/detail/connect.hpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,39 @@ namespace beman::execution26::detail {
2121
* \internal
2222
*/
2323
struct connect_t {
24+
private:
2425
template <typename Sender, typename Receiver>
25-
auto operator()(Sender&& sender, Receiver&& receiver) const noexcept(true /*-dk:TODO*/) {
26+
static auto make_new_sender(Sender&& sender, Receiver&& receiver) noexcept(true) -> decltype(auto) {
27+
return ::beman::execution26::transform_sender(
28+
decltype(::beman::execution26::detail::get_domain_late(::std::forward<Sender>(sender),
29+
::beman::execution26::get_env(receiver))){},
30+
::std::forward<Sender>(sender),
31+
::beman::execution26::get_env(receiver));
32+
}
33+
template <typename Sender, typename Receiver>
34+
static constexpr auto connect_noexcept() -> bool {
35+
if constexpr (requires {
36+
make_new_sender(::std::declval<Sender>(), ::std::declval<Receiver>())
37+
.connect(::std::declval<Receiver>());
38+
}) {
39+
return noexcept(make_new_sender(::std::declval<Sender>(), ::std::declval<Receiver>())
40+
.connect(::std::declval<Receiver>()));
41+
} else if constexpr (requires {
42+
::beman::execution26::detail::connect_awaitable(
43+
make_new_sender(::std::declval<Sender>(), ::std::declval<Receiver>()),
44+
::std::declval<Receiver>());
45+
}) {
46+
return noexcept(::beman::execution26::detail::connect_awaitable(
47+
make_new_sender(::std::declval<Sender>(), ::std::declval<Receiver>()), ::std::declval<Receiver>()));
48+
}
49+
return true;
50+
}
51+
52+
public:
53+
template <typename Sender, typename Receiver>
54+
auto operator()(Sender&& sender, Receiver&& receiver) const noexcept(connect_noexcept<Sender, Receiver>()) {
2655
auto new_sender = [&sender, &receiver]() -> decltype(auto) {
27-
return ::beman::execution26::transform_sender(
28-
decltype(::beman::execution26::detail::get_domain_late(::std::forward<Sender>(sender),
29-
::beman::execution26::get_env(receiver))){},
30-
::std::forward<Sender>(sender),
31-
::beman::execution26::get_env(receiver));
56+
return make_new_sender(::std::forward<Sender>(sender), ::std::forward<Receiver>(receiver));
3257
};
3358

3459
if constexpr (requires { new_sender().connect(::std::forward<Receiver>(receiver)); }) {

include/beman/execution26/detail/connect_all.hpp

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <beman/execution26/detail/basic_state.hpp>
1111
#include <beman/execution26/detail/product_type.hpp>
1212
#include <beman/execution26/detail/sender_decompose.hpp>
13+
#include <beman/execution26/detail/forward_like.hpp>
1314
#include <cstddef>
1415
#include <tuple>
1516
#include <utility>
@@ -25,24 +26,55 @@ namespace beman::execution26::detail {
2526
* \internal
2627
*/
2728
struct connect_all_t {
29+
private:
30+
template <typename Fun, typename Tuple, ::std::size_t... I>
31+
static auto apply_with_index_helper(::std::index_sequence<I...> seq, Fun&& fun, Tuple&& tuple) noexcept(noexcept(
32+
::std::forward<Fun>(fun)(seq, ::beman::execution26::detail::forward_like<Tuple>(::std::get<I>(tuple))...)))
33+
-> decltype(auto) {
34+
return ::std::forward<Fun>(fun)(seq,
35+
::beman::execution26::detail::forward_like<Tuple>(::std::get<I>(tuple))...);
36+
}
37+
template <typename Fun, typename Tuple>
38+
static auto apply_with_index(Fun&& fun, Tuple&& tuple) noexcept(
39+
noexcept(apply_with_index_helper(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>>>{},
40+
::std::forward<Fun>(fun),
41+
::std::forward<Tuple>(tuple)))) -> decltype(auto) {
42+
return apply_with_index_helper(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>>>{},
43+
::std::forward<Fun>(fun),
44+
::std::forward<Tuple>(tuple));
45+
}
46+
47+
template <typename Sender, typename Receiver>
48+
struct connect_helper {
49+
::beman::execution26::detail::basic_state<Sender, Receiver>* op;
50+
51+
template <::std::size_t... J, typename... C>
52+
auto operator()(::std::index_sequence<J...>, C&&... c) noexcept(
53+
(noexcept(::beman::execution26::connect(
54+
::beman::execution26::detail::forward_like<Sender>(c),
55+
::beman::execution26::detail::basic_receiver<Sender, Receiver, ::std::integral_constant<::size_t, J>>{
56+
this->op})) &&
57+
... && true)) -> decltype(auto) {
58+
return ::beman::execution26::detail::product_type{::beman::execution26::connect(
59+
::beman::execution26::detail::forward_like<Sender>(c),
60+
::beman::execution26::detail::basic_receiver<Sender, Receiver, ::std::integral_constant<::size_t, J>>{
61+
this->op})...};
62+
}
63+
};
64+
2865
static auto use(auto&&...) {}
66+
67+
public:
2968
//-dk:TODO is the S parameter deviating from the spec?
3069
template <typename Sender, typename S, typename Receiver, ::std::size_t... I>
3170
auto operator()(::beman::execution26::detail::basic_state<Sender, Receiver>* op,
3271
S&& sender,
33-
::std::index_sequence<I...>) const noexcept(true /*-dk:TODO*/) {
34-
auto data{::beman::execution26::detail::get_sender_data(::std::forward<S>(sender))};
35-
return ::std::apply(
36-
[&op](auto&&... c) {
37-
return [&op]<::std::size_t... J>(::std::index_sequence<J...>, auto&&... c) {
38-
use(op);
39-
return ::beman::execution26::detail::product_type{::beman::execution26::connect(
40-
::beman::execution26::detail::forward_like<Sender>(c),
41-
::beman::execution26::detail::
42-
basic_receiver<Sender, Receiver, ::std::integral_constant<::size_t, J>>{op})...};
43-
}(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<decltype(data.children)>>>{}, c...);
44-
},
45-
data.children);
72+
::std::index_sequence<I...>) const
73+
noexcept(noexcept(apply_with_index(
74+
connect_helper<Sender, Receiver>{op},
75+
::beman::execution26::detail::get_sender_data(::std::forward<S>(sender)).children))) -> decltype(auto) {
76+
return apply_with_index(connect_helper<Sender, Receiver>{op},
77+
::beman::execution26::detail::get_sender_data(::std::forward<S>(sender)).children);
4678
}
4779
};
4880

0 commit comments

Comments
 (0)