Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 include/beman/execution/detail/just.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct just_t {
template <typename... T>
requires ::beman::execution::detail::just_size<Completion, T...> &&
(::beman::execution::detail::movable_value<T> && ...)
auto operator()(T&&... arg) const {
auto operator()(T&&... arg) const noexcept((::std::is_nothrow_constructible_v<::std::remove_cvref_t<T>, T> && ...)) {
return ::beman::execution::detail::make_sender(
*this, ::beman::execution::detail::product_type{::std::forward<T>(arg)...});
}
Expand Down
3 changes: 2 additions & 1 deletion include/beman/execution/detail/let.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,9 @@ struct let_t {
try {
let_bind(state, receiver, ::std::forward<Args>(args)...);
} catch (...) {
if constexpr (not noexcept(let_bind(state, receiver, ::std::forward<Args>(args)...)))
if constexpr (not noexcept(let_bind(state, receiver, ::std::forward<Args>(args)...))) {
::beman::execution::set_error(::std::move(receiver), ::std::current_exception());
}
}
} else {
Tag()(::std::move(receiver), ::std::forward<Args>(args)...);
Expand Down
6 changes: 3 additions & 3 deletions include/beman/execution/detail/product_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ struct product_type_base<::std::index_sequence<I...>, T...>
}

template <::std::size_t J>
auto get() & -> decltype(auto) {
auto get() & noexcept -> decltype(auto) {
return this->element_get<J>(*this);
}
template <::std::size_t J>
auto get() && -> decltype(auto) {
auto get() && noexcept -> decltype(auto) {
return this->element_get<J>(::std::move(*this));
}
template <::std::size_t J>
auto get() const& -> decltype(auto) {
auto get() const& noexcept -> decltype(auto) {
return this->element_get<J>(*this);
}

Expand Down
2 changes: 1 addition & 1 deletion include/beman/execution/detail/run_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class run_loop {
auto operator=(const run_loop&) -> run_loop& = delete;
auto operator=(run_loop&&) -> run_loop& = delete;

auto get_scheduler() -> scheduler { return {this}; }
auto get_scheduler() noexcept -> scheduler { return {this}; }

auto run() -> void {
if (::std::lock_guard guard(this->mutex);
Expand Down
4 changes: 3 additions & 1 deletion include/beman/execution/detail/starts_on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ struct starts_on_t {
return ::beman::execution::let_value(
::beman::execution::schedule(scheduler),
[new_sender = ::beman::execution::detail::forward_like<Sender>(new_sender)]() mutable noexcept(
::std::is_nothrow_constructible_v<::std::decay_t<Sender>>) { return ::std::move(new_sender); });
::std::is_nothrow_constructible_v<::std::decay_t<Sender>, Sender>) {
return ::std::move(new_sender);
});
}

template <::beman::execution::scheduler Scheduler, ::beman::execution::sender Sender>
Expand Down
9 changes: 7 additions & 2 deletions include/beman/execution/detail/then.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,16 @@ struct then_exception<Comp, Fun, ::beman::execution::completion_signatures<Compl
template <typename Completion>
struct then_t : ::beman::execution::sender_adaptor_closure<then_t<Completion>> {
template <::beman::execution::detail::movable_value Fun>
auto operator()(Fun&& fun) const {
auto operator()(Fun&& fun) const
noexcept(::std::is_nothrow_constructible_v<::std::remove_cvref_t<Fun>, Fun>)
{
return ::beman::execution::detail::make_sender_adaptor(*this, std::forward<decltype(fun)>(fun));
}
template <::beman::execution::sender Sender, ::beman::execution::detail::movable_value Fun>
auto operator()(Sender&& sender, Fun&& fun) const {
auto operator()(Sender&& sender, Fun&& fun) const
noexcept(::std::is_nothrow_constructible_v<::std::remove_cvref_t<Sender>, Sender> &&
::std::is_nothrow_constructible_v<::std::remove_cvref_t<Fun>, Fun>)
{
auto domain{::beman::execution::detail::get_domain_early(sender)};
return ::beman::execution::transform_sender(
domain,
Expand Down
29 changes: 29 additions & 0 deletions tests/beman/execution/exec-let.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,42 @@ auto test_let_value_env() -> void {
ex::then([](auto s) { static_assert(ex::scheduler<decltype(s)>); }));
}

struct all_receiver {
using receiver_concept = test_std::receiver_t;
auto set_value(auto&&...) && noexcept {}
auto set_error(auto&&) && noexcept {}
auto set_stopped() && noexcept {}
};

auto test_completion_signatures() -> void {
test_std::sync_wait(
test::completion_test(test_std::just() | test_std::let_value([]() { return test_std::just(); })));
test_std::sync_wait(
test::completion_test(test_std::just() | test_std::let_value([]() noexcept { return test_std::just(); })));
test_std::sync_wait(test::completion_test(
test_std::just() | test_std::let_value([]() noexcept { return test_std::just_error(std::exception_ptr{}); })));

test_std::sync_wait(test::completion_test(test_std::let_value(
test_std::just(),
[]() noexcept { return test_std::just(); })));
static_assert(
std::is_nothrow_move_constructible_v<decltype(test_std::just() | test_std::then([]() noexcept {}))>);
static_assert(
requires{test_std::connect(test_std::just() | test_std::then([]() noexcept {}), all_receiver{}); });
static_assert(noexcept(all_receiver{}));
static_assert(noexcept(test_std::just()));
static_assert(noexcept(test_std::just().connect(all_receiver{})));
static_assert(
noexcept(test_std::connect(test_std::just(), all_receiver{})));
static_assert(noexcept(ex::then(test_std::just(), []() noexcept {})));
static_assert(noexcept(test_std::just() | ex::then([]() noexcept {})));
static_assert(
noexcept((test_std::just() | test_std::then([]() noexcept {})).connect(all_receiver{})));
static_assert(
noexcept(test_std::connect(test_std::just() | test_std::then([]() noexcept {}), all_receiver{})));
test_std::sync_wait(test::completion_test(test_std::let_value(
test_std::just(),
[]() noexcept { return test_std::just() | test_std::then([]() noexcept {}); })));
}
} // namespace

Expand Down
20 changes: 20 additions & 0 deletions tests/beman/execution/exec-starts-on.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <concepts>
#include <test/execution.hpp>
#include <test/completion_test.hpp>
#ifdef BEMAN_HAS_MODULES
import beman.execution;
#else
Expand Down Expand Up @@ -79,6 +80,24 @@ auto test_use(Scheduler&& scheduler, Sender&& sender) -> void {
//-dk:TODO test::check_type<void>(test_std::get_completion_signatures(s, test_std::test_std::env<>{}));
test_std::sync_wait(std::move(s));
}

auto test_starts_on_completions() {
test_std::sync_wait(test::completion_test(test_std::starts_on(test_std::inline_scheduler(),
test_std::just())));
test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([]() noexcept {})));
test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([]() noexcept {})));
test_std::sync_wait(test::completion_test(test_std::let_value(
test_std::just(),
[]() noexcept { return test_std::just(); })));
test_std::sync_wait(test::completion_test(test_std::let_value(
test_std::just(),
[]() noexcept { return test_std::just() | test_std::then([]() noexcept {}); })));
test_std::sync_wait(test::completion_test(test_std::let_value(
test_std::schedule(test_std::inline_scheduler()),
[]() noexcept { return test_std::just() | test_std::then([]() noexcept {}); })));
test_std::sync_wait(test::completion_test(test_std::starts_on(test_std::inline_scheduler(),
test_std::just() | test_std::then([]() noexcept {}))));
}
} // namespace

TEST(exec_starts_on) {
Expand All @@ -94,4 +113,5 @@ TEST(exec_starts_on) {
test_constraints<true>(scheduler{}, sender{});

test_use(scheduler{}, sender{});
test_starts_on_completions();
}
8 changes: 8 additions & 0 deletions tests/beman/execution/exec-then.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <tuple>
#include <utility>
#include <test/execution.hpp>
#include <test/completion_test.hpp>
#ifdef BEMAN_HAS_MODULES
import beman.execution;
#else
Expand Down Expand Up @@ -257,6 +258,12 @@ auto test_then_env() -> void {
}
}

auto test_then_completions() {
test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([](){})));
test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([]() noexcept {})));
test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([](auto&&...) noexcept {})));
}

} // namespace

TEST(exec_then) {
Expand All @@ -275,4 +282,5 @@ TEST(exec_then) {
test_then_allocator();

test_then_env();
test_then_completions();
}
Loading