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
3 changes: 3 additions & 0 deletions include/beman/execution/detail/basic_sender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.connect;
import beman.execution.detail.connect_all;
import beman.execution.detail.decays_to;
import beman.execution.detail.dependent_sender;
import beman.execution.detail.get_completion_signatures;
import beman.execution.detail.impls_for;
import beman.execution.detail.product_type;
Expand All @@ -28,6 +29,7 @@ import beman.execution.detail.sender_decompose;
#include <beman/execution/detail/completion_signatures_for.hpp>
#include <beman/execution/detail/connect.hpp>
#include <beman/execution/detail/decays_to.hpp>
#include <beman/execution/detail/dependent_sender.hpp>
#include <beman/execution/detail/get_completion_signatures.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/product_type.hpp>
Expand Down Expand Up @@ -110,6 +112,7 @@ struct basic_sender : ::beman::execution::detail::product_type<Tag, Data, Child.
}
#endif
template <::beman::execution::detail::decays_to<basic_sender> Self, typename... Env>
requires(sizeof...(Env) == 1) || (... && !::beman::execution::dependent_sender<Child>)
static consteval auto get_completion_signatures() noexcept {
if constexpr (requires { Tag::template get_completion_signatures<Self, Env...>(); })
return Tag::template get_completion_signatures<Self, Env...>();
Expand Down
11 changes: 11 additions & 0 deletions include/beman/execution/detail/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
#define BEMAN_SPECIALIZE_EXPORT template <>
#endif

#define BEMAN_EXECUTION_TRY_EVAL(rcvr, expr) \
do { \
try { \
(expr); \
} catch (...) { \
if constexpr (!noexcept((expr))) { \
::beman::execution::set_error(::std::move((rcvr)), ::std::current_exception()); \
} \
} \
} while (false)

// ----------------------------------------------------------------------------
/*!
* \mainpage Asynchronous Operation Support
Expand Down
41 changes: 41 additions & 0 deletions include/beman/execution/detail/dependent_sender.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// include/beman/execution/detail/dependent_sender.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef INCLUDED_BEMAN_EXECUTION_DETAIL_DEPENDENT_SENDER
#define INCLUDED_BEMAN_EXECUTION_DETAIL_DEPENDENT_SENDER

#include <beman/execution/detail/common.hpp>
#ifdef BEMAN_HAS_IMPORT_STD
import std;
#else
#include <concepts>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.get_completion_signatures;
import beman.execution.detail.sender;
#else
#include <beman/execution/detail/get_completion_signatures.hpp>
#include <beman/execution/detail/sender.hpp>
#endif

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

namespace beman::execution::detail {
template <auto>
auto non_dependent_sender_helper() noexcept -> void {}

template <typename Sender>
concept non_dependent_sender = ::beman::execution::sender<Sender> && requires {
::beman::execution::detail::non_dependent_sender_helper<::beman::execution::get_completion_signatures<Sender>()>();
};
} // namespace beman::execution::detail

namespace beman::execution {
template <typename Sender>
concept dependent_sender =
::beman::execution::sender<Sender> && !::beman::execution::detail::non_dependent_sender<Sender>;
} // namespace beman::execution

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

#endif // INCLUDED_BEMAN_EXECUTION_DETAIL_DEPENDENT_SENDER
44 changes: 26 additions & 18 deletions include/beman/execution/detail/into_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ import beman.execution.detail.completion_signatures;
import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.decayed_tuple;
import beman.execution.detail.default_impls;
import beman.execution.detail.dependent_sender;
import beman.execution.detail.dependent_sender_error;
import beman.execution.detail.env;
import beman.execution.detail.env_of_t;
import beman.execution.detail.error_types_of_t;
import beman.execution.detail.get_domain_early;
import beman.execution.detail.impls_for;
import beman.execution.detail.make_sender;
import beman.execution.detail.meta.combine;
import beman.execution.detail.sender;
import beman.execution.detail.sender_adaptor_closure;
import beman.execution.detail.sends_stopped;
import beman.execution.detail.set_error;
import beman.execution.detail.set_stopped;
Expand All @@ -39,13 +43,17 @@ import beman.execution.detail.variant_or_empty;
#include <beman/execution/detail/completion_signatures_for.hpp>
#include <beman/execution/detail/decayed_tuple.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/dependent_sender.hpp>
#include <beman/execution/detail/dependent_sender_error.hpp>
#include <beman/execution/detail/env.hpp>
#include <beman/execution/detail/env_of_t.hpp>
#include <beman/execution/detail/error_types_of_t.hpp>
#include <beman/execution/detail/get_domain_early.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/make_sender.hpp>
#include <beman/execution/detail/meta_combine.hpp>
#include <beman/execution/detail/sender.hpp>
#include <beman/execution/detail/sender_adaptor_closure.hpp>
#include <beman/execution/detail/sends_stopped.hpp>
#include <beman/execution/detail/set_error.hpp>
#include <beman/execution/detail/set_value.hpp>
Expand All @@ -56,25 +64,25 @@ import beman.execution.detail.variant_or_empty;
// ----------------------------------------------------------------------------

namespace beman::execution::detail {
struct into_variant_t {
struct into_variant_t : ::beman::execution::sender_adaptor_closure<into_variant_t> {
template <::beman::execution::sender Sender>
auto operator()(Sender&& sender) const {
// auto domain{::beman::execution::detail::get_domain_early(sender)};
//(void)domain;
return ::beman::execution::detail::make_sender(*this, {}, ::std::forward<Sender>(sender));
// return ::beman::execution::transform_sender(
// ::std::move(domain),
// ::beman::execution::detail::make_sender(*this, {}, ::std::forward<Sender>(sender))
//);
return ::beman::execution::transform_sender(
::beman::execution::detail::get_domain_early(sender),
::beman::execution::detail::make_sender(*this, {}, ::std::forward<Sender>(sender)));
}

auto operator()() const noexcept { return ::beman::execution::detail::make_sender_adaptor(*this); }

private:
template <typename... E>
using make_error_types = ::beman::execution::completion_signatures<::beman::execution::set_error_t(E)...>;

private:
template <typename, typename>
template <typename, typename...>
struct get_signatures;
template <typename Sender>
struct get_signatures<Sender> : get_signatures<Sender, ::beman::execution::env<>> {};
template <::beman::execution::sender Child, typename State, typename Env>
struct get_signatures<
::beman::execution::detail::basic_sender<::beman::execution::detail::into_variant_t, State, Child>,
Expand All @@ -99,9 +107,9 @@ struct into_variant_t {
};

public:
template <::beman::execution::sender Sender, typename Env>
template <::beman::execution::sender Sender, typename... Env>
static consteval auto get_completion_signatures() {
return get_signatures<::std::remove_cvref_t<Sender>, Env>::get();
return get_signatures<::std::remove_cvref_t<Sender>, Env...>::get();
}
struct impls_for : ::beman::execution::detail::default_impls {
struct get_state_impl {
Expand All @@ -119,14 +127,14 @@ struct into_variant_t {
if constexpr (::std::same_as<Tag, ::beman::execution::set_value_t>) {
using variant_type = typename State::type;
using tuple_type = ::beman::execution::detail::decayed_tuple<Args...>;
try {
if constexpr (sizeof...(Args) == 0u)
::beman::execution::set_value(::std::move(receiver));
else
if constexpr (std::same_as<variant_type, ::beman::execution::detail::empty_variant>) {
static_assert(sizeof...(Args) == 0);
BEMAN_EXECUTION_TRY_EVAL(receiver, ::beman::execution::set_value(std::move(receiver)));
} else {
BEMAN_EXECUTION_TRY_EVAL(
receiver,
::beman::execution::set_value(::std::move(receiver),
variant_type(tuple_type{::std::forward<Args>(args)...}));
} catch (...) {
::beman::execution::set_error(::std::move(receiver), ::std::current_exception());
variant_type(tuple_type{::std::forward<Args>(args)...})));
}
} else {
Tag()(::std::move(receiver), ::std::forward<Args>(args)...);
Expand Down
13 changes: 9 additions & 4 deletions include/beman/execution/detail/read_env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import beman.execution.detail.basic_sender;
import beman.execution.detail.completion_signatures;
import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.default_impls;
import beman.execution.detail.env_of_t;
import beman.execution.detail.get_env;
import beman.execution.detail.impls_for;
import beman.execution.detail.make_sender;
Expand All @@ -27,6 +28,7 @@ import beman.execution.detail.set_value;
#include <beman/execution/detail/completion_signatures.hpp>
#include <beman/execution/detail/completion_signatures_for.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/env_of_t.hpp>
#include <beman/execution/detail/get_env.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/make_sender.hpp>
Expand Down Expand Up @@ -59,18 +61,21 @@ struct read_env_t {
};

public:
template <typename Sender, typename... Env>
template <typename Sender, typename Env>
static consteval auto get_completion_signatures() {
return typename get_signatures<::std::remove_cvref_t<Sender>, Env...>::type{};
return typename get_signatures<::std::remove_cvref_t<Sender>, Env>::type{};
}
struct impls_for : ::beman::execution::detail::default_impls {
struct start_impl {
auto operator()(auto query, auto& receiver) const noexcept -> void {
template <typename Query, typename Receiver>
auto operator()(Query query, Receiver& receiver) const noexcept -> void {
try {
auto env{::beman::execution::get_env(receiver)};
::beman::execution::set_value(::std::move(receiver), query(env));
} catch (...) {
::beman::execution::set_error(::std::move(receiver), ::std::current_exception());
if constexpr (!std::is_nothrow_invocable_v<Query, ::beman::execution::env_of_t<Receiver>>) {
::beman::execution::set_error(::std::move(receiver), ::std::current_exception());
}
}
}
};
Expand Down
5 changes: 4 additions & 1 deletion include/beman/execution/detail/sender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ concept enable_sender =
} // namespace beman::execution::detail
namespace beman::execution {
template <typename Sender>
concept sender = ::beman::execution::detail::enable_sender<::std::remove_cvref_t<Sender>> &&
inline constexpr bool enable_sender = ::beman::execution::detail::enable_sender<Sender>;

template <typename Sender>
concept sender = ::beman::execution::enable_sender<::std::remove_cvref_t<Sender>> &&
requires(const ::std::remove_cvref_t<Sender>& sndr) {
{ ::beman::execution::get_env(sndr) } -> ::beman::execution::detail::queryable;
} && ::std::move_constructible<::std::remove_cvref_t<Sender>> &&
Expand Down
16 changes: 12 additions & 4 deletions include/beman/execution/detail/then.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import beman.execution.detail.completion_signatures;
import beman.execution.detail.completion_signatures_for;
import beman.execution.detail.completion_signatures_of_t;
import beman.execution.detail.default_impls;
import beman.execution.detail.dependent_sender;
import beman.execution.detail.dependent_sender_error;
import beman.execution.detail.env;
import beman.execution.detail.get_domain_early;
import beman.execution.detail.impls_for;
import beman.execution.detail.make_sender;
Expand All @@ -41,6 +44,9 @@ import beman.execution.detail.transform_sender;
#include <beman/execution/detail/completion_signatures_for.hpp>
#include <beman/execution/detail/completion_signatures_of_t.hpp>
#include <beman/execution/detail/default_impls.hpp>
#include <beman/execution/detail/dependent_sender.hpp>
#include <beman/execution/detail/dependent_sender_error.hpp>
#include <beman/execution/detail/env.hpp>
#include <beman/execution/detail/get_domain_early.hpp>
#include <beman/execution/detail/impls_for.hpp>
#include <beman/execution/detail/make_sender.hpp>
Expand Down Expand Up @@ -125,17 +131,19 @@ struct then_t : ::beman::execution::sender_adaptor_closure<then_t<Completion>> {
private:
template <typename, typename...>
struct get_signatures;
template <typename Comp, typename Fun, typename Child, typename... Env>
template <typename Sender>
struct get_signatures<Sender> : get_signatures<Sender, ::beman::execution::env<>> {};
template <typename Comp, typename Fun, typename Child, typename Env>
struct get_signatures<
::beman::execution::detail::basic_sender<::beman::execution::detail::then_t<Comp>, Fun, Child>,
Env...> {
Env> {
using type = ::beman::execution::detail::meta::unique<::beman::execution::detail::meta::combine<
::beman::execution::detail::meta::transform<
::beman::execution::detail::then_transform_t<Fun, Comp>::template transform,
::beman::execution::completion_signatures_of_t<Child, Env...>>,
::beman::execution::completion_signatures_of_t<Child, Env>>,
::std::conditional_t<
::beman::execution::detail::
then_exception<Comp, Fun, ::beman::execution::completion_signatures_of_t<Child, Env...>>::value,
then_exception<Comp, Fun, ::beman::execution::completion_signatures_of_t<Child, Env>>::value,
::beman::execution::completion_signatures<::beman::execution::set_error_t(::std::exception_ptr)>,
::beman::execution::completion_signatures<>>>>;
};
Expand Down
Loading
Loading