Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions include/beman/execution/detail/when_all_with_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,38 @@ import std;
#include <utility>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.basic_sender;
import beman.execution.detail.common_domain;
import beman.execution.detail.compl_domain;
import beman.execution.detail.default_impls;
import beman.execution.detail.env;
import beman.execution.detail.forward_like;
import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_completion_signatures;
import beman.execution.detail.into_variant;
import beman.execution.detail.make_sender;
import beman.execution.detail.sender;
import beman.execution.detail.sender_for;
import beman.execution.detail.set_value;
import beman.execution.detail.set_error;
import beman.execution.detail.set_stopped;
import beman.execution.detail.when_all;
#else
#include <beman/execution/detail/basic_sender.hpp>
#include <beman/execution/detail/common_domain.hpp>
#include <beman/execution/detail/compl_domain.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/env.hpp>
#include <beman/execution/detail/forward_like.hpp>
#include <beman/execution/detail/get_completion_domain.hpp>
#include <beman/execution/detail/get_completion_signatures.hpp>
#include <beman/execution/detail/into_variant.hpp>
#include <beman/execution/detail/make_sender.hpp>
#include <beman/execution/detail/sender.hpp>
#include <beman/execution/detail/sender_for.hpp>
#include <beman/execution/detail/set_value.hpp>
#include <beman/execution/detail/set_error.hpp>
#include <beman/execution/detail/set_stopped.hpp>
#include <beman/execution/detail/when_all.hpp>
#endif

Expand All @@ -45,6 +63,84 @@ struct when_all_with_variant_t {
auto operator()(Sender&&... sender) const {
return ::beman::execution::detail::make_sender(*this, {}, ::std::forward<Sender>(sender)...);
}

private:
template <typename, typename...>
struct get_signatures;
template <typename Sender>
struct get_signatures<Sender> : get_signatures<Sender, ::beman::execution::env<>> {};
template <typename Data, typename Env, typename... Children>
struct get_signatures<::beman::execution::detail::
basic_sender<::beman::execution::detail::when_all_with_variant_t, Data, Children...>,
Env> {

static consteval auto get() {
using sndr_t = decltype(::beman::execution::when_all(
::beman::execution::into_variant(::std::declval<Children>())...));
return ::beman::execution::get_completion_signatures<sndr_t, Env>();
}
};

template <typename... Children>
struct attrs {
template <typename Tag, typename... Env>
using child_domain_t =
::beman::execution::detail::common_domain_t<::beman::execution::detail::compl_domain_of_t<
Tag,
::std::invoke_result_t<::beman::execution::into_variant_t, Children>,
Env...>...>;

template <typename... Env>
requires requires { typename child_domain_t<::beman::execution::set_value_t, Env...>; }
static auto query(::beman::execution::get_completion_domain_t<::beman::execution::set_value_t>,
const Env&...) noexcept -> child_domain_t<::beman::execution::set_value_t, Env...> {
return {};
}

template <typename... Env>
requires requires {
typename ::beman::execution::detail::common_domain_t<
child_domain_t<::beman::execution::set_value_t, Env...>,
child_domain_t<::beman::execution::set_error_t, Env...>,
child_domain_t<::beman::execution::set_stopped_t, Env...>>;
}
static auto query(::beman::execution::get_completion_domain_t<::beman::execution::set_error_t>,
const Env&...) noexcept
-> ::beman::execution::detail::common_domain_t<child_domain_t<::beman::execution::set_value_t, Env...>,
child_domain_t<::beman::execution::set_error_t, Env...>,
child_domain_t<::beman::execution::set_stopped_t, Env...>> {
return {};
}

template <typename... Env>
requires requires {
typename ::beman::execution::detail::common_domain_t<
child_domain_t<::beman::execution::set_value_t, Env...>,
child_domain_t<::beman::execution::set_stopped_t, Env...>>;
}
static auto query(::beman::execution::get_completion_domain_t<::beman::execution::set_stopped_t>,
const Env&...) noexcept
-> ::beman::execution::detail::common_domain_t<child_domain_t<::beman::execution::set_value_t, Env...>,
child_domain_t<::beman::execution::set_stopped_t, Env...>> {
return {};
}
};

public:
template <::beman::execution::sender Sender, typename... Env>
static consteval auto get_completion_signatures() {
return get_signatures<::std::remove_cvref_t<Sender>, Env...>::get();
}

struct impls_for : ::beman::execution::detail::default_impls {
struct get_attrs_impl {
template <typename... Children>
auto operator()(const auto&, const Children&...) const noexcept {
return attrs<Children...>{};
}
};
static constexpr auto get_attrs{get_attrs_impl{}};
};
};
} // namespace beman::execution::detail

Expand Down
10 changes: 10 additions & 0 deletions tests/beman/execution/exec-dependent-sender.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import beman.execution;
#include <beman/execution/detail/let.hpp>
#include <beman/execution/detail/read_env.hpp>
#include <beman/execution/detail/then.hpp>
#include <beman/execution/detail/when_all.hpp>
#include <beman/execution/detail/when_all_with_variant.hpp>
#endif

TEST(exec_dependent_sender) {
Expand All @@ -26,4 +28,12 @@ TEST(exec_dependent_sender) {
test_std::read_env(test_std::get_scheduler),
[](auto sched) noexcept { return test_std::just(sched); }) |
test_std::then([](auto sched) noexcept {}))>);
static_assert(
test_std::dependent_sender<decltype(test_std::when_all(test_std::read_env(test_std::get_scheduler)))>);
static_assert(test_std::dependent_sender<decltype(test_std::when_all_with_variant(
test_std::read_env(test_std::get_scheduler)))>);
static_assert(!test_std::dependent_sender<decltype(test_std::when_all(test_std::just()))>);
static_assert(!test_std::dependent_sender<decltype(test_std::when_all_with_variant(test_std::just()))>);
static_assert(test_std::dependent_sender<decltype(test_std::when_all(
test_std::just(), test_std::read_env(test_std::get_scheduler)))>);
}
4 changes: 2 additions & 2 deletions tests/beman/execution/exec-parallel-scheduler.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ struct thread_pool_backend : replaceability::parallel_scheduler_backend {
const std::size_t n = chunk_count - i; // the count of `bulk_task` which are not enqueued successfully

guard.unlock();
if (n == 1uz) {
if (i == 1uz) {
cv.notify_one();
} else if (n > 1uz) {
} else if (i > 1uz) {
cv.notify_all();
}

Expand Down
Loading