Skip to content
Open
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
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
1 change: 1 addition & 0 deletions tests/beman/execution/exec-dependent-sender.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import std;
import beman.execution;
#else
#include <beman/execution/detail/dependent_sender.hpp>
#include <beman/execution/detail/get_scheduler.hpp>
#include <beman/execution/detail/just.hpp>
#include <beman/execution/detail/let.hpp>
#include <beman/execution/detail/read_env.hpp>
Expand Down
4 changes: 2 additions & 2 deletions tests/beman/execution/exec-get-domain.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ inline auto test_scheduler::schedule() const -> test_sched_sender { return {}; }

static_assert(test_std::scheduler<test_scheduler>);

// Env that has get_scheduler but no get_domain
// Env that has get_start_scheduler but no get_domain
struct env_with_scheduler {
auto query(test_std::get_scheduler_t) const noexcept { return test_scheduler{}; }
auto query(test_std::get_start_scheduler_t) const noexcept { return test_scheduler{}; }
};
} // namespace

Expand Down
7 changes: 2 additions & 5 deletions tests/beman/execution/exec-inline-scheduler.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,13 @@ auto test_sender_env_is_inline_attrs() {
auto sndr = test_std::schedule(test_std::inline_scheduler{});
auto attrs = test_std::get_env(sndr);
static_assert(std::same_as<decltype(attrs), test_detail::inline_attrs<test_std::set_value_t>>);

auto sched = test_std::get_completion_scheduler<test_std::set_value_t>(test_std::get_env(sndr), sndr);
static_assert(std::same_as<decltype(sched), test_std::inline_scheduler>);
}

auto test_inline_attrs_completion_scheduler() {
auto attrs = test_detail::inline_attrs<test_std::set_value_t>{};

struct test_env {
auto query(test_std::get_scheduler_t) const noexcept { return custom_scheduler{42}; }
auto query(test_std::get_start_scheduler_t) const noexcept { return custom_scheduler{42}; }
};

auto sched = attrs.query(test_std::get_completion_scheduler<test_std::set_value_t>, test_env{});
Expand Down Expand Up @@ -202,7 +199,7 @@ auto test_get_completion_scheduler_with_env() {
auto attrs = test_std::get_env(sndr);

struct test_env {
auto query(test_std::get_scheduler_t) const noexcept { return custom_scheduler{7}; }
auto query(test_std::get_start_scheduler_t) const noexcept { return custom_scheduler{7}; }
};

auto sched = test_std::get_completion_scheduler<test_std::set_value_t>(attrs, test_env{});
Expand Down
29 changes: 29 additions & 0 deletions tests/beman/execution/exec-just.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <test/execution.hpp>
#include <test/completion_test.hpp>
#include <test/thread_pool.hpp>
#include <beman/execution/detail/common.hpp>
#ifdef BEMAN_HAS_IMPORT_STD
import std;
Expand Down Expand Up @@ -164,6 +165,33 @@ auto test_just() -> void {
test_just_stopped();
}

auto test_just_attrs() -> void {
test::thread_pool pool;
struct test_domain : test_std::default_domain {};
struct test_env {
auto query(test_std::get_start_scheduler_t) const noexcept { return sch; }
static auto query(test_std::get_domain_t) noexcept { return test_domain{}; }

test::thread_pool::scheduler sch;
};
test_env env{pool.get_scheduler()};
auto domain1 = test_std::get_completion_domain<test_std::set_value_t>(test_std::get_env(test_std::just()), env);
auto domain2 =
test_std::get_completion_domain<test_std::set_error_t>(test_std::get_env(test_std::just_error(0)), env);
auto domain3 =
test_std::get_completion_domain<test_std::set_stopped_t>(test_std::get_env(test_std::just_stopped()), env);
static_assert(std::same_as<decltype(domain1), test_domain>);
static_assert(std::same_as<decltype(domain2), test_domain>);
static_assert(std::same_as<decltype(domain3), test_domain>);

auto sch1 = test_std::get_completion_scheduler<test_std::set_value_t>(test_std::get_env(test_std::just()), env);
auto sch2 =
test_std::get_completion_scheduler<test_std::set_error_t>(test_std::get_env(test_std::just_error(0)), env);
auto sch3 =
test_std::get_completion_scheduler<test_std::set_stopped_t>(test_std::get_env(test_std::just_stopped()), env);
ASSERT(pool.get_scheduler() == sch1 && sch1 == sch2 && sch2 == sch3);
}

struct memory_env {
std::pmr::polymorphic_allocator<> allocator;
auto query(const test_std::get_allocator_t&) const noexcept { return allocator; }
Expand Down Expand Up @@ -225,6 +253,7 @@ TEST(exec_just) {
try {
test_just_constraints();
test_just();
test_just_attrs();
test_completion_signatures();
test_just_allocator();
} catch (...) {
Expand Down
Loading
Loading