diff --git a/MAINTAINERS.md b/MAINTAINERS.md index bb716031a..9cfe73d96 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -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::connect(OuterReceiver)` is by requiring `sender_to>`. diff --git a/include/exec/env.hpp b/include/exec/env.hpp index 9c763f1a4..617d84c8c 100644 --- a/include/exec/env.hpp +++ b/include/exec/env.hpp @@ -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) diff --git a/include/exec/sequence_senders.hpp b/include/exec/sequence_senders.hpp index 0796f67bb..5d553ba84 100644 --- a/include/exec/sequence_senders.hpp +++ b/include/exec/sequence_senders.hpp @@ -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" @@ -158,20 +157,6 @@ namespace experimental::execution "set_value_t() or set_stopped_t()"); return __rcvr.set_next(static_cast<_Item&&>(__item)); } - - template - requires __has_set_next_member<_Receiver, _Item> - || __tag_invocable - [[deprecated("the use of tag_invoke for set_next is deprecated")]] - auto operator()(_Receiver& __rcvr, _Item&& __item) const - noexcept(__nothrow_tag_invocable) - -> __tag_invoke_result_t - { - static_assert(next_sender<__tag_invoke_result_t>, - "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 @@ -304,9 +289,6 @@ namespace experimental::execution concept __with_consteval_static_member = __minvocable_q<__consteval_static_member_result_t, _Sequence, _Env...>; - template - concept __with_tag_invoke = __tag_invocable; - template [[nodiscard]] consteval auto __get_item_types_helper() @@ -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; - return __result_t(); - } else if constexpr (sender_in<_Sequence, _Env...> && !enable_sequence_sender>) { @@ -790,9 +767,6 @@ namespace experimental::execution concept __subscribable_with_static_member = __minvocable_q<__subscribe_static_member_result_t, _Sequence, _Receiver>; - template - concept __subscribable_with_tag_invoke = __tag_invocable; - struct subscribe_t { private: @@ -942,33 +916,6 @@ namespace experimental::execution } } - template ()> - requires STDEXEC::__callable - || STDEXEC::__tag_invocable, - _Receiver> - [[deprecated("the use of tag_invoke for subscribe is deprecated")]] - auto operator()(_Sequence&& __sequence, _Receiver __rcvr) const noexcept( - __nothrow_callable> - && STDEXEC::__nothrow_tag_invocable, - _Receiver>) - -> STDEXEC::__tag_invoke_result_t, - _Receiver> - { - using __tfx_seq_t = __transform_sender_result_t<_Sequence, _Receiver>; - using __result_t = __tag_invoke_result_t; - __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; diff --git a/include/exec/thread_pool_base.hpp b/include/exec/thread_pool_base.hpp index 09c278d46..38518e5fa 100644 --- a/include/exec/thread_pool_base.hpp +++ b/include/exec/thread_pool_base.hpp @@ -494,13 +494,14 @@ namespace experimental::execution struct attrs { - template - requires STDEXEC::__queryable_with, Tag, As...> + template , + STDEXEC::__forwarding_query Tag, + class... As> + requires STDEXEC::__queryable_with<_Env2, Tag, As...> auto query(Tag, As&&... as) const - noexcept(STDEXEC::__nothrow_queryable_with, Tag, As...>) - -> decltype(auto) + noexcept(STDEXEC::__nothrow_queryable_with<_Env2, Tag, As...>) -> decltype(auto) { - return STDEXEC::__query()(STDEXEC::get_env(sndr_.sndr_), static_cast(as)...); + return STDEXEC::get_env(sndr_.sndr_).query(Tag(), static_cast(as)...); } bulk_sender const & sndr_; diff --git a/include/exec/timed_scheduler.hpp b/include/exec/timed_scheduler.hpp index 5b2d4de3a..86de81096 100644 --- a/include/exec/timed_scheduler.hpp +++ b/include/exec/timed_scheduler.hpp @@ -124,18 +124,6 @@ namespace experimental::execution static_assert(time_point<__decay_t>); return __sched.now(); } - - template - requires __has_now<_Scheduler> || __tag_invocable - [[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) - -> __decay_t<__tag_invoke_result_t> - { - static_assert(time_point<__decay_t<__tag_invoke_result_t>>); - return __tag_invoke(now_t{}, __sched); - } }; } // namespace __now @@ -196,22 +184,6 @@ namespace experimental::execution static_assert(sender); return __sched.schedule_after(__duration); } - - template - requires __has_schedule_after_member<_Scheduler> - || __tag_invocable 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 const &>) - -> __tag_invoke_result_t const &> - { - static_assert( - sender< - __tag_invoke_result_t const &>>); - return __tag_invoke(schedule_after, static_cast<_Scheduler &&>(__sched), __duration); - } }; struct schedule_after_t : __schedule_after_base_t @@ -279,22 +251,6 @@ namespace experimental::execution static_assert(sender); return __sched.schedule_at(__time_point); } - - template - requires __has_schedule_at_member<_Scheduler> - || __tag_invocable 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 const &>) - -> __tag_invoke_result_t const &> - { - static_assert( - sender< - __tag_invoke_result_t const &>>); - return __tag_invoke(schedule_at, static_cast<_Scheduler &&>(__sched), __time_point); - } }; struct schedule_at_t : __schedule_at_base_t diff --git a/include/nvexec/stream/common.cuh b/include/nvexec/stream/common.cuh index 28a149704..8364c813d 100644 --- a/include/nvexec/stream/common.cuh +++ b/include/nvexec/stream/common.cuh @@ -460,13 +460,13 @@ namespace nv::execution template struct stream_sender_attrs { - template <__forwarding_query Query> - requires __queryable_with, Query> + template , __forwarding_query Query> + requires __queryable_with<_Env2, Query> STDEXEC_ATTRIBUTE(nodiscard) - constexpr auto query(Query) const noexcept(__nothrow_queryable_with, Query>) - -> __query_result_t, Query> + constexpr auto query(Query) const noexcept(__nothrow_queryable_with<_Env2, Query>) + -> __query_result_t<_Env2, Query> { - return STDEXEC::__query()(STDEXEC::get_env(*child_)); + return STDEXEC::get_env(*child_).query(Query()); } Sender const * child_{}; diff --git a/include/stdexec/__detail/__completion_behavior.hpp b/include/stdexec/__detail/__completion_behavior.hpp index 126b0c482..a41f65d67 100644 --- a/include/stdexec/__detail/__completion_behavior.hpp +++ b/include/stdexec/__detail/__completion_behavior.hpp @@ -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 " @@ -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>(); } @@ -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>(); } diff --git a/include/stdexec/__detail/__connect.hpp b/include/stdexec/__detail/__connect.hpp index d9b4c5d68..b668c925b 100644 --- a/include/stdexec/__detail/__connect.hpp +++ b/include/stdexec/__detail/__connect.hpp @@ -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" @@ -55,14 +54,10 @@ namespace STDEXEC template concept __with_co_await = __awaitable<_Sender, __connect_await::__promise<_Sender, _Receiver>>; - template - concept __with_legacy_tag_invoke = __tag_invocable; - template 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() @@ -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 - 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 requires __with_static_member<_Sender, _Receiver> extern __declfn_t, false> __connect_declfn_v<_Sender, _Receiver, false>; - template - 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, false> - __connect_declfn_v<_Sender, _Receiver, false>; - template using __connect_declfn_t = decltype(__connect_declfn_v< @@ -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(); @@ -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, false>(); - } else { return __declfn(); @@ -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. @@ -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. tag_invoke(connect, sndr, rcvr) — deprecated, retained - //! for backwards compatibility. //! //! **Customization.** //! @@ -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 diff --git a/include/stdexec/__detail/__debug.hpp b/include/stdexec/__detail/__debug.hpp index f102a1cdb..c65f9825a 100644 --- a/include/stdexec/__detail/__debug.hpp +++ b/include/stdexec/__detail/__debug.hpp @@ -143,48 +143,10 @@ namespace STDEXEC //////////////////////////////////////////////////////////////////////////// // `__debug_sender` - // =============== - - // Understanding why a particular sender doesn't connect to a particular - // receiver is nigh impossible in the current design due to limitations in - // how the compiler reports overload resolution failure in the presence of - // constraints. `__debug_sender` is a utility to assist with the process. It - // gives you the deep template instantiation backtrace that you need to - // understand where in a chain of senders the problem is occurring. - - // ```c++ - // template , class _Sender> - // void __debug_sender(_Sender&& __sndr, _Env = {}); - - // template , class _Sender> - // void __debug_sender(_Sender&& __sndr, _Env = {}); - // ``` - - // **Usage:** - - // To find out where in a chain of senders a sender is failing to connect - // to a receiver, pass it to `__debug_sender`, optionally with an - // environment argument; e.g. `__debug_sender(sndr [, env])` - - // To find out why a sender will not connect to a receiver of a particular - // signature, specify the set of completion signatures as an explicit template - // argument that names an instantiation of `completion_signatures`; e.g.: - // `__debug_sender>(sndr [, env])`. - - // **How it works:** - - // The `__debug_sender` function `connect`'s the sender to a - // `__debug_receiver`, whose environment is augmented with a special - // `__is_debug_env_t` query. An additional fall-back overload is added to - // the `connect` CPO that recognizes receivers whose environments respond to - // that query and lets them through. Then in a non-immediate context, it - // looks for a `tag_invoke(connect_t...)` overload for the input sender and - // receiver. This will recurse until it hits the `tag_invoke` call that is - // causing the failure. - - // At least with clang, this gives me a nice backtrace, at the bottom of - // which is the faulty `tag_invoke` overload with a mention of the - // constraint that failed. + // ================ + + // Utility to check whether a sender's actual completions match its declared completion + // signatures. template > constexpr void __debug_sender(_CvSender&& __sndr, _Env const & = {}) { diff --git a/include/stdexec/__detail/__domain.hpp b/include/stdexec/__detail/__domain.hpp index be33b55bf..95294976c 100644 --- a/include/stdexec/__detail/__domain.hpp +++ b/include/stdexec/__detail/__domain.hpp @@ -226,13 +226,13 @@ namespace STDEXEC : __env_{static_cast<_Env &&>(__env)} {} - template <__none_of<_Queries...> _Query, class... _As> - requires __queryable_with<_Env, _Query, _As...> - constexpr auto - operator()(_Query, _As &&...__as) const noexcept(__nothrow_queryable_with<_Env, _Query, _As...>) - -> __query_result_t<_Env, _Query, _As...> + template _Query, class... _As> + requires __queryable_with<_Env2, _Query, _As...> + constexpr auto operator()(_Query, _As &&...__as) const + noexcept(__nothrow_queryable_with<_Env2, _Query, _As...>) + -> __query_result_t<_Env2, _Query, _As...> { - return __query<_Query>()(__env_, static_cast<_As &&>(__as)...); + return __env_.query(_Query(), static_cast<_As &&>(__as)...); } private: @@ -430,9 +430,9 @@ namespace STDEXEC STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) constexpr auto operator()(_Env const &) const noexcept -> auto { - if constexpr (__member_queryable_with<_Env const &, get_domain_t>) + if constexpr (__queryable_with<_Env const &, get_domain_t>) { - return __decay_t<__member_query_result_t<_Env, get_domain_t>>{}; + return __decay_t<__query_result_t<_Env, get_domain_t>>{}; } else if constexpr (__callable) { @@ -448,16 +448,6 @@ namespace STDEXEC } } - // Query with tag_invoke (legacy): - template - requires __tag_invocable - [[deprecated("use a query member function instead of tag_invoke for queries")]] - STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) // - constexpr auto operator()(_Env const &) const noexcept - { - return __decay_t<__tag_invoke_result_t>{}; - } - STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) static consteval auto query(forwarding_query_t) noexcept -> bool { diff --git a/include/stdexec/__detail/__env.hpp b/include/stdexec/__detail/__env.hpp index 0c4a276f3..c1bd0634a 100644 --- a/include/stdexec/__detail/__env.hpp +++ b/include/stdexec/__detail/__env.hpp @@ -28,7 +28,6 @@ import stdexec; # include "__concepts.hpp" # include "__meta.hpp" # include "__query.hpp" -# include "__tag_invoke.hpp" # include "__tuple.hpp" # if !STDEXEC_USE_MODULES() @@ -66,14 +65,14 @@ namespace STDEXEC { static_assert(__nothrow_move_constructible<_Env>); - template <__forwarding_query _Query, class... _Args> - requires __queryable_with<_Env, _Query, _Args...> + template + requires __queryable_with<_Env2, _Query, _Args...> STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) constexpr auto query(_Query, _Args &&...__args) const - noexcept(__nothrow_queryable_with<_Env, _Query, _Args...>) - -> __query_result_t<_Env, _Query, _Args...> + noexcept(__nothrow_queryable_with<_Env2, _Query, _Args...>) + -> __query_result_t<_Env2, _Query, _Args...> { - return __query<_Query>()(__env_, static_cast<_Args &&>(__args)...); + return __env_.query(_Query(), static_cast<_Args &&>(__args)...); } STDEXEC_ATTRIBUTE(no_unique_address) @@ -266,7 +265,7 @@ namespace STDEXEC -> __query_result_t<__1st_env_t<_Query, _Args...>, _Query, _Args...> { auto const &__env = __detail::__get_1st_env<_Query, _Args...>()(*this); - return __query<_Query>()(__env, static_cast<_Args &&>(__args)...); + return __env.query(_Query(), static_cast<_Args &&>(__args)...); } }; @@ -322,9 +321,6 @@ namespace STDEXEC //! the @c get_env CPO will return one automatically via its @c __ignore //! overload). //! - //! @c tag_invoke-based customization is supported via a deprecated - //! overload, retained for backwards compatibility. - //! //! **Environment queries.** //! //! Once you have an environment, you query it by calling the appropriate @@ -362,19 +358,6 @@ namespace STDEXEC return __env_provider.get_env(); } - template - requires __detail::__has_get_env_member<_EnvProvider const &> - || __tag_invocable - [[deprecated("the use of tag_invoke for get_env is deprecated")]] - STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) // - constexpr auto operator()(_EnvProvider const &__env_provider) const noexcept - -> __tag_invoke_result_t - { - static_assert(__nothrow_tag_invocable, - "get_env __tag_invoke overloads must be noexcept"); - return __tag_invoke(*this, __env_provider); - } - STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) constexpr auto operator()(__ignore) const noexcept -> env<> { diff --git a/include/stdexec/__detail/__get_completion_signatures.hpp b/include/stdexec/__detail/__get_completion_signatures.hpp index bc99913ac..621c92906 100644 --- a/include/stdexec/__detail/__get_completion_signatures.hpp +++ b/include/stdexec/__detail/__get_completion_signatures.hpp @@ -32,7 +32,6 @@ import stdexec; # include "__diagnostics.hpp" # include "__env.hpp" # include "__meta.hpp" -# include "__tag_invoke.hpp" # include "__tuple.hpp" // IWYU pragma: keep for __tuple # include "__prologue.hpp" @@ -145,14 +144,6 @@ namespace STDEXEC __non_sender<_Env> // && requires { STDEXEC_GET_COMPLSIGS(_Sender, _Env); }; - template - concept __with_legacy_tag_invoke = - __tag_invocable; - - template - concept __with_legacy_non_dependent_tag_invoke = - (sizeof...(_Env) == 0) && __tag_invocable>; - STDEXEC_MODULE_EXPORT_AUTHORING template concept __with_legacy_member_alias = requires { @@ -184,16 +175,6 @@ namespace STDEXEC using __completions_t = __legacy_member_result_t<_Sender>; return STDEXEC_CHECKED_COMPLSIGS((_Sender), __completions_t()); } - else if constexpr (__with_legacy_tag_invoke<_Sender>) - { - using __completions_t = __tag_invoke_result_t; - return STDEXEC_CHECKED_COMPLSIGS((_Sender), __completions_t()); - } - else if constexpr (__with_legacy_non_dependent_tag_invoke<_Sender>) - { - using __completions_t = __tag_invoke_result_t>; - return STDEXEC_CHECKED_COMPLSIGS((_Sender), __completions_t()); - } else if constexpr (__with_co_await<_Sender>) { return __co_await_completions_t<_Sender>(); @@ -230,11 +211,6 @@ namespace STDEXEC using __completions_t = __legacy_member_result_t<_Sender, _Env>; return STDEXEC_CHECKED_COMPLSIGS((_Sender, _Env), __completions_t()); } - else if constexpr (__with_legacy_tag_invoke<_Sender, _Env>) - { - using __completions_t = __tag_invoke_result_t; - return STDEXEC_CHECKED_COMPLSIGS((_Sender, _Env), __completions_t()); - } else if constexpr (__with_co_await<_Sender, _Env>) { return __co_await_completions_t<_Sender, _Env>(); diff --git a/include/stdexec/__detail/__on.hpp b/include/stdexec/__detail/__on.hpp index 2ceac051d..5e6f5e782 100644 --- a/include/stdexec/__detail/__on.hpp +++ b/include/stdexec/__detail/__on.hpp @@ -127,11 +127,10 @@ namespace STDEXEC { using __trnsfr_sndr_t = __result_of, _Scheduler>; using __clsur_result_t = __call_result_t<_Closure const &, __trnsfr_sndr_t>; - template - using __old_sched_t = - __query_result_t, get_completion_scheduler_t, _Env>; - template - using __attrs_t = __trnsfr::__attrs<__old_sched_t<_Env>, __clsur_result_t>; + template + using __old_sched_t = __query_result_t<_Attrs, get_completion_scheduler_t, _Env>; + template + using __attrs_t = __trnsfr::__attrs<__old_sched_t<_Attrs, _Env>, __clsur_result_t>; using __attrs_base<_Child>::query; explicit constexpr __attrs(_Child const & __child, @@ -141,18 +140,18 @@ namespace STDEXEC , __clsur_result_(__clsur(continues_on(__sender_proxy{__child}, std::move(__sched)))) {} - template + template , class _Query, class _Env> requires __completion_query<_Query> // - && __queryable_with, get_completion_scheduler_t, _Env> - && __queryable_with<__attrs_t<_Env>, _Query, _Env> + && __queryable_with<_Attrs, get_completion_scheduler_t, _Env> + && __queryable_with<__attrs_t<_Attrs, _Env>, _Query, _Env> STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) - constexpr auto query(_Query __query, _Env&& __env) const noexcept - -> __query_result_t<__attrs_t<_Env>, _Query, _Env> + constexpr auto query(_Query, _Env&& __env) const noexcept + -> __query_result_t<__attrs_t<_Attrs, _Env>, _Query, _Env> { auto&& __child_attrs = STDEXEC::get_env(this->__child_); auto __old_sch = get_completion_scheduler(__child_attrs, __env); - auto __attrs = __attrs_t<_Env>(__old_sch, STDEXEC::get_env(__clsur_result_)); - return __query(__attrs, static_cast<_Env&&>(__env)); + auto __attrs = __attrs_t<_Attrs, _Env>(__old_sch, STDEXEC::get_env(__clsur_result_)); + return __attrs.query(_Query(), static_cast<_Env&&>(__env)); } __clsur_result_t __clsur_result_; @@ -170,13 +169,13 @@ namespace STDEXEC template <__completion_query _Query, __queryable_with _Env> requires __queryable_with<__attrs_t<_Env>, _Query, _Env> STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) - constexpr auto query(_Query __query, _Env&& __env) const noexcept + constexpr auto query(_Query, _Env&& __env) const noexcept -> __query_result_t<__attrs_t<_Env>, _Query, _Env> { auto&& __child_attrs = STDEXEC::get_env(this->__child_); auto __old_sch = get_start_scheduler(__env); auto __attrs = __attrs_t<_Env>(__old_sch, __child_attrs_t(__sched_, __child_attrs)); - return __query(__attrs, static_cast<_Env&&>(__env)); + return __attrs.query(_Query(), static_cast<_Env&&>(__env)); } _Scheduler __sched_; diff --git a/include/stdexec/__detail/__operation_states.hpp b/include/stdexec/__detail/__operation_states.hpp index 597204d3c..05e341581 100644 --- a/include/stdexec/__detail/__operation_states.hpp +++ b/include/stdexec/__detail/__operation_states.hpp @@ -27,7 +27,6 @@ import stdexec; // include these after __execution_fwd.hpp # include "__concepts.hpp" -# include "__tag_invoke.hpp" # if !STDEXEC_USE_MODULES() # include @@ -117,9 +116,6 @@ namespace STDEXEC //! handle exceptions. It must also return @c void. The dispatch site //! enforces both with static asserts. //! - //! @c tag_invoke-based customization is supported via a deprecated - //! overload, retained for backwards compatibility. - //! //! @see stdexec::connect — the CPO that produces operation states //! @see stdexec::operation_state — the concept this CPO drives //! @see stdexec::set_value — one of the completions @c start eventually triggers @@ -142,16 +138,6 @@ namespace STDEXEC static_assert(__same_as, "start() members must return void"); __op.start(); } - - template - requires __has_start_member<_Op> || __tag_invocable - [[deprecated("the use of tag_invoke for start is deprecated")]] - STDEXEC_ATTRIBUTE(always_inline) // - constexpr void operator()(_Op &__op) const noexcept - { - static_assert(__nothrow_tag_invocable); - (void) __tag_invoke(start_t{}, __op); - } }; //! @brief The customization point object for starting an operation state. diff --git a/include/stdexec/__detail/__queries.hpp b/include/stdexec/__detail/__queries.hpp index fde5fbc8e..98db3f500 100644 --- a/include/stdexec/__detail/__queries.hpp +++ b/include/stdexec/__detail/__queries.hpp @@ -67,14 +67,14 @@ namespace STDEXEC return __get_completion_behavior<_Tag, _Sender, _Env...>(); } - template <__forwarding_query _Query, class... _Args> - requires __queryable_with, _Query, _Args...> + template , __forwarding_query _Query, class... _Args> + requires __queryable_with<_Env2, _Query, _Args...> [[nodiscard]] constexpr auto query(_Query, _Args &&...__args) const - noexcept(__nothrow_queryable_with, _Query, _Args...>) - -> __query_result_t, _Query, _Args...> + noexcept(__nothrow_queryable_with<_Env2, _Query, _Args...>) + -> __query_result_t<_Env2, _Query, _Args...> { - return __query<_Query>()(get_env(__sndr_), static_cast<_Args &&>(__args)...); + return get_env(__sndr_).query(_Query(), static_cast<_Args &&>(__args)...); } _Sender const &__sndr_; diff --git a/include/stdexec/__detail/__query.hpp b/include/stdexec/__detail/__query.hpp index 7d16c18a2..dfa8cb5a8 100644 --- a/include/stdexec/__detail/__query.hpp +++ b/include/stdexec/__detail/__query.hpp @@ -28,7 +28,6 @@ import stdexec; // // include these after __execution_fwd.hpp # include "__concepts.hpp" # include "__meta.hpp" -# include "__tag_invoke.hpp" # include "__utility.hpp" # if !STDEXEC_USE_MODULES() @@ -43,25 +42,28 @@ namespace STDEXEC template concept __queryable = __std::destructible; + STDEXEC_MODULE_EXPORT_AUTHORING template - concept __member_queryable_with = __queryable<_Env> - && requires(_Env const &__env, - _Query const &__query, - __declfn_t<_Args &&>... __args) { - { __env.query(__query, __args()...) }; - }; + concept __queryable_with = __queryable<_Env> + && requires(_Env const &__env, + _Query const &__query, + __declfn_t<_Args &&>... __args) { + { __env.query(__query, __args()...) }; + }; + STDEXEC_MODULE_EXPORT_AUTHORING template - concept __nothrow_member_queryable_with = __member_queryable_with<_Env, _Query, _Args...> - && requires(_Env const &__env, - _Query const &__query, - __declfn_t<_Args &&>... __args) { - { __env.query(__query, __args()...) } noexcept; - }; + concept __nothrow_queryable_with = __queryable_with<_Env, _Query, _Args...> + && requires(_Env const &__env, + _Query const &__query, + __declfn_t<_Args &&>... __args) { + { __env.query(__query, __args()...) } noexcept; + }; + STDEXEC_MODULE_EXPORT_AUTHORING template - using __member_query_result_t = decltype(__declval<_Env const &>().query(__declval<_Qy const &>(), - __declval<_Args>()...)); + using __query_result_t = decltype(__declval<_Env const &>().query(__declval<_Qy const &>(), + __declval<_Args>()...)); inline constexpr __none_such __no_default{}; @@ -93,11 +95,11 @@ namespace STDEXEC // Query with a .query member function: template - requires __member_queryable_with<_Env const &, _Qy, _Args...> + requires __queryable_with<_Env const &, _Qy, _Args...> STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) constexpr auto operator()(_Env const &__env, _Args &&...__args) const - noexcept(__nothrow_member_queryable_with<_Env, _Qy, _Args...>) - -> __mcall1<_Transform, __member_query_result_t<_Env, _Qy, _Args...>> + noexcept(__nothrow_queryable_with<_Env, _Qy, _Args...>) + -> __mcall1<_Transform, __query_result_t<_Env, _Qy, _Args...>> { if constexpr (__has_validation<_Query, _Env, _Args...>) { @@ -105,36 +107,8 @@ namespace STDEXEC } return __env.query(_Query(), static_cast<_Args &&>(__args)...); } - - // Query with tag_invoke (legacy): - template - requires __tag_invocable<_Qy, _Env const &, _Args...> - [[deprecated("the use of tag_invoke for queries is deprecated")]] - STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) // - constexpr auto operator()(_Env const &__env, _Args &&...__args) const - noexcept(__nothrow_tag_invocable<_Qy, _Env const &, _Args...>) - -> __mcall1<_Transform, __tag_invoke_result_t<_Qy, _Env const &, _Args...>> - { - if constexpr (__has_validation<_Query, _Env, _Args...>) - { - _Query::template __validate<_Env, _Args...>(); - } - return __tag_invoke(_Query(), __env, static_cast<_Args &&>(__args)...); - } }; - STDEXEC_MODULE_EXPORT_AUTHORING - template - concept __queryable_with = __callable<__query<_Query>, _Env &, _Args...>; - - STDEXEC_MODULE_EXPORT_AUTHORING - template - concept __nothrow_queryable_with = __nothrow_callable<__query<_Query>, _Env &, _Args...>; - - STDEXEC_MODULE_EXPORT_AUTHORING - template - using __query_result_t = __call_result_t<__query<_Query>, _Env &, _Args...>; - template concept __statically_queryable_with_impl = requires(_Query __q, _Args &&...__args) { std::remove_reference_t<_Env>::query(__q, static_cast<_Args &&>(__args)...); @@ -180,7 +154,7 @@ STDEXEC_P2300_NAMESPACE_BEGIN() { if constexpr (STDEXEC::__queryable_with<_Query, forwarding_query_t>) { - return STDEXEC::__query()(_Query()); + return _Query().query(forwarding_query_t()); } else { diff --git a/include/stdexec/__detail/__receivers.hpp b/include/stdexec/__detail/__receivers.hpp index f65761c1d..f814888e6 100644 --- a/include/stdexec/__detail/__receivers.hpp +++ b/include/stdexec/__detail/__receivers.hpp @@ -28,7 +28,6 @@ import stdexec; # include "__concepts.hpp" # include "__diagnostics.hpp" # include "__env.hpp" -# include "__tag_invoke.hpp" # include "../functional.hpp" @@ -128,17 +127,6 @@ namespace STDEXEC "set_value member functions must return void"); static_cast<_Receiver &&>(__rcvr).set_value(static_cast<_As &&>(__as)...); } - - template - requires __set_value_member<_Receiver, _As...> - || __tag_invocable - [[deprecated("the use of tag_invoke for set_value is deprecated")]] - STDEXEC_ATTRIBUTE(host, device, always_inline) // - constexpr void operator()(_Receiver &&__rcvr, _As &&...__as) const noexcept - { - static_assert(__nothrow_tag_invocable); - (void) __tag_invoke(*this, static_cast<_Receiver &&>(__rcvr), static_cast<_As &&>(__as)...); - } }; template @@ -207,17 +195,6 @@ namespace STDEXEC "set_error member functions must return void"); static_cast<_Receiver &&>(__rcvr).set_error(static_cast<_Error &&>(__err)); } - - template - requires __set_error_member<_Receiver, _Error> - || __tag_invocable - [[deprecated("the use of tag_invoke for set_error is deprecated")]] - STDEXEC_ATTRIBUTE(host, device, always_inline) // - constexpr void operator()(_Receiver &&__rcvr, _Error &&__err) const noexcept - { - static_assert(__nothrow_tag_invocable); - (void) __tag_invoke(*this, static_cast<_Receiver &&>(__rcvr), static_cast<_Error &&>(__err)); - } }; template @@ -280,16 +257,6 @@ namespace STDEXEC "set_stopped member functions must return void"); static_cast<_Receiver &&>(__rcvr).set_stopped(); } - - template - requires __set_stopped_member<_Receiver> || __tag_invocable - [[deprecated("the use of tag_invoke for set_stopped is deprecated")]] - STDEXEC_ATTRIBUTE(host, device, always_inline) // - constexpr void operator()(_Receiver &&__rcvr) const noexcept - { - static_assert(__nothrow_tag_invocable); - (void) __tag_invoke(*this, static_cast<_Receiver &&>(__rcvr)); - } }; //! @brief The customization point object for delivering a value completion. diff --git a/include/stdexec/__detail/__schedulers.hpp b/include/stdexec/__detail/__schedulers.hpp index 406dd7d28..dac8ee8eb 100644 --- a/include/stdexec/__detail/__schedulers.hpp +++ b/include/stdexec/__detail/__schedulers.hpp @@ -150,25 +150,6 @@ namespace STDEXEC "schedule() member functions must return a sender"); return static_cast<_Scheduler &&>(__sched).schedule(); } - - //! @brief Deprecated overload: obtain a schedule-sender via @c tag_invoke. - //! - //! @deprecated The @c tag_invoke-based customization of @c schedule is - //! deprecated in favor of the sched.schedule() - //! member-function form. New scheduler types should provide - //! a member @c .schedule() instead of a @c tag_invoke - //! overload for @c schedule_t. - template - requires __has_schedule_member<_Scheduler> || __tag_invocable - [[deprecated("the use of tag_invoke for schedule is deprecated")]] - STDEXEC_ATTRIBUTE(host, device, always_inline) // - auto operator()(_Scheduler &&__sched) const - noexcept(__nothrow_tag_invocable) - -> __tag_invoke_result_t - { - static_assert(sender<__tag_invoke_result_t>); - return __tag_invoke(*this, static_cast<_Scheduler &&>(__sched)); - } }; //! @brief The customization point object for the @c schedule sender factory. diff --git a/include/stdexec/__detail/__sequence.hpp b/include/stdexec/__detail/__sequence.hpp index 3bee1dc26..7e380695b 100644 --- a/include/stdexec/__detail/__sequence.hpp +++ b/include/stdexec/__detail/__sequence.hpp @@ -72,14 +72,14 @@ namespace STDEXEC template struct __attrs<_Sender> { - template - requires __queryable_with, _Query, _Args...> + template , class _Query, class... _Args> + requires __queryable_with<_Env2, _Query, _Args...> STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) constexpr auto operator()(_Query, _Args &&...__args) const - noexcept(__nothrow_queryable_with, _Query, _Args...>) - -> __query_result_t, _Query, _Args...> + noexcept(__nothrow_queryable_with<_Env2, _Query, _Args...>) + -> __query_result_t<_Env2, _Query, _Args...> { - return __query<_Query>()(STDEXEC::get_env(__sndr_), static_cast<_Args &&>(__args)...); + return STDEXEC::get_env(__sndr_).query(_Query(), static_cast<_Args &&>(__args)...); } _Sender __sndr_; @@ -174,8 +174,8 @@ namespace STDEXEC noexcept(__nothrow_queryable_with<__joined_t, _Query, _Args...>) -> __query_result_t<__joined_t, _Query, _Args...> { - return __query<_Query>()(__joined_t{STDEXEC::get_env(__sndr2_), STDEXEC::get_env(__sndr1_)}, - static_cast<_Args &&>(__args)...); + return __joined_t{STDEXEC::get_env(__sndr2_), STDEXEC::get_env(__sndr1_)} + .query(_Query(), static_cast<_Args &&>(__args)...); } _Sender1 __sndr1_; diff --git a/include/stdexec/__detail/__tag_invoke.hpp b/include/stdexec/__detail/__tag_invoke.hpp deleted file mode 100644 index 6819e783c..000000000 --- a/include/stdexec/__detail/__tag_invoke.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2021-2024 NVIDIA Corporation - * - * Licensed under the Apache License Version 2.0 with LLVM Exceptions - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * https://llvm.org/LICENSE.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "__config.hpp" - -#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) - -import stdexec; - -#else - -# include "__type_traits.hpp" - -# define STDEXEC_TAG_INVOKE_DEPRECATED_MSG \ - "The use of tag_invoke as a means of customization is deprecated. Please use member functions " \ - "instead." - -# include "__prologue.hpp" - -namespace STDEXEC -{ - // [func.tag_invoke], tag_invoke - namespace __dispatch - { - constexpr void tag_invoke(); - - STDEXEC_MODULE_EXPORT_AUTHORING - template - concept __tag_invocable = requires(_Tag __tag, _Args &&...__args) { - tag_invoke(static_cast<_Tag &&>(__tag), static_cast<_Args &&>(__args)...); - }; - - template - concept __tag_invocable_r = requires(_Tag __tag, _Args &&...__args) { - { - static_cast<_Ret>(tag_invoke(static_cast<_Tag &&>(__tag), static_cast<_Args &&>(__args)...)) - }; - }; - - STDEXEC_MODULE_EXPORT_AUTHORING - template - concept __nothrow_tag_invocable = __tag_invocable<_Tag, _Args...> - && requires(_Tag __tag, _Args &&...__args) { - { - tag_invoke(static_cast<_Tag &&>(__tag), - static_cast<_Args &&>(__args)...) - } noexcept; - }; - - STDEXEC_MODULE_EXPORT_AUTHORING - template - using __tag_invoke_result_t = decltype(tag_invoke(__declval<_Tag>(), __declval<_Args>()...)); - - template - struct __tag_invoke_result - {}; - - template - requires __tag_invocable<_Tag, _Args...> - struct __tag_invoke_result<_Tag, _Args...> - { - using type = __tag_invoke_result_t<_Tag, _Args...>; - }; - - struct __tag_invoke_t - { - template - requires __tag_invocable<_Tag, _Args...> - [[deprecated(STDEXEC_TAG_INVOKE_DEPRECATED_MSG)]] - STDEXEC_ATTRIBUTE(always_inline) constexpr auto - operator()(_Tag __tag, _Args &&...__args) const - noexcept(__nothrow_tag_invocable<_Tag, _Args...>) -> __tag_invoke_result_t<_Tag, _Args...> - { - return tag_invoke(static_cast<_Tag &&>(__tag), static_cast<_Args &&>(__args)...); - } - }; - - } // namespace __dispatch - - using __dispatch::__tag_invoke_t; - - namespace __ti - { - STDEXEC_MODULE_EXPORT_AUTHORING - inline constexpr __tag_invoke_t __tag_invoke{}; - - [[deprecated(STDEXEC_TAG_INVOKE_DEPRECATED_MSG)]] - inline constexpr __tag_invoke_t tag_invoke = __tag_invoke; - } // namespace __ti - - STDEXEC_MODULE_EXPORT_AUTHORING - using namespace __ti; - - STDEXEC_MODULE_EXPORT_AUTHORING - using __dispatch::__tag_invocable; - using __dispatch::__tag_invocable_r; - STDEXEC_MODULE_EXPORT_AUTHORING - using __dispatch::__nothrow_tag_invocable; - STDEXEC_MODULE_EXPORT_AUTHORING - using __dispatch::__tag_invoke_result_t; - using __dispatch::__tag_invoke_result; - - // Deprecated interfaces - template - concept tag_invocable - STDEXEC_DEPRECATE_CONCEPT(STDEXEC_TAG_INVOKE_DEPRECATED_MSG) = __tag_invocable<_Tag, _Args...>; - - template - concept nothrow_tag_invocable STDEXEC_DEPRECATE_CONCEPT(STDEXEC_TAG_INVOKE_DEPRECATED_MSG) = - __nothrow_tag_invocable<_Tag, _Args...>; - - template - using tag_invoke_result_t - [[deprecated(STDEXEC_TAG_INVOKE_DEPRECATED_MSG)]] = __tag_invoke_result_t<_Tag, _Args...>; - - template - using tag_invoke_result - [[deprecated(STDEXEC_TAG_INVOKE_DEPRECATED_MSG)]] = __tag_invoke_result<_Tag, _Args...>; - - template - using tag_t [[deprecated(STDEXEC_TAG_INVOKE_DEPRECATED_MSG)]] - = __decay_t; -} // namespace STDEXEC - -# include "__epilogue.hpp" -#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__task.hpp b/include/stdexec/__detail/__task.hpp index 7326e1534..84d0f1ee4 100644 --- a/include/stdexec/__detail/__task.hpp +++ b/include/stdexec/__detail/__task.hpp @@ -1006,14 +1006,14 @@ namespace STDEXEC } } - template <__forwarding_query _Query, class... _Args> - requires __queryable_with<_TaskEnv, _Query, _Args...> + template + requires __queryable_with<_Env2, _Query, _Args...> [[nodiscard]] constexpr auto query(_Query, _Args&&... __args) const - noexcept(__nothrow_queryable_with<_TaskEnv, _Query, _Args...>) - -> __query_result_t<_TaskEnv, _Query, _Args...> + noexcept(__nothrow_queryable_with<_Env2, _Query, _Args...>) + -> __query_result_t<_Env2, _Query, _Args...> { - return __query<_Query>()(__promise_->__state_->__env_, static_cast<_Args&&>(__args)...); + return __promise_->__state_->__env_.query(_Query(), static_cast<_Args&&>(__args)...); } __promise const * __promise_;