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
42 changes: 18 additions & 24 deletions include/exec/async_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "../stdexec/__detail/__optional.hpp"
#include "../stdexec/execution.hpp"
#include "../stdexec/stop_token.hpp"
#include "completion_signatures.hpp"
#include "env.hpp"

#include "../stdexec/__detail/__atomic.hpp"
Expand All @@ -38,6 +39,9 @@ namespace experimental::execution
struct __impl;
struct async_scope;

template <class _Sender, class _Env>
struct __future;

template <class _A>
concept __async_scope = requires(_A& __a) {
{ __a.nest(STDEXEC::just()) } -> sender_of<STDEXEC::set_value_t()>;
Expand Down Expand Up @@ -130,9 +134,9 @@ namespace experimental::execution

template <__decays_to<__when_empty_sender> _Self, class... _Env>
static consteval auto get_completion_signatures()
-> __completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>, __env_t<_Env>...>
{
return {};
return STDEXEC::get_completion_signatures<__copy_cvref_t<_Self, _Constrained>,
__env_t<_Env>...>();
}

__impl const * __scope_;
Expand Down Expand Up @@ -256,9 +260,9 @@ namespace experimental::execution

template <__decays_to<__nest_sender> _Self, class... _Env>
static consteval auto get_completion_signatures()
-> __completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>, __env_t<_Env>...>
{
return {};
return STDEXEC::get_completion_signatures<__copy_cvref_t<_Self, _Constrained>,
__env_t<_Env>...>();
}

__impl const * __scope_;
Expand Down Expand Up @@ -442,22 +446,11 @@ namespace experimental::execution
static_cast<_Fn*>(nullptr)));
#endif

template <class... _Ts>
using __decay_values_t = completion_signatures<set_value_t(__decay_t<_Ts>...)>;

template <class _Ty>
using __decay_error_t = completion_signatures<set_error_t(__decay_t<_Ty>)>;

template <class _Sender, class _Env>
using __future_completions_t = __transform_completion_signatures_of_t<
_Sender,
__env_t<_Env>,
completion_signatures<set_stopped_t(), set_error_t(std::exception_ptr)>,
__decay_values_t,
__decay_error_t>;
using __future_completions_t = STDEXEC::completion_signatures_of_t<__future<_Sender, _Env>>;

template <class _Completions>
using __completions_as_variant = __mapply<
using __completions_as_variant_t = __mapply<
__mtransform<__q<__completion_as_tuple_t>, __mbind_front_q<std::variant, std::monostate>>,
_Completions>;

Expand Down Expand Up @@ -532,7 +525,7 @@ namespace experimental::execution
std::mutex __mutex_;
__future_step __step_ = __future_step::__created;
std::unique_ptr<__future_state_base, __dynamic_delete<__future_state_base>> __no_future_;
__completions_as_variant<_Completions> __data_;
__completions_as_variant_t<_Completions> __data_;
__intrusive_queue<&__subscription::__next_> __subscribers_;
__env_t<_Env> __env_;
};
Expand Down Expand Up @@ -652,9 +645,6 @@ namespace experimental::execution
struct __future
{
private:
template <class _Self>
using __completions_t = __future_completions_t<__mfront<_Sender, _Self>, _Env>;

template <class _Receiver>
using __future_opstate_t = __future_opstate<_Sender, _Env, _Receiver>;

Expand Down Expand Up @@ -684,7 +674,6 @@ namespace experimental::execution
}

