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
8 changes: 5 additions & 3 deletions include/beman/execution/detail/enter_scope_sender_in.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
#include <beman/execution/detail/common.hpp>
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.enter_scope_sender;
import beman.execution.detail.env;
import beman.execution.detail.exit_scope_sender_of_t;
import beman.execution.detail.sender_in;
#else
#include <beman/execution/detail/enter_scope_sender.hpp>
#include <beman/execution/detail/env.hpp>
#include <beman/execution/detail/exit_scope_sender_of_t.hpp>
#include <beman/execution/detail/sender_in.hpp>
#endif

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

namespace beman::execution {
template <typename Sender, typename... Env>
/*!
* \brief An enter scope sender that can operate in the environment `Env...`.
* \headerfile beman/execution/execution.hpp <beman/execution/execution.hpp>
Expand All @@ -31,9 +32,10 @@ template <typename Sender, typename... Env>
* signature is unary, and the type of the value models `exit_sender_in<Env...>`.
* - Semantic: The above exit sender undoes the action of the enter scope sender which sent it.
*/
template <typename Sender, typename Env = ::beman::execution::env<>>
concept enter_scope_sender_in =
::beman::execution::enter_scope_sender<Sender> && ::beman::execution::sender_in<Sender, Env...> &&
requires { typename ::beman::execution::exit_scope_sender_of_t<Sender, Env...>; };
::beman::execution::enter_scope_sender<Sender> && ::beman::execution::sender_in<Sender, Env> &&
requires { typename ::beman::execution::exit_scope_sender_of_t<Sender, Env>; };
} // namespace beman::execution

// ----------------------------------------------------------------------------
Expand Down
56 changes: 8 additions & 48 deletions include/beman/execution/detail/exit_scope_sender_of_t.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,20 @@ import std;
#include <type_traits>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.completion_signatures_of_t;
import beman.execution.detail.completion_signatures;
import beman.execution.detail.enter_scope_sender;
import beman.execution.detail.env;
import beman.execution.detail.exit_scope_sender_in;
import beman.execution.detail.set_value;
import beman.execution.detail.single_sender_value_type;
#else
#include <beman/execution/detail/completion_signatures_of_t.hpp>
#include <beman/execution/detail/completion_signatures.hpp>
#include <beman/execution/detail/enter_scope_sender.hpp>
#include <beman/execution/detail/env.hpp>
#include <beman/execution/detail/exit_scope_sender_in.hpp>
#include <beman/execution/detail/set_value.hpp>
#include <beman/execution/detail/single_sender_value_type.hpp>
#endif

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

namespace beman::execution {

namespace detail {

/// `true` if `Sig` is a value completion signature, i.e. `set_value_t(Args...)`.
template <typename Sig>
inline constexpr bool is_value_completion_sig = false;
template <typename... Args>
inline constexpr bool is_value_completion_sig<::beman::execution::set_value_t(Args...)> = true;

/// Finds the type T from the unique unary set_value_t(T) in a signature list.
/// Not defined (substitution failure) if there are zero or two or more value signatures,
/// or if the sole value signature is not unary.
template <typename... Sigs>
struct single_value_sender;

template <typename T, typename... Rest>
requires(!(::beman::execution::detail::is_value_completion_sig<Rest> || ...))
struct single_value_sender<::beman::execution::set_value_t(T), Rest...> {
using type = T;
};

template <typename First, typename... Rest>
requires(!::beman::execution::detail::is_value_completion_sig<First>)
struct single_value_sender<First, Rest...> : ::beman::execution::detail::single_value_sender<Rest...> {};

/// Helper that extracts the exit scope sender type from a list of completion signatures.
template <typename Signatures, typename... Env>
struct extract_exit_scope_sender;

template <typename... Sigs, typename... Env>
requires requires { typename ::beman::execution::detail::single_value_sender<Sigs...>::type; } &&
::beman::execution::
exit_scope_sender_in<typename ::beman::execution::detail::single_value_sender<Sigs...>::type, Env...>
struct extract_exit_scope_sender<::beman::execution::completion_signatures<Sigs...>, Env...> {
using type = typename ::beman::execution::detail::single_value_sender<Sigs...>::type;
};

} // namespace detail

/*!
* \brief Represents the type of exit scope sender which an asynchronous operation formed from
* `Sender` in `Env...` yield on completion.
Expand All @@ -77,9 +36,10 @@ struct extract_exit_scope_sender<::beman::execution::completion_signatures<Sigs.
* If there is no value completion signature, or if there are two or more value completion signatures, this type is not
* defined.
*/
template <::beman::execution::enter_scope_sender Sender, typename... Env>
using exit_scope_sender_of_t = typename ::beman::execution::detail::
extract_exit_scope_sender<::beman::execution::completion_signatures_of_t<Sender, Env...>, Env...>::type;
template <::beman::execution::enter_scope_sender Sender, typename Env = ::beman::execution::env<>>
requires ::beman::execution::
exit_scope_sender_in<::beman::execution::detail::single_sender_value_type<Sender, Env>, Env>
using exit_scope_sender_of_t = ::beman::execution::detail::single_sender_value_type<Sender, Env>;
} // namespace beman::execution

// ----------------------------------------------------------------------------
Expand Down
2 changes: 0 additions & 2 deletions tests/beman/execution/exec-scope-snd-concepts.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,4 @@ TEST(exec_scope_snd_concepts) {

using t5 = sender<test_std::set_value_t(int), test_std::set_error_t(int), test_std::set_stopped_t()>;
static_assert(!test_std::enter_scope_sender_in<t5, test_std::env<>>);

// TODO: use sender<...>
}
Loading