Skip to content

Commit

Permalink
tried to reduce the uses of sender_decompose (#118)
Browse files Browse the repository at this point in the history
* tried to reduce the uses of sender_decompose

* clang-format
  • Loading branch information
dietmarkuehl authored Jan 14, 2025
1 parent 145557b commit b52f28c
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 22 deletions.
7 changes: 3 additions & 4 deletions include/beman/execution26/detail/basic_sender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ struct basic_sender : ::beman::execution26::detail::product_type<Tag, Data, Chil
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);
auto&& d{this->template get<1>()};
return sub_apply<2>(
[&d](auto&&... c) { return ::beman::execution26::detail::impls_for<Tag>::get_attrs(d, c...); }, *this);
}

template <typename Receiver>
Expand Down
39 changes: 39 additions & 0 deletions include/beman/execution26/detail/connect_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ struct connect_all_t {
::std::forward<Tuple>(tuple));
}

template <::std::size_t Start, typename Fun, typename Tuple, ::std::size_t... I>
static auto sub_apply_with_index_helper(::std::index_sequence<I...> seq, Fun&& fun, Tuple&& tuple) noexcept(
noexcept(::std::forward<Fun>(fun)(
seq, ::beman::execution26::detail::forward_like<Tuple>(tuple.template get<I + Start>())...)))
-> decltype(auto) {
return ::std::forward<Fun>(fun)(
seq, ::beman::execution26::detail::forward_like<Tuple>(tuple.template get<I + Start>())...);
}
template <::std::size_t Start, typename Fun, typename Tuple>
requires requires { ::std::declval<Tuple>().size(); }
static auto sub_apply_with_index(Fun&& fun, Tuple&& tuple) noexcept(noexcept(sub_apply_with_index_helper<Start>(
::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>> - Start>{},
::std::forward<Fun>(fun),
::std::forward<Tuple>(tuple)))) -> decltype(auto) {
return sub_apply_with_index_helper<Start>(
::std::make_index_sequence<::std::tuple_size_v<::std::decay_t<Tuple>> - Start>{},
::std::forward<Fun>(fun),
::std::forward<Tuple>(tuple));
}
template <::std::size_t Start, typename Fun, typename Tuple>
requires(not requires { ::std::declval<Tuple>().size(); })
static auto
sub_apply_with_index(Fun&& fun,
Tuple&&) noexcept(noexcept(::std::forward<Fun>(fun)(::std::make_index_sequence<0u>{}))) {
return ::std::forward<Fun>(fun)(::std::make_index_sequence<0u>{});
}