template <__decays_to<__future> _Self, receiver _Receiver>
requires receiver_of<_Receiver, __completions_t<_Self>>
STDEXEC_EXPLICIT_THIS_BEGIN(auto connect)(this _Self&& __self, _Receiver __rcvr)
-> __future_opstate_t<_Receiver>
{
Expand All @@ -694,9 +683,14 @@ namespace experimental::execution
STDEXEC_EXPLICIT_THIS_END(connect)

template <__decays_to<__future> _Self, class... _OtherEnv>
static consteval auto get_completion_signatures() -> __completions_t<_Self>
static consteval auto get_completion_signatures()
{
return {};
return exec::transform_completion_signatures(
STDEXEC::get_completion_signatures<_Sender, __env_t<_Env>>(),
exec::decay_arguments<set_value_t>(),
exec::decay_arguments<set_error_t>(),
{},
completion_signatures<set_stopped_t(), set_error_t(std::exception_ptr)>());
}

private:
Expand Down
19 changes: 10 additions & 9 deletions include/exec/at_coroutine_exit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "../stdexec/execution.hpp"

#include "any_sender_of.hpp"
#include "completion_signatures.hpp"

#include <exception>
#include <tuple>
Expand Down Expand Up @@ -79,23 +80,23 @@ namespace experimental::execution
{
using sender_concept = STDEXEC::sender_tag;

template <class... _Env>
using __completions_t = __mapply<__mremove<set_stopped_t(), __q<completion_signatures>>,
__completion_signatures_of_t<_Sender, _Env...>>;

template <receiver _Receiver>
requires sender_to<_Sender, __receiver<_Receiver>>
auto connect(_Receiver __rcvr) && noexcept //
-> connect_result_t<_Sender, __receiver<_Receiver>>
auto connect(_Receiver __rcvr) && //
noexcept(__nothrow_connectable<_Sender, __receiver<_Receiver>>)
-> connect_result_t<_Sender, __receiver<_Receiver>>
{
return STDEXEC::connect(static_cast<_Sender&&>(__sender_),
__receiver<_Receiver>{static_cast<_Receiver&&>(__rcvr)});
}

template <__same_as<__sender> _Self, class... _Env>
static consteval auto get_completion_signatures() -> __completions_t<_Env...>
static consteval auto get_completion_signatures()
{
return {};
return exec::transform_completion_signatures(
STDEXEC::get_completion_signatures<_Sender, _Env...>(),
{},
{},
exec::ignore_completion());
}

auto get_env() const noexcept -> env_of_t<_Sender>
Expand Down
57 changes: 32 additions & 25 deletions include/exec/env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ namespace experimental::execution

struct read_with_default_t;

template <class _Tag, class _Default, class _Receiver>
template <class _Query, class _Default, class _Receiver>
struct __opstate
{
constexpr explicit __opstate(_Default&& __default, _Receiver&& __rcvr)
noexcept(__nothrow_move_constructible<_Default>)
: __default_(static_cast<_Default&&>(__default))
, __rcvr_(static_cast<_Receiver&&>(__rcvr))
{}
Expand All @@ -136,10 +137,10 @@ namespace experimental::execution
{
STDEXEC_TRY
{
if constexpr (__callable<_Tag, env_of_t<_Receiver>>)
if constexpr (__callable<_Query, env_of_t<_Receiver>>)
{
auto const & __env = get_env(__rcvr_);
STDEXEC::set_value(std::move(__rcvr_), _Tag{}(__env));
auto const & __env = STDEXEC::get_env(__rcvr_);
STDEXEC::set_value(std::move(__rcvr_), _Query()(__env));
}
else
{
Expand All @@ -148,7 +149,10 @@ namespace experimental::execution
}
STDEXEC_CATCH_ALL
{
STDEXEC::set_error(std::move(__rcvr_), std::current_exception());
if constexpr (!__nothrow_callable<_Query, env_of_t<_Receiver>>)
{
STDEXEC::set_error(std::move(__rcvr_), std::current_exception());
}
}
}

Expand All @@ -157,37 +161,41 @@ namespace experimental::execution
_Receiver __rcvr_;
};

template <class _Tag, class _Default>
template <class _Query, class _Default>
struct __sender
{
using sender_concept = STDEXEC::sender_tag;

template <class _Env>
using __value_t =
__minvoke<__mwith_default<__mbind_back_q<__call_result_t, _Env>, _Default>, _Tag>;
template <class _Env>
using __default_t = __if_c<__callable<_Tag, _Env>, __ignore, _Default>;

template <class _Env>
using __completions_t =
completion_signatures<set_value_t(__value_t<_Env>), set_error_t(std::exception_ptr)>;
using __default_t = __if_c<__callable<_Query, _Env>, __ignore, _Default>;

template <__decays_to<__sender> _Self, class _Receiver>
requires receiver_of<_Receiver, __completions_t<env_of_t<_Receiver>>>
constexpr STDEXEC_EXPLICIT_THIS_BEGIN(auto connect)(this _Self&& __self, _Receiver __rcvr)
noexcept(std::is_nothrow_move_constructible_v<_Receiver>)
-> __opstate<_Tag, __default_t<env_of_t<_Receiver>>, _Receiver>
-> __opstate<_Query, __default_t<env_of_t<_Receiver>>, _Receiver>
{
using __opstate_t = __opstate<_Tag, __default_t<env_of_t<_Receiver>>, _Receiver>;
using __opstate_t = __opstate<_Query, __default_t<env_of_t<_Receiver>>, _Receiver>;
return __opstate_t{static_cast<_Self&&>(__self).__default_,
static_cast<_Receiver&&>(__rcvr)};
}
STDEXEC_EXPLICIT_THIS_END(connect)

template <class, class _Env>
static consteval auto get_completion_signatures() -> __completions_t<_Env>
static consteval auto get_completion_signatures() noexcept
{
return {};
if constexpr (__nothrow_callable<_Query, _Env>)
{
return STDEXEC::completion_signatures<set_value_t(__call_result_t<_Query, _Env>)>();
}
else if constexpr (__callable<_Query, _Env>)
{
return STDEXEC::completion_signatures<set_value_t(__call_result_t<_Query, _Env>),
set_error_t(std::exception_ptr)>();
}
else
{
return STDEXEC::completion_signatures<set_value_t(_Default)>();
}
}

STDEXEC_ATTRIBUTE(no_unique_address)
Expand All @@ -196,11 +204,11 @@ namespace experimental::execution

struct __read_with_default_t
{
template <class _Tag, class _Default>
constexpr auto
operator()(_Tag, _Default&& __default) const -> __sender<_Tag, __decay_t<_Default>>
template <class _Query, class _Default>
constexpr auto operator()(_Query, _Default&& __default) const //
noexcept(__nothrow_decay_copyable<_Default>)
{
return {static_cast<_Default&&>(__default)};
return __sender<_Query, __decay_t<_Default>>{static_cast<_Default&&>(__default)};
}
};
} // namespace __read_with_default
Expand Down Expand Up @@ -229,9 +237,8 @@ namespace experimental::execution

template <__decays_to<__sender> _Self, class... _Env>
static consteval auto get_completion_signatures()
-> __completion_signatures_of_t<__copy_cvref_t<_Self, _Sender>, _Env...>
{
return {};
return STDEXEC::get_completion_signatures<__copy_cvref_t<_Self, _Sender>, _Env...>();
}

template <__decays_to<__sender> _Self, class _Receiver>
Expand Down
8 changes: 2 additions & 6 deletions include/exec/fork_join.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ namespace experimental::execution
{
struct fork_join_t;

struct PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE
{};

struct INVALID_ARGUMENTS_TO_FORK_JOIN
{};
struct INVALID_ARGUMENTS_TO_FORK_JOIN;

namespace _fork_join
{
Expand Down Expand Up @@ -247,7 +243,7 @@ namespace experimental::execution
else if constexpr (!__decay_copyable_results_t::value)
{
return STDEXEC::__throw_compile_time_error< //
_WHAT_(PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE),
_WHAT_(_PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE_),
_IN_ALGORITHM_(exec::fork_join_t)>();
}
else
Expand Down
62 changes: 41 additions & 21 deletions include/exec/libdispatch_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
# endif

# include "../stdexec/execution.hpp"

# include "completion_signatures.hpp"
# include "sender_for.hpp"

# include <dispatch/dispatch.h>

namespace experimental::execution
Expand Down Expand Up @@ -253,30 +256,11 @@ namespace experimental::execution
{
using sender_concept = STDEXEC::sender_tag;

template <class CvSender, class... Env>
using with_error_invoke_t = STDEXEC::__if_c<
STDEXEC::__value_types_t<STDEXEC::__completion_signatures_of_t<CvSender, Env...>,
STDEXEC::__mbind_front_q<bulk_non_throwing_t, Fun, Shape>,
STDEXEC::__q<STDEXEC::__mand>>::value,
STDEXEC::completion_signatures<>,
STDEXEC::__eptr_completion_t>;

template <class... Tys>
using set_value_t =
STDEXEC::completion_signatures<STDEXEC::set_value_t(STDEXEC::__decay_t<Tys>...)>;

template <class Self, class... Env>
using _completions_t = STDEXEC::__transform_completion_signatures_t<
STDEXEC::__completion_signatures_of_t<STDEXEC::__copy_cvref_t<Self, Sender>, Env...>,
with_error_invoke_t<STDEXEC::__copy_cvref_t<Self, Sender>, Env...>,
set_value_t>;

template <class Self, class Receiver>
using bulk_op_state_t =
bulk_op_state<STDEXEC::__copy_cvref_t<Self, Sender>, Receiver, Shape, Fun>;

template <STDEXEC::__decays_to<bulk_sender> Self, STDEXEC::receiver Receiver>
requires STDEXEC::receiver_of<Receiver, _completions_t<Self, STDEXEC::env_of_t<Receiver>>>
STDEXEC_EXPLICIT_THIS_BEGIN(auto connect)(this Self &&self, Receiver rcvr)
noexcept(STDEXEC::__nothrow_constructible_from<bulk_op_state_t<Self, Receiver>,
libdispatch_queue &,
Expand All @@ -294,11 +278,47 @@ namespace experimental::execution
STDEXEC_EXPLICIT_THIS_END(connect)

template <STDEXEC::__decays_to<bulk_sender> Self, class... Env>
static consteval auto get_completion_signatures() -> _completions_t<Self, Env...>
static consteval auto get_completion_signatures()
{
return {};
using namespace STDEXEC;
return exec::transform_completion_signatures(
STDEXEC::get_completion_signatures<__copy_cvref_t<Self, Sender>, Env...>(),
[]<class... Args>()
{
using value_sig_t = set_value_t(__decay_t<Args>...);
using arg_pack_t = __tuple<Shape, __decay_t<Args> &...>;
// using arg_pack_t = __if_c<__same_as<_AlgoTag, bulk_chunked_t>,
// __tuple<Shape, Shape, Args&...>,
// __tuple<Shape, Args&...>>;
if constexpr (!__decay_copyable<Args...>)
{
return exec::throw_compile_time_error<
_WHAT_(_PREDECESSOR_RESULTS_ARE_NOT_DECAY_COPYABLE_),
_WHERE_(_IN_ALGORITHM_, bulk_t),
_WITH_ARGUMENTS_(Args...),
_WITH_PRETTY_SENDER_<__copy_cvref_t<Self, Sender>>,
_WITH_ENVIRONMENT_(Env...)>();
}
else if constexpr (__nothrow_applicable<Fun &, arg_pack_t>)
{
return completion_signatures<value_sig_t>();
}
else if constexpr (__applicable<Fun &, arg_pack_t>)
{
return completion_signatures<value_sig_t, set_error_t(std::exception_ptr)>();
}
else
{
return STDEXEC::__throw_compile_time_error<
_WHAT_(_FUNCTION_IS_NOT_CALLABLE_WITH_THE_GIVEN_ARGUMENTS_),
_WHERE_(_IN_ALGORITHM_, bulk_t),
_WITH_FUNCTION_(Fun &),
__mapply<__qf<_WITH_ARGUMENTS_>, arg_pack_t>>();
}
});
}

[[nodiscard]]
auto get_env() const noexcept -> STDEXEC::env_of_t<Sender const &>
{
return STDEXEC::get_env(sndr_);
Expand Down
3 changes: 1 addition & 2 deletions include/exec/linux/io_uring_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,8 +1298,7 @@ namespace experimental::execution
}

template <class>
[[nodiscard]]
static consteval auto get_completion_signatures() noexcept -> __completions_t
static consteval auto get_completion_signatures()
{
return __completions_t{};
}
Expand Down
Loading
Loading