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
2 changes: 0 additions & 2 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ stdexec should follow.
* Assume that schedulers and receivers contain nothing but a pointer and
are cheap to copy. Take them by value.

* Do not use `tag_invoke` anywhere. It's deprecated.

* In a sender adaptor, a reasonable way to constrain
`ThisSender<InnerSender>::connect(OuterReceiver)` is by
requiring `sender_to<InnerSender, ThisReceiver<OuterReceiver>>`.
Expand Down
2 changes: 1 addition & 1 deletion include/exec/env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace experimental::execution
noexcept(STDEXEC::__nothrow_queryable_with<_Env, _OtherQuery, _Args...>)
-> STDEXEC::__query_result_t<_Env, _OtherQuery, _Args...>
{
return STDEXEC::__query<_OtherQuery>()(__env_, static_cast<_Args&&>(__args)...);
return __env_.query(_OtherQuery(), static_cast<_Args&&>(__args)...);
}

STDEXEC_ATTRIBUTE(no_unique_address)
Expand Down
53 changes: 0 additions & 53 deletions include/exec/sequence_senders.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import stdexec;
# include "../stdexec/__detail/__receivers.hpp"
# include "../stdexec/__detail/__senders.hpp"
# include "../stdexec/__detail/__stop_token.hpp"
# include "../stdexec/__detail/__tag_invoke.hpp"
# include "../stdexec/__detail/__transform_sender.hpp"
# include "../stdexec/__detail/__type_traits.hpp"
# include "../stdexec/__detail/__utility.hpp"
Expand Down Expand Up @@ -158,20 +157,6 @@ namespace experimental::execution
"set_value_t() or set_stopped_t()");
return __rcvr.set_next(static_cast<_Item&&>(__item));
}

template <receiver _Receiver, sender _Item>
requires __has_set_next_member<_Receiver, _Item>
|| __tag_invocable<set_next_t, _Receiver&, _Item>
[[deprecated("the use of tag_invoke for set_next is deprecated")]]
auto operator()(_Receiver& __rcvr, _Item&& __item) const
noexcept(__nothrow_tag_invocable<set_next_t, _Receiver&, _Item>)
-> __tag_invoke_result_t<set_next_t, _Receiver&, _Item>
{
static_assert(next_sender<__tag_invoke_result_t<set_next_t, _Receiver&, _Item>>,
"The sender returned from set_next is required to complete with "
"set_value_t() or set_stopped_t()");
return __tag_invoke(*this, __rcvr, static_cast<_Item&&>(__item));
}
};
} // namespace __sequence_sndr

Expand Down Expand Up @@ -304,9 +289,6 @@ namespace experimental::execution
concept __with_consteval_static_member =
__minvocable_q<__consteval_static_member_result_t, _Sequence, _Env...>;

template <class _Sequence, class... _Env>
concept __with_tag_invoke = __tag_invocable<get_item_types_t, _Sequence, _Env...>;

template <class _Sequence, class... _Env>
[[nodiscard]]
consteval auto __get_item_types_helper()
Expand Down Expand Up @@ -337,11 +319,6 @@ namespace experimental::execution
{
return STDEXEC_REMOVE_REFERENCE(_Sequence)::template get_item_types<_Sequence>();
}
else if constexpr (__with_tag_invoke<_Sequence, _Env...>)
{
using __result_t = __tag_invoke_result_t<get_item_types_t, _Sequence, _Env...>;
return __result_t();
}
else if constexpr (sender_in<_Sequence, _Env...>
&& !enable_sequence_sender<STDEXEC::__decay_t<_Sequence>>)
{
Expand Down Expand Up @@ -790,9 +767,6 @@ namespace experimental::execution
concept __subscribable_with_static_member =
__minvocable_q<__subscribe_static_member_result_t, _Sequence, _Receiver>;

template <class _Sequence, class _Receiver>
concept __subscribable_with_tag_invoke = __tag_invocable<subscribe_t, _Sequence, _Receiver>;

struct subscribe_t
{
private:
Expand Down Expand Up @@ -942,33 +916,6 @@ namespace experimental::execution
}
}