template <typename Sender, typename Receiver>
struct connect_helper {
::beman::execution26::detail::basic_state<Sender, Receiver>* op;
Expand All @@ -66,6 +93,18 @@ struct connect_all_t {

public:
//-dk:TODO is the S parameter deviating from the spec?
template <typename Sender, typename S, typename Receiver, ::std::size_t... I>
requires requires(Sender&& s) {
s.size();
s.template get<0>();
}
auto operator()(::beman::execution26::detail::basic_state<Sender, Receiver>* op,
S&& sender,
::std::index_sequence<I...>) const
noexcept(noexcept(sub_apply_with_index<2>(connect_helper<Sender, Receiver>{op}, ::std::forward<S>(sender))))
-> decltype(auto) {
return sub_apply_with_index<2>(connect_helper<Sender, Receiver>{op}, ::std::forward<S>(sender));
}
template <typename Sender, typename S, typename Receiver, ::std::size_t... I>
auto operator()(::beman::execution26::detail::basic_state<Sender, Receiver>* op,
S&& sender,
Expand Down
12 changes: 10 additions & 2 deletions include/beman/execution26/detail/default_impls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,18 @@ struct default_impls {
};
static constexpr auto get_state =
[]<typename Sender, typename Receiver>(Sender&& sender, Receiver& receiver) noexcept -> decltype(auto) {
auto&& decompose = ::beman::execution26::detail::get_sender_data(::std::forward<Sender>(sender));
auto&& data{[&sender]() -> decltype(auto) {
if constexpr (requires {
sender.size();
sender.template get<1>();
})
return sender.template get<1>();
else
return ::beman::execution26::detail::get_sender_data(::std::forward<Sender>(sender)).data;
}()};

return ::beman::execution26::detail::allocator_aware_move(
::beman::execution26::detail::forward_like<Sender>(decompose.data), receiver);
::beman::execution26::detail::forward_like<Sender>(data), receiver);
};
static constexpr auto start = [](auto&, auto&, auto&... ops) noexcept -> void {
(::beman::execution26::start(ops), ...);
Expand Down
14 changes: 14 additions & 0 deletions include/beman/execution26/detail/product_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ template <typename... T>
constexpr auto is_product_type(const ::beman::execution26::detail::product_type<T...>&) -> ::std::true_type {
return {};
}

template <::std::size_t Start, typename Fun, typename Tuple, ::std::size_t... I>
constexpr auto sub_apply_helper(Fun&& fun, Tuple&& tuple, ::std::index_sequence<I...>) -> decltype(auto) {
return ::std::forward<Fun>(fun)(::std::forward<Tuple>(tuple).template get<I + Start>()...);
}

template <::std::size_t Start, typename Fun, typename Tuple>
constexpr auto sub_apply(Fun&& fun, Tuple&& tuple) -> decltype(auto) {
static constexpr ::std::size_t TSize{::std::tuple_size_v<::std::remove_cvref_t<Tuple>>};
static_assert(Start <= TSize);
return sub_apply_helper<Start>(
::std::forward<Fun>(fun), ::std::forward<Tuple>(tuple), ::std::make_index_sequence<TSize - Start>());
}

} // namespace beman::execution26::detail

namespace std {
Expand Down
23 changes: 8 additions & 15 deletions include/beman/execution26/detail/sender_decompose.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ struct sender_data {
Data& data;
Children children;
};
template <typename Tag, typename Data, typename Children>
sender_data(Tag&&, Data&, Children&&) -> sender_data<Tag, Data, Children>;

template <typename Sender>
auto get_sender_data(Sender&& sender) {
Expand All @@ -49,33 +51,24 @@ auto get_sender_data(Sender&& sender) {
sender.size();
})
return [&sender]<::std::size_t... I>(::std::index_sequence<I...>) {
return ::beman::execution26::detail::sender_data<decltype(sender.template get<0>()),
decltype(sender.template get<1>()),
decltype(::std::tie(sender.template get<2 + I>()...))>{
return ::beman::execution26::detail::sender_data{
sender.template get<0>(), sender.template get<1>(), ::std::tie(sender.template get<2 + I>()...)};
}(::std::make_index_sequence<::std::decay_t<decltype(sender)>::size() - 2u>{});
else if constexpr (requires { sender_type{at, at, at, at, at, at}; }) {
auto&& [tag, data, c0, c1, c2, c3] = sender;
return ::beman::execution26::detail::
sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1, c2, c3))>{
tag, data, ::std::tie(c0, c1, c2, c3)};
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1, c2, c3)};
} else if constexpr (requires { sender_type{at, at, at, at, at}; }) {
auto&& [tag, data, c0, c1, c2] = sender;
return ::beman::execution26::detail::
sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1, c2))>{
tag, data, ::std::tie(c0, c1, c2)};
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1, c2)};
} else if constexpr (requires { sender_type{at, at, at, at}; }) {
auto&& [tag, data, c0, c1] = sender;
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0, c1))>{
tag, data, ::std::tie(c0, c1)};
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0, c1)};
} else if constexpr (requires { sender_type{at, at, at}; }) {
auto&& [tag, data, c0] = sender;
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), decltype(::std::tie(c0))>{
tag, data, ::std::tie(c0)};
return ::beman::execution26::detail::sender_data{tag, data, ::std::tie(c0)};
} else if constexpr (requires { sender_type{at, at}; }) {
auto&& [tag, data] = sender;
return ::beman::execution26::detail::sender_data<decltype(tag), decltype(data), ::std::tuple<>>{
tag, data, ::std::tuple<>()};
return ::beman::execution26::detail::sender_data{tag, data, ::std::tuple<>()};
} else {
return ::beman::execution26::detail::sender_meta<void, void, void>{};
}
Expand Down
2 changes: 1 addition & 1 deletion tests/beman/execution26/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ foreach(test ${execution_tests})
add_test(NAME ${TEST_EXE} COMMAND $<TARGET_FILE:${TEST_EXE}>)
endforeach()

if(NOT PROJECT_IS_TOP_LEVEL)
if(ROJECT_IS_TOP_LEVEL)
# test if the targets are findable from the build directory
# cmake-format: off
add_test(NAME find-package-test
Expand Down

0 comments on commit b52f28c

Please sign in to comment.