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
20 changes: 10 additions & 10 deletions include/exec/completion_signatures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@ namespace experimental::execution
detail::normalize(static_cast<Sigs*>(nullptr))...));
} // namespace detail

///////////////////////////////////////////////////////////////////////////////////////////////////
// get_child_completion_signatures
template <STDEXEC::sender _Parent, STDEXEC::sender _Child, class... _Env>
[[nodiscard]]
consteval auto get_child_completion_signatures()
{
return STDEXEC::get_completion_signatures<STDEXEC::__copy_cvref_t<_Parent, _Child>,
STDEXEC::__fwd_env_t<_Env>...>();
}

//! Creates a compile-time completion signatures type from explicit and deduced signature types.
//!
//! This function is a compile-time helper that constructs a completion signatures type
Expand Down Expand Up @@ -86,6 +76,16 @@ namespace experimental::execution
return {};
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// get_child_completion_signatures
template <STDEXEC::sender _Parent, STDEXEC::sender _Child, class... _Env>
[[nodiscard]]
consteval auto get_child_completion_signatures()
{
return STDEXEC::get_completion_signatures<STDEXEC::__copy_cvref_t<_Parent, _Child>,
STDEXEC::__fwd_env_t<_Env>...>();
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// concat_completion_signatures
inline constexpr STDEXEC::__detail::__concat_completion_signatures_fn
Expand Down
97 changes: 46 additions & 51 deletions include/exec/repeat_n.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "../stdexec/__detail/__optional.hpp"
#include "../stdexec/execution.hpp"

#include "completion_signatures.hpp"
#include "sequence.hpp"
#include "trampoline_scheduler.hpp"

Expand Down Expand Up @@ -105,21 +106,24 @@ namespace experimental::execution
__opstate_base<_Receiver> *__state_;
};

template <class _Child>
using __bouncy_sndr_t =
__result_of<exec::sequence, schedule_result_t<trampoline_scheduler>, _Child &>;

template <class _Child, class _Receiver>
constexpr bool __nothrow_connect =
__nothrow_invocable<STDEXEC::schedule_t, trampoline_scheduler>
&& __nothrow_invocable<sequence_t, schedule_result_t<trampoline_scheduler>, _Child &>
&& __nothrow_connectable<__bouncy_sndr_t<_Child>, _Receiver>;

template <class _Child, class _Receiver>
struct __opstate final : __opstate_base<_Receiver>
{
using __receiver_t = __receiver<_Receiver>;
using __bouncy_sndr_t =
__result_of<exec::sequence, schedule_result_t<trampoline_scheduler>, _Child &>;
using __child_op_t = STDEXEC::connect_result_t<__bouncy_sndr_t, __receiver_t>;

static constexpr bool __nothrow_connect =
__nothrow_invocable<STDEXEC::schedule_t, trampoline_scheduler>
&& __nothrow_invocable<sequence_t, schedule_result_t<trampoline_scheduler>, _Child &>
&& __nothrow_connectable<__bouncy_sndr_t, __receiver_t>;
using __child_op_t = STDEXEC::connect_result_t<__bouncy_sndr_t<_Child>, __receiver_t>;

constexpr explicit __opstate(std::size_t __count, _Child __child, _Receiver __rcvr)
noexcept(__nothrow_move_constructible<_Child> && __nothrow_connect)
noexcept(__nothrow_move_constructible<_Child> && __nothrow_connect<_Child, _Receiver>)
: __opstate_base<_Receiver>{static_cast<_Receiver &&>(__rcvr), __count}
, __child_(std::move(__child))
{
Expand All @@ -141,7 +145,7 @@ namespace experimental::execution
}
}