template <sender _Sequence,
receiver _Receiver,
auto _DeclFn = __get_declfn<_Sequence, _Receiver>()>
requires STDEXEC::__callable<decltype(_DeclFn)>
|| STDEXEC::__tag_invocable<subscribe_t,
__transform_sender_result_t<_Sequence, _Receiver>,
_Receiver>
[[deprecated("the use of tag_invoke for subscribe is deprecated")]]
auto operator()(_Sequence&& __sequence, _Receiver __rcvr) const noexcept(
__nothrow_callable<transform_sender_t, _Sequence, env_of_t<_Receiver>>
&& STDEXEC::__nothrow_tag_invocable<subscribe_t,
__transform_sender_result_t<_Sequence, _Receiver>,
_Receiver>)
-> STDEXEC::__tag_invoke_result_t<subscribe_t,
__transform_sender_result_t<_Sequence, _Receiver>,
_Receiver>
{
using __tfx_seq_t = __transform_sender_result_t<_Sequence, _Receiver>;
using __result_t = __tag_invoke_result_t<subscribe_t, __tfx_seq_t, _Receiver>;
__check_operation_state<__result_t>();
auto&& __env = STDEXEC::get_env(__rcvr);
auto&& __tfx_seq = STDEXEC::transform_sender(static_cast<_Sequence&&>(__sequence), __env);
return STDEXEC::__tag_invoke(subscribe_t{},
static_cast<__tfx_seq_t&&>(__tfx_seq),
static_cast<_Receiver&&>(__rcvr));
}

static constexpr auto query(STDEXEC::forwarding_query_t) noexcept -> bool
{
return false;
Expand Down
11 changes: 6 additions & 5 deletions include/exec/thread_pool_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,14 @@ namespace experimental::execution

struct attrs
{
template <STDEXEC::__forwarding_query Tag, class... As>
requires STDEXEC::__queryable_with<STDEXEC::env_of_t<Sender>, Tag, As...>
template <class _Env2 = STDEXEC::env_of_t<Sender>,
STDEXEC::__forwarding_query Tag,
class... As>
requires STDEXEC::__queryable_with<_Env2, Tag, As...>
auto query(Tag, As&&... as) const
noexcept(STDEXEC::__nothrow_queryable_with<STDEXEC::env_of_t<Sender>, Tag, As...>)
-> decltype(auto)
noexcept(STDEXEC::__nothrow_queryable_with<_Env2, Tag, As...>) -> decltype(auto)
{
return STDEXEC::__query<Tag>()(STDEXEC::get_env(sndr_.sndr_), static_cast<As&&>(as)...);
return STDEXEC::get_env(sndr_.sndr_).query(Tag(), static_cast<As&&>(as)...);
}

bulk_sender const & sndr_;
Expand Down
44 changes: 0 additions & 44 deletions include/exec/timed_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,6 @@ namespace experimental::execution
static_assert(time_point<__decay_t<decltype(__sched.now())>>);
return __sched.now();
}

template <class _Scheduler>
requires __has_now<_Scheduler> || __tag_invocable<now_t, _Scheduler const &>
[[deprecated("the use of tag_invoke for exec::now() is deprecated")]]
STDEXEC_ATTRIBUTE(always_inline) //
auto operator()(_Scheduler const &__sched) const
noexcept(__nothrow_tag_invocable<now_t, _Scheduler const &>)
-> __decay_t<__tag_invoke_result_t<now_t, _Scheduler const &>>
{
static_assert(time_point<__decay_t<__tag_invoke_result_t<now_t, _Scheduler const &>>>);
return __tag_invoke(now_t{}, __sched);
}
};
} // namespace __now

Expand Down Expand Up @@ -196,22 +184,6 @@ namespace experimental::execution
static_assert(sender<decltype(__sched.schedule_after(__duration))>);
return __sched.schedule_after(__duration);
}

template <class _Scheduler>
requires __has_schedule_after_member<_Scheduler>
|| __tag_invocable<schedule_after_t, _Scheduler, duration_of_t<_Scheduler> const &>
[[deprecated("the use of tag_invoke for exec::schedule_after is deprecated")]]
STDEXEC_ATTRIBUTE(always_inline) //
auto operator()(_Scheduler &&__sched, duration_of_t<_Scheduler> const &__duration) const
noexcept(
__nothrow_tag_invocable<schedule_after_t, _Scheduler, duration_of_t<_Scheduler> const &>)
-> __tag_invoke_result_t<schedule_after_t, _Scheduler, duration_of_t<_Scheduler> const &>
{
static_assert(
sender<
__tag_invoke_result_t<schedule_after_t, _Scheduler, duration_of_t<_Scheduler> const &>>);
return __tag_invoke(schedule_after, static_cast<_Scheduler &&>(__sched), __duration);
}
};

struct schedule_after_t : __schedule_after_base_t
Expand Down Expand Up @@ -279,22 +251,6 @@ namespace experimental::execution
static_assert(sender<decltype(__sched.schedule_at(__time_point))>);
return __sched.schedule_at(__time_point);
}

