Skip to content

Commit fa074d7

Browse files
committed
tried to reduce the uses of sender_decompose
1 parent 145557b commit fa074d7

File tree

6 files changed

+70
-22
lines changed

6 files changed

+70
-22
lines changed

include/beman/execution26/detail/basic_sender.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ struct basic_sender : ::beman::execution26::detail::product_type<Tag, Data, Chil
3333
using indices_for = ::std::index_sequence_for<Child...>;
3434

3535
auto get_env() const noexcept -> decltype(auto) {
36-
auto data{::beman::execution26::detail::get_sender_data(*this)};
37-
return ::std::apply(
38-
[&data](auto&&... c) { return ::beman::execution26::detail::impls_for<Tag>::get_attrs(data.data, c...); },
39-
data.children);
36+
auto&& d{this->template get<1>()};
37+
return sub_apply<2>(
38+
[&d](auto&&... c) { return ::beman::execution26::detail::impls_for<Tag>::get_attrs(d, c...); },
39+
*this);
4040
}
4141

4242
template <typename Receiver>

include/beman/execution26/detail/connect_all.hpp

+34
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,29 @@ struct connect_all_t {
4444
::std::forward<Tuple>(tuple));
4545
}
4646

47+
template <::std::size_t Start, typename Fun, typename Tuple, ::std::size_t... I>
48+
static auto sub_apply_with_index_helper(::std::index_sequence<I...> seq, Fun&& fun, Tuple&& tuple) noexcept(noexcept(
49+
::std::forward<Fun>(fun)(seq, ::beman::execution26::detail::forward_like<Tuple>(tuple.template get<I+Start>())...)))
50+
-> decltype(auto) {
51+
return ::std::forward<Fun>(fun)(seq,
52+
::beman::execution26::detail::forward_like<Tuple>(tuple.template get<I+Start>())...);
53+
}
54+
template <::std::size_t Start, typename Fun, typename Tuple>
55+
requires requires{ ::std::declval<Tuple>().size(); }
56+
static auto sub_apply_with_index(Fun&& fun, Tuple&& tuple) noexcept(
57+
noexcept(sub_apply_with_index_helper<Start>(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>>-Start>{},
58+
::std::forward<Fun>(fun),
59+
::std::forward<Tuple>(tuple)))) -> decltype(auto) {
60+
return sub_apply_with_index_helper<Start>(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>>-Start>{},
61+
::std::forward<Fun>(fun),
62+
::std::forward<Tuple>(tuple));
63+
}
64+
template <::std::size_t Start, typename Fun, typename Tuple>
65+
requires (not requires{ ::std::declval<Tuple>().size(); })
66+
static auto sub_apply_with_index(Fun&& fun, Tuple&& ) noexcept(noexcept(::std::forward<Fun>(fun)(::std::make_index_sequence<0u>{}))) {
67+
return ::std::forward<Fun>(fun)(::std::make_index_sequence<0u>{});
68+
}
69+
4770
template <typename Sender, typename Receiver>
4871
struct connect_helper {
4972
::beman::execution26::detail::basic_state<Sender, Receiver>* op;
@@ -66,6 +89,17 @@ struct connect_all_t {
6689

6790
public:
6891
//-dk:TODO is the S parameter deviating from the spec?
92+
template <typename Sender, typename S, typename Receiver, ::std::size_t... I>
93+
requires requires(Sender&& s){ s.size(); s.template get<0>(); }
94+
auto operator()(::beman::execution26::detail::basic_state<Sender, Receiver>* op,
95+
S&& sender,
96+
::std::index_sequence<I...>) const
97+
noexcept(noexcept(sub_apply_with_index<2>(connect_helper<Sender, Receiver>{op},
98+
::std::forward<S>(sender))))
99+
-> decltype(auto) {
100+
return sub_apply_with_index<2>(connect_helper<Sender, Receiver>{op},
101+
::std::forward<S>(sender));
102+
}
69103
template <typename Sender, typename S, typename Receiver, ::std::size_t... I>
70104
auto operator()(::beman::execution26::detail::basic_state<Sender, Receiver>* op,
71105
S&& sender,

include/beman/execution26/detail/default_impls.hpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@ struct default_impls {
3737
};
3838
static constexpr auto get_state =
3939
[]<typename Sender, typename Receiver>(Sender&& sender, Receiver& receiver) noexcept -> decltype(auto) {
40-
auto&& decompose = ::beman::execution26::detail::get_sender_data(::std::forward<Sender>(sender));
40+
auto&& data{[&sender]()->decltype(auto) {
41+
if constexpr (requires{ sender.size(); sender.template get<1>(); })
42+
return sender.template get<1>();
43+
else
44+
return ::beman::execution26::detail::get_sender_data(::std::forward<Sender>(sender)).data;
45+
}()};
4146

4247
return ::beman::execution26::detail::allocator_aware_move(
43-
::beman::execution26::detail::forward_like<Sender>(decompose.data), receiver);
48+
::beman::execution26::detail::forward_like<Sender>(data), receiver);
4449
};
4550
static constexpr auto start = [](auto&, auto&, auto&... ops) noexcept -> void {
4651
(::beman::execution26::start(ops), ...);

include/beman/execution26/detail/product_type.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,22 @@ template <typename... T>
112112
constexpr auto is_product_type(const ::beman::execution26::detail::product_type<T...>&) -> ::std::true_type {
113113
return {};
114114
}
115+
116+
template <::std::size_t Start, typename Fun, typename Tuple, ::std::size_t... I>
117+
constexpr auto sub_apply_helper(Fun&& fun, Tuple&& tuple, ::std::index_sequence<I...>) -> decltype(auto)
118+
{
119+
return ::std::forward<Fun>(fun)(::std::forward<Tuple>(tuple).template get<I + Start>()...);
120+
}
121+
122+
template <::std::size_t Start, typename Fun, typename Tuple>
123+
constexpr auto sub_apply(Fun&& fun, Tuple&& tuple) -> decltype(auto)
124+
{
125+
static constexpr ::std::size_t TSize{::std::tuple_size_v<::std::remove_cvref_t<Tuple>>};
126+
static_assert(Start <= TSize);
127+
return sub_apply_helper<Start>(::std::forward<Fun>(fun), ::std::forward<Tuple>(tuple),
128+
::std::make_index_sequence<TSize - Start>());
129+
}
130+
115131
} // namespace beman::execution26::detail
116132

117133
namespace std {

include/beman/execution26/detail/sender_decompose.hpp

+8-15
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ struct sender_data {
3333
Data& data;
3434
Children children;
3535
};
36+
template <typename Tag, typename Data, typename Children>
37+
sender_data(Tag&&, Data&, Children&&) -> sender_data<Tag, Data, Children>;
3638

3739
template <typename Sender>
3840
auto get_sender_data(Sender&& sender) {
@@ -49,33 +51,24 @@ auto get_sender_data(Sender&& sender) {
4951
sender.size();
5052
})
5153
return [&sender]<::std::size_t... I>(::std::index_sequence<I...>) {
52-
return ::beman::execution26::detail::sender_data<decltype(sender.template get<0>()),
53-
decltype(sender.template get<1>()),
54-
decltype(::std::tie(sender.template get<2 + I>()...))>{
54+
return ::beman::execution26::detail::sender_data{
5555
sender.template get<0>(), sender.template get<1>(), ::std::tie(sender.template get<2 + I>()...)};
5656
}(::std::make_index_sequence<::std::decay_t<decltype(sender)>::size() - 2u>{});
5757
else if constexpr (requires { sender_type{at, at, at, at, at, at}; }) {
5858
auto&& [tag, data, c0, c1, c2, c3] = sender;
59-
return ::beman::execution26::detail::
60-
sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1, c2, c3))>{
61-
tag, data, ::std::tie(c0, c1, c2, c3)};
59+
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1, c2, c3)};
6260
} else if constexpr (requires { sender_type{at, at, at, at, at}; }) {
6361
auto&& [tag, data, c0, c1, c2] = sender;
64-
return ::beman::execution26::detail::
65-
sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1, c2))>{
66-
tag, data, ::std::tie(c0, c1, c2)};
62+
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1, c2)};
6763
} else if constexpr (requires { sender_type{at, at, at, at}; }) {
6864
auto&& [tag, data, c0, c1] = sender;
69-
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1))>{
70-
tag, data, ::std::tie(c0, c1)};
65+
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1)};
7166
} else if constexpr (requires { sender_type{at, at, at}; }) {
7267
auto&& [tag, data, c0] = sender;
73-
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0))>{
74-
tag, data, ::std::tie(c0)};
68+
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0)};
7569
} else if constexpr (requires { sender_type{at, at}; }) {
7670
auto&& [tag, data] = sender;
77-
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), ::std::tuple<>>{
78-
tag, data, ::std::tuple<>()};
71+
return ::beman::execution26::detail::sender_data{ tag, data, ::std::tuple<>()};
7972
} else {
8073
return ::beman::execution26::detail::sender_meta<void, void, void>{};
8174
}

tests/beman/execution26/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ foreach(test ${execution_tests})
129129
add_test(NAME ${TEST_EXE} COMMAND $<TARGET_FILE:${TEST_EXE}>)
130130
endforeach()
131131

132-
if(NOT PROJECT_IS_TOP_LEVEL)
132+
if(ROJECT_IS_TOP_LEVEL)
133133
# test if the targets are findable from the build directory
134134
# cmake-format: off
135135
add_test(NAME find-package-test

0 commit comments

Comments
 (0)