@@ -381,10 +381,11 @@ namespace stdexec {
381381 return __value;
382382 }
383383
384- prop& operator =(const prop&) = delete ;
384+ auto operator =(const prop&) -> prop& = delete ;
385385 };
386386
387387 template <class _Query , class _Value >
388+ STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE
388389 prop (_Query, _Value) -> prop<_Query, std::unwrap_reference_t <_Value>>;
389390
390391 // utility for joining multiple environments
@@ -398,20 +399,22 @@ namespace stdexec {
398399 // return a reference to the first child env for which
399400 // __queryable<_Envs, _Query, _Args...> is true.
400401 template <class _Query , class ... _Args>
401- STDEXEC_ATTRIBUTE ((always_inline)) constexpr decltype (auto ) __get_1st() const noexcept {
402+ STDEXEC_ATTRIBUTE ((always_inline)) constexpr auto __get_1st () const noexcept -> decltype(auto ) {
403+ // NOLINTNEXTLINE (modernize-avoid-c-arrays)
402404 constexpr bool __flags[] = {__queryable<_Envs, _Query, _Args...>...};
403405 constexpr std::size_t __idx = __pos_of (__flags, __flags + sizeof ...(_Envs));
404406 return __tup_.template __get <__idx>(__tup_);
405407 }
406408
407409 template <class _Query , class ... _Args>
408410 requires (__queryable<_Envs, _Query, _Args...> || ...)
409- STDEXEC_ATTRIBUTE ((always_inline)) constexpr decltype (auto ) query(_Query __q, _Args&&... __args) const
410- noexcept (__nothrow_queryable<decltype (__get_1st<_Query, _Args...>()), _Query, _Args...>) {
411+ STDEXEC_ATTRIBUTE ((always_inline)) constexpr auto query (_Query __q, _Args&&... __args) const
412+ noexcept (__nothrow_queryable<decltype (__get_1st<_Query, _Args...>()), _Query, _Args...>)
413+ -> decltype(auto ) {
411414 return tag_invoke (__q, __get_1st<_Query, _Args...>(), static_cast <_Args&&>(__args)...);
412415 }
413416
414- env& operator =(const env&) = delete ;
417+ auto operator =(const env&) -> env& = delete ;
415418 };
416419
417420 // specialization for two envs to avoid warnings about elided braces
@@ -426,7 +429,7 @@ namespace stdexec {
426429 // return a reference to the first child env for which
427430 // __queryable<_Envs, _Query, _Args...> is true.
428431 template <class _Query , class ... _Args>
429- STDEXEC_ATTRIBUTE ((always_inline)) constexpr decltype ( auto ) __get_1st() const noexcept {
432+ STDEXEC_ATTRIBUTE ((always_inline)) constexpr auto __get_1st () const noexcept -> decltype( auto ) {
430433 if constexpr (__queryable<_Env0, _Query, _Args...>) {
431434 return (__env0_);
432435 } else {
@@ -436,16 +439,17 @@ namespace stdexec {
436439
437440 template <class _Query , class ... _Args>
438441 requires __queryable<_Env0, _Query, _Args...> || __queryable<_Env1, _Query, _Args...>
439- STDEXEC_ATTRIBUTE ((always_inline)) constexpr decltype (auto ) query(_Query __q, _Args&&... __args) const
440- noexcept (__nothrow_queryable<decltype (__get_1st<_Query, _Args...>()), _Query, _Args...>) {
442+ STDEXEC_ATTRIBUTE ((always_inline)) constexpr auto query (_Query __q, _Args&&... __args) const
443+ noexcept (__nothrow_queryable<decltype (__get_1st<_Query, _Args...>()), _Query, _Args...>)
444+ -> decltype(auto ) {
441445 return tag_invoke (__q, __get_1st<_Query, _Args...>(), static_cast <_Args&&>(__args)...);
442446 }
443447
444- env& operator =(const env&) = delete ;
448+ auto operator =(const env&) -> env& = delete ;
445449 };
446450
447451 template <class ... _Envs>
448- env (_Envs...) -> env<std::unwrap_reference_t <_Envs>...>;
452+ STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE env (_Envs...) -> env<std::unwrap_reference_t<_Envs>...>;
449453
450454 template <class _Value , class _Tag , class ... _Tags>
451455 struct __with {
@@ -475,12 +479,17 @@ namespace stdexec {
475479 template <class _Value , class _Tag , class ... _Tags>
476480 __with (_Value, _Tag, _Tags...) -> __with<_Value, _Tag, _Tags...>;
477481
482+ template <class _Env >
483+ struct __fwd_base {
484+ using __fwd_env_t = _Env;
485+ };
486+
478487 template <class _EnvId >
479488 struct __fwd {
480489 using _Env = __cvref_t <_EnvId>;
481490 static_assert (__nothrow_move_constructible<_Env>);
482491
483- struct __t {
492+ struct __t : __fwd_base<_Env> {
484493 using __id = __fwd;
485494 STDEXEC_ATTRIBUTE ((no_unique_address)) _Env __env_;
486495
@@ -501,10 +510,17 @@ namespace stdexec {
501510 };
502511 };
503512
513+ template <class _Env >
514+ concept __is_fwd_env = same_as<_Env, typename _Env::__fwd_env_t >;
515+
504516 struct __fwd_fn {
505517 template <class _Env >
506- auto operator ()(_Env&& __env) const {
507- return __t <__fwd<__cvref_id<_Env>>>{static_cast <_Env&&>(__env)};
518+ auto operator ()(_Env&& __env) const -> decltype(auto ) {
519+ if constexpr (__is_fwd_env<__decay_t <_Env>>) {
520+ return static_cast <_Env>(static_cast <_Env&&>(__env));
521+ } else {
522+ return __t <__fwd<__cvref_id<_Env>>>{{}, static_cast <_Env&&>(__env)};
523+ }
508524 }
509525
510526 auto operator ()(empty_env) const -> empty_env {
0 commit comments