template <class _Scheduler>
requires __has_schedule_at_member<_Scheduler>
|| __tag_invocable<schedule_at_t, _Scheduler, time_point_of_t<_Scheduler> const &>
[[deprecated("the use of tag_invoke for exec::schedule_at is deprecated")]]
STDEXEC_ATTRIBUTE(always_inline) //
auto operator()(_Scheduler &&__sched, time_point_of_t<_Scheduler> const &__time_point) const
noexcept(
__nothrow_tag_invocable<schedule_at_t, _Scheduler, time_point_of_t<_Scheduler> const &>)
-> __tag_invoke_result_t<schedule_at_t, _Scheduler, time_point_of_t<_Scheduler> const &>
{
static_assert(
sender<
__tag_invoke_result_t<schedule_at_t, _Scheduler, time_point_of_t<_Scheduler> const &>>);
return __tag_invoke(schedule_at, static_cast<_Scheduler &&>(__sched), __time_point);
}
};

struct schedule_at_t : __schedule_at_base_t
Expand Down
10 changes: 5 additions & 5 deletions include/nvexec/stream/common.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,13 @@ namespace nv::execution
template <class Sender>
struct stream_sender_attrs
{
template <__forwarding_query Query>
requires __queryable_with<env_of_t<Sender>, Query>
template <class _Env2 = env_of_t<Sender>, __forwarding_query Query>
requires __queryable_with<_Env2, Query>
STDEXEC_ATTRIBUTE(nodiscard)
constexpr auto query(Query) const noexcept(__nothrow_queryable_with<env_of_t<Sender>, Query>)
-> __query_result_t<env_of_t<Sender>, Query>
constexpr auto query(Query) const noexcept(__nothrow_queryable_with<_Env2, Query>)
-> __query_result_t<_Env2, Query>
{
return STDEXEC::__query<Query>()(STDEXEC::get_env(*child_));
return STDEXEC::get_env(*child_).query(Query());
}

Sender const * child_{};
Expand Down
12 changes: 6 additions & 6 deletions include/stdexec/__detail/__completion_behavior.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ namespace STDEXEC
STDEXEC_ATTRIBUTE(always_inline, host, device)
static constexpr auto __validate() noexcept
{
using __result_t = __member_query_result_t<_Attrs, __get_completion_behavior_t, _Env...>;
static_assert(__nothrow_member_queryable_with<_Attrs, __get_completion_behavior_t, _Env...>,
using __result_t = __query_result_t<_Attrs, __get_completion_behavior_t, _Env...>;
static_assert(__nothrow_queryable_with<_Attrs, __get_completion_behavior_t, _Env...>,
"The __get_completion_behavior query must be noexcept.");
static_assert(__std::convertible_to<__result_t, __completion_behavior::__behavior>,
"The __get_completion_behavior query must return one of the static member "
Expand All @@ -172,7 +172,7 @@ namespace STDEXEC
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto operator()(_Attrs const &) const noexcept
{
if constexpr (__member_queryable_with<_Attrs const &, __get_completion_behavior_t<_Tag>>)
if constexpr (__queryable_with<_Attrs const &, __get_completion_behavior_t<_Tag>>)
{
return __validate<_Attrs>();
}
Expand All @@ -186,9 +186,9 @@ namespace STDEXEC
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
constexpr auto operator()([[maybe_unused]] _Attrs const &__attrs, _Env const &) const noexcept
{
if constexpr (__member_queryable_with<_Attrs const &,
__get_completion_behavior_t<_Tag>,
_Env const &>)
if constexpr (__queryable_with<_Attrs const &,
__get_completion_behavior_t<_Tag>,
_Env const &>)
{
return __validate<_Attrs, _Env>();
}
Expand Down
49 changes: 4 additions & 45 deletions include/stdexec/__detail/__connect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import stdexec;
// include these after __execution_fwd.hpp
# include "__completion_signatures_of.hpp"
# include "__connect_awaitable.hpp"
# include "__tag_invoke.hpp"
# include "__transform_sender.hpp"
# include "__type_traits.hpp"

Expand All @@ -55,14 +54,10 @@ namespace STDEXEC
template <class _Sender, class _Receiver>
concept __with_co_await = __awaitable<_Sender, __connect_await::__promise<_Sender, _Receiver>>;

template <class _Sender, class _Receiver>
concept __with_legacy_tag_invoke = __tag_invocable<connect_t, _Sender, _Receiver>;

template <class _Sender, class _Receiver>
concept __with_any_connect = __with_static_member<_Sender, _Receiver>
|| __with_member<_Sender, _Receiver>
|| __with_co_await<_Sender, _Receiver>
|| __with_legacy_tag_invoke<_Sender, _Receiver>;
|| __with_co_await<_Sender, _Receiver>;

# if !STDEXEC_MSVC()

Expand Down Expand Up @@ -94,16 +89,6 @@ namespace STDEXEC
extern __declfn_t<__call_result_t<__connect_awaitable_t, _Sender, _Receiver>, false>
__connect_declfn_v<_Sender, _Receiver, true>;

template <class _Sender, class _Receiver>
requires __with_static_member<_Sender, _Receiver> //
|| __with_member<_Sender, _Receiver> //
|| __with_co_await<_Sender, _Receiver> //
|| __with_legacy_tag_invoke<_Sender, _Receiver>
extern STDEXEC_CONNECT_DECLFN_FOR(__tag_invoke(connect,
__declval<_Sender>(),
__declval<_Receiver>()))
__connect_declfn_v<_Sender, _Receiver, true>;

template <class _Sender, class _Receiver>
requires __with_static_member<_Sender, _Receiver>
extern __declfn_t<decltype(STDEXEC_REMOVE_REFERENCE(_Sender) //
Expand All @@ -124,14 +109,6 @@ namespace STDEXEC
extern __declfn_t<__call_result_t<__connect_awaitable_t, _Sender, _Receiver>, false>
__connect_declfn_v<_Sender, _Receiver, false>;

template <class _Sender, class _Receiver>
requires __with_static_member<_Sender, _Receiver> //
|| __with_member<_Sender, _Receiver> //
|| __with_co_await<_Sender, _Receiver> //
|| __with_legacy_tag_invoke<_Sender, _Receiver>
extern __declfn_t<__tag_invoke_result_t<connect_t, _Sender, _Receiver>, false>
__connect_declfn_v<_Sender, _Receiver, false>;

template <class _Sender, class _Receiver>
using __connect_declfn_t =
decltype(__connect_declfn_v<
Expand Down Expand Up @@ -169,11 +146,6 @@ namespace STDEXEC
{
return __declfn<__call_result_t<__connect_awaitable_t, _Sender, _Receiver>, false>();
}
else if constexpr (__with_legacy_tag_invoke<_Sender, _Receiver>)
{
return STDEXEC_CONNECT_DECLFN_FOR(
__tag_invoke(connect, __declval<_Sender>(), __declval<_Receiver>()));
}
else
{
return __declfn<void, false>();
Expand Down Expand Up @@ -202,10 +174,6 @@ namespace STDEXEC
{
return __declfn<__call_result_t<__connect_awaitable_t, _Sender, _Receiver>, false>();
}
else if constexpr (__with_legacy_tag_invoke<_Sender, _Receiver>)
{
return __declfn<__tag_invoke_result_t<connect_t, _Sender, _Receiver>, false>();
}
else
{
return __declfn<void, false>();
Expand Down Expand Up @@ -247,9 +215,8 @@ namespace STDEXEC
//! Most user code does not call it directly — @c sync_wait, @c spawn,
//! and the various adaptors do — but it is the operation a sender
//! author *must* support, either by exposing a `.connect(receiver)`
//! member, by being a coroutine awaitable (so the fallback awaitable
//! adapter applies), or — historically — via @c tag_invoke (now
//! deprecated).
//! member or by being a coroutine awaitable (so the fallback awaitable
//! adapter applies).
//!
//! See [exec.connect] in the C++26 working draft for the normative
//! specification.
Expand All @@ -270,8 +237,6 @@ namespace STDEXEC
//! 3. The awaitable fallback: if @c sndr is awaitable in stdexec's
//! receiver-promise type, an adapter operation state is synthesized.
//! This is what makes coroutines work as senders.
//! 4. <tt>tag_invoke(connect, sndr, rcvr)</tt> — deprecated, retained
//! for backwards compatibility.
//!
//! **Customization.**
//!
Expand Down Expand Up @@ -345,17 +310,11 @@ namespace STDEXEC
{
return static_cast<__new_sndr_t&&>(__new_sndr).connect(static_cast<_Receiver&&>(__rcvr));
}
else if constexpr (__connect::__with_co_await<__new_sndr_t, _Receiver>)
else
{
return __connect_awaitable(static_cast<__new_sndr_t&&>(__new_sndr),
static_cast<_Receiver&&>(__rcvr));
}
else
{
return __tag_invoke(*this,
static_cast<__new_sndr_t&&>(__new_sndr),
static_cast<_Receiver&&>(__rcvr));
}
}

static constexpr auto query(forwarding_query_t) noexcept -> bool
Expand Down
Loading
Loading