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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Using these operations some fundamental algorithms are implemented,
e.g.:

- `just(args...)` as the starting point of a work graph without a
specified scheduler`.
specified scheduler.
- `let_value(sender, fun)` to produce a sender based on `sender`'s
results.
- `starts_on(scheduler, sender)` to start `sender` on `scheduler`.
Expand Down
32 changes: 23 additions & 9 deletions include/beman/execution/detail/continues_on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_completion_scheduler;
import beman.execution.detail.get_completion_signatures;
import beman.execution.detail.get_env;
import beman.execution.detail.hide_sched;
import beman.execution.detail.impls_for;
import beman.execution.detail.join_env;
import beman.execution.detail.make_sender;
Expand All @@ -49,6 +50,7 @@ import beman.execution.detail.schedule;
import beman.execution.detail.schedule_from;
import beman.execution.detail.schedule_result_t;
import beman.execution.detail.scheduler;
import beman.execution.detail.sched_env;
import beman.execution.detail.sender;
import beman.execution.detail.sender_adaptor_closure;
import beman.execution.detail.sender_in;
Expand All @@ -71,6 +73,7 @@ import beman.execution.detail.start;
#include <beman/execution/detail/get_completion_domain.hpp>
#include <beman/execution/detail/get_completion_scheduler.hpp>
#include <beman/execution/detail/get_env.hpp>
#include <beman/execution/detail/hide_sched.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/join_env.hpp>
#include <beman/execution/detail/make_sender.hpp>
Expand All @@ -84,6 +87,7 @@ import beman.execution.detail.start;
#include <beman/execution/detail/schedule_from.hpp>
#include <beman/execution/detail/schedule_result_t.hpp>
#include <beman/execution/detail/scheduler.hpp>
#include <beman/execution/detail/sched_env.hpp>
#include <beman/execution/detail/sender.hpp>
#include <beman/execution/detail/sender_adaptor.hpp>
#include <beman/execution/detail/sender_in.hpp>
Expand Down Expand Up @@ -155,23 +159,33 @@ struct continues_on_t {

template <typename Scheduler, typename ChildAttrs>
struct attrs {
template <typename Tag, typename Env>
auto wrap_env(const Env& env) const noexcept {
using tag_t = ::std::conditional_t<::std::same_as<Tag, void>, ::beman::execution::set_value_t, Tag>;
if constexpr (requires { ::beman::execution::get_completion_scheduler<tag_t>(this->child_attrs, env); }) {
auto compl_sch = ::beman::execution::get_completion_scheduler<tag_t>(this->child_attrs, env);
return ::beman::execution::detail::join_env(
::beman::execution::detail::sched_env(::std::move(compl_sch)),
::beman::execution::detail::hide_sched(env));
} else {
return ::beman::execution::detail::fwd_env(env);
}
}

template <typename Tag, typename... Env>
requires requires(const Scheduler& scheduler, const Env&... env) {
::beman::execution::get_completion_scheduler<Tag>(scheduler,
::beman::execution::detail::fwd_env(env)...);
requires requires(const attrs& self, const Scheduler& scheduler, const Env&... env) {
::beman::execution::get_completion_scheduler<Tag>(scheduler, self.template wrap_env<Tag>(env)...);
}
auto query(::beman::execution::get_completion_scheduler_t<Tag>, const Env&... env) const noexcept {
return ::beman::execution::get_completion_scheduler<Tag>(this->sch,
::beman::execution::detail::fwd_env(env)...);
return ::beman::execution::get_completion_scheduler<Tag>(this->sch, this->template wrap_env<Tag>(env)...);
}

template <typename Tag, typename... Env>
requires requires(const Scheduler& scheduler, const Env&... env) {
::beman::execution::get_completion_domain<Tag>(scheduler, ::beman::execution::detail::fwd_env(env)...);
requires requires(const attrs& self, const Scheduler& scheduler, const Env&... env) {
::beman::execution::get_completion_domain<Tag>(scheduler, self.template wrap_env<Tag>(env)...);
}
auto query(::beman::execution::get_completion_domain_t<Tag>, const Env&... env) const noexcept {
return ::beman::execution::get_completion_domain<Tag>(this->sch,
::beman::execution::detail::fwd_env(env)...);
return ::beman::execution::get_completion_domain<Tag>(this->sch, this->template wrap_env<Tag>(env)...);
}

template <typename Q, typename... Args>
Expand Down
12 changes: 6 additions & 6 deletions include/beman/execution/detail/get_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import std;
import beman.execution.detail.default_domain;
import beman.execution.detail.forwarding_query;
import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_scheduler;
import beman.execution.detail.get_start_scheduler;
import beman.execution.detail.hide_sched;
import beman.execution.detail.set_value;
#else
#include <beman/execution/detail/default_domain.hpp>
#include <beman/execution/detail/forwarding_query.hpp>
#include <beman/execution/detail/get_completion_domain.hpp>
#include <beman/execution/detail/get_scheduler.hpp>
#include <beman/execution/detail/get_start_scheduler.hpp>
#include <beman/execution/detail/hide_sched.hpp>
#include <beman/execution/detail/set_value.hpp>
#endif
Expand All @@ -40,20 +40,20 @@ struct get_domain_t : ::beman::execution::forwarding_query_t {
return type{};
} else if constexpr (requires {
::beman::execution::get_completion_domain<::beman::execution::set_value_t>(
::beman::execution::get_scheduler(env),
::beman::execution::get_start_scheduler(env),
::beman::execution::detail::hide_sched(env));
}) {
using type = decltype(auto(::beman::execution::get_completion_domain<::beman::execution::set_value_t>(
::beman::execution::get_scheduler(env), ::beman::execution::detail::hide_sched(env))));
::beman::execution::get_start_scheduler(env), ::beman::execution::detail::hide_sched(env))));
static_assert(noexcept(type{}));
return type{};
} else if constexpr (requires {
::beman::execution::get_completion_domain<::beman::execution::set_value_t>(
::beman::execution::get_scheduler(env),
::beman::execution::get_start_scheduler(env),
::beman::execution::detail::hide_sched(env));
}) {
using type = decltype(auto(::beman::execution::get_completion_domain<::beman::execution::set_value_t>(
::beman::execution::get_scheduler(env), ::beman::execution::detail::hide_sched(env))));
::beman::execution::get_start_scheduler(env), ::beman::execution::detail::hide_sched(env))));
static_assert(noexcept(type{}));
return type{};
} else {
Expand Down
5 changes: 4 additions & 1 deletion include/beman/execution/detail/get_start_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import beman.execution.detail.scheduler;

// ----------------------------------------------------------------------------

namespace beman::execution {
namespace beman::execution::detail {
struct get_start_scheduler_t : ::beman::execution::forwarding_query_t {
template <typename Env>
requires requires(const get_start_scheduler_t& self, const Env& env) {
Expand All @@ -31,7 +31,10 @@ struct get_start_scheduler_t : ::beman::execution::forwarding_query_t {
return ::std::as_const(env).query(*this);
}
};
} // namespace beman::execution::detail

namespace beman::execution {
using get_start_scheduler_t = ::beman::execution::detail::get_start_scheduler_t;
inline constexpr get_start_scheduler_t get_start_scheduler{};
} // namespace beman::execution

Expand Down
4 changes: 2 additions & 2 deletions include/beman/execution/detail/hide_sched.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import beman.execution.detail.queryable;

namespace beman::execution::detail {
struct get_domain_t;
struct get_scheduler_t;
struct get_start_scheduler_t;

template <::beman::execution::detail::queryable Q>
struct hide_sched_t {
Expand All @@ -35,7 +35,7 @@ struct hide_sched_t {
auto query(::beman::execution::detail::get_domain_t, Args&&... args) const noexcept -> void = delete;

template <typename... Args>
auto query(::beman::execution::detail::get_scheduler_t, Args&&... args) const noexcept -> void = delete;
auto query(::beman::execution::detail::get_start_scheduler_t, Args&&... args) const noexcept -> void = delete;

const Q& q;
};
Expand Down
12 changes: 6 additions & 6 deletions include/beman/execution/detail/inline_attrs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_completion_scheduler;
import beman.execution.detail.get_domain;
import beman.execution.detail.get_scheduler;
import beman.execution.detail.get_start_scheduler;
#else
#include <beman/execution/detail/get_completion_domain.hpp>
#include <beman/execution/detail/get_completion_scheduler.hpp>
#include <beman/execution/detail/get_domain.hpp>
#include <beman/execution/detail/get_scheduler.hpp>
#include <beman/execution/detail/get_start_scheduler.hpp>
#endif

// ----------------------------------------------------------------------------
Expand All @@ -24,14 +24,14 @@ namespace beman::execution::detail {
template <typename Tag>
struct inline_attrs {
template <typename Env>
requires requires(const Env& env) { ::beman::execution::get_scheduler(env); }
constexpr auto query(const ::beman::execution::get_completion_scheduler_t<Tag>&, const Env& env) const noexcept {
return ::beman::execution::get_scheduler(env);
requires requires(const Env& env) { ::beman::execution::get_start_scheduler(env); }
static constexpr auto query(const ::beman::execution::get_completion_scheduler_t<Tag>&, const Env& env) noexcept {
return ::beman::execution::get_start_scheduler(env);
}

template <typename Env>
requires requires(const Env& env) { ::beman::execution::get_domain(env); }
constexpr auto query(const ::beman::execution::get_completion_domain_t<Tag>&, const Env& env) const noexcept {
static constexpr auto query(const ::beman::execution::get_completion_domain_t<Tag>&, const Env& env) noexcept {
return ::beman::execution::get_domain(env);
}
};
Expand Down
10 changes: 4 additions & 6 deletions include/beman/execution/detail/inline_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import beman.execution.detail.get_forward_progress_guarantee;
import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_completion_scheduler;
import beman.execution.detail.get_domain;
import beman.execution.detail.get_scheduler;
import beman.execution.detail.get_start_scheduler;
import beman.execution.detail.inline_attrs;
import beman.execution.detail.operation_state;
import beman.execution.detail.receiver;
Expand All @@ -32,7 +32,7 @@ import beman.execution.detail.set_value;
#include <beman/execution/detail/get_completion_scheduler.hpp>
#include <beman/execution/detail/get_domain.hpp>
#include <beman/execution/detail/get_forward_progress_guarantee.hpp>
#include <beman/execution/detail/get_scheduler.hpp>
#include <beman/execution/detail/get_start_scheduler.hpp>
#include <beman/execution/detail/inline_attrs.hpp>
#include <beman/execution/detail/operation_state.hpp>
#include <beman/execution/detail/receiver.hpp>
Expand All @@ -54,10 +54,10 @@ struct inline_scheduler {
}

template <typename Env>
requires requires(const Env& env) { ::beman::execution::get_scheduler(env); }
requires requires(const Env& env) { ::beman::execution::get_start_scheduler(env); }
static auto query(const ::beman::execution::get_completion_scheduler_t<::beman::execution::set_value_t>&,
const Env& env) noexcept {
return ::beman::execution::get_scheduler(env);
return ::beman::execution::get_start_scheduler(env);
}

template <typename Env>
Expand Down Expand Up @@ -89,8 +89,6 @@ struct inline_scheduler {
-> state<Rcvr> {
return {::std::forward<Rcvr>(receiver)};
}

inline_scheduler query(const ::beman::execution::get_scheduler_t&) const noexcept { return {}; }
};

static constexpr auto schedule() noexcept -> sender { return {}; }
Expand Down
9 changes: 9 additions & 0 deletions include/beman/execution/detail/just.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import beman.execution.detail.completion_signatures;
import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.default_impls;
import beman.execution.detail.impls_for;
import beman.execution.detail.inline_attrs;
import beman.execution.detail.make_sender;
import beman.execution.detail.movable_value;
import beman.execution.detail.product_type;
Expand All @@ -29,6 +30,7 @@ import beman.execution.detail.set_value;
#include <beman/execution/detail/completion_signatures_for.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/inline_attrs.hpp>
#include <beman/execution/detail/make_sender.hpp>
#include <beman/execution/detail/movable_value.hpp>
#include <beman/execution/detail/product_type.hpp>
Expand Down Expand Up @@ -77,6 +79,13 @@ struct just_t {
return typename get_signatures<::std::remove_cvref_t<Sender>>::type{};
}
struct impls_for : ::beman::execution::detail::default_impls {
struct get_attrs_impl {
auto operator()(const auto&) const noexcept -> ::beman::execution::detail::inline_attrs<Completion> {
return {};
}
};
static constexpr auto get_attrs{get_attrs_impl{}};

struct start_impl {
template <typename State>
auto operator()(State& state, auto& receiver) const noexcept -> void {
Expand Down
2 changes: 1 addition & 1 deletion include/beman/execution/detail/on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct on_t : ::beman::execution::sender_adaptor_closure<on_t> {
if constexpr (::beman::execution::scheduler<decltype(data)>) {
return ::std::bool_constant<::std::invocable<::beman::execution::get_start_scheduler_t, Env>>{};
} else {
::std::bool_constant<
return ::std::bool_constant<
::std::invocable<::beman::execution::get_completion_scheduler_t<::beman::execution::set_value_t>,
::beman::execution::env_of_t<decltype(child)>,
Env>>{};
Expand Down
39 changes: 39 additions & 0 deletions include/beman/execution/detail/read_env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.data_type;
import beman.execution.detail.default_impls;
import beman.execution.detail.env_of_t;
import beman.execution.detail.get_completion_domain;
import beman.execution.detail.get_completion_scheduler;
import beman.execution.detail.get_domain;
import beman.execution.detail.get_env;
import beman.execution.detail.get_start_scheduler;
import beman.execution.detail.impls_for;
import beman.execution.detail.make_sender;
import beman.execution.detail.sender;
Expand All @@ -32,7 +36,11 @@ import beman.execution.detail.set_value;
#include <beman/execution/detail/data_type.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/env_of_t.hpp>
#include <beman/execution/detail/get_completion_domain.hpp>
#include <beman/execution/detail/get_completion_scheduler.hpp>
#include <beman/execution/detail/get_domain.hpp>
#include <beman/execution/detail/get_env.hpp>
#include <beman/execution/detail/get_start_scheduler.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/make_sender.hpp>
#include <beman/execution/detail/set_error.hpp>
Expand Down Expand Up @@ -71,6 +79,37 @@ struct read_env_t {
return typename get_signatures<::std::remove_cvref_t<Sender>, Env>::type{};
}
struct impls_for : ::beman::execution::detail::default_impls {
template <typename Query>
struct attrs {
template <typename Tag, typename Env>
requires requires(const Env& env) { ::beman::execution::get_start_scheduler(env); } &&
(::std::same_as<Tag, ::beman::execution::set_value_t> ||
(!::std::is_nothrow_invocable_v<Query, const Env&> &&
::std::same_as<Tag, ::beman::execution::set_error_t>))
constexpr auto query(const ::beman::execution::get_completion_scheduler_t<Tag>&,
const Env& env) const noexcept {
return ::beman::execution::get_start_scheduler(env);
}

template <typename Tag, typename Env>
requires requires(const Env& env) { ::beman::execution::get_domain(env); } &&
(::std::same_as<Tag, ::beman::execution::set_value_t> ||
(!::std::is_nothrow_invocable_v<Query, const Env&> &&
::std::same_as<Tag, ::beman::execution::set_error_t>))
constexpr auto query(const ::beman::execution::get_completion_domain_t<Tag>&,
const Env& env) const noexcept {
return ::beman::execution::get_domain(env);
}
};

struct get_attrs_impl {
template <typename Query>
auto operator()(const Query&) const noexcept {
return attrs<Query>{};
}
};
static constexpr auto get_attrs{get_attrs_impl{}};

struct start_impl {
template <typename Query, typename Receiver>
auto operator()(Query query, Receiver& receiver) const noexcept -> void {
Expand Down
13 changes: 5 additions & 8 deletions include/beman/execution/detail/sched_env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import std;
#include <utility>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.default_domain;
import beman.execution.detail.get_domain;
import beman.execution.detail.get_start_scheduler;
#else
#include <beman/execution/detail/default_domain.hpp>
#include <beman/execution/detail/get_domain.hpp>
#include <beman/execution/detail/get_start_scheduler.hpp>
#endif
Expand All @@ -31,15 +29,14 @@ class sched_env {

public:
template <typename S>
explicit sched_env(S sch) noexcept(std::is_nothrow_constructible_v<Scheduler, S>) : sched(::std::move(sch)) {}
explicit sched_env(S sch) noexcept(::std::is_nothrow_constructible_v<Scheduler, S>) : sched(::std::move(sch)) {}

auto query(::beman::execution::get_start_scheduler_t) const noexcept { return this->sched; }

auto query(::beman::execution::get_domain_t q) const noexcept {
if constexpr (requires { this->sched.query(q); })
return this->sched.query(q);
else
return ::beman::execution::default_domain{};
auto query(::beman::execution::get_domain_t q) const noexcept
requires requires { this->sched.query(q); }
{
return this->sched.query(q);
}
};

Expand Down
11 changes: 4 additions & 7 deletions include/beman/execution/detail/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,13 +455,9 @@ class propagator<StopSource, StopToken> {

template <typename Sched, typename Env, typename Alloc>
auto make_sched(const Env& env, const Alloc& alloc) noexcept -> Sched {
if constexpr (requires {
::std::make_obj_using_allocator<Sched>(alloc, ::beman::execution::get_start_scheduler(env));
}) {
if constexpr (requires { Sched(::beman::execution::get_start_scheduler(env)); }) {
return ::std::make_obj_using_allocator<Sched>(alloc, ::beman::execution::get_start_scheduler(env));
} else if constexpr (requires {
::std::make_obj_using_allocator<Sched>(alloc, ::beman::execution::get_scheduler(env));
}) {
} else if constexpr (requires { Sched(::beman::execution::get_scheduler(env)); }) {
return ::std::make_obj_using_allocator<Sched>(alloc, ::beman::execution::get_scheduler(env));
} else if constexpr (::std::default_initializable<Sched>) {
return Sched();
Expand Down Expand Up @@ -802,7 +798,8 @@ class task {
template <typename ParentPromise>
auto as_awaitable(ParentPromise& parent) && noexcept -> awaiter<ParentPromise> {
auto env = ::beman::execution::get_env(parent);
return awaiter<ParentPromise>(parent, ::std::move(this->handle), env);
return awaiter<ParentPromise>(
::std::coroutine_handle<ParentPromise>::from_promise(parent), ::std::move(this->handle), env);
}

private:
Expand Down
Loading
Loading