constexpr auto __connect() noexcept(__nothrow_connect) -> __child_op_t &
constexpr auto __connect() noexcept(__nothrow_connect<_Child, _Receiver>) -> __child_op_t &
{
return __child_op_.__emplace_from(STDEXEC::connect,
exec::sequence(STDEXEC::schedule(trampoline_scheduler{}),
Expand Down Expand Up @@ -171,7 +175,7 @@ namespace experimental::execution
}
STDEXEC_CATCH_ALL
{
if constexpr (!__nothrow_connect)
if constexpr (!__nothrow_connect<_Child, _Receiver>)
{
STDEXEC::set_error(std::move(this->__rcvr_), std::current_exception());
}
Expand All @@ -186,36 +190,6 @@ namespace experimental::execution
STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE
__opstate(std::size_t, _Child, _Receiver) -> __opstate<_Child, _Receiver>;

template <class _Child, class... _Args>
using __values_t =
// There's something funny going on with __if_c here. Use std::conditional_t instead. :-(
std::conditional_t<(sizeof...(_Args) == 0),
completion_signatures<>,
__mexception<_WHAT_(_INVALID_ARGUMENT_),
_WHERE_(_IN_ALGORITHM_, repeat_n_t),
_WHY_(_THE_INPUT_SENDER_MUST_HAVE_VOID_VALUE_COMPLETION_),
_WITH_PRETTY_SENDER_<_Child>>>;

template <class _Error>
using __error_t = completion_signatures<set_error_t(__decay_t<_Error>)>;

template <typename _Sender, typename... _Env>
using __with_eptr_completion_t = __eptr_completion_unless_t<__mbool<
__cmplsigs::__partitions_of_t<
__completion_signatures_of_t<_Sender, _Env...>>::__nothrow_decay_copyable::__errors::value
&& (__nothrow_connectable<_Sender, __receiver_archetype<_Env>> && ...)>>;

template <class _Child, class... _Env>
using __completions_t = STDEXEC::__transform_completion_signatures_t<
__completion_signatures_of_t<_Child &, _Env...>,
STDEXEC::__transform_completion_signatures_t<
__completion_signatures_of_t<STDEXEC::schedule_result_t<trampoline_scheduler>, _Env...>,
__with_eptr_completion_t<_Child, _Env...>,
__cmplsigs::__default_set_value,
__error_t>,
__mbind_front_q<__values_t, _Child>::template __f,
__error_t>;

struct __impls : __sexpr_defaults
{
static constexpr auto __get_attrs =
Expand All @@ -225,19 +199,40 @@ namespace experimental::execution
return {STDEXEC::schedule(trampoline_scheduler{}), const_cast<_Child &>(__child)};
};

template <class _Sender>
requires(!STDEXEC::dependent_sender<__child_of<_Sender>>)
template <class _Sender, class... _Env>
static consteval auto __get_completion_signatures()
{
// TODO: port this to use constant evaluation
return __completions_t<__child_of<_Sender>>{};
}
using __child_t = __child_of<_Sender>;

template <class _Sender, class _Env>
static consteval auto __get_completion_signatures()
{
// TODO: port this to use constant evaluation
return __completions_t<__child_of<_Sender>, _Env>{};
auto __completions = transform_completion_signatures(
STDEXEC::get_completion_signatures<__bouncy_sndr_t<__child_t>, _Env...>(),
// transform for set_value completions:
[]<class... _Args>()
{
if constexpr (sizeof...(_Args) == 0)
return completion_signatures<set_value_t()>();
else
return STDEXEC::__throw_compile_time_error<
_WHAT_(_INVALID_ARGUMENT_),
_WHERE_(_IN_ALGORITHM_, repeat_n_t),
_WHY_(_THE_INPUT_SENDER_MUST_HAVE_VOID_VALUE_COMPLETION_),
_WITH_PRETTY_SENDER_<__child_t &>>();
},
// transform for set_error completions:
decay_arguments<set_error_t, repeat_n_t>());

STDEXEC_IF_OK(__completions)
{
// Conditionally add set_error(std::exception_ptr) when appropriate
if constexpr (__completions.template __contains<set_error_t(std::exception_ptr)>())
return __completions; // NOLINT(bugprone-branch-clone)
else if constexpr (sizeof...(_Env) == 0)
return STDEXEC::__throw_dependent_sender_error<__child_t>();
else if constexpr ((__nothrow_connect<__child_t, __receiver_archetype<_Env>> || ...))
return __completions;
else
return concat_completion_signatures(__completions, __eptr_completion_t());
}
}

static constexpr auto __connect = //
Expand Down
6 changes: 6 additions & 0 deletions include/stdexec/__detail/__completion_signatures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "__tuple.hpp" // IWYU pragma: keep for __tuple
#include "__utility.hpp"

#include <exception>
#include <type_traits>

#include "__prologue.hpp"
Expand Down Expand Up @@ -432,6 +433,11 @@ namespace STDEXEC
}
};

using __eptr_completion_t = completion_signatures<set_error_t(std::exception_ptr)>;

template <class _NoExcept>
using __eptr_completion_unless_t = __if<_NoExcept, completion_signatures<>, __eptr_completion_t>;

#if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS()

template <class, class... _What, class... _Values>
Expand Down
5 changes: 1 addition & 4 deletions include/stdexec/__detail/__finally.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ namespace STDEXEC
}
else
{
using __is_nothrow_t = __nothrow_decay_copyable_results_t<__initial_completions_t>;
// The finally sender's completion signatures are ...
return STDEXEC::__concat_completion_signatures(
// ... the initial sender's completions with value types decayed ...
Expand All @@ -333,9 +332,7 @@ namespace STDEXEC
__decay_arguments<set_value_t, __finally_t>()),
// ... and the final sender's error and stopped completions ...
STDEXEC::__transform_completion_signatures(__final_completions,
__ignore_completion()),
// ... and possibly a set_error(exception_ptr) completion.
__eptr_completion_unless_t<__is_nothrow_t>());
__ignore_completion()));
}
}
}
Expand Down
11 changes: 3 additions & 8 deletions include/stdexec/__detail/__transform_completion_signatures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
#include "__get_completion_signatures.hpp"
#include "__meta.hpp"

#include <exception>

#include "__prologue.hpp"

namespace STDEXEC
Expand Down Expand Up @@ -444,7 +442,9 @@ namespace STDEXEC
{
if constexpr (__decay_copyable<_Args...>)
{
return completion_signatures<_SetTag(__decay_t<_Args>...)>();
return __concat_completion_signatures(
completion_signatures<_SetTag(__decay_t<_Args>...)>(),
__eptr_completion_unless_t<__nothrow_decay_copyable_t<_Args...>>());
}
else
{
Expand Down Expand Up @@ -591,11 +591,6 @@ namespace STDEXEC
}
}

using __eptr_completion_t = completion_signatures<set_error_t(std::exception_ptr)>;

template <class _NoExcept>
using __eptr_completion_unless_t = __if<_NoExcept, completion_signatures<>, __eptr_completion_t>;

// The following utilities are needed fairly often:
template <class _Fun, class... _Args>
requires __invocable<_Fun, _Args...>
Expand Down
Loading