stdexec: update to latest commit

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I52e2ff4ea33617fb055981000ce3c2f40faab43e
diff --git a/include/sdbusplus/async/stdexec/__detail/__as_awaitable.hpp b/include/sdbusplus/async/stdexec/__detail/__as_awaitable.hpp
new file mode 100644
index 0000000..e68ef30
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__as_awaitable.hpp
@@ -0,0 +1,295 @@
+/*
+ * 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 "__awaitable.hpp"
+#include "__concepts.hpp"
+#include "__config.hpp"
+#include "__cpo.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__senders.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__type_traits.hpp"
+
+#include <exception>
+#include <system_error>
+#include <variant>
+
+namespace stdexec
+{
+#if !STDEXEC_STD_NO_COROUTINES()
+/////////////////////////////////////////////////////////////////////////////
+// stdexec::as_awaitable [execution.coro_utils.as_awaitable]
+namespace __as_awaitable
+{
+struct __void
+{};
+
+template <class _Value>
+using __value_or_void_t = __if_c<__same_as<_Value, void>, __void, _Value>;
+
+template <class _Value>
+using __expected_t =
+    std::variant<std::monostate, __value_or_void_t<_Value>, std::exception_ptr>;
+
+template <class _Value>
+struct __receiver_base
+{
+    using receiver_concept = receiver_t;
+
+    template <class... _Us>
+        requires constructible_from<__value_or_void_t<_Value>, _Us...>
+    void set_value(_Us&&... __us) noexcept
+    {
+        try
+        {
+            __result_->template emplace<1>(static_cast<_Us&&>(__us)...);
+            __continuation_.resume();
+        }
+        catch (...)
+        {
+            stdexec::set_error(static_cast<__receiver_base&&>(*this),
+                               std::current_exception());
+        }
+    }
+
+    template <class _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        if constexpr (__decays_to<_Error, std::exception_ptr>)
+            __result_->template emplace<2>(static_cast<_Error&&>(__err));
+        else if constexpr (__decays_to<_Error, std::error_code>)
+            __result_->template emplace<2>(
+                std::make_exception_ptr(std::system_error(__err)));
+        else
+            __result_->template emplace<2>(
+                std::make_exception_ptr(static_cast<_Error&&>(__err)));
+        __continuation_.resume();
+    }
+
+    __expected_t<_Value>* __result_;
+    __coro::coroutine_handle<> __continuation_;
+};
+
+template <class _PromiseId, class _Value>
+struct __receiver
+{
+    using _Promise = stdexec::__t<_PromiseId>;
+
+    struct __t : __receiver_base<_Value>
+    {
+        using __id = __receiver;
+
+        void set_stopped() noexcept
+        {
+            auto __continuation =
+                __coro::coroutine_handle<_Promise>::from_address(
+                    this->__continuation_.address());
+            __coro::coroutine_handle<> __stopped_continuation =
+                __continuation.promise().unhandled_stopped();
+            __stopped_continuation.resume();
+        }
+
+        // Forward get_env query to the coroutine promise
+        auto get_env() const noexcept -> env_of_t<_Promise&>
+        {
+            auto __continuation =
+                __coro::coroutine_handle<_Promise>::from_address(
+                    this->__continuation_.address());
+            return stdexec::get_env(__continuation.promise());
+        }
+    };
+};
+
+// BUGBUG NOT TO SPEC: make senders of more-than-one-value awaitable
+// by packaging the values into a tuple.
+// See: https://github.com/cplusplus/sender-receiver/issues/182
+template <std::size_t _Count>
+extern const __q<__decayed_std_tuple> __as_single;
+
+template <>
+inline const __q<__midentity> __as_single<1>;
+
+template <>
+inline const __mconst<void> __as_single<0>;
+
+template <class... _Values>
+using __single_value =
+    __minvoke<decltype(__as_single<sizeof...(_Values)>), _Values...>;
+
+template <class _Sender, class _Promise>
+using __value_t =
+    __decay_t<__value_types_of_t<_Sender, env_of_t<_Promise&>,
+                                 __q<__single_value>, __msingle_or<void>>>;
+
+template <class _Sender, class _Promise>
+using __receiver_t =
+    __t<__receiver<__id<_Promise>, __value_t<_Sender, _Promise>>>;
+
+template <class _Value>
+struct __sender_awaitable_base
+{
+    [[nodiscard]] auto await_ready() const noexcept -> bool
+    {
+        return false;
+    }
+
+    auto await_resume() -> _Value
+    {
+        switch (__result_.index())
+        {
+            case 0: // receiver contract not satisfied
+                STDEXEC_ASSERT(false && +"_Should never get here" == nullptr);
+                break;
+            case 1: // set_value
+                if constexpr (!__same_as<_Value, void>)
+                    return static_cast<_Value&&>(std::get<1>(__result_));
+                else
+                    return;
+            case 2: // set_error
+                std::rethrow_exception(std::get<2>(__result_));
+        }
+        std::terminate();
+    }
+
+  protected:
+    __expected_t<_Value> __result_;
+};
+
+template <class _PromiseId, class _SenderId>
+struct __sender_awaitable
+{
+    using _Promise = stdexec::__t<_PromiseId>;
+    using _Sender = stdexec::__t<_SenderId>;
+    using __value = __value_t<_Sender, _Promise>;
+
+    struct __t : __sender_awaitable_base<__value>
+    {
+        __t(_Sender&& sndr, __coro::coroutine_handle<_Promise> __hcoro) //
+            noexcept(__nothrow_connectable<_Sender, __receiver>) :
+            __op_state_(connect(static_cast<_Sender&&>(sndr),
+                                __receiver{{&this->__result_, __hcoro}}))
+        {}
+
+        void await_suspend(__coro::coroutine_handle<_Promise>) noexcept
+        {
+            stdexec::start(__op_state_);
+        }
+
+      private:
+        using __receiver = __receiver_t<_Sender, _Promise>;
+        connect_result_t<_Sender, __receiver> __op_state_;
+    };
+};
+
+template <class _Promise, class _Sender>
+using __sender_awaitable_t =
+    __t<__sender_awaitable<__id<_Promise>, __id<_Sender>>>;
+
+template <class _Sender, class _Promise>
+concept __awaitable_sender =
+    sender_in<_Sender, env_of_t<_Promise&>> &&             //
+    __mvalid<__value_t, _Sender, _Promise> &&              //
+    sender_to<_Sender, __receiver_t<_Sender, _Promise>> && //
+    requires(_Promise& __promise) {
+        {
+            __promise.unhandled_stopped()
+        } -> convertible_to<__coro::coroutine_handle<>>;
+    };
+
+struct __unspecified
+{
+    auto get_return_object() noexcept -> __unspecified;
+    auto initial_suspend() noexcept -> __unspecified;
+    auto final_suspend() noexcept -> __unspecified;
+    void unhandled_exception() noexcept;
+    void return_void() noexcept;
+    auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>;
+};
+
+struct as_awaitable_t
+{
+    template <class _Tp, class _Promise>
+    static constexpr auto __select_impl_() noexcept
+    {
+        if constexpr (tag_invocable<as_awaitable_t, _Tp, _Promise&>)
+        {
+            using _Result = tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
+            constexpr bool _Nothrow =
+                nothrow_tag_invocable<as_awaitable_t, _Tp, _Promise&>;
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+            // NOLINTNEXTLINE(bugprone-branch-clone)
+        }
+        else if constexpr (__awaitable<_Tp, __unspecified>)
+        { // NOT __awaitable<_Tp, _Promise> !!
+            using _Result = _Tp&&;
+            return static_cast<_Result (*)() noexcept>(nullptr);
+        }
+        else if constexpr (__awaitable_sender<_Tp, _Promise>)
+        {
+            using _Result = __sender_awaitable_t<_Promise, _Tp>;
+            constexpr bool _Nothrow = __nothrow_constructible_from<
+                _Result, _Tp, __coro::coroutine_handle<_Promise>>;
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else
+        {
+            using _Result = _Tp&&;
+            return static_cast<_Result (*)() noexcept>(nullptr);
+        }
+    }
+
+    template <class _Tp, class _Promise>
+    using __select_impl_t = decltype(__select_impl_<_Tp, _Promise>());
+
+    template <class _Tp, class _Promise>
+    auto operator()(_Tp&& __t, _Promise& __promise) const
+        noexcept(__nothrow_callable<__select_impl_t<_Tp, _Promise>>)
+            -> __call_result_t<__select_impl_t<_Tp, _Promise>>
+    {
+        if constexpr (tag_invocable<as_awaitable_t, _Tp, _Promise&>)
+        {
+            using _Result = tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
+            static_assert(__awaitable<_Result, _Promise>);
+            return tag_invoke(*this, static_cast<_Tp&&>(__t), __promise);
+            // NOLINTNEXTLINE(bugprone-branch-clone)
+        }
+        else if constexpr (__awaitable<_Tp, __unspecified>)
+        { // NOT __awaitable<_Tp, _Promise> !!
+            return static_cast<_Tp&&>(__t);
+        }
+        else if constexpr (__awaitable_sender<_Tp, _Promise>)
+        {
+            auto __hcoro =
+                __coro::coroutine_handle<_Promise>::from_promise(__promise);
+            return __sender_awaitable_t<_Promise, _Tp>{static_cast<_Tp&&>(__t),
+                                                       __hcoro};
+        }
+        else
+        {
+            return static_cast<_Tp&&>(__t);
+        }
+    }
+};
+} // namespace __as_awaitable
+
+using __as_awaitable::as_awaitable_t;
+inline constexpr as_awaitable_t as_awaitable{};
+#endif
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__awaitable.hpp b/include/sdbusplus/async/stdexec/__detail/__awaitable.hpp
new file mode 100644
index 0000000..7b6c2a1
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__awaitable.hpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__config.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+#if !STDEXEC_STD_NO_COROUTINES()
+// Define some concepts and utilities for working with awaitables
+template <class _Tp>
+concept __await_suspend_result =
+    __one_of<_Tp, void, bool> ||
+    __is_instance_of<_Tp, __coro::coroutine_handle>;
+
+template <class _Awaiter, class _Promise>
+concept __with_await_suspend =
+    requires(_Awaiter& __awaiter, __coro::coroutine_handle<_Promise> __h) {
+        {
+            __awaiter.await_suspend(__h)
+        } -> __await_suspend_result;
+    };
+
+template <class _Awaiter, class... _Promise>
+concept __awaiter = //
+    requires(_Awaiter& __awaiter) {
+        __awaiter.await_ready() ? 1 : 0;
+        __awaiter.await_resume();
+    } && //
+    (__with_await_suspend<_Awaiter, _Promise> && ...);
+
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/operator-co_await-not-found-in-requires/10452721
+
+template <class _Awaitable>
+void __co_await_constraint(_Awaitable&& __awaitable)
+    requires requires {
+                 operator co_await(static_cast<_Awaitable&&>(__awaitable));
+             };
+#endif
+
+template <class _Awaitable>
+auto __get_awaiter(_Awaitable&& __awaitable, __ignore = {}) -> decltype(auto)
+{
+    if constexpr (requires {
+                      static_cast<_Awaitable&&>(__awaitable)
+                          .
+                          operator co_await();
+                  })
+    {
+        return static_cast<_Awaitable&&>(__awaitable).operator co_await();
+    }
+    else if constexpr (requires {
+#if STDEXEC_MSVC()
+                           __co_await_constraint(
+                               static_cast<_Awaitable&&>(__awaitable));
+#else
+        operator co_await(static_cast<_Awaitable&&>(__awaitable));
+#endif
+                       })
+    {
+        return operator co_await(static_cast<_Awaitable&&>(__awaitable));
+    }
+    else
+    {
+        return static_cast<_Awaitable&&>(__awaitable);
+    }
+}
+
+template <class _Awaitable, class _Promise>
+auto __get_awaiter(_Awaitable&& __awaitable, _Promise* __promise)
+    -> decltype(auto)
+    requires requires {
+                 __promise->await_transform(
+                     static_cast<_Awaitable&&>(__awaitable));
+             }
+{
+    if constexpr (requires {
+                      __promise
+                          ->await_transform(
+                              static_cast<_Awaitable&&>(__awaitable))
+                          .
+                          operator co_await();
+                  })
+    {
+        return __promise
+            ->await_transform(static_cast<_Awaitable&&>(__awaitable))
+            .
+            operator co_await();
+    }
+    else if constexpr (requires {
+#if STDEXEC_MSVC()
+                           __co_await_constraint(__promise->await_transform(
+                               static_cast<_Awaitable&&>(__awaitable)));
+#else
+        operator co_await(__promise->await_transform(static_cast<_Awaitable&&>(__awaitable)));
+#endif
+                       })
+    {
+        return operator co_await(
+            __promise->await_transform(static_cast<_Awaitable&&>(__awaitable)));
+    }
+    else
+    {
+        return __promise->await_transform(
+            static_cast<_Awaitable&&>(__awaitable));
+    }
+}
+
+template <class _Awaitable, class... _Promise>
+concept __awaitable = //
+    requires(_Awaitable&& __awaitable, _Promise*... __promise) {
+        {
+            stdexec::__get_awaiter(static_cast<_Awaitable&&>(__awaitable),
+                                   __promise...)
+        } -> __awaiter<_Promise...>;
+    };
+
+template <class _Tp>
+auto __as_lvalue(_Tp&&) -> _Tp&;
+
+template <class _Awaitable, class... _Promise>
+    requires __awaitable<_Awaitable, _Promise...>
+using __await_result_t =
+    decltype(stdexec::__as_lvalue(
+                 stdexec::__get_awaiter(std::declval<_Awaitable>(),
+                                        static_cast<_Promise*>(nullptr)...))
+                 .await_resume());
+
+#else
+
+template <class _Awaitable, class... _Promise>
+concept __awaitable = false;
+
+template <class _Awaitable, class... _Promise>
+    requires __awaitable<_Awaitable, _Promise...>
+using __await_result_t = void;
+
+#endif
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
index 843c5e4..3228fa2 100644
--- a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -15,12 +15,13 @@
  */
 #pragma once
 
-#include "../concepts.hpp"
 #include "__concepts.hpp"
-#include "__config.hpp"
+#include "__diagnostics.hpp"
 #include "__env.hpp"
 #include "__execution_fwd.hpp"
 #include "__meta.hpp"
+#include "__sender_introspection.hpp"
+#include "__senders_core.hpp"
 #include "__tuple.hpp"
 #include "__type_traits.hpp"
 
@@ -37,116 +38,40 @@
 template <class _Sender>
 using __impl_of = decltype((__declval<_Sender>().__impl_));
 
-struct __get_tag
-{
-    template <class _Tag, class... _Rest>
-    STDEXEC_ATTRIBUTE((always_inline))
-    _Tag operator()(_Tag, _Rest&&...) const noexcept
-    {
-        return {};
-    }
-};
-
 struct __get_data
 {
-    template <class _Data, class... _Rest>
+    template <class _Data>
     STDEXEC_ATTRIBUTE((always_inline))
-    _Data&& operator()(__ignore, _Data&& __data, _Rest&&...) const noexcept
+    _Data&& operator()(__ignore, _Data&& __data, auto&&...) const noexcept
     {
         return static_cast<_Data&&>(__data);
     }
 };
-
-template <class _Continuation>
-struct __get_children
-{
-    template <class... _Child>
-    STDEXEC_ATTRIBUTE((always_inline))
-    auto operator()(__ignore, __ignore, _Child&&...) const noexcept
-        -> __mtype<__minvoke<_Continuation, _Child...>> (*)()
-    {
-        return nullptr;
-    }
-};
-
-template <class _Tag, class _Data, class... _Child>
-struct __desc
-{
-    using __tag = _Tag;
-    using __data = _Data;
-    using __children = __types<_Child...>;
-
-    template <class _Fn>
-    using __f = __minvoke<_Fn, _Tag, _Data, _Child...>;
-};
-
-template <class _Fn>
-struct __sexpr_uncurry_fn
-{
-    template <class _Tag, class _Data, class... _Child>
-        requires __minvocable<_Fn, _Tag, _Data, _Child...>
-    constexpr auto operator()(_Tag, _Data&&, _Child&&...) const noexcept
-        -> __minvoke<_Fn, _Tag, _Data, _Child...>;
-};
-
-template <class _Sender, class _Fn>
-using __sexpr_uncurry =
-    __call_result_t<__impl_of<_Sender>, __copy_cvref_fn<_Sender>,
-                    __sexpr_uncurry_fn<_Fn>>;
-
-template <class _Sender>
-using __desc_of = __sexpr_uncurry<_Sender, __q<__desc>>;
-
-using __get_desc = __sexpr_uncurry_fn<__q<__desc>>;
-
-template <class _Sender>
-extern __q<__midentity> __name_of_v;
-
-template <class _Sender>
-using __name_of_fn = decltype(__name_of_v<_Sender>);
-
-template <class _Sender>
-using __name_of = __minvoke<__name_of_fn<_Sender>, _Sender>;
 } // namespace __detail
 
-template <class _Sender>
-using tag_of_t = typename __detail::__desc_of<_Sender>::__tag;
-
-template <class _Sender>
-using __data_of = typename __detail::__desc_of<_Sender>::__data;
-
-template <class _Sender, class _Continuation = __q<__types>>
-using __children_of = //
-    __mapply<_Continuation, typename __detail::__desc_of<_Sender>::__children>;
-
-template <class _Ny, class _Sender>
-using __nth_child_of = __children_of<_Sender, __mbind_front_q<__m_at, _Ny>>;
-
-template <std::size_t _Ny, class _Sender>
-using __nth_child_of_c =
-    __children_of<_Sender, __mbind_front_q<__m_at, __msize_t<_Ny>>>;
-
-template <class _Sender>
-using __child_of = __children_of<_Sender, __q<__mfront>>;
-
-template <class _Sender>
-inline constexpr std::size_t __nbr_children_of =
-    __v<__children_of<_Sender, __msize>>;
-
-template <class _Fn, class _Tp>
-    requires __mvalid<tag_of_t, _Tp> &&
-             __mvalid<__detail::__sexpr_uncurry, _Tp, _Fn>
-struct __uncurry_<_Fn, _Tp>
+namespace
 {
-    using __t = __detail::__sexpr_uncurry<_Tp, _Fn>;
-};
+template <class _Descriptor, auto _DescriptorFn = [] { return _Descriptor(); }>
+inline constexpr auto __descriptor_fn_v = _DescriptorFn;
+
+template <class _Tag, class _Data, class... _Child>
+inline constexpr auto __descriptor_fn()
+{
+    return __descriptor_fn_v<__detail::__desc<_Tag, _Data, _Child...>>;
+}
+} // namespace
+
+#if STDEXEC_NVHPC()
+#define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child)                          \
+    stdexec::__descriptor_fn<_Tag, _Data, _Child>()
+#else
+#define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child)                          \
+    stdexec::__descriptor_fn_v<stdexec::__detail::__desc<_Tag, _Data, _Child>>
+#endif
 
 template <class _Tag>
 struct __sexpr_impl;
 
-template <class _Sender>
-using __name_of = __detail::__name_of<_Sender>;
-
 namespace __detail
 {
 template <class _Sexpr, class _Receiver>
@@ -159,10 +84,11 @@
 using __state_type_t =
     __decay_t<__result_of<__sexpr_impl<_Tag>::get_state, _Sexpr, _Receiver&>>;
 
-template <class _Tag, class _Index, class _Sexpr, class _Receiver>
-using __env_type_t =
-    __result_of<__sexpr_impl<_Tag>::get_env, _Index,
-                __state_type_t<_Tag, _Sexpr, _Receiver>&, _Receiver&>;
+template <class _Self, class _Tag, class _Index, class _Sexpr, class _Receiver>
+using __env_type_t = __result_of<
+    __sexpr_impl<__meval<__msecond, _Self, _Tag>>::get_env, _Index,
+    __state_type_t<__meval<__msecond, _Self, _Tag>, _Sexpr, _Receiver>&,
+    _Receiver&>;
 
 template <class _Sexpr, class _Receiver>
 concept __connectable =
@@ -199,13 +125,14 @@
 
 inline constexpr auto __get_state = //
     []<class _Sender>(_Sender&& __sndr, __ignore) noexcept -> decltype(auto) {
-    return STDEXEC_CALL_EXPLICIT_THIS_MEMFN(static_cast<_Sender&&>(__sndr),
-                                            apply)(__get_data());
+    return __sndr.apply(static_cast<_Sender&&>(__sndr), __get_data());
 };
 
-inline constexpr auto __connect = //
-    []<class _Sender, class _Receiver>(
-        _Sender&& __sndr, _Receiver __rcvr) -> __op_state<_Sender, _Receiver>
+inline constexpr auto __connect =                                          //
+    []<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver __rcvr) //
+    noexcept(__nothrow_constructible_from<__op_state<_Sender, _Receiver>,
+                                          _Sender, _Receiver>)
+    -> __op_state<_Sender, _Receiver>
     requires __connectable<_Sender, _Receiver>
 {
     return __op_state<_Sender, _Receiver>{static_cast<_Sender&&>(__sndr),
@@ -228,8 +155,12 @@
     _SetTag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
 };
 
-inline constexpr auto __get_completion_signatures = //
-    [](__ignore, __ignore) noexcept { return void(); };
+inline constexpr auto __sigs = //
+    []<class _Sender>(_Sender&& __sndr, __ignore = {}) noexcept {
+    static_assert(
+        __mnever<tag_of_t<_Sender>>,
+        "No customization of get_completion_signatures for this sender tag type.");
+};
 
 template <class _ReceiverId, class _Sexpr, class _Idx>
 struct __receiver
@@ -258,29 +189,43 @@
         //   (static_cast<char*>(__child) - __offset); return __t{__parent};
         // }
 
-        template <__completion_tag _Tag, class... _Args>
+        template <class... _Args>
         STDEXEC_ATTRIBUTE((always_inline))
-        friend void tag_invoke(_Tag, __t&& __self, _Args&&... __args) noexcept
+        void set_value(_Args&&... __args) noexcept
         {
-            __self.__op_->__complete(_Idx(), _Tag(),
-                                     static_cast<_Args&&>(__args)...);
+            __op_->__complete(_Idx(), stdexec::set_value,
+                              static_cast<_Args&&>(__args)...);
         }
 
-        template <same_as<get_env_t> _Tag, class _SexprTag = __tag_t>
+        template <class _Error>
         STDEXEC_ATTRIBUTE((always_inline))
-        friend auto tag_invoke(_Tag, const __t& __self) noexcept
-            -> __env_type_t<_SexprTag, _Idx, _Sexpr, _Receiver>
+        void set_error(_Error&& __err) noexcept
         {
-            return __self.__op_->__get_env(_Idx());
+            __op_->__complete(_Idx(), stdexec::set_error,
+                              static_cast<_Error&&>(__err));
+        }
+
+        STDEXEC_ATTRIBUTE((always_inline))
+        void set_stopped() noexcept
+        {
+            __op_->__complete(_Idx(), stdexec::set_stopped);
+        }
+
+        template <__same_as<__t> _Self = __t>
+        STDEXEC_ATTRIBUTE((always_inline))
+        auto get_env() const noexcept
+            -> __env_type_t<_Self, __tag_t, _Idx, _Sexpr, _Receiver>
+        {
+            return __op_->__get_env(_Idx());
         }
     };
 };
 
-template <class _Receiver>
-using __sexpr_connected_with =
-    __mapply<__mbind_front_q<__m_at, typename _Receiver::__index>,
-             typename __call_result_t<__impl_of<typename _Receiver::__sexpr>,
-                                      __cp, __get_desc>::__children>;
+// template <class _Receiver>
+// using __sexpr_connected_with = __mapply<
+//   __mbind_front_q<__m_at, typename _Receiver::__index>,
+//   typename __call_result_t<__impl_of<typename _Receiver::__sexpr>, __cp,
+//   __get_desc>::__children>;
 
 template <class _Sexpr, class _Receiver>
 struct __op_base : __immovable
@@ -291,7 +236,9 @@
     STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
     STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS __state_t __state_;
 
-    __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr) :
+    __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr) //
+        noexcept(__nothrow_decay_copyable<_Receiver> &&
+                 __nothrow_move_constructible<__state_t>) :
         __rcvr_(static_cast<_Receiver&&>(__rcvr)),
         __state_(__sexpr_impl<__tag_t>::get_state(static_cast<_Sexpr&&>(__sndr),
                                                   __rcvr_))
@@ -301,6 +248,11 @@
     {
         return __rcvr_;
     }
+
+    auto __rcvr() const& noexcept -> const _Receiver&
+    {
+        return __rcvr_;
+    }
 };
 
 // template <class _Sexpr, class _Receiver>
@@ -355,7 +307,7 @@
 {
     template <std::size_t _Idx>
     using __receiver_t =
-        __t<__receiver<__id<_Receiver>, _Sexpr, __mconstant<_Idx>>>;
+        __t<__receiver<__id<_Receiver>, _Sexpr, __msize_t<_Idx>>>;
 
     __op_state<_Sexpr, _Receiver>* __op_;
 
@@ -363,26 +315,29 @@
     {
         __op_state<_Sexpr, _Receiver>* __op_;
 
-        template <std::size_t... _Is, class _Tag, class _Data, class... _Child>
-        auto operator()(__indices<_Is...>, _Tag, _Data&&,
-                        _Child&&... __child) const
-            -> __tup::__tuple<__indices<_Is...>,
-                              connect_result_t<_Child, __receiver_t<_Is>>...>
+        template <std::size_t... _Is, class... _Child>
+        auto operator()(__indices<_Is...>, _Child&&... __child) const
+            noexcept((__nothrow_connectable<_Child, __receiver_t<_Is>> && ...))
+                -> __tuple_for<connect_result_t<_Child, __receiver_t<_Is>>...>
         {
             return __tuple{connect(static_cast<_Child&&>(__child),
                                    __receiver_t<_Is>{__op_})...};
         }
     };
 
-    template <class _Tag, class _Data, class... _Child>
-    auto operator()(_Tag, _Data&& __data, _Child&&... __child) const
-        -> __call_result_t<__impl, __indices_for<_Child...>, _Tag, _Data,
-                           _Child...>
+    template <class... _Child>
+    auto operator()(__ignore, __ignore, _Child&&... __child) const noexcept(
+        __nothrow_callable<__impl, __indices_for<_Child...>, _Child...>)
+        -> __call_result_t<__impl, __indices_for<_Child...>, _Child...>
     {
-        return __impl{__op_}(__indices_for<_Child...>(), _Tag(),
-                             static_cast<_Data&&>(__data),
+        return __impl{__op_}(__indices_for<_Child...>(),
                              static_cast<_Child&&>(__child)...);
     }
+
+    auto operator()(__ignore, __ignore) const noexcept -> __tuple_for<>
+    {
+        return {};
+    }
 };
 STDEXEC_PRAGMA_POP()
 
@@ -392,7 +347,7 @@
     using __desc_t = typename __decay_t<_Sexpr>::__desc_t;
     using __tag_t = typename __desc_t::__tag;
     using __data_t = typename __desc_t::__data;
-    using __children_t = typename __desc_t::__children;
+    // using __children_t = typename __desc_t::__children;
     using __state_t = typename __op_state::__state_t;
     using __inner_ops_t =
         __result_of<__sexpr_apply, _Sexpr, __connect_fn<_Sexpr, _Receiver>>;
@@ -402,29 +357,31 @@
     // template <std::size_t _Idx>
     // static std::ptrdiff_t __get_child_op_offset() noexcept {
     //   __op_state* __self = (__op_state*) &__self;
-    //   return (std::ptrdiff_t)((char*)
-    //   &__tup::__get<_Idx>(__self->__inner_ops_) -
-    //   static_cast<char*>(__self));
+    //   return (std::ptrdiff_t)((char*) &__tup::get<_Idx>(__self->__inner_ops_)
+    //   - static_cast<char*>(__self));
     // }
 
-    __op_state(_Sexpr&& __sexpr, _Receiver __rcvr) :
+    __op_state(_Sexpr&& __sexpr, _Receiver __rcvr) //
+        noexcept(__nothrow_constructible_from<__op_base<_Sexpr, _Receiver>,
+                                              _Sexpr&&, _Receiver&&> &&
+                 __nothrow_callable<__sexpr_apply_t, _Sexpr&&,
+                                    __connect_fn<_Sexpr, _Receiver>>) :
         __op_state::__op_base{static_cast<_Sexpr&&>(__sexpr),
                               static_cast<_Receiver&&>(__rcvr)},
         __inner_ops_(__sexpr_apply(static_cast<_Sexpr&&>(__sexpr),
                                    __connect_fn<_Sexpr, _Receiver>{this}))
     {}
 
-    template <same_as<start_t> _Tag2>
     STDEXEC_ATTRIBUTE((always_inline))
-    friend void tag_invoke(_Tag2, __op_state& __self) noexcept
+    void start() & noexcept
     {
         using __tag_t = typename __op_state::__tag_t;
-        auto&& __rcvr = __self.__rcvr();
-        __tup::__apply(
+        auto&& __rcvr = this->__rcvr();
+        __inner_ops_.apply(
             [&](auto&... __ops) noexcept {
-            __sexpr_impl<__tag_t>::start(__self.__state_, __rcvr, __ops...);
+            __sexpr_impl<__tag_t>::start(this->__state_, __rcvr, __ops...);
         },
-            __self.__inner_ops_);
+            __inner_ops_);
     }
 
     template <class _Index, class _Tag2, class... _Args>
@@ -433,15 +390,25 @@
     {
         using __tag_t = typename __op_state::__tag_t;
         auto&& __rcvr = this->__rcvr();
-        __sexpr_impl<__tag_t>::complete(_Index(), this->__state_, __rcvr,
-                                        _Tag2(),
-                                        static_cast<_Args&&>(__args)...);
+        using _CompleteFn = __mtypeof<__sexpr_impl<__tag_t>::complete>;
+        if constexpr (__callable<_CompleteFn, _Index, __op_state&, _Tag2,
+                                 _Args...>)
+        {
+            __sexpr_impl<__tag_t>::complete(_Index(), *this, _Tag2(),
+                                            static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            __sexpr_impl<__tag_t>::complete(_Index(), this->__state_, __rcvr,
+                                            _Tag2(),
+                                            static_cast<_Args&&>(__args)...);
+        }
     }
 
     template <class _Index>
     STDEXEC_ATTRIBUTE((always_inline))
-    auto __get_env(_Index) noexcept
-        -> __env_type_t<__tag_t, _Index, _Sexpr, _Receiver>
+    auto __get_env(_Index) const noexcept
+        -> __env_type_t<_Index, __tag_t, _Index, _Sexpr, _Receiver>
     {
         const auto& __rcvr = this->__rcvr();
         return __sexpr_impl<__tag_t>::get_env(_Index(), this->__state_, __rcvr);
@@ -451,9 +418,8 @@
 inline constexpr auto __drop_front = //
     []<class _Fn>(_Fn __fn) noexcept {
     return
-        [__fn = std::move(__fn)]<class... _Rest>(
-            auto&&, _Rest&&... __rest) noexcept(__nothrow_callable<const _Fn&,
-                                                                   _Rest...>)
+        [__fn = std::move(__fn)]<class... _Rest>(auto&&, _Rest&&... __rest) //
+        noexcept(__nothrow_callable<const _Fn&, _Rest...>)
             -> __call_result_t<const _Fn&, _Rest...> {
         return __fn(static_cast<_Rest&&>(__rest)...);
     };
@@ -480,19 +446,6 @@
     };
 }
 
-template <class _Sender>
-concept __non_dependent_sender = //
-    requires { typename _Sender::completion_signatures; } ||
-    requires { requires _Sender::__is_non_dependent(); };
-
-template <class _Tag, class... _Child>
-concept __is_non_dependent_sexpr = //
-    !requires { typename __sexpr_impl<_Tag>::is_dependent; } &&
-    (__non_dependent_sender<_Child> && ...);
-
-template <class _Tag, class _Data, class... _Child>
-using __is_non_dependent_t = __mbool<__is_non_dependent_sexpr<_Tag, _Child...>>;
-
 template <class _Tag, class _Data, class... _Child>
 using __captures_t = decltype(__detail::__captures(_Tag(), __declval<_Data>(),
                                                    __declval<_Child>()...));
@@ -514,13 +467,14 @@
     static constexpr auto connect = __detail::__connect;
     static constexpr auto start = __detail::__start;
     static constexpr auto complete = __detail::__complete;
-    static constexpr auto get_completion_signatures =
-        __detail::__get_completion_signatures;
+    static constexpr auto get_completion_signatures = __detail::__sigs;
 };
 
 template <class _Tag>
 struct __sexpr_impl : __sexpr_defaults
-{};
+{
+    using not_specialized = void;
+};
 
 using __detail::__enable_receiver_from_this;
 
@@ -548,11 +502,6 @@
     using __tag_t = typename __desc_t::__tag;
     using __captures_t = __minvoke<__desc_t, __q<__detail::__captures_t>>;
 
-    static constexpr auto __is_non_dependent() noexcept -> bool
-    {
-        return __v<__minvoke<__desc_t, __q<__detail::__is_non_dependent_t>>>;
-    }
-
     mutable __captures_t __impl_;
 
     template <class _Tag, class _Data, class... _Child>
@@ -562,55 +511,45 @@
                                      static_cast<_Child&&>(__child)...))
     {}
 
-    template <class _Tag>
-    using __impl = __sexpr_impl<__meval<__msecond, _Tag, __tag_t>>;
+    template <class _Self>
+    using __impl = __sexpr_impl<__meval<__msecond, _Self, __tag_t>>;
 
-    template <same_as<get_env_t> _Tag, same_as<__sexpr> _Self>
+    template <class _Self = __sexpr>
     STDEXEC_ATTRIBUTE((always_inline))
-    friend auto tag_invoke(_Tag, const _Self& __self) noexcept           //
-        -> __msecond<
-            __if_c<same_as<_Tag, get_env_t> && same_as<_Self, __sexpr>>, //
-            __result_of<__sexpr_apply, const _Self&, __get_attrs_fn<__tag_t>>>
+    auto get_env() const noexcept
+        -> __result_of<__sexpr_apply, const _Self&, __get_attrs_fn<__tag_t>>
     {
-        return __sexpr_apply(__self,
-                             __detail::__drop_front(__impl<_Tag>::get_attrs));
+        return __sexpr_apply(*this,
+                             __detail::__drop_front(__impl<_Self>::get_attrs));
     }
 
-    template <same_as<get_completion_signatures_t> _Tag,
-              __decays_to<__sexpr> _Self, class _Env>
+    template <__decays_to<__sexpr> _Self, class... _Env>
     STDEXEC_ATTRIBUTE((always_inline))
-    friend auto tag_invoke(_Tag, _Self&& __self, _Env&& __env) noexcept //
-        -> __msecond<
-            __if_c<same_as<_Tag, get_completion_signatures_t> &&
-                   __decays_to<_Self, __sexpr>>,
-            __result_of<__impl<_Tag>::get_completion_signatures, _Self, _Env>>
+    static auto get_completion_signatures(_Self&&, _Env&&...) noexcept //
+        -> __msecond<__if_c<__decays_to<_Self, __sexpr>>,
+                     __result_of<__impl<_Self>::get_completion_signatures,
+                                 _Self, _Env...>>
     {
         return {};
     }
 
     // BUGBUG fix receiver constraint here:
-    template <same_as<connect_t> _Tag, __decays_to<__sexpr> _Self,
-              /*receiver*/ class _Receiver>
+    template <__decays_to<__sexpr> _Self, /*receiver*/ class _Receiver>
     STDEXEC_ATTRIBUTE((always_inline))
-    friend auto tag_invoke(_Tag, _Self&& __self, _Receiver&& __rcvr)          //
-        noexcept(noexcept(__impl<_Tag>::connect(
-            static_cast<_Self&&>(__self), static_cast<_Receiver&&>(__rcvr)))) //
-        -> __msecond<
-            __if_c<same_as<_Tag, connect_t> && __decays_to<_Self, __sexpr>>,
-            __result_of<__impl<_Tag>::connect, _Self, _Receiver>>
+    static auto connect(_Self&& __self, _Receiver&& __rcvr)               //
+        noexcept(__noexcept_of<__impl<_Self>::connect, _Self, _Receiver>) //
+        -> __msecond<__if_c<__decays_to<_Self, __sexpr>>,
+                     __result_of<__impl<_Self>::connect, _Self, _Receiver>>
     {
-        return __impl<_Tag>::connect(static_cast<_Self&&>(__self),
-                                     static_cast<_Receiver&&>(__rcvr));
+        return __impl<_Self>::connect(static_cast<_Self&&>(__self),
+                                      static_cast<_Receiver&&>(__rcvr));
     }
 
     template <class _Sender, class _ApplyFn>
     STDEXEC_ATTRIBUTE((always_inline))
-    STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(auto apply)(
-        this _Sender&& __sndr,
-        _ApplyFn&&
-            __fun) noexcept(__nothrow_callable<__detail::__impl_of<_Sender>,
-                                               __copy_cvref_fn<_Sender>,
-                                               _ApplyFn>) //
+    static auto apply(_Sender&& __sndr, _ApplyFn&& __fun)                //
+        noexcept(__nothrow_callable<__detail::__impl_of<_Sender>,
+                                    __copy_cvref_fn<_Sender>, _ApplyFn>) //
         -> __call_result_t<__detail::__impl_of<_Sender>,
                            __copy_cvref_fn<_Sender>, _ApplyFn>
     {                                                                    //
@@ -620,7 +559,7 @@
 
     template <std::size_t _Idx, __decays_to_derived_from<__sexpr> _Self>
     STDEXEC_ATTRIBUTE((always_inline))
-    friend decltype(auto) get(_Self&& __self) noexcept
+    friend auto get(_Self&& __self) noexcept -> decltype(auto)
         requires __detail::__in_range<_Idx, __desc_t>
     {
         if constexpr (_Idx == 0)
@@ -635,26 +574,6 @@
     }
 };
 
-namespace
-{
-template <class _Descriptor, auto _DescriptorFn = [] { return _Descriptor(); }>
-inline constexpr auto __descriptor_fn_v = _DescriptorFn;
-
-template <class _Tag, class _Data, class... _Child>
-inline constexpr auto __descriptor_fn()
-{
-    return __descriptor_fn_v<__detail::__desc<_Tag, _Data, _Child...>>;
-}
-} // namespace
-
-#if STDEXEC_NVHPC()
-#define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child)                          \
-    stdexec::__descriptor_fn<_Tag, _Data, _Child>()
-#else
-#define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child)                          \
-    stdexec::__descriptor_fn_v<stdexec::__detail::__desc<_Tag, _Data, _Child>>
-#endif
-
 template <class _Tag, class _Data, class... _Child>
 STDEXEC_ATTRIBUTE((host, device))
 __sexpr(_Tag, _Data, _Child...)
@@ -683,42 +602,6 @@
 template <class _Tag>
 inline constexpr __detail::__make_sexpr_t<_Tag> __make_sexpr{};
 
-namespace __detail
-{
-struct __sexpr_apply_t
-{
-    template <class _Sender, class _ApplyFn>
-    STDEXEC_ATTRIBUTE((always_inline))
-    auto operator()(_Sender&& __sndr, _ApplyFn&& __fun) const
-        noexcept(noexcept(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(
-            (static_cast<_Sender&&>(__sndr)),
-            apply)(static_cast<_ApplyFn&&>(__fun)))) //
-        -> decltype(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(
-            (static_cast<_Sender&&>(__sndr)),
-            apply)(static_cast<_ApplyFn&&>(__fun)))
-    {
-        return STDEXEC_CALL_EXPLICIT_THIS_MEMFN(
-            (static_cast<_Sender&&>(__sndr)),
-            apply)(static_cast<_ApplyFn&&>(__fun)); //
-    }
-};
-} // namespace __detail
-
-using __detail::__sexpr_apply_t;
-inline constexpr __sexpr_apply_t __sexpr_apply{};
-
-template <class _Sender, class _ApplyFn>
-using __sexpr_apply_result_t =
-    __call_result_t<__sexpr_apply_t, _Sender, _ApplyFn>;
-
-template <class _Sender>
-concept sender_expr = //
-    __mvalid<tag_of_t, _Sender>;
-
-template <class _Sender, class _Tag>
-concept sender_expr_for = //
-    sender_expr<_Sender> && same_as<tag_of_t<_Sender>, _Tag>;
-
 // The __name_of utility defined below is used to pretty-print the type names of
 // senders in compiler diagnostics.
 namespace __detail
diff --git a/include/sdbusplus/async/stdexec/__detail/__bulk.hpp b/include/sdbusplus/async/stdexec/__detail/__bulk.hpp
new file mode 100644
index 0000000..1878534
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__bulk.hpp
@@ -0,0 +1,182 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.bulk]
+namespace __bulk
+{
+inline constexpr __mstring __bulk_context =
+    "In stdexec::bulk(Sender, Shape, Function)..."_mstr;
+using __on_not_callable = __callable_error<__bulk_context>;
+
+template <class _Shape, class _Fun>
+struct __data
+{
+    _Shape __shape_;
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Fun __fun_;
+    static constexpr auto __mbrs_ =
+        __mliterals<&__data::__shape_, &__data::__fun_>();
+};
+template <class _Shape, class _Fun>
+__data(_Shape, _Fun) -> __data<_Shape, _Fun>;
+
+template <class _Ty>
+using __decay_ref = __decay_t<_Ty>&;
+
+template <class _Catch, class _Fun, class _Shape, class _CvrefSender,
+          class... _Env>
+using __with_error_invoke_t = //
+    __if<__value_types_t<
+             __completion_signatures_of_t<_CvrefSender, _Env...>,
+             __mtransform<
+                 __q<__decay_ref>,
+                 __mbind_front<__mtry_catch_q<__nothrow_invocable_t, _Catch>,
+                               _Fun, _Shape>>,
+             __q<__mand>>,
+         completion_signatures<>, __eptr_completion>;
+
+template <class _Fun, class _Shape, class _CvrefSender, class... _Env>
+using __completion_signatures = //
+    transform_completion_signatures<
+        __completion_signatures_of_t<_CvrefSender, _Env...>,
+        __with_error_invoke_t<__on_not_callable, _Fun, _Shape, _CvrefSender,
+                              _Env...>>;
+
+struct bulk_t
+{
+    template <sender _Sender, integral _Shape, __movable_value _Fun>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<bulk_t>(__data{__shape, static_cast<_Fun&&>(__fun)},
+                                 static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <integral _Shape, class _Fun>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Shape __shape, _Fun __fun) const
+        -> __binder_back<bulk_t, _Shape, _Fun>
+    {
+        return {{static_cast<_Shape&&>(__shape), static_cast<_Fun&&>(__fun)},
+                {},
+                {}};
+    }
+
+    // This describes how to use the pieces of a bulk sender to find
+    // legacy customizations of the bulk algorithm.
+    using _Sender = __1;
+    using _Shape = __nth_member<0>(__0);
+    using _Fun = __nth_member<1>(__0);
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(bulk_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Shape, _Fun),
+                tag_invoke_t(bulk_t, _Sender, _Shape, _Fun)>;
+};
+
+struct __bulk_impl : __sexpr_defaults
+{
+    template <class _Sender>
+    using __fun_t = decltype(__decay_t<__data_of<_Sender>>::__fun_);
+
+    template <class _Sender>
+    using __shape_t = decltype(__decay_t<__data_of<_Sender>>::__shape_);
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
+        -> __completion_signatures<__fun_t<_Sender>, __shape_t<_Sender>,
+                                   __child_of<_Sender>, _Env...> {
+        static_assert(sender_expr_for<_Sender, bulk_t>);
+        return {};
+    };
+
+    static constexpr auto complete = //
+        []<class _Tag, class _State, class _Receiver, class... _Args>(
+            __ignore, _State& __state, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (std::same_as<_Tag, set_value_t>)
+        {
+            using __shape_t = decltype(__state.__shape_);
+            if constexpr (noexcept(__state.__fun_(__shape_t{}, __args...)))
+            {
+                for (__shape_t __i{}; __i != __state.__shape_; ++__i)
+                {
+                    __state.__fun_(__i, __args...);
+                }
+                _Tag()(static_cast<_Receiver&&>(__rcvr),
+                       static_cast<_Args&&>(__args)...);
+            }
+            else
+            {
+                try
+                {
+                    for (__shape_t __i{}; __i != __state.__shape_; ++__i)
+                    {
+                        __state.__fun_(__i, __args...);
+                    }
+                    _Tag()(static_cast<_Receiver&&>(__rcvr),
+                           static_cast<_Args&&>(__args)...);
+                }
+                catch (...)
+                {
+                    stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                       std::current_exception());
+                }
+            }
+        }
+        else
+        {
+            _Tag()(static_cast<_Receiver&&>(__rcvr),
+                   static_cast<_Args&&>(__args)...);
+        }
+    };
+};
+} // namespace __bulk
+
+using __bulk::bulk_t;
+inline constexpr bulk_t bulk{};
+
+template <>
+struct __sexpr_impl<bulk_t> : __bulk::__bulk_impl
+{};
+} // namespace stdexec
+
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__completion_signatures.hpp b/include/sdbusplus/async/stdexec/__detail/__completion_signatures.hpp
new file mode 100644
index 0000000..dd16858
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__completion_signatures.hpp
@@ -0,0 +1,58 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__meta.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// completion_signatures
+namespace __sigs
+{
+template <class... _Args>
+inline constexpr bool __is_compl_sig<set_value_t(_Args...)> = true;
+template <class _Error>
+inline constexpr bool __is_compl_sig<set_error_t(_Error)> = true;
+template <>
+inline constexpr bool __is_compl_sig<set_stopped_t()> = true;
+
+template <class>
+inline constexpr bool __is_completion_signatures = false;
+template <class... _Sigs>
+inline constexpr bool
+    __is_completion_signatures<completion_signatures<_Sigs...>> = true;
+} // namespace __sigs
+
+template <class... _Sigs>
+struct completion_signatures
+{};
+
+template <class _Completions>
+concept __valid_completion_signatures = //
+    __same_as<__ok_t<_Completions>, __msuccess> &&
+    __sigs::__is_completion_signatures<_Completions>;
+
+template <class _Sender, class _Env>
+using __unrecognized_sender_error = //
+    __mexception<_UNRECOGNIZED_SENDER_TYPE_<>, _WITH_SENDER_<_Sender>,
+                 _WITH_ENVIRONMENT_<_Env>>;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__concepts.hpp b/include/sdbusplus/async/stdexec/__detail/__concepts.hpp
index a3187a7..667dcb4 100644
--- a/include/sdbusplus/async/stdexec/__detail/__concepts.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__concepts.hpp
@@ -15,12 +15,30 @@
  */
 #pragma once
 
+#if __cpp_concepts < 201907L
+#error This library requires support for C++20 concepts
+#endif
+
 #include "__config.hpp"
 #include "__type_traits.hpp"
 
+#include <version>
+
+// Perhaps the stdlib lacks support for concepts though:
+#if __has_include(<concepts>) && __cpp_lib_concepts >= 202002
+#define STDEXEC_HAS_STD_CONCEPTS_HEADER() 1
+#else
+#define STDEXEC_HAS_STD_CONCEPTS_HEADER() 0
+#endif
+
+#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
+#include <concepts>
+#else
+#include <type_traits>
+#endif
+
 namespace stdexec
 {
-
 //////////////////////////////////////////////////////////////////////////////////////////////////
 template <class _Fun, class... _As>
 concept __callable =                                             //
@@ -44,28 +62,8 @@
 concept __typename = requires { typename __types<_Ts...>; };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-#if STDEXEC_CLANG()
-
 template <class _Ap, class _Bp>
-concept __same_as = __is_same(_Ap, _Bp);
-
-#elif STDEXEC_GCC()
-
-template <class _Ap, class _Bp>
-concept __same_as = __is_same_as(_Ap, _Bp);
-
-#else
-
-template <class _Ap, class _Bp>
-inline constexpr bool __same_as_v = false;
-
-template <class _Ap>
-inline constexpr bool __same_as_v<_Ap, _Ap> = true;
-
-template <class _Ap, class _Bp>
-concept __same_as = __same_as_v<_Ap, _Bp>;
-
-#endif
+concept __same_as = STDEXEC_IS_SAME(_Ap, _Bp);
 
 // Handy concepts
 template <class _Ty, class _Up>
@@ -102,5 +100,229 @@
 
 template <class _Ay, template <class...> class _Ty>
 concept __is_not_instance_of = !__is_instance_of<_Ay, _Ty>;
+} // namespace stdexec
 
+namespace stdexec::__std_concepts
+{
+// Make sure we're using a same_as concept that doesn't instantiate std::is_same
+template <class _Ap, class _Bp>
+concept same_as = __same_as<_Ap, _Bp> && __same_as<_Bp, _Ap>;
+
+#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
+
+using std::convertible_to;
+using std::derived_from;
+using std::equality_comparable;
+using std::integral;
+
+#else
+
+template <class T>
+concept integral = std::is_integral_v<T>;
+
+template <class _Ap, class _Bp>
+concept derived_from =              //
+    STDEXEC_IS_BASE_OF(_Bp, _Ap) && //
+    STDEXEC_IS_CONVERTIBLE_TO(const volatile _Ap*, const volatile _Bp*);
+
+template <class _From, class _To>
+concept convertible_to =                     //
+    STDEXEC_IS_CONVERTIBLE_TO(_From, _To) && //
+    requires(_From (&__fun)()) { static_cast<_To>(__fun()); };
+
+template <class _Ty>
+concept equality_comparable = //
+    requires(__cref_t<_Ty> __t) {
+        {
+            __t == __t
+        } -> convertible_to<bool>;
+        {
+            __t != __t
+        } -> convertible_to<bool>;
+    };
+#endif
+} // namespace stdexec::__std_concepts
+
+namespace stdexec
+{
+using namespace __std_concepts;
+
+// Avoid using libstdc++'s object concepts because they instantiate a
+// lot of templates.
+#if STDEXEC_HAS_BUILTIN(__is_nothrow_destructible) || STDEXEC_MSVC()
+template <class _Ty>
+concept destructible = __is_nothrow_destructible(_Ty);
+#else
+template <class _Ty>
+inline constexpr bool __destructible_ = //
+    requires(_Ty && (&__fn)() noexcept) {
+        {
+            __fn().~_Ty()
+        } noexcept;
+    };
+template <class _Ty>
+inline constexpr bool __destructible_<_Ty&> = true;
+template <class _Ty>
+inline constexpr bool __destructible_<_Ty&&> = true;
+template <class _Ty, std::size_t _Np>
+inline constexpr bool __destructible_<_Ty[_Np]> = __destructible_<_Ty>;
+
+template <class T>
+concept destructible = __destructible_<T>;
+#endif
+
+template <class _Ty, class... _As>
+concept constructible_from = //
+    destructible<_Ty> &&     //
+    STDEXEC_IS_CONSTRUCTIBLE(_Ty, _As...);
+
+template <class _Ty>
+concept default_initializable = //
+    constructible_from<_Ty> &&  //
+    requires { _Ty{}; } &&      //
+    requires { ::new _Ty; };
+
+template <class _Ty>
+concept move_constructible = //
+    constructible_from<_Ty, _Ty>;
+
+template <class _Ty>
+concept copy_constructible = //
+    move_constructible<_Ty>  //
+    && constructible_from<_Ty, const _Ty&>;
+
+template <class _LHS, class _RHS>
+concept assignable_from =   //
+    same_as<_LHS, _LHS&> && //
+    // std::common_reference_with<
+    //   const std::remove_reference_t<_LHS>&,
+    //   const std::remove_reference_t<_RHS>&> &&
+    requires(_LHS __lhs, _RHS&& __rhs) {
+        {
+            __lhs = static_cast<_RHS&&>(__rhs)
+        } -> same_as<_LHS>;
+    };
+
+namespace __swap
+{
+using std::swap;
+
+template <class _Ty, class _Uy>
+concept swappable_with =             //
+    requires(_Ty&& __t, _Uy&& __u) { //
+        swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u));
+    };
+
+inline constexpr const auto __fn =                               //
+    []<class _Ty, swappable_with<_Ty> _Uy>(_Ty&& __t, _Uy&& __u) //
+    noexcept(noexcept(swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u)))) {
+    swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u));
+};
+} // namespace __swap
+
+using __swap::swappable_with;
+inline constexpr const auto& swap = __swap::__fn;
+
+template <class _Ty>
+concept swappable = //
+    requires(_Ty& a, _Ty& b) { swap(a, b); };
+
+template <class _Ty>
+concept movable =                 //
+    std::is_object_v<_Ty> &&      //
+    move_constructible<_Ty> &&    //
+    assignable_from<_Ty&, _Ty> && //
+    swappable<_Ty>;
+
+template <class _Ty>
+concept copyable =                       //
+    copy_constructible<_Ty> &&           //
+    movable<_Ty> &&                      //
+    assignable_from<_Ty&, _Ty&> &&       //
+    assignable_from<_Ty&, const _Ty&> && //
+    assignable_from<_Ty&, const _Ty>;
+
+template <class _Ty>
+concept semiregular = //
+    copyable<_Ty> &&  //
+    default_initializable<_Ty>;
+
+template <class _Ty>
+concept regular =       //
+    semiregular<_Ty> && //
+    equality_comparable<_Ty>;
+
+// Not exactly right, but close.
+template <class _Ty>
+concept __boolean_testable_ = convertible_to<_Ty, bool>;
+
+template <class T, class U>
+concept __partially_ordered_with = //
+    requires(__cref_t<T> t, __cref_t<U> u) {
+        {
+            t < u
+        } -> __boolean_testable_;
+        {
+            t > u
+        } -> __boolean_testable_;
+        {
+            t <= u
+        } -> __boolean_testable_;
+        {
+            t >= u
+        } -> __boolean_testable_;
+        {
+            u < t
+        } -> __boolean_testable_;
+        {
+            u > t
+        } -> __boolean_testable_;
+        {
+            u <= t
+        } -> __boolean_testable_;
+        {
+            u >= t
+        } -> __boolean_testable_;
+    };
+
+template <class _Ty>
+concept totally_ordered =       //
+    equality_comparable<_Ty> && //
+    __partially_ordered_with<_Ty, _Ty>;
+
+template <class _Ty>
+concept __movable_value =                 //
+    move_constructible<__decay_t<_Ty>> && //
+    constructible_from<__decay_t<_Ty>, _Ty>;
+
+template <class _Ty>
+concept __nothrow_movable_value = //
+    __movable_value<_Ty> &&       //
+    requires(_Ty&& __t) {
+        {
+            __decay_t<_Ty>{__decay_t<_Ty>{static_cast<_Ty&&>(__t)}}
+        } noexcept;
+    };
+
+template <class _Ty, class... _As>
+concept __nothrow_constructible_from =
+    constructible_from<_Ty, _As...> &&
+    STDEXEC_IS_NOTHROW_CONSTRUCTIBLE(_Ty, _As...);
+
+template <class _Ty>
+concept __nothrow_move_constructible = __nothrow_constructible_from<_Ty, _Ty>;
+
+template <class _Ty>
+concept __nothrow_copy_constructible =
+    __nothrow_constructible_from<_Ty, const _Ty&>;
+
+template <class... _Ts>
+concept __decay_copyable = (constructible_from<__decay_t<_Ts>, _Ts> && ...);
+
+template <class... _Ts>
+concept __nothrow_decay_copyable =
+    (__nothrow_constructible_from<__decay_t<_Ts>, _Ts> && ...);
+
+template <class _Ty, class _Up>
+concept __decays_to_derived_from = derived_from<__decay_t<_Ty>, _Up>;
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__config.hpp b/include/sdbusplus/async/stdexec/__detail/__config.hpp
index 68dfa93..acf6498 100644
--- a/include/sdbusplus/async/stdexec/__detail/__config.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__config.hpp
@@ -16,8 +16,17 @@
 #pragma once
 
 #if __cplusplus < 202002L
+#if defined(_MSC_VER) && !defined(__clang__)
+#    error This library requires the use of C++20. Use /Zc:__cplusplus to enable __cplusplus conformance.
+#else
 #error This library requires the use of C++20.
 #endif
+#endif
+
+#if defined(_MSC_VER) && !defined(__clang__) &&                                \
+    (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+#  error This library requires the use of the new conforming preprocessor enabled by /Zc:preprocessor.
+#endif
 
 #if __has_include(<version>)
 #include <version>
@@ -26,7 +35,7 @@
 #endif
 
 #include <cassert>
-#include <version>
+#include <type_traits>
 
 #define STDEXEC_STRINGIZE(_ARG) #_ARG
 
@@ -37,18 +46,16 @@
 #define STDEXEC_EVAL(_MACRO, ...) _MACRO(__VA_ARGS__)
 #define STDEXEC_EAT(...)
 
-#define STDEXEC_NOT(_XP) STDEXEC_CAT(STDEXEC_NOT_, _XP)
-
-enum
-{
-    STDEXEC_NOT_0 = 1,
-    STDEXEC_NOT_1 = 0
-};
-
+#define STDEXEC_IIF(_XP, _YP, ...)                                             \
+    STDEXEC_IIF_EVAL(STDEXEC_CAT(STDEXEC_IIF_, _XP), _YP, __VA_ARGS__)
 #define STDEXEC_IIF_0(_YP, ...) __VA_ARGS__
 #define STDEXEC_IIF_1(_YP, ...) _YP
-#define STDEXEC_IIF(_XP, _YP, ...)                                             \
-    STDEXEC_EVAL(STDEXEC_CAT(STDEXEC_IIF_, _XP), _YP, __VA_ARGS__)
+#define STDEXEC_IIF_EVAL(_MACRO, ...) _MACRO(__VA_ARGS__)
+
+#define STDEXEC_COMPL(_B) STDEXEC_COMPL_CAT(STDEXEC_COMPL_, _B)
+#define STDEXEC_COMPL_0 1
+#define STDEXEC_COMPL_1 0
+#define STDEXEC_COMPL_CAT(_XP, ...) _XP##__VA_ARGS__
 
 #define STDEXEC_COUNT(...)                                                     \
     STDEXEC_EXPAND(STDEXEC_COUNT_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
@@ -59,6 +66,16 @@
 #define STDEXEC_PROBE(...) STDEXEC_PROBE_(__VA_ARGS__, 1)
 #define STDEXEC_PROBE_(_XP, _NP, ...) _XP, _NP,
 
+#define STDEXEC_NOT(_XP) STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_NOT_, _XP))
+#define STDEXEC_NOT_0 STDEXEC_PROBE(~, 1)
+
+#define STDEXEC_BOOL(_XP) STDEXEC_COMPL(STDEXEC_NOT(_XP))
+#define STDEXEC_IF(_XP, _YP, ...)                                              \
+    STDEXEC_IIF(STDEXEC_BOOL(_XP), _YP, __VA_ARGS__)
+
+#define STDEXEC_WHEN(_XP, ...)                                                 \
+    STDEXEC_IF(_XP, STDEXEC_EXPAND, STDEXEC_EAT)(__VA_ARGS__)
+
 ////////////////////////////////////////////////////////////////////////////////
 // STDEXEC_FOR_EACH
 //   Inspired by "Recursive macros with C++20 __VA_OPT__", by David Mazières
@@ -90,6 +107,15 @@
 #define STDEXEC_FOR_EACH_AGAIN() STDEXEC_FOR_EACH_HELPER
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
+#define STDEXEC_FRONT(...) __VA_OPT__(STDEXEC_FRONT_HELPER(__VA_ARGS__))
+#define STDEXEC_FRONT_HELPER(_A1, ...) _A1
+#define STDEXEC_BACK(...)                                                      \
+    __VA_OPT__(STDEXEC_EXPAND_R(STDEXEC_BACK_HELPER(__VA_ARGS__)))
+#define STDEXEC_BACK_HELPER(_A1, ...)                                          \
+    STDEXEC_FRONT(__VA_OPT__(, ) _A1, )                                        \
+    __VA_OPT__(STDEXEC_BACK_AGAIN STDEXEC_PARENS(__VA_ARGS__))
+#define STDEXEC_BACK_AGAIN() STDEXEC_BACK_HELPER
+
 // If tail is non-empty, expand to the tail. Otherwise, expand to the head
 #define STDEXEC_HEAD_OR_TAIL(_XP, ...)                                         \
     STDEXEC_EXPAND __VA_OPT__((__VA_ARGS__)STDEXEC_EAT)(_XP)
@@ -113,6 +139,9 @@
 #if defined(_MSC_VER)
 #define STDEXEC_CLANG_CL(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #endif
+#if defined(__apple_build_version__)
+#define STDEXEC_APPLE_CLANG(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
+#endif
 #elif defined(__GNUC__)
 #define STDEXEC_GCC(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
 #elif defined(_MSC_VER)
@@ -134,6 +163,9 @@
 #ifndef STDEXEC_CLANG_CL
 #define STDEXEC_CLANG_CL(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
+#ifndef STDEXEC_APPLE_CLANG
+#define STDEXEC_APPLE_CLANG(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
+#endif
 #ifndef STDEXEC_GCC
 #define STDEXEC_GCC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
@@ -141,6 +173,11 @@
 #define STDEXEC_MSVC(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 
+#if STDEXEC_NVHPC()
+#define STDEXEC_NVHPC_VERSION()                                                \
+    (__NVCOMPILER_MAJOR__ * 100 + __NVCOMPILER_MINOR__)
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 #ifdef __CUDACC__
 #define STDEXEC_CUDA(...) STDEXEC_HEAD_OR_TAIL(1, __VA_ARGS__)
@@ -149,6 +186,19 @@
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
+#if __cpp_impl_coroutine >= 201902 && __cpp_lib_coroutine >= 201902
+#include <coroutine>
+#define STDEXEC_STD_NO_COROUTINES() 0
+namespace __coro = std;
+#elif defined(__cpp_coroutines) && __has_include(<experimental/coroutine>)
+#include <experimental/coroutine>
+#define STDEXEC_STD_NO_COROUTINES() 0
+namespace __coro = std::experimental;
+#else
+#define STDEXEC_STD_NO_COROUTINES() 1
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
 // For portably declaring attributes on functions and types
 //   Usage:
 //
@@ -209,6 +259,14 @@
 #endif
 #define STDEXEC_ATTR_always_inline STDEXEC_PROBE(~, 4)
 
+#if STDEXEC_CLANG() || STDEXEC_GCC()
+#define STDEXEC_ATTR_WHICH_5(_ATTR) __attribute__((__weak__))
+#else
+#define STDEXEC_ATTR_WHICH_5(_ATTR) /*nothing*/
+#endif
+#define STDEXEC_ATTR_weak STDEXEC_PROBE(~, 5)
+#define STDEXEC_ATTR___weak__ STDEXEC_PROBE(~, 5)
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // warning push/pop portability macros
 #if STDEXEC_NVCC()
@@ -232,6 +290,10 @@
 #define STDEXEC_PRAGMA_POP() _Pragma("GCC diagnostic pop")
 #define STDEXEC_PRAGMA_IGNORE_GNU(...)                                         \
     _Pragma(STDEXEC_STRINGIZE(GCC diagnostic ignored __VA_ARGS__))
+#elif STDEXEC_MSVC()
+#define STDEXEC_PRAGMA_PUSH() __pragma(warning(push))
+#define STDEXEC_PRAGMA_POP() __pragma(warning(pop))
+#define STDEXEC_PRAGMA_IGNORE_MSVC(...) __pragma(warning(disable : __VA_ARGS__))
 #else
 #define STDEXEC_PRAGMA_PUSH()
 #define STDEXEC_PRAGMA_POP()
@@ -243,6 +305,9 @@
 #ifndef STDEXEC_PRAGMA_IGNORE_EDG
 #define STDEXEC_PRAGMA_IGNORE_EDG(...)
 #endif
+#ifndef STDEXEC_PRAGMA_IGNORE_MSVC
+#define STDEXEC_PRAGMA_IGNORE_MSVC(...)
+#endif
 
 #if !STDEXEC_MSVC() && defined(__has_builtin)
 #define STDEXEC_HAS_BUILTIN __has_builtin
@@ -280,9 +345,77 @@
 #if STDEXEC_HAS_BUILTIN(__is_const)
 #define STDEXEC_IS_CONST(...) __is_const(__VA_ARGS__)
 #else
-#define STDEXEC_IS_CONST(...) stdexec::__is_const<__VA_ARGS__>
+#define STDEXEC_IS_CONST(...) stdexec::__is_const_<__VA_ARGS__>
 #endif
 
+#if STDEXEC_HAS_BUILTIN(__is_same)
+#define STDEXEC_IS_SAME(...) __is_same(__VA_ARGS__)
+#elif STDEXEC_HAS_BUILTIN(__is_same_as)
+#define STDEXEC_IS_SAME(...) __is_same_as(__VA_ARGS__)
+#elif STDEXEC_MSVC()
+// msvc replaces std::is_same_v with a compile-time constant
+#define STDEXEC_IS_SAME(...) std::is_same_v<__VA_ARGS__>
+#else
+#define STDEXEC_IS_SAME(...) stdexec::__same_as_v<__VA_ARGS__>
+#endif
+
+#if STDEXEC_HAS_BUILTIN(__is_constructible) || STDEXEC_MSVC()
+#define STDEXEC_IS_CONSTRUCTIBLE(...) __is_constructible(__VA_ARGS__)
+#else
+#define STDEXEC_IS_CONSTRUCTIBLE(...) std::is_constructible_v<__VA_ARGS__>
+#endif
+
+#if STDEXEC_HAS_BUILTIN(__is_nothrow_constructible) || STDEXEC_MSVC()
+#define STDEXEC_IS_NOTHROW_CONSTRUCTIBLE(...)                                  \
+    __is_nothrow_constructible(__VA_ARGS__)
+#else
+#define STDEXEC_IS_NOTHROW_CONSTRUCTIBLE(...)                                  \
+    std::is_nothrow_constructible_v<__VA_ARGS__>
+#endif
+
+#if STDEXEC_HAS_BUILTIN(__is_trivially_constructible) || STDEXEC_MSVC()
+#define STDEXEC_IS_TRIVIALLY_CONSTRUCTIBLE(...)                                \
+    __is_trivially_constructible(__VA_ARGS__)
+#else
+#define STDEXEC_IS_TRIVIALLY_CONSTRUCTIBLE(...)                                \
+    std::is_trivially_constructible_v<__VA_ARGS__>
+#endif
+
+#if STDEXEC_HAS_BUILTIN(__is_empty) || STDEXEC_MSVC()
+#define STDEXEC_IS_EMPTY(...) __is_empty(__VA_ARGS__)
+#else
+#define STDEXEC_IS_EMPTY(...) std::is_empty_v<__VA_ARGS__>
+#endif
+
+#if STDEXEC_HAS_BUILTIN(__remove_reference)
+namespace stdexec
+{
+template <class Ty>
+using _remove_reference_t = __remove_reference(Ty);
+} // namespace stdexec
+
+#define STDEXEC_REMOVE_REFERENCE(...) stdexec::_remove_reference_t<__VA_ARGS__>
+#elif STDEXEC_HAS_BUILTIN(__remove_reference_t)
+namespace stdexec
+{
+template <class Ty>
+using _remove_reference_t = __remove_reference_t(Ty);
+} // namespace stdexec
+
+#define STDEXEC_REMOVE_REFERENCE(...) stdexec::_remove_reference_t<__VA_ARGS__>
+#else
+#define STDEXEC_REMOVE_REFERENCE(...) ::std::remove_reference_t<__VA_ARGS__>
+#endif
+
+namespace stdexec
+{
+template <class _Ap, class _Bp>
+inline constexpr bool __same_as_v = false;
+
+template <class _Ap>
+inline constexpr bool __same_as_v<_Ap, _Ap> = true;
+} // namespace stdexec
+
 #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
 #define STDEXEC_UNREACHABLE() std::unreachable()
 #elif STDEXEC_HAS_BUILTIN(__builtin_unreachable)
@@ -381,18 +514,6 @@
 #define STDEXEC_EXPLICIT_THIS(...) STDEXEC_HEAD_OR_NULL(0, __VA_ARGS__)
 #endif
 
-#if STDEXEC_EXPLICIT_THIS()
-#define STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(...) __VA_ARGS__
-#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN(_OBJ, _NAME) (_OBJ)._NAME( STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL
-#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL(...) __VA_ARGS__ )
-#else
-#define STDEXEC_DEFINE_EXPLICIT_THIS_MEMFN(...) static __VA_ARGS__(STDEXEC_FUN_ARGS
-#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN(_OBJ, _NAME) (_OBJ)._NAME((_OBJ) STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL
-#define STDEXEC_CALL_EXPLICIT_THIS_MEMFN_DETAIL(...) __VA_OPT__(, ) __VA_ARGS__)
-#define STDEXEC_EAT_THIS_DETAIL_this
-#define STDEXEC_FUN_ARGS(...) STDEXEC_CAT(STDEXEC_EAT_THIS_DETAIL_, __VA_ARGS__))
-#endif
-
 // Configure extra type checking
 #define STDEXEC_TYPE_CHECKING_ZERO() 0
 #define STDEXEC_TYPE_CHECKING_ONE() 1
diff --git a/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp b/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp
new file mode 100644
index 0000000..5f11184
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__connect_awaitable.hpp
@@ -0,0 +1,258 @@
+/*
+ * 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 "__awaitable.hpp"
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__config.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__tag_invoke.hpp"
+
+#include <exception>
+#include <utility>
+
+namespace stdexec
+{
+#if !STDEXEC_STD_NO_COROUTINES()
+/////////////////////////////////////////////////////////////////////////////
+// __connect_awaitable_
+namespace __connect_awaitable_
+{
+struct __promise_base
+{
+    auto initial_suspend() noexcept -> __coro::suspend_always
+    {
+        return {};
+    }
+
+    [[noreturn]] auto final_suspend() noexcept -> __coro::suspend_always
+    {
+        std::terminate();
+    }
+
+    [[noreturn]] void unhandled_exception() noexcept
+    {
+        std::terminate();
+    }
+
+    [[noreturn]] void return_void() noexcept
+    {
+        std::terminate();
+    }
+};
+
+struct __operation_base
+{
+    __coro::coroutine_handle<> __coro_;
+
+    explicit __operation_base(__coro::coroutine_handle<> __hcoro) noexcept :
+        __coro_(__hcoro)
+    {}
+
+    __operation_base(__operation_base&& __other) noexcept :
+        __coro_(std::exchange(__other.__coro_, {}))
+    {}
+
+    ~__operation_base()
+    {
+        if (__coro_)
+        {
+#if STDEXEC_MSVC()
+            // MSVCBUG
+            // https://developercommunity.visualstudio.com/t/Double-destroy-of-a-local-in-coroutine-d/10456428
+
+            // Reassign __coro_ before calling destroy to make the mutation
+            // observable and to hopefully ensure that the compiler does not
+            // eliminate it.
+            auto __coro = __coro_;
+            __coro_ = {};
+            __coro.destroy();
+#else
+            __coro_.destroy();
+#endif
+        }
+    }
+
+    void start() & noexcept
+    {
+        __coro_.resume();
+    }
+};
+
+template <class _ReceiverId>
+struct __promise;
+
+template <class _ReceiverId>
+struct __operation
+{
+    struct __t : __operation_base
+    {
+        using promise_type = stdexec::__t<__promise<_ReceiverId>>;
+        using __operation_base::__operation_base;
+    };
+};
+
+template <class _ReceiverId>
+struct __promise
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+
+    struct __t : __promise_base
+    {
+        using __id = __promise;
+
+        explicit __t(auto&, _Receiver& __rcvr) noexcept : __rcvr_(__rcvr) {}
+
+        auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>
+        {
+            stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr_));
+            // Returning noop_coroutine here causes the __connect_awaitable
+            // coroutine to never resume past the point where it co_await's
+            // the awaitable.
+            return __coro::noop_coroutine();
+        }
+
+        auto get_return_object() noexcept
+            -> stdexec::__t<__operation<_ReceiverId>>
+        {
+            return stdexec::__t<__operation<_ReceiverId>>{
+                __coro::coroutine_handle<__t>::from_promise(*this)};
+        }
+
+        template <class _Awaitable>
+        auto await_transform(_Awaitable&& __awaitable) noexcept -> _Awaitable&&
+        {
+            return static_cast<_Awaitable&&>(__awaitable);
+        }
+
+        template <class _Awaitable>
+            requires tag_invocable<as_awaitable_t, _Awaitable, __t&>
+        auto await_transform(_Awaitable&& __awaitable) //
+            noexcept(nothrow_tag_invocable<as_awaitable_t, _Awaitable, __t&>)
+                -> tag_invoke_result_t<as_awaitable_t, _Awaitable, __t&>
+        {
+            return tag_invoke(as_awaitable,
+                              static_cast<_Awaitable&&>(__awaitable), *this);
+        }
+
+        // Pass through the get_env receiver query
+        auto get_env() const noexcept -> env_of_t<_Receiver>
+        {
+            return stdexec::get_env(__rcvr_);
+        }
+
+        _Receiver& __rcvr_;
+    };
+};
+
+template <receiver _Receiver>
+using __promise_t = __t<__promise<__id<_Receiver>>>;
+
+template <receiver _Receiver>
+using __operation_t = __t<__operation<__id<_Receiver>>>;
+
+struct __connect_awaitable_t
+{
+  private:
+    template <class _Fun, class... _Ts>
+    static auto __co_call(_Fun __fun, _Ts&&... __as) noexcept
+    {
+        auto __fn = [&, __fun]() noexcept {
+            __fun(static_cast<_Ts&&>(__as)...);
+        };
+
+        struct __awaiter
+        {
+            decltype(__fn) __fn_;
+
+            static constexpr auto await_ready() noexcept -> bool
+            {
+                return false;
+            }
+
+            void await_suspend(__coro::coroutine_handle<>) noexcept
+            {
+                __fn_();
+            }
+
+            [[noreturn]] void await_resume() noexcept
+            {
+                std::terminate();
+            }
+        };
+
+        return __awaiter{__fn};
+    }
+
+    template <class _Awaitable, class _Receiver>
+#if STDEXEC_GCC() && (__GNUC__ > 11)
+    __attribute__((__used__))
+#endif
+    static auto
+        __co_impl(_Awaitable __awaitable, _Receiver __rcvr)
+            -> __operation_t<_Receiver>
+    {
+        using __result_t = __await_result_t<_Awaitable, __promise_t<_Receiver>>;
+        std::exception_ptr __eptr;
+        try
+        {
+            if constexpr (same_as<__result_t, void>)
+                co_await (
+                    co_await static_cast<_Awaitable&&>(__awaitable),
+                    __co_call(set_value, static_cast<_Receiver&&>(__rcvr)));
+            else
+                co_await __co_call(
+                    set_value, static_cast<_Receiver&&>(__rcvr),
+                    co_await static_cast<_Awaitable&&>(__awaitable));
+        }
+        catch (...)
+        {
+            __eptr = std::current_exception();
+        }
+        co_await __co_call(set_error, static_cast<_Receiver&&>(__rcvr),
+                           static_cast<std::exception_ptr&&>(__eptr));
+    }
+
+    template <receiver _Receiver, class _Awaitable>
+    using __completions_t = //
+        completion_signatures<
+            __minvoke<      // set_value_t() or set_value_t(T)
+                __mremove<void, __qf<set_value_t>>,
+                __await_result_t<_Awaitable, __promise_t<_Receiver>>>,
+            set_error_t(std::exception_ptr), set_stopped_t()>;
+
+  public:
+    template <class _Receiver, __awaitable<__promise_t<_Receiver>> _Awaitable>
+        requires receiver_of<_Receiver, __completions_t<_Receiver, _Awaitable>>
+    auto operator()(_Awaitable&& __awaitable, _Receiver __rcvr) const
+        -> __operation_t<_Receiver>
+    {
+        return __co_impl(static_cast<_Awaitable&&>(__awaitable),
+                         static_cast<_Receiver&&>(__rcvr));
+    }
+};
+} // namespace __connect_awaitable_
+
+using __connect_awaitable_::__connect_awaitable_t;
+#else
+struct __connect_awaitable_t
+{};
+#endif
+inline constexpr __connect_awaitable_t __connect_awaitable{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__continue_on.hpp b/include/sdbusplus/async/stdexec/__detail/__continue_on.hpp
new file mode 100644
index 0000000..a5566f6
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__continue_on.hpp
@@ -0,0 +1,130 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__schedule_from.hpp"
+#include "__schedulers.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__sender_introspection.hpp"
+#include "__senders.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <utility>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.continue_on]
+namespace __continue_on
+{
+using __schfr::__environ;
+
+template <class _Env>
+using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>;
+
+template <class _Sender>
+using __lowered_t = //
+    __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>,
+                __child_of<_Sender>>;
+
+struct continue_on_t
+{
+    template <sender _Sender, scheduler _Scheduler>
+    auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<continue_on_t>(
+                          _Env{{static_cast<_Scheduler&&>(__sched)}},
+                          static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <scheduler _Scheduler>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Scheduler&& __sched) const
+        -> __binder_back<continue_on_t, __decay_t<_Scheduler>>
+    {
+        return {{static_cast<_Scheduler&&>(__sched)}, {}, {}};
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////////////////
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(continue_on_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender,
+                             get_completion_scheduler_t<set_value_t>(_Env)),
+                tag_invoke_t(continue_on_t, _Sender,
+                             get_completion_scheduler_t<set_value_t>(_Env))>;
+
+    template <class _Env>
+    static auto __transform_sender_fn(const _Env&)
+    {
+        return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
+                                              _Child&& __child) {
+            auto __sched = get_completion_scheduler<set_value_t>(__data);
+            return schedule_from(std::move(__sched),
+                                 static_cast<_Child&&>(__child));
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             __transform_sender_fn(__env));
+    }
+};
+
+struct __continue_on_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Data, class _Child>(
+            const _Data& __data,
+            const _Child& __child) noexcept -> decltype(auto) {
+        return __env::__join(__data, stdexec::get_env(__child));
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {};
+};
+} // namespace __continue_on
+
+using __continue_on::continue_on_t;
+inline constexpr continue_on_t continue_on{};
+
+using transfer_t = continue_on_t;
+inline constexpr transfer_t transfer{};
+
+template <>
+struct __sexpr_impl<continue_on_t> : __continue_on::__continue_on_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__cpo.hpp b/include/sdbusplus/async/stdexec/__detail/__cpo.hpp
index 7a5d680..b5fb859 100644
--- a/include/sdbusplus/async/stdexec/__detail/__cpo.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__cpo.hpp
@@ -18,10 +18,6 @@
 #include "__config.hpp"
 #include "__execution_fwd.hpp"
 
-#define STDEXEC_EAT_THIS_this
-#define STDEXEC_EAT_AUTO_auto
-#define STDEXEC_EAT_VOID_void
-
 ///////////////////////////////////////////////////////////////////////////////
 /// To hook a customization point like stdexec::get_env, first bring the names
 /// in stdexec::tags into scope:
@@ -38,39 +34,54 @@
 /// }
 /// @endcode
 #define STDEXEC_MEMFN_DECL(...)                                                \
-    friend STDEXEC_TAG_INVOKE(STDEXEC_IS_AUTO(__VA_ARGS__), __VA_ARGS__)       \
-        STDEXEC_TAG_INVOKE_ARGS
+    friend STDEXEC_EVAL(STDEXEC_MEMFN_DECL_TAG_INVOKE,                         \
+                        STDEXEC_MEMFN_DECL_WHICH(__VA_ARGS__), __VA_ARGS__)
 
-#define STDEXEC_TAG_INVOKE(_ISAUTO, ...)                                        \
-    STDEXEC_IIF(_ISAUTO, STDEXEC_RETURN_AUTO, STDEXEC_RETURN_TYPE)(__VA_ARGS__) \
-    tag_invoke( \
-    STDEXEC_IIF(_ISAUTO, STDEXEC_TAG_AUTO, STDEXEC_TAG_WHAT)(__VA_ARGS__)
+#define STDEXEC_MEMFN_DECL_WHICH(_A1, ...)                                     \
+    STDEXEC_CAT(STDEXEC_MEMFN_DECL_WHICH_, STDEXEC_FRONT(__VA_OPT__(1, ) 0))   \
+    (_A1, __VA_ARGS__)
+#define STDEXEC_MEMFN_DECL_WHICH_0(_A1, ...)                                   \
+    STDEXEC_CHECK(STDEXEC_MEMFN_DECL_PROBE_##_A1),                             \
+        STDEXEC_CHECK(_A1##_STDEXEC_MEMFN_DECL_PROBE)
+#define STDEXEC_MEMFN_DECL_WHICH_1(_A1, ...)                                   \
+    0, STDEXEC_CHECK(                                                          \
+           STDEXEC_CAT(STDEXEC_BACK(__VA_ARGS__), _STDEXEC_MEMFN_DECL_PROBE))
 
-#define STDEXEC_PROBE_AUTO_auto STDEXEC_PROBE(~)
-#define STDEXEC_IS_AUTO(_TY, ...)                                              \
-    STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_PROBE_AUTO_, _TY))
+#define STDEXEC_MEMFN_DECL_TAG_INVOKE(_WHICH, _QUERY, ...)                     \
+  STDEXEC_MEMFN_DECL_RETURN_ ## _WHICH(__VA_ARGS__)                                                \
+  tag_invoke(STDEXEC_MEMFN_DECL_TAG_ ## _WHICH ## _QUERY(__VA_ARGS__)
 
-#define STDEXEC_PROBE_VOID_void STDEXEC_PROBE(~)
-#define STDEXEC_IS_VOID(_TY, ...)                                              \
-    STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_PROBE_VOID_, _TY))
+#define STDEXEC_MEMFN_DECL_ARGS(...)                                           \
+  STDEXEC_CAT(STDEXEC_EAT_THIS_, __VA_ARGS__))
 
-#define STDEXEC_RETURN_AUTO(...) auto
-#define STDEXEC_RETURN_TYPE(...) ::stdexec::__arg_type_t<void(__VA_ARGS__())>
+#define STDEXEC_MEMFN_DECL_QUERY(_SELF, _TAG, ...)                             \
+  _TAG, STDEXEC_CAT(STDEXEC_EAT_THIS_, _SELF) __VA_OPT__(, __VA_ARGS__))
 
-#define STDEXEC_TAG_AUTO(...)                                                  \
-    STDEXEC_CAT(STDEXEC_CAT(STDEXEC_EAT_AUTO_, __VA_ARGS__), _t)
-#define STDEXEC_TAG_WHAT(...)                                                  \
-    STDEXEC_IIF(STDEXEC_IS_VOID(__VA_ARGS__), STDEXEC_TAG_VOID,                \
-                STDEXEC_TAG_TYPE)                                              \
-    (__VA_ARGS__)
+#define STDEXEC_EAT_THIS_this
+#define STDEXEC_EAT_AUTO_auto
+#define STDEXEC_EAT_VOID_void
 
-#define STDEXEC_TAG_VOID(...)                                                  \
-    STDEXEC_CAT(STDEXEC_CAT(STDEXEC_EAT_VOID_, __VA_ARGS__), _t)
-#define STDEXEC_TAG_TYPE(...)                                                  \
-    ::stdexec::__tag_type_t<STDEXEC_CAT(__VA_ARGS__, _t::*)>
+#define query_STDEXEC_MEMFN_DECL_PROBE STDEXEC_PROBE(~, 1)
+#define STDEXEC_MEMFN_DECL_PROBE_auto STDEXEC_PROBE(~, 1)
+#define STDEXEC_MEMFN_DECL_PROBE_void STDEXEC_PROBE(~, 2)
 
-#define STDEXEC_TAG_INVOKE_ARGS(...)                                           \
-    __VA_OPT__(,) STDEXEC_CAT(STDEXEC_EAT_THIS_, __VA_ARGS__))
+#define STDEXEC_MEMFN_DECL_RETURN_0(...)                                       \
+    ::stdexec::__arg_type_t<void(__VA_ARGS__())>
+#define STDEXEC_MEMFN_DECL_RETURN_1(...) auto
+#define STDEXEC_MEMFN_DECL_RETURN_2(...) void
+
+#define STDEXEC_MEMFN_DECL_TAG_00(...)                                         \
+    const ::stdexec::__tag_type_t<__VA_ARGS__##_t::*>&, STDEXEC_MEMFN_DECL_ARGS
+#define STDEXEC_MEMFN_DECL_TAG_10(...)                                         \
+    const STDEXEC_EAT_AUTO_##__VA_ARGS__##_t&, STDEXEC_MEMFN_DECL_ARGS
+#define STDEXEC_MEMFN_DECL_TAG_20(...)                                         \
+    const STDEXEC_EAT_VOID_##__VA_ARGS__##_t&, STDEXEC_MEMFN_DECL_ARGS
+#define STDEXEC_MEMFN_DECL_TAG_01(...) STDEXEC_MEMFN_DECL_QUERY
+#define STDEXEC_MEMFN_DECL_TAG_11(...) STDEXEC_MEMFN_DECL_QUERY
+#define STDEXEC_MEMFN_DECL_TAG_21(...) STDEXEC_MEMFN_DECL_QUERY
+
+#define STDEXEC_MEMFN_FRIEND(_TAG)                                             \
+    using STDEXEC_CAT(_TAG, _t) = STDEXEC_CAT(stdexec::_TAG, _t)
 
 #if STDEXEC_MSVC()
 #pragma deprecated(STDEXEC_CUSTOM)
diff --git a/include/sdbusplus/async/stdexec/__detail/__debug.hpp b/include/sdbusplus/async/stdexec/__detail/__debug.hpp
new file mode 100644
index 0000000..05036b1
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__debug.hpp
@@ -0,0 +1,282 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__cpo.hpp"
+#include "__diagnostics.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__tag_invoke.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// Some utilities for debugging senders
+namespace __debug
+{
+struct __is_debug_env_t
+{
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return true;
+    }
+    template <class _Env>
+        requires tag_invocable<__is_debug_env_t, const _Env&>
+    auto operator()(const _Env&) const noexcept
+        -> tag_invoke_result_t<__is_debug_env_t, const _Env&>;
+};
+
+template <class _Env>
+using __debug_env_t = env<prop<__is_debug_env_t, bool>, _Env>;
+
+template <class _Env>
+concept __is_debug_env = tag_invocable<__is_debug_env_t, _Env>;
+
+struct __completion_signatures
+{};
+
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Explicit-variable-template-specialisatio/10360032
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Non-function-type-interpreted-as-functio/10447831
+
+template <class _Sig>
+struct __normalize_sig;
+
+template <class _Tag, class... _Args>
+struct __normalize_sig<_Tag(_Args...)>
+{
+    using __type = _Tag (*)(_Args&&...);
+};
+
+template <class _Sig>
+using __normalize_sig_t = typename __normalize_sig<_Sig>::__type;
+#else
+template <class _Sig>
+extern int __normalize_sig;
+
+template <class _Tag, class... _Args>
+extern _Tag (*__normalize_sig<_Tag(_Args...)>)(_Args&&...);
+
+template <class _Sig>
+using __normalize_sig_t = decltype(__normalize_sig<_Sig>);
+#endif
+
+template <class... _Sigs>
+struct __valid_completions
+{
+    template <class... _Args>
+        requires __one_of<set_value_t (*)(_Args&&...), _Sigs...>
+    STDEXEC_ATTRIBUTE((host, device)) void set_value(_Args&&...) noexcept
+    {
+        STDEXEC_TERMINATE();
+    }
+
+    template <class _Error>
+        requires __one_of<set_error_t (*)(_Error&&), _Sigs...>
+    STDEXEC_ATTRIBUTE((host, device)) void set_error(_Error&&) noexcept
+    {
+        STDEXEC_TERMINATE();
+    }
+
+    STDEXEC_ATTRIBUTE((host, device))
+    void set_stopped() noexcept
+        requires __one_of<set_stopped_t (*)(), _Sigs...>
+    {
+        STDEXEC_TERMINATE();
+    }
+};
+
+template <class _CvrefSenderId, class _Env, class _Completions>
+struct __debug_receiver
+{
+    using __t = __debug_receiver;
+    using __id = __debug_receiver;
+    using receiver_concept = receiver_t;
+};
+
+template <class _CvrefSenderId, class _Env, class... _Sigs>
+struct __debug_receiver<_CvrefSenderId, _Env,
+                        completion_signatures<_Sigs...>> //
+    : __valid_completions<__normalize_sig_t<_Sigs>...>
+{
+    using __t = __debug_receiver;
+    using __id = __debug_receiver;
+    using receiver_concept = receiver_t;
+
+    STDEXEC_ATTRIBUTE((host, device))
+    auto get_env() const noexcept -> __debug_env_t<_Env>
+    {
+        STDEXEC_TERMINATE();
+    }
+};
+
+struct _COMPLETION_SIGNATURES_MISMATCH_
+{};
+
+template <class _Sig>
+struct _COMPLETION_SIGNATURE_
+{};
+
+template <class... _Sigs>
+struct _IS_NOT_ONE_OF_
+{};
+
+template <class _Sender>
+struct _SIGNAL_SENT_BY_SENDER_
+{};
+
+template <class _Warning>
+[[deprecated(
+    "The sender claims to send a particular set of completions,"
+    " but in actual fact it completes with a result that is not"
+    " one of the declared completion signatures.")]] STDEXEC_ATTRIBUTE((host,
+                                                                        device)) void _ATTENTION_() noexcept
+{}
+
+template <class _Sig>
+struct __invalid_completion
+{
+    struct __t
+    {
+        template <class _CvrefSenderId, class _Env, class... _Sigs>
+        // BUGBUG this works around a recently (aug 2023) introduced regression
+        // in nvc++
+            requires(!__one_of<_Sig, _Sigs...>)
+        __t(__debug_receiver<_CvrefSenderId, _Env,
+                             completion_signatures<_Sigs...>>&&) noexcept
+        {
+            using _SenderId = __decay_t<_CvrefSenderId>;
+            using _Sender = stdexec::__t<_SenderId>;
+            using _What =  //
+                _WARNING_< //
+                    _COMPLETION_SIGNATURES_MISMATCH_,
+                    _COMPLETION_SIGNATURE_<_Sig>, _IS_NOT_ONE_OF_<_Sigs...>,
+                    _SIGNAL_SENT_BY_SENDER_<__name_of<_Sender>>>;
+            __debug::_ATTENTION_<_What>();
+        }
+    };
+};
+
+template <__completion_tag _Tag, class... _Args>
+STDEXEC_ATTRIBUTE((host, device))
+void tag_invoke(_Tag, __t<__invalid_completion<_Tag(_Args...)>>,
+                _Args&&...) noexcept
+{}
+
+struct __debug_operation
+{
+    void start() & noexcept {}
+};
+
+////////////////////////////////////////////////////////////////////////////
+// `__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 _Sigs, class _Env = empty_env, class _Sender>
+//   void __debug_sender(_Sender&& __sndr, _Env = {});
+//
+// template <class _Env = empty_env, 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<completion_signatures<set_value_t(int)>>(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.
+template <class _Sigs, class _Env = empty_env, class _Sender>
+void __debug_sender(_Sender&& __sndr, const _Env& = {})
+{
+    if constexpr (!__is_debug_env<_Env>)
+    {
+        if (sizeof(_Sender) == ~0u)
+        { // never true
+            using _Receiver =
+                __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>;
+            using _Operation = connect_result_t<_Sender, _Receiver>;
+            // static_assert(receiver_of<_Receiver, _Sigs>);
+            if constexpr (!same_as<_Operation, __debug_operation>)
+            {
+                auto __op = connect(static_cast<_Sender&&>(__sndr),
+                                    _Receiver{});
+                stdexec::start(__op);
+            }
+        }
+    }
+}
+
+template <class _Env = empty_env, class _Sender>
+void __debug_sender(_Sender&& __sndr, const _Env& = {})
+{
+    if constexpr (!__is_debug_env<_Env>)
+    {
+        if (sizeof(_Sender) == ~0ul)
+        { // never true
+            using _Sigs =
+                __completion_signatures_of_t<_Sender, __debug_env_t<_Env>>;
+            if constexpr (!same_as<_Sigs, __debug::__completion_signatures>)
+            {
+                using _Receiver =
+                    __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>;
+                using _Operation = connect_result_t<_Sender, _Receiver>;
+                // static_assert(receiver_of<_Receiver, _Sigs>);
+                if constexpr (!same_as<_Operation, __debug_operation>)
+                {
+                    auto __op = connect(static_cast<_Sender&&>(__sndr),
+                                        _Receiver{});
+                    stdexec::start(__op);
+                }
+            }
+        }
+    }
+}
+} // namespace __debug
+
+using __debug::__debug_sender;
+using __debug::__is_debug_env;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__diagnostics.hpp b/include/sdbusplus/async/stdexec/__detail/__diagnostics.hpp
new file mode 100644
index 0000000..9180cf3
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__diagnostics.hpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "__meta.hpp"
+
+namespace stdexec
+{
+namespace __detail
+{
+template <class _Ty>
+extern __q<__midentity> __name_of_v;
+
+template <class _Ty>
+using __name_of_fn = decltype(__name_of_v<_Ty>);
+
+template <class _Ty>
+using __name_of = __minvoke<__name_of_fn<_Ty>, _Ty>;
+} // namespace __detail
+
+// A utility for pretty-printing type names in diagnostics
+template <class _Ty>
+using __name_of = __detail::__name_of<_Ty>;
+
+namespace __errs
+{
+inline constexpr __mstring __unrecognized_sender_type_diagnostic =
+    "The given type cannot be used as a sender with the given environment "
+    "because the attempt to compute the completion signatures failed."_mstr;
+
+template <class _Sender>
+struct _WITH_SENDER_;
+
+template <class... _Senders>
+struct _WITH_SENDERS_;
+} // namespace __errs
+
+struct _WHERE_;
+
+struct _IN_ALGORITHM_;
+
+template <__mstring _Diagnostic = __errs::__unrecognized_sender_type_diagnostic>
+struct _UNRECOGNIZED_SENDER_TYPE_;
+
+template <class _Sender>
+using _WITH_SENDER_ = __errs::_WITH_SENDER_<__name_of<_Sender>>;
+
+template <class... _Senders>
+using _WITH_SENDERS_ = __errs::_WITH_SENDERS_<__name_of<_Senders>...>;
+
+template <class _Env>
+struct _WITH_ENVIRONMENT_;
+
+template <class _Ty>
+struct _WITH_TYPE_;
+
+template <class _Receiver>
+struct _WITH_RECEIVER_;
+
+template <class _Sig>
+struct _MISSING_COMPLETION_SIGNAL_;
+
+template <class _Sig>
+struct _WITH_COMPLETION_SIGNATURE_;
+
+template <class _Fun>
+struct _WITH_FUNCTION_;
+
+template <class... _Args>
+struct _WITH_ARGUMENTS_;
+
+template <class _Tag>
+struct _WITH_QUERY_;
+
+struct _SENDER_TYPE_IS_NOT_COPYABLE_;
+
+inline constexpr __mstring __not_callable_diag =
+    "The specified function is not callable with the arguments provided."_mstr;
+
+template <__mstring _Context, __mstring _Diagnostic = __not_callable_diag>
+struct _NOT_CALLABLE_;
+
+template <auto _Reason = "You cannot pipe one sender into another."_mstr>
+struct _CANNOT_PIPE_INTO_A_SENDER_
+{};
+
+template <class _Sender>
+using __bad_pipe_sink_t =
+    __mexception<_CANNOT_PIPE_INTO_A_SENDER_<>, _WITH_SENDER_<_Sender>>;
+
+template <__mstring _Context>
+struct __callable_error
+{
+    template <class _Fun, class... _Args>
+    using __f =       //
+        __mexception< //
+            _NOT_CALLABLE_<_Context>, _WITH_FUNCTION_<_Fun>,
+            _WITH_ARGUMENTS_<_Args...>>;
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__domain.hpp b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
index a82a1e6..7d6135d 100644
--- a/include/sdbusplus/async/stdexec/__detail/__domain.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -16,12 +16,12 @@
 #pragma once
 
 #include "../functional.hpp"
-#include "__basic_sender.hpp"
 #include "__concepts.hpp"
 #include "__config.hpp"
 #include "__env.hpp"
 #include "__execution_fwd.hpp"
 #include "__meta.hpp"
+#include "__sender_introspection.hpp"
 
 namespace stdexec
 {
@@ -83,6 +83,41 @@
     requires(_DomainOrTag __tag, _Args&&... __args) {
         __tag.apply_sender(static_cast<_Args&&>(__args)...);
     };
+
+template <class _Sender>
+constexpr bool __is_nothrow_transform_sender()
+{
+    if constexpr (__callable<__sexpr_apply_t, _Sender,
+                             __domain::__legacy_customization>)
+    {
+        return __nothrow_callable<__sexpr_apply_t, _Sender,
+                                  __domain::__legacy_customization>;
+    }
+    else if constexpr (__domain::__has_default_transform_sender<_Sender>)
+    {
+        return noexcept(
+            tag_of_t<_Sender>().transform_sender(__declval<_Sender>()));
+    }
+    else
+    {
+        return __nothrow_constructible_from<_Sender, _Sender>;
+    }
+}
+
+template <class _Sender, class _Env>
+constexpr bool __is_nothrow_transform_sender() noexcept
+{
+    if constexpr (__domain::__has_default_transform_sender<_Sender, _Env>)
+    {
+        return //
+            noexcept(tag_of_t<_Sender>().transform_sender(
+                __declval<_Sender>(), __declval<const _Env&>()));
+    }
+    else
+    {
+        return __nothrow_constructible_from<_Sender, _Sender>;
+    }
+}
 } // namespace __domain
 
 struct default_domain
@@ -93,6 +128,7 @@
     template <class _Sender>
     STDEXEC_ATTRIBUTE((always_inline))
     decltype(auto) transform_sender(_Sender&& __sndr) const
+        noexcept(__domain::__is_nothrow_transform_sender<_Sender>())
     {
         // Look for a legacy customization for the given tag, and if found,
         // apply it.
@@ -117,6 +153,7 @@
     template <class _Sender, class _Env>
     STDEXEC_ATTRIBUTE((always_inline))
     decltype(auto) transform_sender(_Sender&& __sndr, const _Env& __env) const
+        noexcept(__domain::__is_nothrow_transform_sender<_Sender, _Env>())
     {
         if constexpr (__domain::__has_default_transform_sender<_Sender, _Env>)
         {
@@ -185,9 +222,9 @@
 // are no completion schedulers or if they don't specify a domain.
 template <class _Env>
 struct __completion_domain_or_none_ :
-    __mdefer_<__transform<
+    __mdefer_<__mtransform<
                   __mbind_front_q<__completion_domain_for, _Env>,
-                  __remove<__none_such, __munique<__msingle_or<__none_such>>>>,
+                  __mremove<__none_such, __munique<__msingle_or<__none_such>>>>,
               set_value_t, set_error_t, set_stopped_t>
 {};
 
@@ -215,7 +252,7 @@
     {
         if constexpr (__callable<get_domain_t, env_of_t<_Sender>>)
         {
-            return __call_result_t<get_domain_t, env_of_t<_Sender>>();
+            return __domain_of_t<env_of_t<_Sender>>();
         }
         else if constexpr (__detail::__has_completion_domain<_Sender>)
         {
diff --git a/include/sdbusplus/async/stdexec/__detail/__ensure_started.hpp b/include/sdbusplus/async/stdexec/__detail/__ensure_started.hpp
new file mode 100644
index 0000000..0657379
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__ensure_started.hpp
@@ -0,0 +1,124 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__intrusive_ptr.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__shared.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <utility>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.ensure_started]
+namespace __ensure_started
+{
+using namespace __shared;
+
+struct __ensure_started_t
+{};
+
+struct ensure_started_t
+{
+    template <sender _Sender, class _Env = empty_env>
+        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
+    [[nodiscard]] auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
+        -> __well_formed_sender auto
+    {
+        if constexpr (sender_expr_for<_Sender, __ensure_started_t>)
+        {
+            return static_cast<_Sender&&>(__sndr);
+        }
+        else
+        {
+            auto __domain = __get_late_domain(__sndr, __env);
+            return stdexec::transform_sender(
+                __domain,
+                __make_sexpr<ensure_started_t>(static_cast<_Env&&>(__env),
+                                               static_cast<_Sender&&>(__sndr)));
+        }
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()() const noexcept -> __binder_back<ensure_started_t>
+    {
+        return {{}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(ensure_started_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(ensure_started_t, _Sender)>;
+
+    template <class _CvrefSender, class _Env>
+    using __receiver_t =
+        __t<__meval<__receiver, __cvref_id<_CvrefSender>, __id<_Env>>>;
+
+    template <class _Sender>
+    static auto transform_sender(_Sender&& __sndr)
+    {
+        using _Receiver =
+            __receiver_t<__child_of<_Sender>, __decay_t<__data_of<_Sender>>>;
+        static_assert(sender_to<__child_of<_Sender>, _Receiver>);
+
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             [&]<class _Env, class _Child>(
+                                 __ignore, _Env&& __env, _Child&& __child) {
+            // The shared state starts life with a ref-count of one.
+            auto __sh_state =
+                __make_intrusive<__shared_state<_Child, __decay_t<_Env>>, 2>(
+                    static_cast<_Child&&>(__child), static_cast<_Env&&>(__env));
+
+            // Eagerly start the work:
+            __sh_state->__try_start();
+
+            return __make_sexpr<__ensure_started_t>(
+                __box{__ensure_started_t(), std::move(__sh_state)});
+        });
+    }
+};
+} // namespace __ensure_started
+
+using __ensure_started::ensure_started_t;
+inline constexpr ensure_started_t ensure_started{};
+
+template <>
+struct __sexpr_impl<__ensure_started::__ensure_started_t> :
+    __shared::__shared_impl<__ensure_started::__ensure_started_t>
+{};
+
+template <>
+struct __sexpr_impl<ensure_started_t> : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {};
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__env.hpp b/include/sdbusplus/async/stdexec/__detail/__env.hpp
index 178b913..325ba79 100644
--- a/include/sdbusplus/async/stdexec/__detail/__env.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__env.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023 NVIDIA Corporation
+ * 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
@@ -15,15 +15,16 @@
  */
 #pragma once
 
-#include "../functional.hpp"
-#include "../stop_token.hpp"
 #include "__concepts.hpp"
-#include "__config.hpp"
+#include "__cpo.hpp"
 #include "__execution_fwd.hpp"
 #include "__meta.hpp"
+#include "__stop_token.hpp"
+#include "__tag_invoke.hpp"
+#include "__tuple.hpp"
 
-#include <concepts>
 #include <exception>
+#include <functional>
 #include <type_traits>
 
 STDEXEC_PRAGMA_PUSH()
@@ -47,16 +48,32 @@
 // [exec.queries]
 namespace __queries
 {
+template <class _Tp>
+concept __is_bool_constant = //
+    requires {               //
+        typename __mbool<_Tp::value>;
+    };
+
 struct forwarding_query_t
 {
     template <class _Query>
-    constexpr auto operator()(_Query __query) const noexcept -> bool
+    consteval auto operator()(_Query __query) const noexcept -> bool
     {
         if constexpr (tag_invocable<forwarding_query_t, _Query>)
         {
-            return tag_invoke(*this, static_cast<_Query&&>(__query));
+            using __result_t = tag_invoke_result_t<forwarding_query_t, _Query>;
+            // If this a integral type wrapper, unpack it and return the value.
+            // Otherwise, return the result of the tag_invoke call expression.
+            if constexpr (__is_bool_constant<__result_t>)
+            {
+                return __result_t::value;
+            }
+            else
+            {
+                return tag_invoke(*this, static_cast<_Query&&>(__query));
+            }
         }
-        else if constexpr (std::derived_from<_Query, forwarding_query_t>)
+        else if constexpr (derived_from<_Query, forwarding_query_t>)
         {
             return true;
         }
@@ -115,7 +132,8 @@
         requires tag_invocable<get_forward_progress_guarantee_t, __cref_t<_Tp>>
     constexpr auto operator()(_Tp&& __t) const noexcept(
         nothrow_tag_invocable<get_forward_progress_guarantee_t, __cref_t<_Tp>>)
-        -> tag_invoke_result_t<get_forward_progress_guarantee_t, __cref_t<_Tp>>
+        -> __decay_t<tag_invoke_result_t<get_forward_progress_guarantee_t,
+                                         __cref_t<_Tp>>>
     {
         return tag_invoke(get_forward_progress_guarantee_t{},
                           std::as_const(__t));
@@ -160,8 +178,7 @@
 
 struct get_scheduler_t : __query<get_scheduler_t>
 {
-    friend constexpr auto tag_invoke(forwarding_query_t,
-                                     const get_scheduler_t&) noexcept -> bool
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
         return true;
     }
@@ -177,9 +194,7 @@
 
 struct get_delegatee_scheduler_t : __query<get_delegatee_scheduler_t>
 {
-    friend constexpr auto tag_invoke(forwarding_query_t,
-                                     const get_delegatee_scheduler_t&) noexcept
-        -> bool
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
         return true;
     }
@@ -195,8 +210,7 @@
 
 struct get_allocator_t : __query<get_allocator_t>
 {
-    friend constexpr auto tag_invoke(forwarding_query_t,
-                                     const get_allocator_t&) noexcept -> bool
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
         return true;
     }
@@ -218,26 +232,26 @@
 
 struct get_stop_token_t : __query<get_stop_token_t>
 {
-    friend constexpr auto tag_invoke(forwarding_query_t,
-                                     const get_stop_token_t&) noexcept -> bool
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
         return true;
     }
 
-    template <class _Env>
-    auto operator()(const _Env&) const noexcept -> never_stop_token
+    template <class _Env, class _Token = never_stop_token>
+    auto operator()(const _Env&) const noexcept -> _Token
     {
         return {};
     }
 
-    template <class _Env>
+    template <class _Env, class = void>
         requires tag_invocable<get_stop_token_t, const _Env&>
     auto operator()(const _Env& __env) const noexcept
         -> tag_invoke_result_t<get_stop_token_t, const _Env&>
     {
         static_assert(nothrow_tag_invocable<get_stop_token_t, const _Env&>);
-        static_assert(stoppable_token<
-                      tag_invoke_result_t<get_stop_token_t, const _Env&>>);
+        static_assert(
+            stoppable_token<
+                __decay_t<tag_invoke_result_t<get_stop_token_t, const _Env&>>>);
         return tag_invoke(get_stop_token_t{}, __env);
     }
 
@@ -245,24 +259,22 @@
     auto operator()() const noexcept;
 };
 
-template <class _Queryable, class _CPO>
+template <class _Queryable, class _Tag>
 concept __has_completion_scheduler_for =
     queryable<_Queryable> && //
-    tag_invocable<get_completion_scheduler_t<_CPO>, const _Queryable&>;
+    tag_invocable<get_completion_scheduler_t<_Tag>, const _Queryable&>;
 
-template <__completion_tag _CPO>
-struct get_completion_scheduler_t : __query<get_completion_scheduler_t<_CPO>>
+template <__completion_tag _Tag>
+struct get_completion_scheduler_t : __query<get_completion_scheduler_t<_Tag>>
 {
-    friend constexpr auto
-        tag_invoke(forwarding_query_t,
-                   const get_completion_scheduler_t<_CPO>&) noexcept -> bool
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
     {
         return true;
     }
 
-    template <__has_completion_scheduler_for<_CPO> _Queryable>
+    template <__has_completion_scheduler_for<_Tag> _Queryable>
     auto operator()(const _Queryable& __queryable) const noexcept
-        -> tag_invoke_result_t<get_completion_scheduler_t<_CPO>,
+        -> tag_invoke_result_t<get_completion_scheduler_t<_Tag>,
                                const _Queryable&>;
 };
 
@@ -271,16 +283,68 @@
     template <class _Ty>
         requires tag_invocable<get_domain_t, const _Ty&>
     constexpr auto operator()(const _Ty& __ty) const noexcept
-        -> tag_invoke_result_t<get_domain_t, const _Ty&>
+        -> __decay_t<tag_invoke_result_t<get_domain_t, const _Ty&>>
     {
         static_assert(nothrow_tag_invocable<get_domain_t, const _Ty&>,
                       "Customizations of get_domain must be noexcept.");
-        static_assert(__class<tag_invoke_result_t<get_domain_t, const _Ty&>>,
-                      "Customizations of get_domain must return a class type.");
-        return tag_invoke(get_domain_t{}, __ty);
+        static_assert(
+            __class<__decay_t<tag_invoke_result_t<get_domain_t, const _Ty&>>>,
+            "Customizations of get_domain must return a class type.");
+        return {};
     }
 
-    friend constexpr auto tag_invoke(forwarding_query_t, get_domain_t) noexcept
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return true;
+    }
+};
+
+struct __is_scheduler_affine_t
+{
+    template <class _Env>
+    constexpr auto operator()(const _Env&) const noexcept
+    {
+        if constexpr (tag_invocable<__is_scheduler_affine_t, const _Env&>)
+        {
+            using _Result =
+                tag_invoke_result_t<__is_scheduler_affine_t, const _Env&>;
+            static_assert(__same_as<decltype(__v<_Result>), const bool>);
+            return _Result();
+        }
+        else
+        {
+            return std::false_type();
+        }
+    }
+
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return false;
+    }
+};
+
+struct __root_t
+{
+    template <class _Env>
+        requires tag_invocable<__root_t, const _Env&>
+    constexpr auto operator()(const _Env& __env) const noexcept -> bool
+    {
+        STDEXEC_ASSERT(tag_invoke(__root_t{}, __env) == true);
+        return true;
+    }
+
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return false;
+    }
+};
+
+struct __root_env
+{
+    using __t = __root_env;
+    using __id = __root_env;
+
+    constexpr STDEXEC_MEMFN_DECL(auto __root)(this const __root_env&) noexcept
         -> bool
     {
         return true;
@@ -289,6 +353,9 @@
 } // namespace __queries
 
 using __queries::__has_algorithm_customizations_t;
+using __queries::__is_scheduler_affine_t;
+using __queries::__root_env;
+using __queries::__root_t;
 using __queries::execute_may_block_caller_t;
 using __queries::forwarding_query_t;
 using __queries::get_allocator_t;
@@ -312,8 +379,8 @@
 inline constexpr get_allocator_t get_allocator{};
 inline constexpr get_stop_token_t get_stop_token{};
 #if !STDEXEC_GCC() || defined(__OPTIMIZE_SIZE__)
-template <__completion_tag _CPO>
-inline constexpr get_completion_scheduler_t<_CPO> get_completion_scheduler{};
+template <__completion_tag _Tag>
+inline constexpr get_completion_scheduler_t<_Tag> get_completion_scheduler{};
 #else
 template <>
 inline constexpr get_completion_scheduler_t<set_value_t>
@@ -331,36 +398,15 @@
 
 inline constexpr get_domain_t get_domain{};
 
+template <class _Env>
+using __domain_of_t = __decay_t<__call_result_t<get_domain_t, _Env>>;
+
 template <class _Tag, class _Queryable, class _Default>
 using __query_result_or_t =
     __call_result_t<query_or_t, _Tag, _Queryable, _Default>;
 
-/////////////////////////////////////////////////////////////////////////////
 namespace __env
 {
-// For getting an execution environment from a receiver,
-// or the attributes from a sender.
-struct get_env_t
-{
-    template <class _EnvProvider>
-        requires tag_invocable<get_env_t, const _EnvProvider&>
-    STDEXEC_ATTRIBUTE((always_inline)) constexpr auto
-        operator()(const _EnvProvider& __env_provider) const noexcept
-        -> tag_invoke_result_t<get_env_t, const _EnvProvider&>
-    {
-        static_assert(
-            queryable<tag_invoke_result_t<get_env_t, const _EnvProvider&>>);
-        static_assert(nothrow_tag_invocable<get_env_t, const _EnvProvider&>);
-        return tag_invoke(*this, __env_provider);
-    }
-
-    template <class _EnvProvider>
-    constexpr auto operator()(const _EnvProvider&) const noexcept -> empty_env
-    {
-        return {};
-    }
-};
-
 // To be kept in sync with the promise type used in __connect_awaitable
 template <class _Env>
 struct __promise
@@ -380,13 +426,127 @@
         return tag_invoke(as_awaitable, static_cast<_Ty&&>(__value), *this);
     }
 
-    template <same_as<get_env_t> _Tag>
-    friend auto tag_invoke(_Tag, const __promise&) noexcept -> const _Env&
-    {
-        std::terminate();
-    }
+    auto get_env() const noexcept -> const _Env&;
 };
 
+template <class _Env, class _Query, class... _Args>
+concept __queryable = //
+    tag_invocable<_Query, const _Env&, _Args...>;
+
+template <class _Env, class _Query, class... _Args>
+concept __nothrow_queryable = //
+    nothrow_tag_invocable<_Query, const _Env&, _Args...>;
+
+template <class _Env, class _Query, class... _Args>
+using __query_result_t = //
+    tag_invoke_result_t<_Query, const _Env&, _Args...>;
+
+// A singleton environment from a query/value pair
+template <class _Query, class _Value>
+struct prop
+{
+    using __t = prop;
+    using __id = prop;
+
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Query __query;
+
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Value __value;
+
+    STDEXEC_ATTRIBUTE((nodiscard))
+    constexpr const _Value& query(_Query) const noexcept
+    {
+        return __value;
+    }
+
+    prop& operator=(const prop&) = delete;
+};
+
+template <class _Query, class _Value>
+prop(_Query, _Value) -> prop<_Query, std::unwrap_reference_t<_Value>>;
+
+// utility for joining multiple environments
+template <class... _Envs>
+struct env
+{
+    using __t = env;
+    using __id = env;
+
+    __tuple_for<_Envs...> __tup_;
+
+    // return a reference to the first child env for which
+    // __queryable<_Envs, _Query, _Args...> is true.
+    template <class _Query, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline))
+    constexpr decltype(auto) __get_1st() const noexcept
+    {
+        constexpr bool __flags[] = {__queryable<_Envs, _Query, _Args...>...};
+        constexpr std::size_t __idx = __pos_of(__flags,
+                                               __flags + sizeof...(_Envs));
+        return __tup::get<__idx>(__tup_);
+    }
+
+    template <class _Query, class... _Args>
+        requires(__queryable<_Envs, _Query, _Args...> || ...)
+    STDEXEC_ATTRIBUTE((always_inline)) constexpr decltype(auto)
+        query(_Query __q, _Args&&... __args) const
+        noexcept(__nothrow_queryable<decltype(__get_1st<_Query, _Args...>()),
+                                     _Query, _Args...>)
+    {
+        return tag_invoke(__q, __get_1st<_Query, _Args...>(),
+                          static_cast<_Args&&>(__args)...);
+    }
+
+    env& operator=(const env&) = delete;
+};
+
+// specialization for two envs to avoid warnings about elided braces
+template <class _Env0, class _Env1>
+struct env<_Env0, _Env1>
+{
+    using __t = env;
+    using __id = env;
+
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Env0 __env0_;
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Env1 __env1_;
+
+    // return a reference to the first child env for which
+    // __queryable<_Envs, _Query, _Args...> is true.
+    template <class _Query, class... _Args>
+    STDEXEC_ATTRIBUTE((always_inline))
+    constexpr decltype(auto) __get_1st() const noexcept
+    {
+        if constexpr (__queryable<_Env0, _Query, _Args...>)
+        {
+            return (__env0_);
+        }
+        else
+        {
+            return (__env1_);
+        }
+    }
+
+    template <class _Query, class... _Args>
+        requires __queryable<_Env0, _Query, _Args...> ||
+                 __queryable<_Env1, _Query, _Args...>
+    STDEXEC_ATTRIBUTE((always_inline)) constexpr decltype(auto)
+        query(_Query __q, _Args&&... __args) const
+        noexcept(__nothrow_queryable<decltype(__get_1st<_Query, _Args...>()),
+                                     _Query, _Args...>)
+    {
+        return tag_invoke(__q, __get_1st<_Query, _Args...>(),
+                          static_cast<_Args&&>(__args)...);
+    }
+
+    env& operator=(const env&) = delete;
+};
+
+template <class... _Envs>
+env(_Envs...) -> env<std::unwrap_reference_t<_Envs>...>;
+
 template <class _Value, class _Tag, class... _Tags>
 struct __with
 {
@@ -408,101 +568,104 @@
     {}
 
     template <__one_of<_Tag, _Tags...> _Key>
-    friend auto tag_invoke(_Key, const __with& __self) //
-        noexcept(__nothrow_decay_copyable<_Value>) -> _Value
+    auto query(_Key) const noexcept -> const _Value&
     {
-        return __self.__value_;
+        return __value_;
     }
+
+    __with& operator=(const __with&) = delete;
 };
 
 template <class _Value, class _Tag, class... _Tags>
 __with(_Value, _Tag, _Tags...) -> __with<_Value, _Tag, _Tags...>;
 
-template <class _Env>
+template <class _EnvId>
 struct __fwd
 {
+    using _Env = __cvref_t<_EnvId>;
     static_assert(__nothrow_move_constructible<_Env>);
-    using __t = __fwd;
-    using __id = __fwd;
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _Env __env_;
 
-    template <__forwarding_query _Tag>
-        requires tag_invocable<_Tag, const _Env&>
-    friend auto tag_invoke(_Tag, const __fwd& __self) //
-        noexcept(nothrow_tag_invocable<_Tag, const _Env&>)
-            -> tag_invoke_result_t<_Tag, const _Env&>
+    struct __t
     {
-        return _Tag()(__self.__env_);
-    }
+        using __id = __fwd;
+        STDEXEC_ATTRIBUTE((no_unique_address))
+        _Env __env_;
+
+#if STDEXEC_GCC() && __GNUC__ < 12
+        using __cvref_env_t = std::add_const_t<_Env>&;
+#else
+        using __cvref_env_t = const _Env&;
+#endif
+
+        template <__forwarding_query _Tag>
+            requires tag_invocable<_Tag, __cvref_env_t>
+        auto query(_Tag) const
+            noexcept(nothrow_tag_invocable<_Tag, __cvref_env_t>)
+                -> tag_invoke_result_t<_Tag, __cvref_env_t>
+        {
+            return tag_invoke(_Tag(), __env_);
+        }
+
+        __t& operator=(const __t&) = delete;
+    };
 };
 
-template <class _Env>
-__fwd(_Env&&) -> __fwd<_Env>;
-
-template <class _Env>
-struct __ref
-{
-    using __t = __ref;
-    using __id = __ref;
-    const _Env& __env_;
-
-    template <class _Tag>
-        requires tag_invocable<_Tag, const _Env&>
-    friend auto tag_invoke(_Tag, const __ref& __self) //
-        noexcept(nothrow_tag_invocable<_Tag, const _Env&>)
-            -> tag_invoke_result_t<_Tag, const _Env&>
-    {
-        return _Tag()(__self.__env_);
-    }
-};
-
-template <class _Env>
-__ref(_Env&) -> __ref<_Env>;
-
-struct __ref_fn
+struct __fwd_fn
 {
     template <class _Env>
-    constexpr auto operator()(_Env&& __env) const
+    auto operator()(_Env&& __env) const
     {
-        if constexpr (same_as<_Env, _Env&>)
-        {
-            return __ref{static_cast<_Env&&>(__env)};
-        }
-        else
-        {
-            return static_cast<_Env&&>(__env);
-        }
+        return __t<__fwd<__cvref_id<_Env>>>{static_cast<_Env&&>(__env)};
+    }
+
+    auto operator()(empty_env) const -> empty_env
+    {
+        return {};
     }
 };
 
-template <class _Env, class _Tag, class... _Tags>
-struct __without_ : _Env
+template <class _EnvId, class _Tag>
+struct __without_
 {
+    using _Env = __cvref_t<_EnvId>;
     static_assert(__nothrow_move_constructible<_Env>);
-    using __t = __without_;
-    using __id = __without_;
 
-    constexpr explicit __without_(_Env&& __env, _Tag, _Tags...) noexcept :
-        _Env(static_cast<_Env&&>(__env))
-    {}
+    struct __t
+    {
+        using __id = __without_;
+        _Env __env_;
 
-    template <__one_of<_Tag, _Tags...> _Key, class _Self>
-        requires(std::is_base_of_v<__without_, __decay_t<_Self>>)
-    friend auto tag_invoke(_Key, _Self&&) noexcept = delete;
+#if STDEXEC_GCC() && __GNUC__ < 12
+        using __cvref_env_t = std::add_const_t<_Env>&;
+#else
+        using __cvref_env_t = const _Env&;
+#endif
+
+        auto query(_Tag) const noexcept = delete;
+
+        template <tag_invocable<__cvref_env_t> _Key>
+        STDEXEC_ATTRIBUTE((always_inline))
+        auto query(_Key) const
+            noexcept(nothrow_tag_invocable<_Key, __cvref_env_t>)
+                -> decltype(auto)
+        {
+            return tag_invoke(_Key(), __env_);
+        }
+
+        __t& operator=(const __t&) = delete;
+    };
 };
 
 struct __without_fn
 {
-    template <class _Env, class _Tag, class... _Tags>
-    constexpr auto operator()(_Env&& __env, _Tag, _Tags...) const noexcept
+    template <class _Env, class _Tag>
+    constexpr auto operator()(_Env&& __env, _Tag) const noexcept
         -> decltype(auto)
     {
-        if constexpr (tag_invocable<_Tag, _Env> ||
-                      (tag_invocable<_Tags, _Env> || ...))
+        if constexpr (tag_invocable<_Tag, _Env>)
         {
-            return __without_{__ref_fn()(static_cast<_Env&&>(__env)), _Tag(),
-                              _Tags()...};
+            using _Without = __t<__without_<__cvref_id<_Env>, _Tag>>;
+            return _Without{static_cast<_Env&&>(__env)};
         }
         else
         {
@@ -516,30 +679,6 @@
 template <class _Env, class _Tag, class... _Tags>
 using __without_t = __result_of<__without, _Env, _Tag, _Tags...>;
 
-template <class _Second, class _First>
-struct __joined : _Second
-{
-    static_assert(__nothrow_move_constructible<_First>);
-    static_assert(__nothrow_move_constructible<_Second>);
-    using __t = __joined;
-    using __id = __joined;
-
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _First __env_;
-
-    template <class _Tag>
-        requires tag_invocable<_Tag, const _First&>
-    friend auto tag_invoke(_Tag, const __joined& __self) //
-        noexcept(nothrow_tag_invocable<_Tag, const _First&>)
-            -> tag_invoke_result_t<_Tag, const _First&>
-    {
-        return _Tag()(__self.__env_);
-    }
-};
-
-template <class _Second, class _First>
-__joined(_Second&&, _First&&) -> __joined<_Second, _First>;
-
 template <__nothrow_move_constructible _Fun>
 struct __from
 {
@@ -550,82 +689,110 @@
 
     template <class _Tag>
         requires __callable<const _Fun&, _Tag>
-    friend auto tag_invoke(_Tag, const __from& __self) //
-        noexcept(__nothrow_callable<const _Fun&, _Tag>)
-            -> __call_result_t<const _Fun&, _Tag>
+    auto query(_Tag) const noexcept(__nothrow_callable<const _Fun&, _Tag>)
+        -> __call_result_t<const _Fun&, _Tag>
     {
-        return __self.__fun_(_Tag());
+        return __fun_(_Tag());
     }
+
+    __from& operator=(const __from&) = delete;
 };
 
 template <class _Fun>
 __from(_Fun) -> __from<_Fun>;
 
-struct __fwd_fn
-{
-    template <class Env>
-    auto operator()(Env&& env) const
-    {
-        return __fwd{static_cast<Env&&>(env)};
-    }
-
-    auto operator()(empty_env) const -> empty_env
-    {
-        return {};
-    }
-};
-
 struct __join_fn
 {
-    auto operator()() const -> empty_env
+    auto operator()(empty_env, empty_env) const noexcept -> empty_env
     {
         return {};
     }
 
     template <class _Env>
-    auto operator()(_Env&& __env) const -> _Env
+    auto operator()(_Env&& __env, empty_env = {}) const noexcept -> _Env
     {
         return static_cast<_Env&&>(__env);
     }
 
-    auto operator()(empty_env) const -> empty_env
-    {
-        return {};
-    }
-
     template <class _Env>
-    auto operator()(_Env&& __env, empty_env) const -> _Env
+    auto operator()(empty_env, _Env&& __env) const noexcept -> decltype(auto)
     {
-        return static_cast<_Env&&>(__env);
+        return __fwd_fn()(static_cast<_Env&&>(__env));
     }
 
-    auto operator()(empty_env, empty_env) const -> empty_env
+    template <class _First, class _Second>
+    auto operator()(_First&& __first, _Second&& __second) const noexcept
+        -> env<_First, __call_result_t<__fwd_fn, _Second>>
     {
-        return {};
-    }
-
-    template <class... Rest>
-    auto operator()(empty_env, Rest&&... rest) const -> decltype(auto)
-    {
-        return __fwd_fn()(__join_fn()(static_cast<Rest&&>(rest)...));
-    }
-
-    template <class First, class... Rest>
-    auto operator()(First&& first, Rest&&... rest) const -> decltype(auto)
-    {
-        return __joined{__fwd_fn()(__join_fn()(static_cast<Rest&&>(rest)...)),
-                        static_cast<First&&>(first)};
+        return {static_cast<_First&&>(__first),
+                __fwd_fn()(static_cast<_Second&&>(__second))};
     }
 };
 
 inline constexpr __join_fn __join{};
 
-template <class... _Envs>
-using __join_t = __result_of<__join, _Envs...>;
+template <class _First, class... _Second>
+using __join_t = __result_of<__join, _First, _Second...>;
+
+struct __as_root_env_fn
+{
+    template <class _Env>
+    constexpr auto operator()(_Env __env) const noexcept
+        -> __join_t<__root_env, std::unwrap_reference_t<_Env>>
+    {
+        return __join(__root_env{},
+                      static_cast<std::unwrap_reference_t<_Env>&&>(__env));
+    }
+};
+
+inline constexpr __as_root_env_fn __as_root_env{};
+
+template <class _Env>
+using __as_root_env_t = __result_of<__as_root_env, _Env>;
 } // namespace __env
 
-using __env::empty_env;
-using __env::get_env_t;
+using __env::env;
+using __env::prop;
+using empty_env = env<>;
+
+/////////////////////////////////////////////////////////////////////////////
+namespace __get_env
+{
+// For getting an execution environment from a receiver or the attributes from a
+// sender.
+struct get_env_t
+{
+    template <__same_as<get_env_t> _Self, class _EnvProvider>
+    STDEXEC_ATTRIBUTE((always_inline))
+    friend auto tag_invoke(_Self, const _EnvProvider& __env_provider) noexcept
+        -> decltype(__env_provider.get_env())
+    {
+        static_assert(noexcept(__env_provider.get_env()),
+                      "get_env() members must be noexcept");
+        return __env_provider.get_env();
+    }
+
+    template <class _EnvProvider>
+        requires tag_invocable<get_env_t, const _EnvProvider&>
+    STDEXEC_ATTRIBUTE((always_inline)) constexpr auto
+        operator()(const _EnvProvider& __env_provider) const noexcept
+        -> tag_invoke_result_t<get_env_t, const _EnvProvider&>
+    {
+        static_assert(
+            queryable<tag_invoke_result_t<get_env_t, const _EnvProvider&>>);
+        static_assert(nothrow_tag_invocable<get_env_t, const _EnvProvider&>);
+        return tag_invoke(*this, __env_provider);
+    }
+
+    template <class _EnvProvider>
+    constexpr auto operator()(const _EnvProvider&) const noexcept -> empty_env
+    {
+        return {};
+    }
+};
+} // namespace __get_env
+
+using __get_env::get_env_t;
 inline constexpr get_env_t get_env{};
 
 template <class _EnvProvider>
@@ -635,6 +802,23 @@
             get_env(std::as_const(__ep))
         } -> queryable;
     };
+
+using __env::__as_root_env;
+using __env::__as_root_env_t;
+
+template <class _Env>
+concept __is_root_env = requires(_Env&& __env) {
+                            {
+                                __root_t{}(__env)
+                            } -> same_as<bool>;
+                        };
+
+template <class _Sender>
+concept __is_scheduler_affine = //
+    requires {
+        requires __v<
+            __call_result_t<__is_scheduler_affine_t, env_of_t<_Sender>>>;
+    };
 } // namespace stdexec
 
 STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__execute.hpp b/include/sdbusplus/async/stdexec/__detail/__execute.hpp
new file mode 100644
index 0000000..cb62593
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__execute.hpp
@@ -0,0 +1,92 @@
+/*
+ * 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 "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__cpo.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__schedulers.hpp"
+#include "__senders.hpp"
+#include "__submit.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <exception>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.execute]
+namespace __execute_
+{
+template <class _Fun>
+struct __as_receiver
+{
+    using receiver_concept = receiver_t;
+    _Fun __fun_;
+
+    void set_value() noexcept
+    {
+        // terminates on exception:
+        __fun_();
+    }
+
+    [[noreturn]] void set_error(std::exception_ptr) noexcept
+    {
+        std::terminate();
+    }
+
+    void set_stopped() noexcept {}
+};
+
+struct execute_t
+{
+    template <scheduler _Scheduler, class _Fun>
+        requires __callable<_Fun&> && move_constructible<_Fun>
+    void operator()(_Scheduler&& __sched, _Fun __fun) const noexcept(false)
+    {
+        // Look for a legacy customization
+        if constexpr (tag_invocable<execute_t, _Scheduler, _Fun>)
+        {
+            tag_invoke(execute_t{}, static_cast<_Scheduler&&>(__sched),
+                       static_cast<_Fun&&>(__fun));
+        }
+        else
+        {
+            auto __domain = query_or(get_domain, __sched, default_domain());
+            stdexec::apply_sender(__domain, *this,
+                                  schedule(static_cast<_Scheduler&&>(__sched)),
+                                  static_cast<_Fun&&>(__fun));
+        }
+    }
+
+    template <sender_of<set_value_t()> _Sender, class _Fun>
+        requires __callable<_Fun&> && move_constructible<_Fun>
+    void apply_sender(_Sender&& __sndr, _Fun __fun) const noexcept(false)
+    {
+        __submit(static_cast<_Sender&&>(__sndr),
+                 __as_receiver<_Fun>{static_cast<_Fun&&>(__fun)});
+    }
+};
+} // namespace __execute_
+
+using __execute_::execute_t;
+inline constexpr execute_t execute{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
index 43e123a..7b25130 100644
--- a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
@@ -28,16 +28,16 @@
 struct default_domain;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __receivers
+namespace __rcvrs
 {
 struct set_value_t;
 struct set_error_t;
 struct set_stopped_t;
-} // namespace __receivers
+} // namespace __rcvrs
 
-using __receivers::set_error_t;
-using __receivers::set_stopped_t;
-using __receivers::set_value_t;
+using __rcvrs::set_error_t;
+using __rcvrs::set_stopped_t;
+using __rcvrs::set_value_t;
 extern const set_value_t set_value;
 extern const set_error_t set_error;
 extern const set_stopped_t set_stopped;
@@ -51,20 +51,26 @@
 template <class _Sender>
 extern const bool enable_receiver;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////
 namespace __env
 {
-struct get_env_t;
+template <class _Query, class _Value>
+struct prop;
 
-struct empty_env
-{
-    using __t = empty_env;
-    using __id = empty_env;
-};
+template <class... _Envs>
+struct env;
 } // namespace __env
 
-using __env::empty_env;
-using __env::get_env_t;
+using __env::env;
+using __env::prop;
+using empty_env = env<>;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __get_env
+{
+struct get_env_t;
+} // namespace __get_env
+
+using __get_env::get_env_t;
 extern const get_env_t get_env;
 
 template <class _EnvProvider>
@@ -113,6 +119,12 @@
 template <__completion_tag _CPO>
 extern const get_completion_scheduler_t<_CPO> get_completion_scheduler;
 
+struct never_stop_token;
+class inplace_stop_source;
+class inplace_stop_token;
+template <class _Fn>
+class inplace_stop_callback;
+
 template <class _Tp>
 using stop_token_of_t = __decay_t<__call_result_t<get_stop_token_t, _Tp>>;
 
@@ -125,14 +137,27 @@
     __call_result_t<get_completion_scheduler_t<_CPO>, env_of_t<const _Sender&>>;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __get_completion_signatures
+namespace __sigs
 {
-struct get_completion_signatures_t;
-} // namespace __get_completion_signatures
+template <class _Sig>
+inline constexpr bool __is_compl_sig = false;
 
-using __get_completion_signatures::get_completion_signatures_t;
+struct get_completion_signatures_t;
+} // namespace __sigs
+
+template <class _Sig>
+concept __completion_signature = __sigs::__is_compl_sig<_Sig>;
+
+template <class... _Sigs>
+struct completion_signatures;
+
+using __sigs::get_completion_signatures_t;
 extern const get_completion_signatures_t get_completion_signatures;
 
+template <class _Sender, class... _Env>
+using __completion_signatures_of_t = //
+    __call_result_t<get_completion_signatures_t, _Sender, _Env...>;
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 namespace __connect
 {
@@ -164,12 +189,12 @@
 extern const start_t start;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __schedule
+namespace __sched
 {
 struct schedule_t;
-} // namespace __schedule
+} // namespace __sched
 
-using __schedule::schedule_t;
+using __sched::schedule_t;
 extern const schedule_t schedule;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -182,12 +207,27 @@
 extern const as_awaitable_t as_awaitable;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
-namespace __transfer
+namespace __start_on
 {
-struct transfer_t;
-} // namespace __transfer
+struct start_on_t;
+} // namespace __start_on
 
-using __transfer::transfer_t;
+using __start_on::start_on_t;
+extern const start_on_t start_on;
+
+using on_t = start_on_t;
+extern const on_t on;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+namespace __continue_on
+{
+struct continue_on_t;
+} // namespace __continue_on
+
+using __continue_on::continue_on_t;
+extern const continue_on_t continue_on;
+
+using transfer_t = continue_on_t;
 extern const transfer_t transfer;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -249,8 +289,8 @@
 } // namespace stdexec
 
 template <class...>
-[[deprecated]] void print()
+[[deprecated]] void __print()
 {}
 
-template <class>
-struct undef;
+template <class...>
+struct __undef;
diff --git a/include/sdbusplus/async/stdexec/__detail/__inline_scheduler.hpp b/include/sdbusplus/async/stdexec/__detail/__inline_scheduler.hpp
new file mode 100644
index 0000000..e65a48b
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__inline_scheduler.hpp
@@ -0,0 +1,88 @@
+/*
+ * 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 "__basic_sender.hpp"
+#include "__cpo.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__receivers.hpp"
+#include "__schedulers.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+namespace __inln
+{
+struct __schedule_t
+{};
+
+struct __scheduler
+{
+    using __t = __scheduler;
+    using __id = __scheduler;
+
+    template <class _Tag = __schedule_t>
+    STDEXEC_ATTRIBUTE((host, device))
+    STDEXEC_MEMFN_DECL(auto schedule)(this __scheduler)
+    {
+        return __make_sexpr<_Tag>();
+    }
+
+    auto query(get_forward_progress_guarantee_t) const noexcept
+        -> forward_progress_guarantee
+    {
+        return forward_progress_guarantee::weakly_parallel;
+    }
+
+    auto operator==(const __scheduler&) const noexcept -> bool = default;
+};
+
+struct __env
+{
+    static constexpr bool query(__is_scheduler_affine_t) noexcept
+    {
+        return true;
+    }
+
+    constexpr auto query(get_completion_scheduler_t<set_value_t>) const noexcept
+        -> __scheduler
+    {
+        return {};
+    }
+};
+} // namespace __inln
+
+template <>
+struct __sexpr_impl<__inln::__schedule_t> : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        [](__ignore) noexcept { return __inln::__env(); };
+
+    static constexpr auto get_completion_signatures = //
+        [](__ignore,
+           __ignore = {}) noexcept -> completion_signatures<set_value_t()> {
+        return {};
+    };
+
+    static constexpr auto start = //
+        []<class _Receiver>(__ignore, _Receiver& __rcvr) noexcept -> void {
+        stdexec::set_value(static_cast<_Receiver&&>(__rcvr));
+    };
+};
+
+static_assert(__is_scheduler_affine<schedule_result_t<__inln::__scheduler>>);
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__into_variant.hpp b/include/sdbusplus/async/stdexec/__detail/__into_variant.hpp
new file mode 100644
index 0000000..5673b49
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__into_variant.hpp
@@ -0,0 +1,130 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+#include "__utility.hpp"
+
+#include <exception>
+#include <tuple>
+#include <variant>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.into_variant]
+namespace __into_variant
+{
+template <class _Sender, class _Env>
+    requires sender_in<_Sender, _Env>
+using __into_variant_result_t = value_types_of_t<_Sender, _Env>;
+
+template <class _Sender, class... _Env>
+using __variant_t =
+    __value_types_t<__completion_signatures_of_t<_Sender, _Env...>>;
+
+template <class _Variant>
+using __variant_completions =
+    completion_signatures<set_value_t(_Variant),
+                          set_error_t(std::exception_ptr)>;
+
+template <class _Sender, class... _Env>
+using __completions = //
+    transform_completion_signatures<
+        __completion_signatures_of_t<_Sender, _Env...>,
+        __meval<__variant_completions, __variant_t<_Sender, _Env...>>,
+        __mconst<completion_signatures<>>::__f>;
+
+struct into_variant_t
+{
+    template <sender _Sender>
+    auto operator()(_Sender&& __sndr) const -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<into_variant_t>(__(), static_cast<_Sender&&>(__sndr)));
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()() const noexcept -> __binder_back<into_variant_t>
+    {
+        return {{}, {}, {}};
+    }
+};
+
+struct __into_variant_impl : __sexpr_defaults
+{
+    static constexpr auto get_state = //
+        []<class _Self, class _Receiver>(_Self&&, _Receiver&) noexcept {
+        using __variant_t =
+            value_types_of_t<__child_of<_Self>, env_of_t<_Receiver>>;
+        return __mtype<__variant_t>();
+    };
+
+    static constexpr auto complete = //
+        []<class _State, class _Receiver, class _Tag, class... _Args>(
+            __ignore, _State, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Tag, set_value_t>)
+        {
+            using __variant_t = __t<_State>;
+            try
+            {
+                set_value(static_cast<_Receiver&&>(__rcvr),
+                          __variant_t{std::tuple<_Args&&...>{
+                              static_cast<_Args&&>(__args)...}});
+            }
+            catch (...)
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                   std::current_exception());
+            }
+        }
+        else
+        {
+            _Tag()(static_cast<_Receiver&&>(__rcvr),
+                   static_cast<_Args&&>(__args)...);
+        }
+    };
+
+    static constexpr auto get_completion_signatures =               //
+        []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept //
+        -> __completions<__child_of<_Self>, _Env...> {
+        static_assert(sender_expr_for<_Self, into_variant_t>);
+        return {};
+    };
+};
+} // namespace __into_variant
+
+using __into_variant::into_variant_t;
+inline constexpr into_variant_t into_variant{};
+
+template <>
+struct __sexpr_impl<into_variant_t> : __into_variant::__into_variant_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_mpsc_queue.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_mpsc_queue.hpp
new file mode 100644
index 0000000..2830784
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_mpsc_queue.hpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) Dmitiy V'jukov
+ * Copyright (c) 2024 Maikel Nadolski
+ * Copyright (c) 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.
+ */
+
+// general design of this MPSC queue is taken from
+// https://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
+
+#pragma once
+
+#include <sdbusplus/async/stdexec/__spin_loop_pause.hpp>
+
+#include <atomic>
+
+namespace stdexec
+{
+template <auto _Ptr>
+class __intrusive_mpsc_queue;
+
+template <class _Node, std::atomic<void*> _Node::*_Next>
+class __intrusive_mpsc_queue<_Next>
+{
+    std::atomic<void*> __back_{&__nil_};
+    void* __front_{&__nil_};
+    std::atomic<_Node*> __nil_ = nullptr;
+
+    void push_back_nil()
+    {
+        __nil_.store(nullptr, std::memory_order_relaxed);
+        _Node* __prev = static_cast<_Node*>(
+            __back_.exchange(&__nil_, std::memory_order_acq_rel));
+        (__prev->*_Next).store(&__nil_, std::memory_order_release);
+    }
+
+  public:
+    bool push_back(_Node* __new_node) noexcept
+    {
+        (__new_node->*_Next).store(nullptr, std::memory_order_relaxed);
+        void* __prev_back = __back_.exchange(__new_node,
+                                             std::memory_order_acq_rel);
+        bool __is_nil = __prev_back == static_cast<void*>(&__nil_);
+        if (__is_nil)
+        {
+            __nil_.store(__new_node, std::memory_order_release);
+        }
+        else
+        {
+            (static_cast<_Node*>(__prev_back)->*_Next)
+                .store(__new_node, std::memory_order_release);
+        }
+        return __is_nil;
+    }
+
+    _Node* pop_front() noexcept
+    {
+        if (__front_ == static_cast<void*>(&__nil_))
+        {
+            _Node* __next = __nil_.load(std::memory_order_acquire);
+            if (!__next)
+            {
+                return nullptr;
+            }
+            __front_ = __next;
+        }
+        _Node* __front = static_cast<_Node*>(__front_);
+        void* __next = (__front->*_Next).load(std::memory_order_acquire);
+        if (__next)
+        {
+            __front_ = __next;
+            return __front;
+        }
+        STDEXEC_ASSERT(!__next);
+        push_back_nil();
+        do
+        {
+            __spin_loop_pause();
+            __next = (__front->*_Next).load(std::memory_order_acquire);
+        } while (!__next);
+        __front_ = __next;
+        return __front;
+    }
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
index 9897a0b..9242067 100644
--- a/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
@@ -15,8 +15,7 @@
  */
 #pragma once
 
-#include "../concepts.hpp"
-#include "__config.hpp"
+#include "__concepts.hpp"
 #include "__meta.hpp"
 
 #include <atomic>
@@ -33,41 +32,79 @@
 {
 namespace __ptr
 {
-template <class _Ty>
+template <std::size_t _ReservedBits>
+struct __count_and_bits
+{
+    static constexpr std::size_t __ref_count_increment = 1ul << _ReservedBits;
+
+    enum struct __bits : std::size_t
+    {
+    };
+
+    friend constexpr std::size_t __count(__bits __b) noexcept
+    {
+        return static_cast<std::size_t>(__b) / __ref_count_increment;
+    }
+
+    template <std::size_t _Bit>
+    friend constexpr bool __bit(__bits __b) noexcept
+    {
+        static_assert(_Bit < _ReservedBits, "Bit index out of range");
+        return (static_cast<std::size_t>(__b) & (1ul << _Bit)) != 0;
+    }
+};
+
+template <std::size_t _ReservedBits>
+using __bits_t = typename __count_and_bits<_ReservedBits>::__bits;
+
+template <class _Ty, std::size_t _ReservedBits>
 struct __make_intrusive_t;
 
-template <class _Ty>
+template <class _Ty, std::size_t _ReservedBits = 0ul>
 class __intrusive_ptr;
 
-template <class _Ty>
+template <class _Ty, std::size_t _ReservedBits = 0ul>
 struct __enable_intrusive_from_this
 {
-    auto __intrusive_from_this() noexcept -> __intrusive_ptr<_Ty>;
-    auto __intrusive_from_this() const noexcept -> __intrusive_ptr<const _Ty>;
+    auto __intrusive_from_this() noexcept
+        -> __intrusive_ptr<_Ty, _ReservedBits>;
+    auto __intrusive_from_this() const noexcept
+        -> __intrusive_ptr<const _Ty, _ReservedBits>;
 
   private:
+    using __bits_t = typename __count_and_bits<_ReservedBits>::__bits;
     friend _Ty;
-    void __inc_ref() noexcept;
-    void __dec_ref() noexcept;
+    __bits_t __inc_ref() noexcept;
+    __bits_t __dec_ref() noexcept;
+
+    template <std::size_t _Bit>
+    bool __is_set() const noexcept;
+    template <std::size_t _Bit>
+    __bits_t __set_bit() noexcept;
+    template <std::size_t _Bit>
+    __bits_t __clear_bit() noexcept;
 };
 
 STDEXEC_PRAGMA_PUSH()
 STDEXEC_PRAGMA_IGNORE_GNU("-Wtsan")
 
-template <class _Ty>
+template <class _Ty, std::size_t _ReservedBits>
 struct __control_block
 {
+    using __bits_t = typename __count_and_bits<_ReservedBits>::__bits;
+    static constexpr std::size_t __ref_count_increment = 1ul << _ReservedBits;
+
     alignas(_Ty) unsigned char __value_[sizeof(_Ty)];
-    std::atomic<unsigned long> __refcount_;
+    std::atomic<std::size_t> __ref_count_;
 
     template <class... _Us>
     explicit __control_block(_Us&&... __us) noexcept(noexcept(_Ty{
         __declval<_Us>()...})) :
-        __refcount_(1u)
+        __ref_count_(__ref_count_increment)
     {
-        // Construct the value *after* the initialization of the
-        // atomic in case the constructor of _Ty calls
-        // __intrusive_from_this() (which increments the atomic):
+        // Construct the value *after* the initialization of the atomic in case
+        // the constructor of _Ty calls __intrusive_from_this() (which
+        // increments the ref count):
         ::new (static_cast<void*>(__value_)) _Ty{static_cast<_Us&&>(__us)...};
     }
 
@@ -81,36 +118,68 @@
         return *reinterpret_cast<_Ty*>(__value_);
     }
 
-    void __inc_ref_() noexcept
+    __bits_t __inc_ref_() noexcept
     {
-        __refcount_.fetch_add(1, std::memory_order_relaxed);
+        auto __old = __ref_count_.fetch_add(__ref_count_increment,
+                                            std::memory_order_relaxed);
+        return static_cast<__bits_t>(__old);
     }
 
-    void __dec_ref_() noexcept
+    __bits_t __dec_ref_() noexcept
     {
-        if (1u == __refcount_.fetch_sub(1, std::memory_order_release))
+        auto __old = __ref_count_.fetch_sub(__ref_count_increment,
+                                            std::memory_order_acq_rel);
+        if (__count(static_cast<__bits_t>(__old)) == 1)
         {
-            std::atomic_thread_fence(std::memory_order_acquire);
-            // TSan does not support std::atomic_thread_fence, so we
-            // need to use the TSan-specific __tsan_acquire instead:
-            STDEXEC_TSAN(__tsan_acquire(&__refcount_));
             delete this;
         }
+        return static_cast<__bits_t>(__old);
+    }
+
+    // Returns true if the bit was set, false if it was already set.
+    template <std::size_t _Bit>
+    [[nodiscard]] bool __is_set_() const noexcept
+    {
+        auto __old = __ref_count_.load(std::memory_order_relaxed);
+        return __bit<_Bit>(static_cast<__bits_t>(__old));
+    }
+
+    template <std::size_t _Bit>
+    __bits_t __set_bit_() noexcept
+    {
+        static_assert(_Bit < _ReservedBits, "Bit index out of range");
+        constexpr std::size_t __mask = 1ul << _Bit;
+        auto __old = __ref_count_.fetch_or(__mask, std::memory_order_acq_rel);
+        return static_cast<__bits_t>(__old);
+    }
+
+    // Returns true if the bit was cleared, false if it was already cleared.
+    template <std::size_t _Bit>
+    __bits_t __clear_bit_() noexcept
+    {
+        static_assert(_Bit < _ReservedBits, "Bit index out of range");
+        constexpr std::size_t __mask = 1ul << _Bit;
+        auto __old = __ref_count_.fetch_and(~__mask, std::memory_order_acq_rel);
+        return static_cast<__bits_t>(__old);
     }
 };
 
 STDEXEC_PRAGMA_POP()
 
-template <class _Ty>
+template <class _Ty, std::size_t _ReservedBits /* = 0ul */>
 class __intrusive_ptr
 {
     using _UncvTy = std::remove_cv_t<_Ty>;
-    friend struct __make_intrusive_t<_Ty>;
-    friend struct __enable_intrusive_from_this<_UncvTy>;
+    using __enable_intrusive_t =
+        __enable_intrusive_from_this<_UncvTy, _ReservedBits>;
+    friend _Ty;
+    friend struct __make_intrusive_t<_Ty, _ReservedBits>;
+    friend struct __enable_intrusive_from_this<_UncvTy, _ReservedBits>;
 
-    __control_block<_UncvTy>* __data_{nullptr};
+    __control_block<_UncvTy, _ReservedBits>* __data_{nullptr};
 
-    explicit __intrusive_ptr(__control_block<_UncvTy>* __data) noexcept :
+    explicit __intrusive_ptr(
+        __control_block<_UncvTy, _ReservedBits>* __data) noexcept :
         __data_(__data)
     {}
 
@@ -130,6 +199,16 @@
         }
     }
 
+    // For use when types want to take over manual control of the reference
+    // count. Very unsafe, but useful for implementing custom reference
+    // counting.
+    [[nodiscard]] __enable_intrusive_t* __release_() noexcept
+    {
+        auto* __data = std::exchange(__data_, nullptr);
+        return __data ? &__c_upcast<__enable_intrusive_t>(__data->__value())
+                      : nullptr;
+    }
+
   public:
     using element_type = _Ty;
 
@@ -145,7 +224,8 @@
         __inc_ref_();
     }
 
-    __intrusive_ptr(__enable_intrusive_from_this<_Ty>* __that) noexcept :
+    __intrusive_ptr(
+        __enable_intrusive_from_this<_Ty, _ReservedBits>* __that) noexcept :
         __intrusive_ptr(__that ? __that->__intrusive_from_this()
                                : __intrusive_ptr())
     {}
@@ -162,7 +242,8 @@
         return operator=(__intrusive_ptr(__that));
     }
 
-    auto operator=(__enable_intrusive_from_this<_Ty>* __that) noexcept
+    auto operator=(
+        __enable_intrusive_from_this<_Ty, _ReservedBits>* __that) noexcept
         -> __intrusive_ptr&
     {
         return operator=(__that ? __that->__intrusive_from_this()
@@ -217,59 +298,93 @@
     }
 };
 
-template <class _Ty>
-auto __enable_intrusive_from_this<_Ty>::__intrusive_from_this() noexcept
-    -> __intrusive_ptr<_Ty>
+template <class _Ty, std::size_t _ReservedBits>
+auto __enable_intrusive_from_this<
+    _Ty, _ReservedBits>::__intrusive_from_this() noexcept
+    -> __intrusive_ptr<_Ty, _ReservedBits>
 {
-    auto* __data =
-        reinterpret_cast<__control_block<_Ty>*>(static_cast<_Ty*>(this));
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
     __data->__inc_ref_();
-    return __intrusive_ptr<_Ty>{__data};
+    return __intrusive_ptr<_Ty, _ReservedBits>{__data};
 }
 
-template <class _Ty>
-auto __enable_intrusive_from_this<_Ty>::__intrusive_from_this() const noexcept
-    -> __intrusive_ptr<const _Ty>
+template <class _Ty, std::size_t _ReservedBits>
+auto __enable_intrusive_from_this<_Ty, _ReservedBits>::__intrusive_from_this()
+    const noexcept -> __intrusive_ptr<const _Ty, _ReservedBits>
 {
-    auto* __data =
-        reinterpret_cast<__control_block<_Ty>*>(static_cast<const _Ty*>(this));
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
     __data->__inc_ref_();
-    return __intrusive_ptr<const _Ty>{__data};
+    return __intrusive_ptr<const _Ty, _ReservedBits>{__data};
 }
 
-template <class _Ty>
-void __enable_intrusive_from_this<_Ty>::__inc_ref() noexcept
+template <class _Ty, std::size_t _ReservedBits>
+__bits_t<_ReservedBits>
+    __enable_intrusive_from_this<_Ty, _ReservedBits>::__inc_ref() noexcept
 {
-    auto* __data =
-        reinterpret_cast<__control_block<_Ty>*>(static_cast<_Ty*>(this));
-    __data->__inc_ref_();
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
+    return __data->__inc_ref_();
 }
 
-template <class _Ty>
-void __enable_intrusive_from_this<_Ty>::__dec_ref() noexcept
+template <class _Ty, std::size_t _ReservedBits>
+__bits_t<_ReservedBits>
+    __enable_intrusive_from_this<_Ty, _ReservedBits>::__dec_ref() noexcept
 {
-    auto* __data =
-        reinterpret_cast<__control_block<_Ty>*>(static_cast<_Ty*>(this));
-    __data->__dec_ref_();
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
+    return __data->__dec_ref_();
 }
 
-template <class _Ty>
+template <class _Ty, std::size_t _ReservedBits>
+template <std::size_t _Bit>
+bool __enable_intrusive_from_this<_Ty, _ReservedBits>::__is_set() const noexcept
+{
+    auto* __data = reinterpret_cast<const __control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
+    return __data->template __is_set_<_Bit>();
+}
+
+template <class _Ty, std::size_t _ReservedBits>
+template <std::size_t _Bit>
+__bits_t<_ReservedBits>
+    __enable_intrusive_from_this<_Ty, _ReservedBits>::__set_bit() noexcept
+{
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
+    return __data->template __set_bit_<_Bit>();
+}
+
+template <class _Ty, std::size_t _ReservedBits>
+template <std::size_t _Bit>
+__bits_t<_ReservedBits>
+    __enable_intrusive_from_this<_Ty, _ReservedBits>::__clear_bit() noexcept
+{
+    auto* __data = reinterpret_cast<__control_block<_Ty, _ReservedBits>*>(
+        &__c_downcast<_Ty>(*this));
+    return __data->template __clear_bit_<_Bit>();
+}
+
+template <class _Ty, std::size_t _ReservedBits>
 struct __make_intrusive_t
 {
     template <class... _Us>
         requires constructible_from<_Ty, _Us...>
-    auto operator()(_Us&&... __us) const -> __intrusive_ptr<_Ty>
+    auto operator()(_Us&&... __us) const -> __intrusive_ptr<_Ty, _ReservedBits>
     {
         using _UncvTy = std::remove_cv_t<_Ty>;
-        return __intrusive_ptr<_Ty>{
-            ::new __control_block<_UncvTy>{static_cast<_Us&&>(__us)...}};
+        return __intrusive_ptr<_Ty, _ReservedBits>{
+            ::new __control_block<_UncvTy, _ReservedBits>{
+                static_cast<_Us&&>(__us)...}};
     }
 };
 } // namespace __ptr
 
 using __ptr::__enable_intrusive_from_this;
 using __ptr::__intrusive_ptr;
-template <class _Ty>
-inline constexpr __ptr::__make_intrusive_t<_Ty> __make_intrusive{};
+template <class _Ty, std::size_t _ReservedBits = 0ul>
+inline constexpr __ptr::__make_intrusive_t<_Ty, _ReservedBits>
+    __make_intrusive{};
 
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
index dbcccf4..dc3f1c3 100644
--- a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021-2022 Facebook, Inc. and its affiliates
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_slist.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_slist.hpp
new file mode 100644
index 0000000..8d3e03e
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_slist.hpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 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"
+
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+
+namespace stdexec
+{
+namespace __slist
+{
+template <auto _Next>
+class __intrusive_slist;
+
+template <class _Item, _Item* _Item::*_Next>
+class __intrusive_slist<_Next>
+{
+  public:
+    __intrusive_slist() noexcept = default;
+
+    __intrusive_slist(__intrusive_slist&& __other) noexcept :
+        __head_(std::exchange(__other.__head_, nullptr))
+    {}
+
+    __intrusive_slist(_Item* __head) noexcept : __head_(__head) {}
+
+    auto swap(__intrusive_slist& __other) noexcept -> void
+    {
+        std::swap(__head_, __other.__head_);
+    }
+
+    auto operator=(__intrusive_slist __other) noexcept -> __intrusive_slist&
+    {
+        swap(__other);
+        return *this;
+    }
+
+    [[nodiscard]] auto empty() const noexcept -> bool
+    {
+        return __head_ == nullptr;
+    }
+
+    auto front() const noexcept -> _Item*
+    {
+        return __head_;
+    }
+
+    void clear() noexcept
+    {
+        __head_ = nullptr;
+    }
+
+    [[nodiscard]] auto pop_front() noexcept -> _Item*
+    {
+        STDEXEC_ASSERT(!empty());
+        return std::exchange(__head_, __head_->*_Next);
+    }
+
+    void push_front(_Item* __item) noexcept
+    {
+        STDEXEC_ASSERT(__item != nullptr);
+        __item->*_Next = std::exchange(__head_, __item);
+    }
+
+    [[nodiscard]] _Item* remove(_Item* __item) noexcept
+    {
+        STDEXEC_ASSERT(__item != nullptr);
+        if (__head_ == __item)
+        {
+            return pop_front();
+        }
+
+        for (_Item* __current : *this)
+        {
+            if (__current->*_Next == __item)
+            {
+                __current->*_Next = __item->*_Next;
+                return __item;
+            }
+        }
+
+        return nullptr;
+    }
+
+    struct iterator
+    {
+        using iterator_category = std::forward_iterator_tag;
+        using difference_type = std::ptrdiff_t;
+        using value_type = _Item*;
+        using reference = _Item*;
+        using pointer = _Item**;
+
+        _Item* __item_ = nullptr;
+
+        iterator() noexcept = default;
+
+        explicit iterator(_Item* __item) noexcept : __item_(__item) {}
+
+        [[nodiscard]] auto operator*() const noexcept -> _Item*
+        {
+            STDEXEC_ASSERT(__item_ != nullptr);
+            return __item_;
+        }
+
+        [[nodiscard]] auto operator->() const noexcept -> _Item**
+        {
+            STDEXEC_ASSERT(__item_ != nullptr);
+            return &__item_;
+        }
+
+        auto operator++() noexcept -> iterator&
+        {
+            STDEXEC_ASSERT(__item_ != nullptr);
+            __item_ = __item_->*_Next;
+            return *this;
+        }
+
+        auto operator++(int) noexcept -> iterator
+        {
+            iterator __result = *this;
+            ++*this;
+            return __result;
+        }
+
+        auto operator==(const iterator&) const noexcept -> bool = default;
+    };
+
+    [[nodiscard]] auto begin() const noexcept -> iterator
+    {
+        return iterator(__head_);
+    }
+
+    [[nodiscard]] auto end() const noexcept -> iterator
+    {
+        return iterator(nullptr);
+    }
+
+  private:
+    _Item* __head_ = nullptr;
+};
+} // namespace __slist
+
+using __slist::__intrusive_slist;
+
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__just.hpp b/include/sdbusplus/async/stdexec/__detail/__just.hpp
new file mode 100644
index 0000000..767bbd4
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__just.hpp
@@ -0,0 +1,119 @@
+/*
+ * 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 "__basic_sender.hpp"
+#include "__completion_signatures.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__type_traits.hpp"
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.factories]
+namespace __just
+{
+template <class _JustTag>
+struct __impl : __sexpr_defaults
+{
+    using __tag_t = typename _JustTag::__tag_t;
+
+    static constexpr auto get_completion_signatures =
+        []<class _Sender>(_Sender&&, auto&&...) noexcept {
+        static_assert(sender_expr_for<_Sender, _JustTag>);
+        return completion_signatures<
+            __mapply<__qf<__tag_t>, __decay_t<__data_of<_Sender>>>>{};
+    };
+
+    static constexpr auto start =
+        []<class _State, class _Receiver>(_State& __state,
+                                          _Receiver& __rcvr) noexcept -> void {
+        __state.apply(
+            [&]<class... _Ts>(_Ts&... __ts) noexcept {
+            __tag_t()(static_cast<_Receiver&&>(__rcvr),
+                      static_cast<_Ts&&>(__ts)...);
+        },
+            __state);
+    };
+};
+
+struct just_t
+{
+    using __tag_t = set_value_t;
+
+    template <__movable_value... _Ts>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Ts&&... __ts) const
+        noexcept((__nothrow_decay_copyable<_Ts> && ...))
+    {
+        return __make_sexpr<just_t>(__tuple{static_cast<_Ts&&>(__ts)...});
+    }
+};
+
+struct just_error_t
+{
+    using __tag_t = set_error_t;
+
+    template <__movable_value _Error>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()(_Error&& __err) const
+        noexcept(__nothrow_decay_copyable<_Error>)
+    {
+        return __make_sexpr<just_error_t>(
+            __tuple{static_cast<_Error&&>(__err)});
+    }
+};
+
+struct just_stopped_t
+{
+    using __tag_t = set_stopped_t;
+
+    template <class _Tag = just_stopped_t>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto operator()() const noexcept
+    {
+        return __make_sexpr<_Tag>(__tuple{});
+    }
+};
+} // namespace __just
+
+using __just::just_error_t;
+using __just::just_stopped_t;
+using __just::just_t;
+
+template <>
+struct __sexpr_impl<just_t> : __just::__impl<just_t>
+{};
+
+template <>
+struct __sexpr_impl<just_error_t> : __just::__impl<just_error_t>
+{};
+
+template <>
+struct __sexpr_impl<just_stopped_t> : __just::__impl<just_stopped_t>
+{};
+
+inline constexpr just_t just{};
+inline constexpr just_error_t just_error{};
+inline constexpr just_stopped_t just_stopped{};
+} // namespace stdexec
+
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__let.hpp b/include/sdbusplus/async/stdexec/__detail/__let.hpp
new file mode 100644
index 0000000..e72a452
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__let.hpp
@@ -0,0 +1,622 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__inline_scheduler.hpp"
+#include "__meta.hpp"
+#include "__receiver_ref.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+#include "__variant.hpp"
+
+#include <exception>
+
+namespace stdexec
+{
+//////////////////////////////////////////////////////////////////////////////
+// [exec.let]
+namespace __let
+{
+// A dummy scheduler that is used by the metaprogramming below when the input
+// sender doesn't have a completion scheduler.
+struct __unknown_scheduler
+{
+    struct __env
+    {
+        static constexpr bool query(__is_scheduler_affine_t) noexcept
+        {
+            return true;
+        }
+
+        constexpr auto
+            query(get_completion_scheduler_t<set_value_t>) const noexcept
+        {
+            return __unknown_scheduler{};
+        }
+    };
+
+    struct __sender
+    {
+        using sender_concept = sender_t;
+
+        constexpr auto get_env() const noexcept -> __env
+        {
+            return __env();
+        }
+    };
+
+    auto schedule() const noexcept
+    {
+        return __sender();
+    }
+
+    bool operator==(const __unknown_scheduler&) const noexcept = default;
+};
+
+inline constexpr auto __get_rcvr =
+    [](auto& __op_state) noexcept -> decltype(auto) {
+    return (__op_state.__rcvr_);
+};
+
+inline constexpr auto __get_env =
+    [](auto& __op_state) noexcept -> decltype(auto) {
+    return __op_state.__state_.__get_env(__op_state.__rcvr_);
+};
+
+template <class _Set, class _Domain = dependent_domain>
+struct __let_t;
+
+template <class _Set>
+inline constexpr __mstring __in_which_let_msg{
+    "In stdexec::let_value(Sender, Function)..."};
+
+template <>
+inline constexpr __mstring __in_which_let_msg<set_error_t>{
+    "In stdexec::let_error(Sender, Function)..."};
+
+template <>
+inline constexpr __mstring __in_which_let_msg<set_stopped_t>{
+    "In stdexec::let_stopped(Sender, Function)..."};
+
+template <class _Set>
+using __on_not_callable = __callable_error<__in_which_let_msg<_Set>>;
+
+template <class _Receiver, class _Scheduler>
+struct __receiver_with_sched
+{
+    using receiver_concept = receiver_t;
+    _Receiver __rcvr_;
+    _Scheduler __sched_;
+
+    template <class... _As>
+    void set_value(_As&&... __as) noexcept
+    {
+        stdexec::set_value(static_cast<_Receiver&&>(__rcvr_),
+                           static_cast<_As&&>(__as)...);
+    }
+
+    template <class _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        stdexec::set_error(static_cast<_Receiver&&>(__rcvr_),
+                           static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+    {
+        stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr_));
+    }
+
+    auto get_env() const noexcept
+    {
+        return __env::__join(
+            prop{get_scheduler, __sched_},
+            __env::__without(stdexec::get_env(__rcvr_), get_domain));
+    }
+};
+
+template <class _Receiver, class _Scheduler>
+__receiver_with_sched(_Receiver, _Scheduler)
+    -> __receiver_with_sched<_Receiver, _Scheduler>;
+
+// If the input sender knows its completion scheduler, make it the current
+// scheduler in the environment seen by the result sender.
+template <class _Scheduler, class _Env>
+using __result_env_t =
+    __if_c<__is_scheduler_affine<schedule_result_t<_Scheduler>>, _Env,
+           __env::__join_t< //
+               prop<get_scheduler_t, _Scheduler>,
+               __env::__without_t<_Env, get_domain_t>>>;
+
+template <__mstring _Where, __mstring _What>
+struct _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_
+{};
+
+#if STDEXEC_NVHPC()
+template <class _Sender, class _Set, class... _Env>
+struct __bad_result_sender_
+{
+    using __t = __mexception<
+        _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_<
+            __in_which_let_msg<_Set>,
+            "The function must return a valid sender for the current environment"_mstr>,
+        _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>...>;
+};
+template <class _Sender, class _Set, class... _Env>
+using __bad_result_sender = __t<__bad_result_sender_<_Sender, _Set, _Env...>>;
+#else
+template <class _Sender, class _Set, class... _Env>
+using __bad_result_sender = __mexception<
+    _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_<
+        __in_which_let_msg<_Set>,
+        "The function must return a valid sender for the current environment"_mstr>,
+    _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>...>;
+#endif
+
+template <class _Sender, class... _Env>
+concept __potentially_valid_sender_in =
+    sender_in<_Sender, _Env...> || (sender<_Sender> && (sizeof...(_Env) == 0));
+
+template <class _Set, class _Sender, class... _Env>
+using __ensure_sender = //
+    __minvoke_if_c<__potentially_valid_sender_in<_Sender, _Env...>,
+                   __q<__midentity>,
+                   __mbind_back_q<__bad_result_sender, _Set, _Env...>, _Sender>;
+
+// A metafunction that computes the result sender type for a given set of
+// argument types
+template <class _Set, class _Fun, class _Sched, class... _Env>
+struct __result_sender_fn
+{
+    template <class... _Args>
+    using __f = //
+        __meval<
+            __ensure_sender, _Set,
+            __mcall<__mtry_catch_q<__call_result_t, __on_not_callable<_Set>>,
+                    _Fun, __decay_t<_Args>&...>,
+            __result_env_t<_Sched, _Env>...>;
+};
+
+// The receiver that gets connected to the result sender is the input receiver,
+// possibly augmented with the input sender's completion scheduler (which is
+// where the result sender will be started).
+template <class _Receiver, class _Scheduler>
+using __result_receiver_t =
+    __if_c<__is_scheduler_affine<schedule_result_t<_Scheduler>>, _Receiver,
+           __receiver_with_sched<_Receiver, _Scheduler>>;
+
+template <class _ResultSender, class _Scheduler, class... _Env>
+using __receiver_ref_t = //
+    __meval<__any_::__receiver_ref,
+            __completion_signatures_of_t<_ResultSender,
+                                         __result_env_t<_Scheduler, _Env>...>,
+            __result_env_t<_Scheduler, _Env>...>;
+
+template <class _ResultSender, class _Scheduler, class _Receiver>
+concept __needs_receiver_ref =
+    __nothrow_connectable<
+        _ResultSender,
+        __receiver_ref_t<_ResultSender, _Scheduler, env_of_t<_Receiver>>> &&
+    !__nothrow_connectable<_ResultSender,
+                           __result_receiver_t<_Receiver, _Scheduler>>;
+
+template <class _Sender, class _Receiver>
+using __nothrow_connectable_t =
+    __mbool<__nothrow_connectable<_Sender, _Receiver>>;
+
+template <class _ResultSender, class _Scheduler, class... _Env>
+using __nothrow_connectable_receiver_ref_t =
+    __meval<__nothrow_connectable_t, _ResultSender,
+            __receiver_ref_t<_ResultSender, _Scheduler, _Env...>>;
+
+template <class _ResultSender, class _Scheduler, class _Receiver>
+using __checked_result_receiver_t = //
+    __if_c<__needs_receiver_ref<_ResultSender, _Scheduler, _Receiver>,
+           __receiver_ref_t<_ResultSender, _Scheduler, env_of_t<_Receiver>>,
+           __result_receiver_t<_Receiver, _Scheduler>>;
+
+template <class _ResultSender, class _Scheduler, class _Receiver>
+using __op_state_t = connect_result_t<
+    _ResultSender,
+    __checked_result_receiver_t<_ResultSender, _Scheduler, _Receiver>>;
+
+template <class _SetTag, class _Fun, class _Sched, class... _Env>
+struct __transform_signal_fn
+{
+    template <class... _Args>
+    using __nothrow_connect =
+        __mand<__mbool<(__nothrow_decay_copyable<_Args> && ...) &&
+                       __nothrow_callable<_Fun, _Args...>>,
+               __nothrow_connectable_receiver_ref_t<
+                   __mcall<__result_sender_fn<_SetTag, _Fun, _Sched, _Env...>,
+                           _Args...>,
+                   _Sched, _Env...>>;
+
+    template <class... _Args>
+    using __f = //
+        __mcall<__mtry_q<__concat_completion_signatures>,
+                __completion_signatures_of_t<
+                    __mcall<__result_sender_fn<_SetTag, _Fun, _Sched, _Env...>,
+                            _Args...>,
+                    __result_env_t<_Sched, _Env>...>,
+                __eptr_completion_if_t<__nothrow_connect<_Args...>>>;
+};
+
+template <class _Sender, class _Set>
+using __completion_sched =
+    __query_result_or_t<get_completion_scheduler_t<_Set>, env_of_t<_Sender>,
+                        __unknown_scheduler>;
+
+template <class _LetTag, class _Fun, class _CvrefSender, class... _Env>
+using __completions = //
+    __gather_completion_signatures<
+        __completion_signatures_of_t<_CvrefSender, _Env...>, __t<_LetTag>,
+        __transform_signal_fn<__t<_LetTag>, _Fun,
+                              __completion_sched<_CvrefSender, __t<_LetTag>>,
+                              _Env...>::template __f,
+        __sigs::__default_completion,
+        __mtry_q<__concat_completion_signatures>::__f>;
+
+template <__mstring _Where, __mstring _What>
+struct _NO_COMMON_DOMAIN_
+{};
+
+template <class _Set>
+using __no_common_domain_t = //
+    _NO_COMMON_DOMAIN_<
+        __in_which_let_msg<_Set>,
+        "The senders returned by Function do not all share a common domain"_mstr>;
+
+template <class _Set>
+struct __try_common_domain_fn
+{
+    struct __error_fn
+    {
+        template <class... _Senders>
+        using __f = __mexception<__no_common_domain_t<_Set>,
+                                 _WITH_SENDERS_<_Senders...>>;
+    };
+
+    template <class... _Senders>
+    using __f = __mcall<__mtry_catch_q<__domain::__common_domain_t, __error_fn>,
+                        _Senders...>;
+};
+
+// Compute all the domains of all the result senders and make sure they're all
+// the same
+template <class _Set, class _Child, class _Fun, class _Env, class _Sched>
+using __result_domain_t = //
+    __gather_completions<_Set, __completion_signatures_of_t<_Child, _Env>,
+                         __result_sender_fn<_Set, _Fun, _Sched, _Env>,
+                         __try_common_domain_fn<_Set>>;
+
+template <class _LetTag, class _Env>
+auto __mk_transform_env_fn(_Env&& __env) noexcept
+{
+    using _Set = __t<_LetTag>;
+    return [&]<class _Fun, class _Child>(__ignore, _Fun&&,
+                                         _Child&& __child) -> decltype(auto) {
+        using __completions_t = __completion_signatures_of_t<_Child, _Env>;
+        if constexpr (__merror<__completions_t>)
+        {
+            return __completions_t();
+        }
+        else
+        {
+            using _Scheduler = __completion_sched<_Child, _Set>;
+            if constexpr (__is_scheduler_affine<schedule_result_t<_Scheduler>>)
+            {
+                return (__env);
+            }
+            else
+            {
+                return __env::__join(
+                    prop{get_scheduler, get_completion_scheduler<_Set>(
+                                            stdexec::get_env(__child))},
+                    __env::__without(static_cast<_Env&&>(__env), get_domain));
+            }
+        }
+    };
+}
+
+template <class _LetTag, class _Env>
+auto __mk_transform_sender_fn(_Env&&) noexcept
+{
+    using _Set = __t<_LetTag>;
+
+    return
+        []<class _Fun, class _Child>(__ignore, _Fun&& __fun, _Child&& __child) {
+        using __completions_t = __completion_signatures_of_t<_Child, _Env>;
+
+        if constexpr (__merror<__completions_t>)
+        {
+            return __completions_t();
+        }
+        else
+        {
+            using _Sched = __completion_sched<_Child, _Set>;
+            using _Domain = __result_domain_t<_Set, _Child, _Fun, _Env, _Sched>;
+
+            if constexpr (__merror<_Domain>)
+            {
+                return _Domain();
+            }
+            else if constexpr (same_as<_Domain, dependent_domain>)
+            {
+                using _Domain2 = __late_domain_of_t<_Child, _Env>;
+                return __make_sexpr<__let_t<_Set, _Domain2>>(
+                    static_cast<_Fun&&>(__fun), static_cast<_Child&&>(__child));
+            }
+            else
+            {
+                static_assert(!same_as<_Domain, __unknown_scheduler>);
+                return __make_sexpr<__let_t<_Set, _Domain>>(
+                    static_cast<_Fun&&>(__fun), static_cast<_Child&&>(__child));
+            }
+        }
+    };
+}
+
+template <class _Receiver, class _Fun, class _Set, class _Sched>
+struct __op_state_for
+{
+    template <class... _Args>
+    using __f = __op_state_t<
+        __mcall<__result_sender_fn<_Set, _Fun, _Sched, env_of_t<_Receiver>>,
+                _Args...>,
+        _Sched, _Receiver>;
+};
+
+template <class _Receiver, class _Fun, class _Set, class _Sched,
+          class... _Tuples>
+struct __let_state
+{
+    using __fun_t = _Fun;
+    using __sched_t = _Sched;
+    using __env_t = __result_env_t<_Sched, env_of_t<_Receiver>>;
+    using __result_variant = __variant_for<__monostate, _Tuples...>;
+    using __op_state_variant = //
+        __variant_for<__monostate,
+                      __mapply<__op_state_for<_Receiver, _Fun, _Set, _Sched>,
+                               _Tuples>...>;
+
+    template <class _ResultSender, class _OpState>
+    auto __get_result_receiver(const _ResultSender&, _OpState& __op_state)
+        -> decltype(auto)
+    {
+        if constexpr (__needs_receiver_ref<_ResultSender, _Sched, _Receiver>)
+        {
+            using __receiver_ref =
+                __receiver_ref_t<_ResultSender, _Sched, env_of_t<_Receiver>>;
+            return __receiver_ref{__op_state, __let::__get_env,
+                                  __let::__get_rcvr};
+        }
+        else
+        {
+            _Receiver& __rcvr = __op_state.__rcvr_;
+            if constexpr (__is_scheduler_affine<schedule_result_t<_Sched>>)
+            {
+                return static_cast<_Receiver&&>(__rcvr);
+            }
+            else
+            {
+                return __receiver_with_sched{static_cast<_Receiver&&>(__rcvr),
+                                             this->__sched_};
+            }
+        }
+    }
+
+    auto __get_env(const _Receiver& __rcvr) const noexcept -> __env_t
+    {
+        if constexpr (__is_scheduler_affine<schedule_result_t<_Sched>>)
+        {
+            return stdexec::get_env(__rcvr);
+        }
+        else
+        {
+            return __env::__join(
+                prop{get_scheduler, __sched_},
+                __env::__without(stdexec::get_env(__rcvr), get_domain));
+        }
+    }
+
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Fun __fun_;
+    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Sched __sched_;
+    __result_variant __args_{};
+    __op_state_variant __op_state3_{};
+};
+
+template <class _Set, class _Domain>
+struct __let_t
+{
+    using __domain_t = _Domain;
+    using __t = _Set;
+
+    template <sender _Sender, __movable_value _Fun>
+    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
+        auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<__let_t<_Set>>(static_cast<_Fun&&>(__fun),
+                                        static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <class _Fun>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Fun __fun) const -> __binder_back<__let_t, _Fun>
+    {
+        return {{static_cast<_Fun&&>(__fun)}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using _Function = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(__let_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender, _Function),
+                tag_invoke_t(__let_t, _Sender, _Function)>;
+
+    template <sender_expr_for<__let_t<_Set>> _Sender, class _Env>
+    static auto transform_env(_Sender&& __sndr, const _Env& __env)
+        -> decltype(auto)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             __mk_transform_env_fn<__let_t<_Set>>(__env));
+    }
+
+    template <sender_expr_for<__let_t<_Set>> _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+        -> decltype(auto)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             __mk_transform_sender_fn<__let_t<_Set>>(__env));
+    }
+};
+
+template <class _Set, class _Domain>
+struct __let_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Child>(__ignore, const _Child& __child) noexcept {
+        return __env::__join(prop{get_domain, _Domain()},
+                             stdexec::get_env(__child));
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept
+        -> __completions<__let_t<_Set, _Domain>, __data_of<_Self>,
+                         __child_of<_Self>, _Env...> {
+        static_assert(sender_expr_for<_Self, __let_t<_Set, _Domain>>);
+        return {};
+    };
+
+    static constexpr auto get_state = //
+        []<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver&) {
+        static_assert(sender_expr_for<_Sender, __let_t<_Set, _Domain>>);
+        using _Fun = __data_of<_Sender>;
+        using _Child = __child_of<_Sender>;
+        using _Sched = __completion_sched<_Child, _Set>;
+        using __mk_let_state =
+            __mbind_front_q<__let_state, _Receiver, _Fun, _Set, _Sched>;
+
+        using __let_state_t =
+            __gather_completions_of<_Set, _Child, env_of_t<_Receiver>,
+                                    __q<__decayed_tuple>, __mk_let_state>;
+
+        return __sndr.apply(static_cast<_Sender&&>(__sndr),
+                            [&]<class _Fn, class _Child>(__ignore, _Fn&& __fn,
+                                                         _Child&& __child) {
+            _Sched __sched = query_or(get_completion_scheduler<_Set>,
+                                      stdexec::get_env(__child),
+                                      __unknown_scheduler());
+            return __let_state_t{static_cast<_Fn&&>(__fn), __sched};
+        });
+    };
+
+    template <class _State, class _OpState, class... _As>
+    static void __bind_(_State& __state, _OpState& __op_state, _As&&... __as)
+    {
+        auto& __args = __state.__args_.emplace_from(
+            __tup::__mktuple, static_cast<_As&&>(__as)...);
+        auto __sndr2 = __args.apply(std::move(__state.__fun_), __args);
+        auto __rcvr2 = __state.__get_result_receiver(__sndr2, __op_state);
+        auto& __op2 = __state.__op_state3_.emplace_from(
+            stdexec::connect, std::move(__sndr2), std::move(__rcvr2));
+        stdexec::start(__op2);
+    }
+
+    template <class _OpState, class... _As>
+    static void __bind(_OpState& __op_state, _As&&... __as) noexcept
+    {
+        using _State = decltype(__op_state.__state_);
+        using _Receiver = decltype(__op_state.__rcvr_);
+        using _Fun = typename _State::__fun_t;
+        using _Sched = typename _State::__sched_t;
+        using _ResultSender =
+            __mcall<__result_sender_fn<_Set, _Fun, _Sched, env_of_t<_Receiver>>,
+                    _As...>;
+
+        _State& __state = __op_state.__state_;
+        _Receiver& __rcvr = __op_state.__rcvr_;
+
+        if constexpr ((__nothrow_decay_copyable<_As> && ...) &&
+                      __nothrow_callable<_Fun, _As...> &&
+                      __v<__nothrow_connectable_receiver_ref_t<
+                          _ResultSender, _Sched, env_of_t<_Receiver>>>)
+        {
+            __bind_(__state, __op_state, static_cast<_As&&>(__as)...);
+        }
+        else
+        {
+            try
+            {
+                __bind_(__state, __op_state, static_cast<_As&&>(__as)...);
+            }
+            catch (...)
+            {
+                using _Receiver = decltype(__op_state.__rcvr_);
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                   std::current_exception());
+            }
+        }
+    }
+
+    static constexpr auto complete = //
+        []<class _OpState, class _Tag, class... _As>(
+            __ignore, _OpState& __op_state, _Tag,
+            _As&&... __as) noexcept -> void {
+        if constexpr (__same_as<_Tag, _Set>)
+        {
+            __bind(__op_state, static_cast<_As&&>(__as)...);
+        }
+        else
+        {
+            using _Receiver = decltype(__op_state.__rcvr_);
+            _Tag()(static_cast<_Receiver&&>(__op_state.__rcvr_),
+                   static_cast<_As&&>(__as)...);
+        }
+    };
+};
+} // namespace __let
+
+using let_value_t = __let::__let_t<set_value_t>;
+inline constexpr let_value_t let_value{};
+
+using let_error_t = __let::__let_t<set_error_t>;
+inline constexpr let_error_t let_error{};
+
+using let_stopped_t = __let::__let_t<set_stopped_t>;
+inline constexpr let_stopped_t let_stopped{};
+
+template <class _Set, class _Domain>
+struct __sexpr_impl<__let::__let_t<_Set, _Domain>> :
+    __let::__let_impl<_Set, _Domain>
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__meta.hpp b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
index a926d68..a309bec 100644
--- a/include/sdbusplus/async/stdexec/__detail/__meta.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -18,8 +18,10 @@
 #include "__concepts.hpp"
 #include "__config.hpp"
 #include "__type_traits.hpp"
+#include "__utility.hpp"
 
 #include <cassert>
+#include <compare>
 #include <cstddef>
 #include <exception>
 #include <type_traits>
@@ -27,61 +29,18 @@
 
 namespace stdexec
 {
-
-template <class...>
-struct __undefined;
-
-struct __
-{};
-
-struct __ignore
-{
-    __ignore() = default;
-
-    STDEXEC_ATTRIBUTE((always_inline))
-    constexpr __ignore(auto&&...) noexcept {}
-};
-
-struct __none_such
-{};
-
-namespace
-{
-struct __anon
-{};
-} // namespace
-
-struct __immovable
-{
-    __immovable() = default;
-
-  private:
-    STDEXEC_IMMOVABLE(__immovable);
-};
-
-struct __move_only
-{
-    __move_only() = default;
-
-    __move_only(__move_only&&) noexcept = default;
-    auto operator=(__move_only&&) noexcept -> __move_only& = default;
-
-    __move_only(const __move_only&) = delete;
-    auto operator=(const __move_only&) -> __move_only& = delete;
-};
-
 template <class _Tp>
 using __t = typename _Tp::__t;
 
-template <bool _Bp>
-using __mbool = std::bool_constant<_Bp>;
-
 template <class _Ty>
 struct __mtype
 {
     using __t = _Ty;
 };
 
+template <class...>
+inline constexpr bool __mnever = false;
+
 template <auto _Value>
 using __mtypeof = decltype(_Value);
 
@@ -91,14 +50,49 @@
 template <class _Tp>
 using __midentity = _Tp;
 
+template <auto _Np>
+struct __mconstant
+{
+    using type = __mconstant;
+    using value_type = __mtypeof<_Np>;
+    static constexpr auto value = _Np;
+
+    constexpr operator value_type() const noexcept
+    {
+        return value;
+    }
+
+    constexpr auto operator()() const noexcept -> value_type
+    {
+        return value;
+    }
+};
+
+// Because of nvc++ nvbugs#4679848, we can't make __mbool a simple alias for
+// __mconstant, and because of nvc++ nvbugs#4668709 it can't be a simple alias
+// for std::bool_constant, either. :-( template <bool _Bp> using __mbool =
+// __mconstant<_Bp>;
+
+template <bool _Bp>
+struct __mbool : std::bool_constant<_Bp>
+{};
+
+using __mtrue = __mbool<true>;
+using __mfalse = __mbool<false>;
+
+// nvbugs#4679848 and nvbugs#4668709 also preclude __mconstant from representing
+// a compile-time size_t.
+enum class __muchar : unsigned char
+{
+};
+
+#if STDEXEC_MSVC()
 template <std::size_t _Np>
-using __msize_t = char[_Np + 1];
-
-template <auto _Np>
-struct __mconstant_;
-
-template <auto _Np>
-using __mconstant = __mconstant_<_Np>*;
+using __msize_t = __mconstant<_Np>;
+#else
+template <std::size_t _Np>
+using __msize_t = __muchar (*)[_Np + 1]; // +1 to avoid zero-size array
+#endif
 
 template <class _Tp, class _Up>
 using __mfirst = _Tp;
@@ -106,6 +100,9 @@
 template <class _Tp, class _Up>
 using __msecond = _Up;
 
+template <class...>
+struct __undefined;
+
 template <class _Tp>
 extern const __undefined<_Tp> __v;
 
@@ -113,6 +110,8 @@
     requires __typename<__mtypeof<_Tp::value>>
 inline constexpr auto __v<_Tp> = _Tp::value;
 
+// These specializations exist because instantiating a variable template is
+// cheaper than instantiating a class template.
 template <class _Tp, class _Up>
 inline constexpr bool __v<std::is_same<_Tp, _Up>> = false;
 
@@ -123,98 +122,171 @@
 inline constexpr _Tp __v<std::integral_constant<_Tp, _Ip>> = _Ip;
 
 template <auto _Np>
-inline constexpr __mtypeof<_Np> __v<__mconstant<_Np>> = _Np;
-
-template <std::size_t _Ip>
-inline constexpr std::size_t __v<char[_Ip]> = _Ip - 1;
-
-template <std::size_t... _Is>
-using __indices = std::index_sequence<_Is...>*;
+inline constexpr auto __v<__mconstant<_Np>> = _Np;
 
 template <std::size_t _Np>
-using __make_indices = std::make_index_sequence<_Np>*;
+inline constexpr std::size_t __v<__muchar (*)[_Np]> =
+    _Np - 1; // see definition of __msize_t
+
+namespace __pack
+{
+template <std::size_t... _Is>
+struct __t;
+} // namespace __pack
+
+template <std::size_t... _Is>
+using __indices = __pack::__t<_Is...>*;
+
+#if STDEXEC_MSVC()
+namespace __pack
+{
+template <class _Ty, _Ty... _Is>
+struct __idx;
+
+template <class>
+extern int __mkidx;
+
+template <std::size_t... _Is>
+extern __indices<_Is...> __mkidx<__idx<std::size_t, _Is...>>;
+} // namespace __pack
+
+template <std::size_t _Np>
+using __make_indices = //
+    decltype(__pack::__mkidx<
+             __make_integer_seq<__pack::__idx, std::size_t, _Np>>);
+#elif STDEXEC_HAS_BUILTIN(__make_integer_seq)
+namespace __pack
+{
+template <class _Ty, _Ty... _Is>
+using __idx = __indices<_Is...>;
+} // namespace __pack
+
+template <std::size_t _Np>
+using __make_indices = __make_integer_seq<__pack::__idx, std::size_t, _Np>;
+#elif STDEXEC_HAS_BUILTIN(__integer_pack)
+namespace __pack
+{
+template <std::size_t _Np>
+extern __indices<__integer_pack(_Np)...> __make_indices;
+} // namespace __pack
+
+template <std::size_t _Np>
+using __make_indices = decltype(__pack::__make_indices<_Np>);
+#else
+namespace __pack
+{
+template <std::size_t... _Is>
+auto __mk_indices(__indices<0, _Is...>) -> __indices<_Is...>;
+
+template <std::size_t _Np, class = char[_Np], std::size_t... _Is>
+auto __mk_indices(__indices<_Np, _Is...>)
+    -> decltype(__mk_indices(__indices<_Np - 1, 0, (_Is + 1)...>{}));
+} // namespace __pack
+
+template <std::size_t _Np>
+using __make_indices = decltype(__pack::__mk_indices(__indices<_Np>{}));
+#endif
 
 template <class... _Ts>
 using __indices_for = __make_indices<sizeof...(_Ts)>;
 
-template <class _Char>
-concept __mchar = __same_as<_Char, char>;
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_MSVC(4293)
+
+constexpr std::size_t __mpow2(std::size_t __size) noexcept
+{
+    --__size;
+    __size |= __size >> 1;
+    __size |= __size >> 2;
+    __size |= __size >> 4;
+    __size |= __size >> 8;
+    if constexpr (sizeof(__size) >= 4)
+        __size |= __size >> 16;
+    if constexpr (sizeof(__size) >= 8)
+        __size |= __size >> 32;
+    return ++__size;
+}
+
+STDEXEC_PRAGMA_POP()
 
 template <std::size_t _Len>
-class __mstring
+struct __mstring
 {
-    template <std::size_t... _Is>
-    constexpr __mstring(const char (&__str)[_Len], __indices<_Is...>) noexcept :
-        __what_{__str[_Is]...}
+#if STDEXEC_NVHPC()
+    template <std::size_t _Ny, std::size_t... _Is>
+    constexpr __mstring(const char (&__str)[_Ny], __indices<_Is...>) noexcept :
+        __what_{(_Is < _Ny ? __str[_Is] : '\0')...}
     {}
 
-  public:
-    constexpr __mstring(const char (&__str)[_Len]) noexcept :
+    template <std::size_t _Ny>
+    constexpr __mstring(const char (&__str)[_Ny], int = 0) noexcept :
         __mstring{__str, __make_indices<_Len>{}}
     {}
-
-    template <__mchar... _Char>
-        requires(sizeof...(_Char) == _Len)
-    constexpr __mstring(_Char... __chars) noexcept : __what_{__chars...}
-    {}
+#else
+    template <std::size_t _Ny>
+    constexpr __mstring(const char (&__str)[_Ny], int = 0) noexcept : __what_{}
+    {
+        for (auto __i = 0ull; char __ch : __str)
+        {
+            __what_[__i++] = __ch;
+        }
+    }
+#endif
 
     static constexpr auto __length() noexcept -> std::size_t
     {
         return _Len;
     }
 
-    template <std::size_t... _Is>
-    constexpr auto __equal(__mstring __other, __indices<_Is...>) const noexcept
+    constexpr auto operator==(const __mstring&) const noexcept
+        -> bool = default;
+
+    template <std::size_t _OtherLen>
+    constexpr auto operator==(const __mstring<_OtherLen>&) const noexcept
         -> bool
     {
-        return ((__what_[_Is] == __other.__what_[_Is]) && ...);
+        return false;
     }
 
-    constexpr auto operator==(__mstring __other) const noexcept -> bool
+#if !STDEXEC_NVHPC()
+    constexpr auto operator<=>(const __mstring&) const noexcept
+        -> std::strong_ordering = default;
+#endif
+
+    template <std::size_t _OtherLen>
+    constexpr auto
+        operator<=>(const __mstring<_OtherLen>& __other) const noexcept
+        -> std::strong_ordering
     {
-        return __equal(__other, __make_indices<_Len>());
+        constexpr std::size_t __len = _Len < _OtherLen ? _Len : _OtherLen;
+        for (std::size_t __i = 0; __i < __len; ++__i)
+        {
+            auto __cmp = (__what_[__i] <=> __other.__what_[__i]);
+            if (__cmp != 0)
+            {
+                return __cmp;
+            }
+        }
+        if constexpr (_Len == _OtherLen)
+        {
+            return std::strong_ordering::equal;
+        }
+        return (_Len < _OtherLen) ? std::strong_ordering::less
+                                  : std::strong_ordering::greater;
     }
 
-    const char __what_[_Len];
+    char __what_[_Len];
 };
 
 template <std::size_t _Len>
 __mstring(const char (&__str)[_Len]) -> __mstring<_Len>;
 
+template <std::size_t _Len>
+__mstring(const char (&__str)[_Len], int) -> __mstring<__mpow2(_Len)>;
+
 STDEXEC_PRAGMA_PUSH()
 STDEXEC_PRAGMA_IGNORE_GNU("-Wuser-defined-literals")
 
-#if STDEXEC_NVHPC() && (__EDG_VERSION__ < 604)
-// Use a non-standard extension for older nvc++ releases
-template <__mchar _Char, _Char... _Str>
-[[deprecated("Use _mstr instead")]] constexpr __mstring<sizeof...(_Str)>
-    operator""__csz() noexcept
-{
-    return {_Str...};
-}
-
-// Use a non-standard extension for older nvc++ releases
-template <__mchar _Char, _Char... _Str>
-constexpr __mstring<sizeof...(_Str)> operator""_mstr() noexcept
-{
-    return {_Str...};
-}
-#elif STDEXEC_NVHPC() && (__EDG_VERSION__ < 605)
-// This is to work around an unfiled (by me) EDG bug that fixed in build 605
-template <__mstring _Str>
-[[deprecated("Use _mstr instead")]] constexpr const __mtypeof<_Str>
-    operator""__csz() noexcept
-{
-    return _Str;
-}
-
-// This is to work around an unfiled (by me) EDG bug that fixed in build 605
-template <__mstring _Str>
-constexpr const __mtypeof<_Str> operator""_mstr() noexcept
-{
-    return _Str;
-}
-#else
 // Use a standard user-defined string literal template
 template <__mstring _Str>
 [[deprecated("Use _mstr instead")]] constexpr auto operator""__csz() noexcept
@@ -229,10 +301,19 @@
 {
     return _Str;
 }
-#endif
 
 STDEXEC_PRAGMA_POP()
 
+template <class T>
+constexpr auto __mnameof() noexcept
+{
+#if STDEXEC_MSVC()
+    return __mstring{__FUNCSIG__, 0};
+#else
+    return __mstring{__PRETTY_FUNCTION__, 0};
+#endif
+}
+
 using __msuccess = int;
 
 template <class _What, class... _With>
@@ -245,7 +326,7 @@
     auto operator,(__msuccess) const noexcept -> _ERROR_;
 };
 
-template <__mstring _What>
+template <__mstring... _What>
 struct _WHAT_
 {};
 
@@ -265,15 +346,15 @@
 using __disp = decltype((__msuccess(), ..., __ok_t<_Ts>()));
 
 template <class _Arg>
-concept __ok = __same_as<__ok_t<_Arg>, __msuccess>;
+concept __ok = STDEXEC_IS_SAME(__ok_t<_Arg>, __msuccess);
 
 template <class _Arg>
-concept __merror = !__ok<_Arg>;
+concept __merror = !STDEXEC_IS_SAME(__ok_t<_Arg>, __msuccess);
 
 template <class... _Args>
-concept _Ok = (__ok<_Args> && ...);
+concept _Ok = (STDEXEC_IS_SAME(__ok_t<_Args>, __msuccess) && ...);
 
-template <bool _AllOK>
+template <bool _ArgsOK, bool _FnOK = true>
 struct __i;
 
 #if STDEXEC_NVHPC()
@@ -281,7 +362,9 @@
 // nvc++ does not. So we memoize the type computations by
 // indirecting through a class template specialization.
 template <template <class...> class _Fn, class... _Args>
-using __meval__ = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
+using __meval__ =                  //
+    typename __i<_Ok<_Args...>>    //
+    ::template __g<_Fn, _Args...>; //
 
 template <template <class...> class _Fn, class... _Args>
 struct __meval_
@@ -298,7 +381,10 @@
 using __meval = __t<__meval_<_Fn, _Args...>>;
 
 template <class _Fn, class... _Args>
-using __minvoke__ = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
+using __minvoke__ =                       //
+    typename __i<_Ok<_Args...>, _Ok<_Fn>> //
+    ::template __f<_Fn>                   //
+    ::template __f<_Args...>;             //
 
 template <class _Fn, class... _Args>
 struct __minvoke_
@@ -317,40 +403,89 @@
 #else
 
 template <template <class...> class _Fn, class... _Args>
-using __meval = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
+using __meval =                    //
+    typename __i<_Ok<_Args...>>    //
+    ::template __g<_Fn, _Args...>; //
 
 template <class _Fn, class... _Args>
-using __minvoke = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
+using __minvoke =                         //
+    typename __i<_Ok<_Args...>, _Ok<_Fn>> //
+    ::template __f<_Fn>                   //
+    ::template __f<_Args...>;             //
 
 #endif
 
-template <bool _AllOK>
-struct __i
+template <class _Fn, class... _Args>
+using __mcall = typename _Fn::template __f<_Args...>;
+
+struct __disp_q
+{
+    template <class... _Args>
+    using __f = __disp<_Args...>;
+};
+
+template <>
+struct __i<true, true>
 {
     template <template <class...> class _Fn, class... _Args>
     using __g = _Fn<_Args...>;
 
-    template <class _Fn, class... _Args>
-    using __h = __meval<_Fn::template __f, _Args...>;
+    template <class _Fn>
+    using __f = _Fn;
 };
 
 template <>
-struct __i<false>
+struct __i<false, true>
 {
     template <template <class...> class, class... _Args>
     using __g = __disp<_Args...>;
 
-    template <class _Fn, class...>
-    using __h = _Fn;
+    template <class>
+    using __f = __disp_q;
+};
+
+template <bool _ArgsOK>
+struct __i<_ArgsOK, false>
+{
+    template <class _Fn>
+    using __f = _Fn;
 };
 
 template <template <class...> class _Fn>
 struct __q
 {
     template <class... _Args>
-    using __f = __meval<_Fn, _Args...>;
+    using __f = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
 };
 
+template <template <class...> class _Fn>
+struct __qq
+{
+    template <class... _Args>
+    using __f = _Fn<_Args...>;
+};
+
+template <template <class> class _Fn>
+struct __q1
+{
+    template <class _Ty>
+    using __f = _Fn<_Ty>;
+};
+
+template <template <class, class> class _Fn>
+struct __q2
+{
+    template <class _Ty, class _Uy>
+    using __f = _Fn<_Ty, _Uy>;
+};
+
+template <template <class...> class _Fn>
+using __mtry_q = __q<_Fn>;
+
+template <class _Fn>
+struct __mtry : __mtry_q<_Fn::template __f>
+{};
+
 template <template <class...> class _Fn, class... _Front>
 struct __mbind_front_q
 {
@@ -385,12 +520,12 @@
                                 __ok<__minvoke<_Fn, _Args...>>;
 
 template <class _Fn, class... _Args>
-struct __force_minvoke_
+struct __minvoke_force_
 {
     using __t = __minvoke<_Fn, _Args...>;
 };
 template <class _Fn, class... _Args>
-using __force_minvoke = __t<__force_minvoke_<_Fn, _Args...>>;
+using __minvoke_force = __t<__minvoke_force_<_Fn, _Args...>>;
 
 template <class _Fn, class... _Args>
 struct __mdefer_
@@ -527,8 +662,11 @@
 template <class _Ty, class... _Default>
 using __msuccess_or_t = __if_c<__ok<_Ty>, _Ty, _Default...>;
 
+template <class _Ty, class... _Default>
+using __merror_or_t = __if_c<__merror<_Ty>, _Ty, _Default...>;
+
 template <class _Fn, class _Continuation = __q<__types>>
-struct __transform
+struct __mtransform
 {
     template <class... _Args>
     using __f = __minvoke<_Continuation, __minvoke<_Fn, _Args>...>;
@@ -557,102 +695,97 @@
         __minvoke<__mfold_right_<sizeof...(_Args) == 0>, _Fn, _Init, _Args...>;
 };
 
-template <class _Continuation, class... _As>
-struct __mconcat_
-{};
-
-template <class _Continuation, class... _As>
-    requires(sizeof...(_As) == 0) && __minvocable<_Continuation, _As...>
-struct __mconcat_<_Continuation, _As...>
+template <bool>
+struct __mfold_left_
 {
-    using __t = __minvoke<_Continuation, _As...>;
+    template <class _Fn, class _State, class _Head, class... _Tail>
+    using __f = __minvoke<
+        _Fn,
+        __mcall<__mfold_left_<sizeof...(_Tail) == 0>, _Fn, _State, _Tail...>,
+        _Head>;
 };
 
-template <class _Continuation, template <class...> class _Ap, class... _As>
-    requires __minvocable<_Continuation, _As...>
-struct __mconcat_<_Continuation, _Ap<_As...>>
-{
-    using __t = __minvoke<_Continuation, _As...>;
+template <>
+struct __mfold_left_<true>
+{ // empty pack
+    template <class _Fn, class _State, class...>
+    using __f = _State;
 };
 
-template <               //
-    class _Continuation, //
-    template <class...> class _Ap,
-    class... _As,        //
-    template <class...> class _Bp, class... _Bs>
-    requires __minvocable<_Continuation, _As..., _Bs...>
-struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>>
-{
-    using __t = __minvoke<_Continuation, _As..., _Bs...>;
-};
-
-template <               //
-    class _Continuation, //
-    template <class...> class _Ap,
-    class... _As,        //
-    template <class...> class _Bp,
-    class... _Bs,        //
-    template <class...> class _Cp, class... _Cs>
-    requires __minvocable<_Continuation, _As..., _Bs..., _Cs...>
-struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>>
-{
-    using __t = __minvoke<_Continuation, _As..., _Bs..., _Cs...>;
-};
-
-template <               //
-    class _Continuation, //
-    template <class...> class _Ap,
-    class... _As,        //
-    template <class...> class _Bp,
-    class... _Bs,        //
-    template <class...> class _Cp,
-    class... _Cs,        //
-    template <class...> class _Dp,
-    class... _Ds,        //
-    class... _Tail>
-struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>,
-                  _Dp<_Ds...>, _Tail...> :
-    __mconcat_<_Continuation, __types<_As..., _Bs..., _Cs..., _Ds...>, _Tail...>
-{};
-
-template <class _Continuation = __q<__types>>
-struct __mconcat
+template <class _Init, class _Fn>
+struct __mfold_left
 {
     template <class... _Args>
-    using __f = __t<__mconcat_<_Continuation, _Args...>>;
+    using __f =
+        __minvoke<__mfold_left_<sizeof...(_Args) == 0>, _Fn, _Init, _Args...>;
 };
 
 template <class _Fn>
-struct __curry
+struct __mcurry
 {
     template <class... _Ts>
     using __f = __minvoke<_Fn, _Ts...>;
 };
 
-template <class _Fn, class _Tp>
-struct __uncurry_;
+template <class _Tp>
+struct __muncurry_;
 
-template <__merror _Fn, class _Tp>
-struct __uncurry_<_Fn, _Tp>
+template <template <class...> class _Ap, class... _As>
+struct __muncurry_<_Ap<_As...>>
 {
-    using __t = _Fn;
+    template <class _Fn>
+    using __f = __minvoke<_Fn, _As...>;
 };
 
-template <class _Fn, template <class...> class _Ap, class... _As>
-    requires __minvocable<_Fn, _As...>
-struct __uncurry_<_Fn, _Ap<_As...>>
+template <class _What, class... _With>
+struct __muncurry_<_ERROR_<_What, _With...>>
 {
-    using __t = __minvoke<_Fn, _As...>;
+    template <class _Fn>
+    using __f = _ERROR_<_What, _With...>;
 };
 
 template <class _Fn>
-struct __uncurry
+struct __muncurry
 {
     template <class _Tp>
-    using __f = __t<__uncurry_<_Fn, _Tp>>;
+    using __f = typename __muncurry_<_Tp>::template __f<_Fn>;
 };
+
 template <class _Fn, class _List>
-using __mapply = __minvoke<__uncurry<_Fn>, _List>;
+using __mapply = __minvoke<__muncurry<_Fn>, _List>;
+
+template <bool>
+struct __mconcat_
+{
+    template <class... _Ts, template <class...> class _Ap = __types,
+              class... _As, template <class...> class _Bp = __types,
+              class... _Bs, template <class...> class _Cp = __types,
+              class... _Cs, template <class...> class _Dp = __types,
+              class... _Ds, class... _Tail>
+    static auto __f(__types<_Ts...>*, _Ap<_As...>*, _Bp<_Bs...>* = nullptr,
+                    _Cp<_Cs...>* = nullptr, _Dp<_Ds...>* = nullptr,
+                    _Tail*... __tail)
+        -> decltype(__mconcat_<(sizeof...(_Tail) == 0)>::__f(
+            static_cast<__types<_Ts..., _As..., _Bs..., _Cs..., _Ds...>*>(
+                nullptr),
+            __tail...));
+};
+
+template <>
+struct __mconcat_<true>
+{
+    template <class... _As>
+    static auto __f(__types<_As...>*) -> __types<_As...>;
+};
+
+template <class _Continuation = __qq<__types>>
+struct __mconcat
+{
+    template <class... _Args>
+    using __f = __mapply<_Continuation,
+                         decltype(__mconcat_<(sizeof...(_Args) == 0)>::__f(
+                             {}, static_cast<_Args*>(nullptr)...))>;
+};
 
 struct __msize
 {
@@ -675,38 +808,19 @@
 };
 
 template <class _Tp>
-struct __contains
+struct __mcontains
 {
     template <class... _Args>
     using __f = __mbool<(__same_as<_Tp, _Args> || ...)>;
 };
 
 template <class _Continuation = __q<__types>>
-struct __push_back
+struct __mpush_back
 {
     template <class _List, class _Item>
     using __f = __mapply<__mbind_back<_Continuation, _Item>, _List>;
 };
 
-template <class _Continuation = __q<__types>>
-struct __push_back_unique
-{
-    template <class _List, class _Item>
-    using __f = //
-        __mapply<__if<__mapply<__contains<_Item>, _List>, _Continuation,
-                      __mbind_back<_Continuation, _Item>>,
-                 _List>;
-};
-
-template <class _Continuation = __q<__types>>
-struct __munique
-{
-    template <class... _Ts>
-    using __f = __mapply<
-        _Continuation,
-        __minvoke<__mfold_right<__types<>, __push_back_unique<>>, _Ts...>>;
-};
-
 template <class...>
 struct __mcompose
 {};
@@ -731,8 +845,15 @@
                   __minvoke<__mcompose<_Penultimate, _Rest...>, _Args...>>;
 };
 
+template <template <class...> class _Second, template <class...> class _First>
+struct __mcompose_q
+{
+    template <class... _Args>
+    using __f = _Second<_First<_Args...>>;
+};
+
 template <class _Old, class _New, class _Continuation = __q<__types>>
-struct __replace
+struct __mreplace
 {
     template <class... _Args>
     using __f = __minvoke<_Continuation,
@@ -740,7 +861,7 @@
 };
 
 template <class _Old, class _Continuation = __q<__types>>
-struct __remove
+struct __mremove
 {
     template <class... _Args>
     using __f = //
@@ -749,7 +870,7 @@
 };
 
 template <class _Pred, class _Continuation = __q<__types>>
-struct __remove_if
+struct __mremove_if
 {
     template <class... _Args>
     using __f = //
@@ -777,13 +898,6 @@
 template <class _Default>
 using __msingle_or = __mbind_front_q<__msingle_or_, _Default>;
 
-template <class _Continuation = __q<__types>>
-struct __pop_front
-{
-    template <class, class... _Ts>
-    using __f = __minvoke<_Continuation, _Ts...>;
-};
-
 template <class _Ty>
 concept __has_id = requires { typename _Ty::__id; };
 
@@ -835,24 +949,22 @@
 using __call_result_t = decltype(__declval<_Fun>()(__declval<_As>()...));
 #endif
 
+// BUGBUG TODO file this bug with nvc++
+#if STDEXEC_NVHPC()
 template <const auto& _Fun, class... _As>
 using __result_of = __call_result_t<decltype(_Fun), _As...>;
+#else
+template <const auto& _Fun, class... _As>
+using __result_of = decltype(_Fun(__declval<_As>()...));
+#endif
 
-// For working around clang's lack of support for CWG#2369:
-// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2369
-struct __qcall_result
-{
-    template <class _Fun, class... _As>
-    using __f = __call_result_t<_Fun, _As...>;
-};
-template <bool _Enable, class _Fun, class... _As>
-using __call_result_if_t =
-    __minvoke<__if<__mbool<_Enable>, __qcall_result, __>, _Fun, _As...>;
+template <const auto& _Fun, class... _As>
+inline constexpr bool __noexcept_of = noexcept(_Fun(__declval<_As>()...));
 
 // For emplacing non-movable types into optionals:
 template <class _Fn>
     requires std::is_nothrow_move_constructible_v<_Fn>
-struct __conv
+struct __emplace_from
 {
     _Fn __fn_;
     using __t = __call_result_t<_Fn>;
@@ -867,18 +979,9 @@
         return static_cast<_Fn&&>(__fn_)();
     }
 };
-template <class _Fn>
-__conv(_Fn) -> __conv<_Fn>;
 
-// Implemented as a class instead of a free function
-// because of a bizarre nvc++ compiler bug:
-struct __cref_fn
-{
-    template <class _Ty>
-    auto operator()(const _Ty&) -> const _Ty&;
-};
-template <class _Ty>
-using __cref_t = decltype(__cref_fn{}(__declval<_Ty>()));
+template <class _Fn>
+__emplace_from(_Fn) -> __emplace_from<_Fn>;
 
 template <class, class, class, class>
 struct __mzip_with2_;
@@ -904,27 +1007,6 @@
     using __f = __t<__mzip_with2_<_Fn, _Continuation, _Cp, _Dp>>;
 };
 
-#if STDEXEC_GCC() && (__GNUC__ < 12)
-template <class>
-extern int __mconvert_indices;
-template <std::size_t... _Indices>
-extern __types<__msize_t<_Indices>...>
-    __mconvert_indices<std::index_sequence<_Indices...>>;
-template <std::size_t _Np>
-using __mmake_index_sequence =
-    decltype(stdexec::__mconvert_indices<std::make_index_sequence<_Np>>);
-#else
-template <std::size_t... _Indices>
-auto __mconvert_indices(std::index_sequence<_Indices...>*)
-    -> __types<__msize_t<_Indices>...>;
-template <std::size_t _Np>
-using __mmake_index_sequence = decltype(stdexec::__mconvert_indices(
-    static_cast<std::make_index_sequence<_Np>*>(nullptr)));
-#endif
-
-template <class... _Ts>
-using __mindex_sequence_for = __mmake_index_sequence<sizeof...(_Ts)>;
-
 template <bool>
 struct __mfind_if_
 {
@@ -960,20 +1042,37 @@
                            __v<__minvoke<__mfind_if<_Fn, __msize>, _Args...>>)>;
 };
 
-template <class... _Booleans>
-using __mand_ = __mbool<(__v<_Booleans> && ...)>;
-template <class... _Booleans>
-using __mand = __meval<__mand_, _Booleans...>;
+#if STDEXEC_MSVC()
+#define __mvalue_of(...) __VA_ARGS__::value
+#else
+#define __mvalue_of(...) __v<__VA_ARGS__>
+#endif
 
 template <class... _Booleans>
-using __mor_ = __mbool<(__v<_Booleans> || ...)>;
+using __mand_t = __mbool<(__mvalue_of(_Booleans) && ...)>;
 template <class... _Booleans>
-using __mor = __meval<__mor_, _Booleans...>;
+using __mand = __meval<__mand_t, _Booleans...>;
+
+template <class... _Booleans>
+using __mor_t = __mbool<(__mvalue_of(_Booleans) || ...)>;
+template <class... _Booleans>
+using __mor = __meval<__mor_t, _Booleans...>;
 
 template <class _Boolean>
-using __mnot_ = __mbool<!__v<_Boolean>>;
+using __mnot_t = __mbool<!__mvalue_of(_Boolean)>;
 template <class _Boolean>
-using __mnot = __meval<__mnot_, _Boolean>;
+using __mnot = __meval<__mnot_t, _Boolean>;
+
+#if STDEXEC_NVHPC()
+template <class... _Ints>
+struct __mplus_t : __mconstant<(__v<_Ints> + ...)>
+{};
+#else
+template <class... _Ints>
+using __mplus_t = __mconstant<(__mvalue_of(_Ints) + ...)>;
+#endif
+
+#undef __mvalue_of
 
 template <class _Fn>
 struct __mall_of
@@ -996,15 +1095,25 @@
     using __f = __mor<__minvoke<_Fn, _Args>...>;
 };
 
-#if STDEXEC_HAS_BUILTIN(__type_pack_element)
-template <std::size_t _Np, class... _Ts>
-struct __m_at_
-{
-    using __t = __type_pack_element<_Np, _Ts...>;
-};
+#if defined(__cpp_pack_indexing)
+template <class _Np, class... _Ts>
+using __m_at = _Ts...[__v<_Np>];
 
 template <std::size_t _Np, class... _Ts>
-using __m_at_c = __t<__m_at_<_Np, _Ts...>>;
+using __m_at_c = _Ts...[_Np];
+#elif STDEXEC_HAS_BUILTIN(__type_pack_element)
+template <bool>
+struct __m_at_
+{
+    template <class _Np, class... _Ts>
+    using __f = __type_pack_element<__v<_Np>, _Ts...>;
+};
+
+template <class _Np, class... _Ts>
+using __m_at = __minvoke<__m_at_<__v<_Np> == ~0ul>, _Np, _Ts...>;
+
+template <std::size_t _Np, class... _Ts>
+using __m_at_c = __minvoke<__m_at_<_Np == ~0ul>, __msize_t<_Np>, _Ts...>;
 #else
 template <std::size_t>
 using __void_ptr = void*;
@@ -1016,7 +1125,7 @@
 struct __m_at_;
 
 template <std::size_t... _Is>
-struct __m_at_<std::index_sequence<_Is...>>
+struct __m_at_<__indices<_Is...>>
 {
     template <class _Up, class... _Us>
     static _Up __f_(__void_ptr<_Is>..., _Up*, _Us*...);
@@ -1025,11 +1134,11 @@
 };
 
 template <std::size_t _Np, class... _Ts>
-using __m_at_c = __minvoke<__m_at_<std::make_index_sequence<_Np>>, _Ts...>;
-#endif
+using __m_at_c = __minvoke<__m_at_<__make_indices<_Np>>, _Ts...>;
 
 template <class _Np, class... _Ts>
 using __m_at = __m_at_c<__v<_Np>, _Ts...>;
+#endif
 
 template <class... _Ts>
 using __mback = __m_at_c<sizeof...(_Ts) - 1, _Ts...>;
@@ -1059,7 +1168,7 @@
 
     constexpr __placeholder(void*) noexcept {}
 
-    friend constexpr auto __get_placeholder_offset(__placeholder) noexcept
+    constexpr friend auto __get_placeholder_offset(__placeholder) noexcept
         -> std::size_t
     {
         return _Np;
@@ -1071,22 +1180,19 @@
 using __2 = __placeholder<2>;
 using __3 = __placeholder<3>;
 
-#if STDEXEC_MSVC()
-// MSVCBUG
-// https://developercommunity.visualstudio.com/t/Incorrect-function-template-argument-sub/10437827
-
-template <std::size_t>
-struct __ignore_t
+#if defined(__cpp_pack_indexing)
+template <std::size_t _Np>
+struct __nth_pack_element_t
 {
-    __ignore_t() = default;
-
-    constexpr __ignore_t(auto&&...) noexcept {}
+    template <class... _Ts>
+    STDEXEC_ATTRIBUTE((always_inline))
+    constexpr decltype(auto) operator()(_Ts&&... __ts) const noexcept
+    {
+        static_assert(_Np < sizeof...(_Ts));
+        return (static_cast<_Ts&&>(__ts)...[_Np]);
+    }
 };
 #else
-template <std::size_t>
-using __ignore_t = __ignore;
-#endif
-
 template <class... _Ignore>
 struct __nth_pack_element_impl
 {
@@ -1116,6 +1222,7 @@
         return __impl(__make_indices<_Np>())(static_cast<_Ts&&>(__ts)...);
     }
 };
+#endif
 
 template <std::size_t _Np>
 inline constexpr __nth_pack_element_t<_Np> __nth_pack_element{};
@@ -1268,7 +1375,7 @@
                 __callable<
                     __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
                     _Ts...>
-    auto operator()(_Ts&&... __ts) const
+    auto operator()(_Ts&&... __ts) const //
         noexcept(__nothrow_callable<
                  __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
                  _Ts...>)
@@ -1327,4 +1434,59 @@
     __minvoke<__mtry_catch<__mcompose<__q<__mdispatch>, __which<_Signatures>>,
                            _DefaultFn>,
               _Args...>;
+
+template <class _Set, class... _Ty>
+concept __mset_contains = (STDEXEC_IS_BASE_OF(__mtype<_Ty>, _Set) && ...);
+
+namespace __set
+{
+template <class... _Ts>
+struct __inherit
+{};
+
+template <class _Ty, class... _Ts>
+struct __inherit<_Ty, _Ts...> : __mtype<_Ty>, __inherit<_Ts...>
+{};
+
+template <class... _Set>
+auto operator+(__inherit<_Set...>&) -> __inherit<_Set...>;
+
+template <class... _Set, class _Ty>
+auto operator%(__inherit<_Set...>&, __mtype<_Ty>&) //
+    -> __if_c<                                     //
+        __mset_contains<__inherit<_Set...>, _Ty>, __inherit<_Set...>,
+        __inherit<_Ty, _Set...>>&;
+
+template <class _ExpectedSet, class... _Ts>
+concept __mset_eq =                                            //
+    (sizeof...(_Ts) == __v<__mapply<__msize, _ExpectedSet>>)&& //
+    __mset_contains<_ExpectedSet, _Ts...>;
+
+template <class _ExpectedSet>
+struct __eq
+{
+    template <class... _Ts>
+    using __f = __mbool<__mset_eq<_ExpectedSet, _Ts...>>;
+};
+} // namespace __set
+
+template <class... _Ts>
+using __mset = __set::__inherit<_Ts...>;
+
+template <class _Set, class... _Ts>
+using __mset_insert =
+    decltype(+(__declval<_Set&>() % ... % __declval<__mtype<_Ts>&>()));
+
+template <class... _Ts>
+using __mmake_set = __mset_insert<__mset<>, _Ts...>;
+
+template <class _Set1, class _Set2>
+concept __mset_eq = __v<__mapply<__set::__eq<_Set1>, _Set2>>;
+
+template <class _Continuation = __q<__types>>
+struct __munique
+{
+    template <class... _Ts>
+    using __f = __mapply<_Continuation, __mmake_set<_Ts...>>;
+};
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__on.hpp b/include/sdbusplus/async/stdexec/__detail/__on.hpp
new file mode 100644
index 0000000..3e5f704
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__on.hpp
@@ -0,0 +1,267 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__continue_on.hpp"
+#include "__cpo.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__inline_scheduler.hpp"
+#include "__meta.hpp"
+#include "__schedulers.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__sender_introspection.hpp"
+#include "__senders_core.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+#include "__utility.hpp"
+#include "__write_env.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.on]
+namespace __on_v2
+{
+inline constexpr __mstring __on_context =
+    "In stdexec::on(Scheduler, Sender)..."_mstr;
+inline constexpr __mstring __no_scheduler_diag =
+    "stdexec::on() requires a scheduler to transition back to."_mstr;
+inline constexpr __mstring __no_scheduler_details =
+    "The provided environment lacks a value for the get_scheduler() query."_mstr;
+
+template <__mstring _Context = __on_context,
+          __mstring _Diagnostic = __no_scheduler_diag,
+          __mstring _Details = __no_scheduler_details>
+struct _CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_
+{};
+
+struct on_t;
+
+template <class _Sender, class _Env>
+struct __no_scheduler_in_environment
+{
+    using sender_concept = sender_t;
+
+    static auto get_completion_signatures(const __no_scheduler_in_environment&,
+                                          const auto&) noexcept
+    {
+        return __mexception<_CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_<>,
+                            _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>{};
+    }
+};
+
+template <class _Scheduler, class _Closure>
+struct __continue_on_data
+{
+    _Scheduler __sched_;
+    _Closure __clsur_;
+};
+template <class _Scheduler, class _Closure>
+__continue_on_data(_Scheduler, _Closure)
+    -> __continue_on_data<_Scheduler, _Closure>;
+
+template <class _Scheduler>
+struct __with_sched
+{
+    using __t = __with_sched;
+    using __id = __with_sched;
+
+    _Scheduler __sched_;
+
+    auto query(get_scheduler_t) const noexcept -> _Scheduler
+    {
+        return __sched_;
+    }
+
+    auto query(get_domain_t) const noexcept
+    {
+        return query_or(get_domain, __sched_, default_domain());
+    }
+};
+
+template <class _Scheduler>
+__with_sched(_Scheduler) -> __with_sched<_Scheduler>;
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct on_t
+{
+    template <scheduler _Scheduler, sender _Sender>
+    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<on_t>(static_cast<_Scheduler&&>(__sched),
+                                         static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <sender _Sender, scheduler _Scheduler,
+              __sender_adaptor_closure_for<_Sender> _Closure>
+    auto operator()(_Sender&& __sndr, _Scheduler&& __sched,
+                    _Closure&& __clsur) const -> __well_formed_sender auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<on_t>(
+                          __continue_on_data{static_cast<_Scheduler&&>(__sched),
+                                             static_cast<_Closure&&>(__clsur)},
+                          static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <scheduler _Scheduler, __sender_adaptor_closure _Closure>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Scheduler&& __sched, _Closure&& __clsur) const
+    {
+        return __binder_back<on_t, __decay_t<_Scheduler>, __decay_t<_Closure>>{
+            {{static_cast<_Scheduler&&>(__sched)},
+             {static_cast<_Closure&&>(__clsur)}},
+            {},
+            {}};
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&]<class _Data>(__ignore, _Data&& __data,
+                                __ignore) noexcept -> decltype(auto) {
+            if constexpr (scheduler<_Data>)
+            {
+                return __detail::__mkenv_sched(static_cast<_Env&&>(__env),
+                                               static_cast<_Data&&>(__data));
+            }
+            else
+            {
+                return static_cast<_Env>(static_cast<_Env&&>(__env));
+            }
+        };
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_sender_fn(const _Env& __env) noexcept
+    {
+        return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
+                                              _Child&& __child) {
+            if constexpr (scheduler<_Data>)
+            {
+                // This branch handles the case where `on` was called like
+                // `on(sch, snd)`
+                auto __old = query_or(get_scheduler, __env, __none_such{});
+                if constexpr (__same_as<decltype(__old), __none_such>)
+                {
+                    if constexpr (__is_root_env<_Env>)
+                    {
+                        return continue_on(
+                            start_on(static_cast<_Data&&>(__data),
+                                     static_cast<_Child&&>(__child)),
+                            __inln::__scheduler{});
+                    }
+                    else
+                    {
+                        return __none_such{};
+                    }
+                }
+                else
+                {
+                    return continue_on(start_on(static_cast<_Data&&>(__data),
+                                                static_cast<_Child&&>(__child)),
+                                       static_cast<decltype(__old)&&>(__old));
+                }
+            }
+            else
+            {
+                // This branch handles the case where `on` was called like
+                // `on(snd, sch, clsur)`
+                auto __old = query_or(
+                    get_completion_scheduler<set_value_t>, get_env(__child),
+                    query_or(get_scheduler, __env, __none_such{}));
+                if constexpr (__same_as<decltype(__old), __none_such>)
+                {
+                    return __none_such{};
+                }
+                else
+                {
+                    auto&& [__sched, __clsur] = static_cast<_Data&&>(__data);
+                    return __write_env(                               //
+                        continue_on(                                  //
+                            __forward_like<_Data>(__clsur)(           //
+                                continue_on(                          //
+                                    __write_env(static_cast<_Child&&>(__child),
+                                                __with_sched{__old}), //
+                                    __sched)),                        //
+                            __old),
+                        __with_sched{__sched});
+                }
+            }
+        };
+    }
+
+    template <class _Sender, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__sndr,
+                             __transform_env_fn(static_cast<_Env&&>(__env)));
+    }
+
+    template <class _Sender, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        auto __tfx_sndr_fn = __transform_sender_fn(__env);
+        using _TfxSndrFn = decltype(__tfx_sndr_fn);
+        using _NewSndr = __sexpr_apply_result_t<_Sender, _TfxSndrFn>;
+        if constexpr (__same_as<_NewSndr, __none_such>)
+        {
+            return __no_scheduler_in_environment<_Sender, _Env>{};
+        }
+        else
+        {
+            return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                                 static_cast<_TfxSndrFn&&>(__tfx_sndr_fn));
+        }
+    }
+};
+} // namespace __on_v2
+
+namespace v2
+{
+using __on_v2::on_t;
+inline constexpr on_t on{};
+
+using continue_on_t = v2::on_t;
+inline constexpr continue_on_t continue_on{}; // for back-compat
+} // namespace v2
+
+template <>
+struct __sexpr_impl<v2::on_t> : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __merror_or_t<                             //
+            __completion_signatures_of_t<             //
+                transform_sender_result_t<default_domain, _Sender, empty_env>>,
+            dependent_completions> { return {}; };
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__operation_states.hpp b/include/sdbusplus/async/stdexec/__detail/__operation_states.hpp
new file mode 100644
index 0000000..a59817e
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__operation_states.hpp
@@ -0,0 +1,72 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__tag_invoke.hpp"
+
+#include <type_traits>
+
+namespace stdexec
+{
+// operation state tag type
+struct operation_state_t
+{};
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.op_state]
+namespace __start
+{
+struct start_t
+{
+    template <__same_as<start_t> _Self, class _OpState>
+    STDEXEC_ATTRIBUTE((always_inline))
+    friend auto tag_invoke(_Self, _OpState& __op) noexcept
+        -> decltype(__op.start())
+    {
+        static_assert(noexcept(__op.start()),
+                      "start() members must be noexcept");
+        static_assert(__same_as<decltype(__op.start()), void>,
+                      "start() members must return void");
+        __op.start();
+    }
+
+    template <class _Op>
+        requires tag_invocable<start_t, _Op&>
+    STDEXEC_ATTRIBUTE((always_inline)) void operator()(_Op& __op) const noexcept
+    {
+        static_assert(nothrow_tag_invocable<start_t, _Op&>);
+        (void)tag_invoke(start_t{}, __op);
+    }
+};
+} // namespace __start
+
+using __start::start_t;
+inline constexpr start_t start{};
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.op_state]
+template <class _Op>
+concept operation_state =    //
+    destructible<_Op> &&     //
+    std::is_object_v<_Op> && //
+    requires(_Op& __op) {    //
+        stdexec::start(__op);
+    };
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__optional.hpp b/include/sdbusplus/async/stdexec/__detail/__optional.hpp
new file mode 100644
index 0000000..7591e20
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__optional.hpp
@@ -0,0 +1,170 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__type_traits.hpp"
+
+#include <exception>
+#include <memory>
+#include <new>
+#include <utility>
+
+namespace stdexec
+{
+namespace __opt
+{
+struct __bad_optional_access : std::exception
+{
+    const char* what() const noexcept override
+    {
+        return "stdexec::__optional: bad access";
+    }
+};
+
+inline constexpr struct __nullopt_t
+{
+} __nullopt{};
+
+// A simplified version of std::optional for better compile times
+template <class _Tp>
+struct __optional
+{
+    static_assert(destructible<_Tp>);
+
+    union
+    {
+        _Tp __value;
+    };
+
+    bool __has_value = false;
+
+    __optional() noexcept {}
+
+    __optional(__nullopt_t) noexcept {}
+
+    __optional(__optional&&) = delete; // immovable for simplicity's sake
+
+    template <__not_decays_to<__optional> _Up>
+        requires constructible_from<_Tp, _Up>
+    __optional(_Up&& __v) : __value(static_cast<_Up&&>(__v)), __has_value(true)
+    {}
+
+    template <class... _Us>
+        requires constructible_from<_Tp, _Us...>
+    __optional(std::in_place_t, _Us&&... __us) :
+        __value(static_cast<_Us&&>(__us)...), __has_value(true)
+    {}
+
+    ~__optional()
+    {
+        if (__has_value)
+        {
+            std::destroy_at(std::addressof(__value));
+        }
+    }
+
+    template <class... _Us>
+        requires constructible_from<_Tp, _Us...>
+    _Tp& emplace(_Us&&... __us) noexcept(
+        __nothrow_constructible_from<_Tp, _Us...>)
+    {
+        reset(); // sets __has_value to false in case the next line throws
+        ::new (&__value) _Tp{static_cast<_Us&&>(__us)...};
+        __has_value = true;
+        return __value;
+    }
+
+    _Tp& value() &
+    {
+        if (!__has_value)
+        {
+            throw __bad_optional_access();
+        }
+        return __value;
+    }
+
+    const _Tp& value() const&
+    {
+        if (!__has_value)
+        {
+            throw __bad_optional_access();
+        }
+        return __value;
+    }
+
+    _Tp&& value() &&
+    {
+        if (!__has_value)
+        {
+            throw __bad_optional_access();
+        }
+        return static_cast<_Tp&&>(__value);
+    }
+
+    _Tp& operator*() & noexcept
+    {
+        STDEXEC_ASSERT(__has_value);
+        return __value;
+    }
+
+    const _Tp& operator*() const& noexcept
+    {
+        STDEXEC_ASSERT(__has_value);
+        return __value;
+    }
+
+    _Tp&& operator*() && noexcept
+    {
+        STDEXEC_ASSERT(__has_value);
+        return static_cast<_Tp&&>(__value);
+    }
+
+    _Tp* operator->() & noexcept
+    {
+        STDEXEC_ASSERT(__has_value);
+        return &__value;
+    }
+
+    const _Tp* operator->() const& noexcept
+    {
+        STDEXEC_ASSERT(__has_value);
+        return &__value;
+    }
+
+    bool has_value() const noexcept
+    {
+        return __has_value;
+    }
+
+    void reset() noexcept
+    {
+        if (__has_value)
+        {
+            std::destroy_at(std::addressof(__value));
+            __has_value = false;
+        }
+    }
+};
+} // namespace __opt
+
+using __opt::__bad_optional_access;
+using __opt::__nullopt;
+using __opt::__optional;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__read_env.hpp b/include/sdbusplus/async/stdexec/__detail/__read_env.hpp
new file mode 100644
index 0000000..48bef46
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__read_env.hpp
@@ -0,0 +1,167 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__optional.hpp"
+#include "__receivers.hpp"
+#include "__tag_invoke.hpp"
+
+#include <exception>
+
+namespace stdexec
+{
+namespace __read
+{
+template <class _Tag, class _ReceiverId>
+using __result_t = __call_result_t<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
+
+template <class _Tag, class _ReceiverId>
+concept __nothrow_t =
+    __nothrow_callable<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
+
+inline constexpr __mstring __query_failed_diag =
+    "The current execution environment doesn't have a value for the given query."_mstr;
+
+template <class _Tag, class _Env>
+using __query_failed_error = //
+    __mexception<            //
+        _NOT_CALLABLE_<"In stdexec::read()..."_mstr, __query_failed_diag>,
+        _WITH_QUERY_<_Tag>, _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Tag, class _Env>
+    requires __callable<_Tag, _Env>
+using __completions_t = //
+    __if_c<__nothrow_callable<_Tag, _Env>,
+           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>)>,
+           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>),
+                                 set_error_t(std::exception_ptr)>>;
+
+template <class _Tag, class _Ty>
+struct __state
+{
+    using __query = _Tag;
+    using __result = _Ty;
+    __optional<_Ty> __result_;
+};
+
+template <class _Tag, class _Ty>
+    requires __same_as<_Ty, _Ty&&>
+struct __state<_Tag, _Ty>
+{
+    using __query = _Tag;
+    using __result = _Ty;
+};
+
+struct __read_env_t
+{
+    template <class _Tag>
+    constexpr auto operator()(_Tag) const noexcept
+    {
+        return __make_sexpr<__read_env_t>(_Tag());
+    }
+};
+
+struct __read_env_impl : __sexpr_defaults
+{
+    template <class _Tag, class _Env>
+    using __completions_t = __minvoke<
+        __mtry_catch_q<__read::__completions_t, __q<__query_failed_error>>,
+        _Tag, _Env>;
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Self, class _Env>(const _Self&, _Env&&) noexcept
+        -> __completions_t<__data_of<_Self>, _Env> { return {}; };
+
+    static constexpr auto get_state = //
+        []<class _Self, class _Receiver>(const _Self&, _Receiver&) noexcept {
+        using __query = __data_of<_Self>;
+        using __result = __call_result_t<__query, env_of_t<_Receiver>>;
+        return __state<__query, __result>();
+    };
+
+    static constexpr auto start = //
+        []<class _State, class _Receiver>(_State& __state,
+                                          _Receiver& __rcvr) noexcept -> void {
+        using __query = typename _State::__query;
+        using __result = typename _State::__result;
+        if constexpr (__same_as<__result, __result&&>)
+        {
+            // The query returns a reference type; pass it straight through to
+            // the receiver.
+            stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr),
+                                        __query(), stdexec::get_env(__rcvr));
+        }
+        else
+        {
+            constexpr bool _Nothrow =
+                __nothrow_callable<__query, env_of_t<_Receiver>>;
+            auto __query_fn = [&]() noexcept(_Nothrow) -> __result&& {
+                __state.__result_.emplace(
+                    __emplace_from{[&]() noexcept(_Nothrow) {
+                    return __query()(stdexec::get_env(__rcvr));
+                }});
+                return static_cast<__result&&>(*__state.__result_);
+            };
+            stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr),
+                                        __query_fn);
+        }
+    };
+};
+} // namespace __read
+
+inline constexpr __read::__read_env_t read{};
+inline constexpr __read::__read_env_t read_env{};
+
+template <>
+struct __sexpr_impl<__read::__read_env_t> : __read::__read_env_impl
+{};
+
+namespace __queries
+{
+template <class _Tag>
+inline auto get_scheduler_t::operator()() const noexcept
+{
+    return read_env(get_scheduler);
+}
+
+template <class _Tag>
+inline auto get_delegatee_scheduler_t::operator()() const noexcept
+{
+    return read_env(get_delegatee_scheduler);
+}
+
+template <class _Tag>
+inline auto get_allocator_t::operator()() const noexcept
+{
+    return read_env(get_allocator);
+}
+
+template <class _Tag>
+inline auto get_stop_token_t::operator()() const noexcept
+{
+    return read_env(get_stop_token);
+}
+} // namespace __queries
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__receiver_adaptor.hpp b/include/sdbusplus/async/stdexec/__detail/__receiver_adaptor.hpp
new file mode 100644
index 0000000..95a8c29
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__receiver_adaptor.hpp
@@ -0,0 +1,187 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__cpo.hpp"
+#include "__execution_fwd.hpp"
+#include "__receivers.hpp"
+#include "__tag_invoke.hpp"
+#include "__type_traits.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+namespace __adaptors
+{
+namespace __no
+{
+struct __nope
+{};
+
+struct __receiver : __nope
+{
+    using receiver_concept = receiver_t;
+
+    void set_error(std::exception_ptr) noexcept;
+    void set_stopped() noexcept;
+    auto get_env() const noexcept -> empty_env;
+};
+} // namespace __no
+
+using __not_a_receiver = __no::__receiver;
+
+template <class _Base>
+struct __adaptor_base
+{
+    template <class _T1>
+        requires constructible_from<_Base, _T1>
+    explicit __adaptor_base(_T1&& __base) : __base_(static_cast<_T1&&>(__base))
+    {}
+
+  private:
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Base __base_;
+
+  protected:
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    _Base& base() & noexcept
+    {
+        return __base_;
+    }
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    const _Base& base() const& noexcept
+    {
+        return __base_;
+    }
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    _Base&& base() && noexcept
+    {
+        return static_cast<_Base&&>(__base_);
+    }
+};
+
+template <derived_from<__no::__nope> _Base>
+struct __adaptor_base<_Base>
+{};
+
+// BUGBUG Not to spec: on gcc and nvc++, member functions in derived classes
+// don't shadow type aliases of the same name in base classes. :-O
+// On mingw gcc, 'bool(type::existing_member_function)' evaluates to true,
+// but 'int(type::existing_member_function)' is an error (as desired).
+#define STDEXEC_DISPATCH_MEMBER(_TAG)                                          \
+    template <class _Self, class... _Ts>                                       \
+    STDEXEC_ATTRIBUTE((host, device, always_inline))                           \
+    static auto __call_##_TAG(_Self&& __self, _Ts&&... __ts) noexcept          \
+        -> decltype((static_cast<_Self&&>(__self))                             \
+                        ._TAG(static_cast<_Ts&&>(__ts)...))                    \
+    {                                                                          \
+        static_assert(noexcept((static_cast<_Self&&>(__self))                  \
+                                   ._TAG(static_cast<_Ts&&>(__ts)...)));       \
+        return static_cast<_Self&&>(__self)._TAG(static_cast<_Ts&&>(__ts)...); \
+    } /**/
+#define STDEXEC_CALL_MEMBER(_TAG, ...) __call_##_TAG(__VA_ARGS__)
+
+#if STDEXEC_CLANG()
+// Only clang gets this right.
+#define STDEXEC_MISSING_MEMBER(_Dp, _TAG) requires { typename _Dp::_TAG; }
+#define STDEXEC_DEFINE_MEMBER(_TAG)                                            \
+    STDEXEC_DISPATCH_MEMBER(_TAG) using _TAG = void
+#else
+#define STDEXEC_MISSING_MEMBER(_Dp, _TAG) (__missing_##_TAG<_Dp>())
+#define STDEXEC_DEFINE_MEMBER(_TAG)                                            \
+    template <class _Dp>                                                       \
+    static constexpr bool __missing_##_TAG() noexcept                          \
+    {                                                                          \
+        return requires { requires bool(int(_Dp::_TAG)); };                    \
+    }                                                                          \
+    STDEXEC_DISPATCH_MEMBER(_TAG)                                              \
+    static constexpr int _TAG = 1 /**/
+#endif
+
+template <__class _Derived, class _Base = __not_a_receiver>
+struct receiver_adaptor : __adaptor_base<_Base>, receiver_t
+{
+    static constexpr bool __has_base = !derived_from<_Base, __no::__nope>;
+
+    template <class _Self>
+    using __base_from_derived_t = decltype(__declval<_Self>().base());
+
+    using __get_base_fn =
+        __if_c<__has_base, __mbind_back_q<__copy_cvref_t, _Base>,
+               __q<__base_from_derived_t>>;
+
+    template <class _Self>
+    using __base_t = __minvoke<__get_base_fn, _Self&&>;
+
+    template <class _Self>
+    STDEXEC_ATTRIBUTE((host, device))
+    static auto __get_base(_Self&& __self) noexcept -> __base_t<_Self>
+    {
+        if constexpr (__has_base)
+        {
+            return __c_upcast<receiver_adaptor>(static_cast<_Self&&>(__self))
+                .base();
+        }
+        else
+        {
+            return static_cast<_Self&&>(__self).base();
+        }
+    }
+
+  public:
+    using receiver_concept = receiver_t;
+
+    receiver_adaptor() = default;
+    using __adaptor_base<_Base>::__adaptor_base;
+
+    template <class... _As, class _Self = _Derived>
+        requires __callable<set_value_t, __base_t<_Self>, _As...>
+    STDEXEC_ATTRIBUTE((host, device)) void set_value(_As&&... __as) && noexcept
+    {
+        return stdexec::set_value(__get_base(static_cast<_Self&&>(*this)),
+                                  static_cast<_As&&>(__as)...);
+    }
+
+    template <class _Error, class _Self = _Derived>
+        requires __callable<set_error_t, __base_t<_Self>, _Error>
+    STDEXEC_ATTRIBUTE((host, device)) void set_error(_Error&& __err) && noexcept
+    {
+        return stdexec::set_error(__get_base(static_cast<_Self&&>(*this)),
+                                  static_cast<_Error&&>(__err));
+    }
+
+    template <class _Self = _Derived>
+        requires __callable<set_stopped_t, __base_t<_Self>>
+    STDEXEC_ATTRIBUTE((host, device)) void set_stopped() && noexcept
+    {
+        return stdexec::set_stopped(__get_base(static_cast<_Self&&>(*this)));
+    }
+
+    template <class _Self = _Derived>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto get_env() const noexcept -> env_of_t<__base_t<const _Self&>>
+    {
+        return stdexec::get_env(__get_base(static_cast<const _Self&>(*this)));
+    }
+};
+} // namespace __adaptors
+
+template <__class _Derived, receiver _Base = __adaptors::__not_a_receiver>
+using receiver_adaptor = __adaptors::receiver_adaptor<_Derived, _Base>;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__receiver_ref.hpp b/include/sdbusplus/async/stdexec/__detail/__receiver_ref.hpp
new file mode 100644
index 0000000..fdb2d7e
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__receiver_ref.hpp
@@ -0,0 +1,134 @@
+/*
+ * 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 "__completion_signatures.hpp"
+#include "__cpo.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__schedulers.hpp"
+
+#include <functional>
+
+namespace stdexec
+{
+namespace __any_
+{
+template <class _Sig>
+struct __rcvr_vfun;
+
+template <class _Tag, class... _Args>
+struct __rcvr_vfun<_Tag(_Args...)>
+{
+    void (*__complete_)(void*, _Args&&...) noexcept;
+
+    void operator()(void* __obj, _Tag, _Args&&... __args) const noexcept
+    {
+        __complete_(__obj, static_cast<_Args&&>(__args)...);
+    }
+};
+
+template <class _GetReceiver = std::identity, class _Obj, class _Tag,
+          class... _Args>
+constexpr auto __rcvr_vfun_fn(_Obj*, _Tag (*)(_Args...)) noexcept
+{
+    return +[](void* __ptr, _Args&&... __args) noexcept {
+        _Obj* __obj = static_cast<_Obj*>(__ptr);
+        _Tag()(std::move(_GetReceiver()(*__obj)),
+               static_cast<_Args&&>(__args)...);
+    };
+}
+
+template <class _Sigs, class _Env>
+struct __receiver_vtable_for;
+
+template <class _Env, class... _Sigs>
+struct __receiver_vtable_for<completion_signatures<_Sigs...>, _Env> :
+    __rcvr_vfun<_Sigs>...
+{
+    _Env (*__do_get_env)(const void* __op_state) noexcept;
+
+    template <class _OpState, class _GetEnv>
+    static auto __s_get_env(const void* __ptr) noexcept -> _Env
+    {
+        auto* __op_state = static_cast<const _OpState*>(__ptr);
+        return _GetEnv()(*__op_state);
+    }
+
+    template <class _OpState, class _GetEnv, class _GetReceiver = std::identity>
+    explicit constexpr __receiver_vtable_for(_OpState* __op, _GetEnv,
+                                             _GetReceiver = {}) noexcept :
+        __rcvr_vfun<_Sigs>{__rcvr_vfun_fn<_GetReceiver>(
+            __op, static_cast<_Sigs*>(nullptr))}...,
+        __do_get_env{&__s_get_env<_OpState, _GetEnv>}
+    {}
+
+    using __rcvr_vfun<_Sigs>::operator()...;
+
+    auto __get_env(const void* __op_state) const noexcept -> _Env
+    {
+        return __do_get_env(__op_state);
+    }
+};
+
+template <class _OpState, class _GetEnv, class _GetReceiver, class _Env,
+          class _Sigs>
+inline constexpr __receiver_vtable_for<_Sigs, _Env> __receiver_vtable_for_v{
+    static_cast<_OpState*>(nullptr), _GetEnv{}, _GetReceiver{}};
+
+template <class _Sigs, class _Env = empty_env>
+class __receiver_ref
+{
+  public:
+    using receiver_concept = receiver_t;
+    using __t = __receiver_ref;
+    using __id = __receiver_ref;
+
+    template <class _OpState, class _GetEnv, class _GetReceiver = std::identity>
+    __receiver_ref(_OpState& __op_state, _GetEnv, _GetReceiver = {}) noexcept :
+        __vtable_{&__any_::__receiver_vtable_for_v<_OpState, _GetEnv,
+                                                   _GetReceiver, _Env, _Sigs>},
+        __op_state_{&__op_state}
+    {}
+
+    auto get_env() const noexcept -> decltype(auto)
+    {
+        return __vtable_->__get_env(__op_state_);
+    }
+
+    template <class... _As>
+    void set_value(_As&&... __as) noexcept
+    {
+        (*__vtable_)(__op_state_, set_value_t(), static_cast<_As&&>(__as)...);
+    }
+
+    template <class _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        (*__vtable_)(__op_state_, set_error_t(), static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+    {
+        (*__vtable_)(__op_state_, set_stopped_t());
+    }
+
+  private:
+    const __receiver_vtable_for<_Sigs, _Env>* __vtable_;
+    void* __op_state_;
+};
+} // namespace __any_
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__receivers.hpp b/include/sdbusplus/async/stdexec/__detail/__receivers.hpp
new file mode 100644
index 0000000..cd51c93
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__receivers.hpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2022-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 "../functional.hpp"
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__tag_invoke.hpp"
+
+#include <exception>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.receivers]
+namespace __rcvrs
+{
+struct set_value_t
+{
+    template <class _Fn, class... _Args>
+    using __f = __minvoke<_Fn, _Args...>;
+
+    template <__same_as<set_value_t> _Self, class _Receiver, class... _As>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    friend auto tag_invoke(_Self, _Receiver&& __rcvr, _As&&... __as) noexcept
+        -> decltype(static_cast<_Receiver&&>(__rcvr).set_value(
+            static_cast<_As&&>(__as)...))
+    {
+        static_assert(noexcept(static_cast<_Receiver&&>(__rcvr).set_value(
+                          static_cast<_As&&>(__as)...)),
+                      "set_value member functions must be noexcept");
+        static_assert(
+            __same_as<decltype(static_cast<_Receiver&&>(__rcvr).set_value(
+                          static_cast<_As&&>(__as)...)),
+                      void>,
+            "set_value member functions must return void");
+        static_cast<_Receiver&&>(__rcvr).set_value(static_cast<_As&&>(__as)...);
+    }
+
+    template <class _Receiver, class... _As>
+        requires tag_invocable<set_value_t, _Receiver, _As...>
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
+        operator()(_Receiver&& __rcvr, _As&&... __as) const noexcept
+    {
+        static_assert(nothrow_tag_invocable<set_value_t, _Receiver, _As...>);
+        (void)tag_invoke(stdexec::set_value_t{},
+                         static_cast<_Receiver&&>(__rcvr),
+                         static_cast<_As&&>(__as)...);
+    }
+};
+
+struct set_error_t
+{
+    template <class _Fn, class... _Args>
+        requires(sizeof...(_Args) == 1)
+    using __f = __minvoke<_Fn, _Args...>;
+
+    template <__same_as<set_error_t> _Self, class _Receiver, class _Error>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    friend auto tag_invoke(_Self, _Receiver&& __rcvr, _Error&& __err) noexcept
+        -> decltype(static_cast<_Receiver&&>(__rcvr).set_error(
+            static_cast<_Error&&>(__err)))
+    {
+        static_assert(noexcept(static_cast<_Receiver&&>(__rcvr).set_error(
+                          static_cast<_Error&&>(__err))),
+                      "set_error member functions must be noexcept");
+        static_assert(
+            __same_as<decltype(static_cast<_Receiver&&>(__rcvr).set_error(
+                          static_cast<_Error&&>(__err))),
+                      void>,
+            "set_error member functions must return void");
+        static_cast<_Receiver&&>(__rcvr).set_error(
+            static_cast<_Error&&>(__err));
+    }
+
+    template <class _Receiver, class _Error>
+        requires tag_invocable<set_error_t, _Receiver, _Error>
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
+        operator()(_Receiver&& __rcvr, _Error&& __err) const noexcept
+    {
+        static_assert(nothrow_tag_invocable<set_error_t, _Receiver, _Error>);
+        (void)tag_invoke(stdexec::set_error_t{},
+                         static_cast<_Receiver&&>(__rcvr),
+                         static_cast<_Error&&>(__err));
+    }
+};
+
+struct set_stopped_t
+{
+    template <class _Fn, class... _Args>
+        requires(sizeof...(_Args) == 0)
+    using __f = __minvoke<_Fn, _Args...>;
+
+    template <__same_as<set_stopped_t> _Self, class _Receiver>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    friend auto tag_invoke(_Self, _Receiver&& __rcvr) noexcept
+        -> decltype(static_cast<_Receiver&&>(__rcvr).set_stopped())
+    {
+        static_assert(noexcept(static_cast<_Receiver&&>(__rcvr).set_stopped()),
+                      "set_stopped member functions must be noexcept");
+        static_assert(
+            __same_as<decltype(static_cast<_Receiver&&>(__rcvr).set_stopped()),
+                      void>,
+            "set_stopped member functions must return void");
+        static_cast<_Receiver&&>(__rcvr).set_stopped();
+    }
+
+    template <class _Receiver>
+        requires tag_invocable<set_stopped_t, _Receiver>
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
+        operator()(_Receiver&& __rcvr) const noexcept
+    {
+        static_assert(nothrow_tag_invocable<set_stopped_t, _Receiver>);
+        (void)tag_invoke(stdexec::set_stopped_t{},
+                         static_cast<_Receiver&&>(__rcvr));
+    }
+};
+} // namespace __rcvrs
+
+using __rcvrs::set_error_t;
+using __rcvrs::set_stopped_t;
+using __rcvrs::set_value_t;
+inline constexpr set_value_t set_value{};
+inline constexpr set_error_t set_error{};
+inline constexpr set_stopped_t set_stopped{};
+
+struct receiver_t
+{
+    using receiver_concept = receiver_t; // NOT TO SPEC
+};
+
+namespace __detail
+{
+template <class _Receiver>
+concept __enable_receiver =                                              //
+    (STDEXEC_NVHPC(requires { typename _Receiver::receiver_concept; }&&) //
+     derived_from<typename _Receiver::receiver_concept, receiver_t>) ||
+    requires { typename _Receiver::is_receiver; } // back-compat, NOT TO SPEC
+    || STDEXEC_IS_BASE_OF(receiver_t,
+                          _Receiver); // NOT TO SPEC, for receiver_adaptor
+} // namespace __detail
+
+template <class _Receiver>
+inline constexpr bool enable_receiver =
+    __detail::__enable_receiver<_Receiver>; // NOT TO SPEC
+
+template <class _Receiver>
+concept receiver =                               //
+    enable_receiver<__decay_t<_Receiver>>        //
+    && environment_provider<__cref_t<_Receiver>> //
+    && move_constructible<__decay_t<_Receiver>>  //
+    && constructible_from<__decay_t<_Receiver>, _Receiver>;
+
+namespace __detail
+{
+template <class _Receiver, class _Tag, class... _Args>
+auto __try_completion(_Tag (*)(_Args...))
+    -> __mexception<_MISSING_COMPLETION_SIGNAL_<_Tag(_Args...)>,
+                    _WITH_RECEIVER_<_Receiver>>;
+
+template <class _Receiver, class _Tag, class... _Args>
+    requires nothrow_tag_invocable<_Tag, _Receiver, _Args...>
+auto __try_completion(_Tag (*)(_Args...)) -> __msuccess;
+
+template <class _Receiver, class... _Sigs>
+auto __try_completions(completion_signatures<_Sigs...>*) //
+    -> decltype((
+        __msuccess(), ...,
+        __detail::__try_completion<_Receiver>(static_cast<_Sigs*>(nullptr))));
+} // namespace __detail
+
+template <class _Receiver, class _Completions>
+concept receiver_of =      //
+    receiver<_Receiver> && //
+    requires(_Completions* __completions) {
+        {
+            __detail::__try_completions<__decay_t<_Receiver>>(__completions)
+        } -> __ok;
+    };
+
+template <class _Receiver, class _Sender>
+concept __receiver_from =
+    receiver_of<_Receiver,
+                __completion_signatures_of_t<_Sender, env_of_t<_Receiver>>>;
+
+/// A utility for calling set_value with the result of a function invocation:
+template <bool _CanThrow = false, class _Receiver, class _Fun, class... _As>
+void __set_value_invoke(_Receiver&& __rcvr, _Fun&& __fun,
+                        _As&&... __as) noexcept(!_CanThrow)
+{
+    if constexpr (_CanThrow || __nothrow_invocable<_Fun, _As...>)
+    {
+        if constexpr (same_as<void, __invoke_result_t<_Fun, _As...>>)
+        {
+            __invoke(static_cast<_Fun&&>(__fun), static_cast<_As&&>(__as)...);
+            stdexec::set_value(static_cast<_Receiver&&>(__rcvr));
+        }
+        else
+        {
+            set_value(static_cast<_Receiver&&>(__rcvr),
+                      __invoke(static_cast<_Fun&&>(__fun),
+                               static_cast<_As&&>(__as)...));
+        }
+    }
+    else
+    {
+        try
+        {
+            stdexec::__set_value_invoke<true>(static_cast<_Receiver&&>(__rcvr),
+                                              static_cast<_Fun&&>(__fun),
+                                              static_cast<_As&&>(__as)...);
+        }
+        catch (...)
+        {
+            stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                               std::current_exception());
+        }
+    }
+}
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__run_loop.hpp b/include/sdbusplus/async/stdexec/__detail/__run_loop.hpp
new file mode 100644
index 0000000..0323f89
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__run_loop.hpp
@@ -0,0 +1,264 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__completion_signatures.hpp"
+#include "__cpo.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__utility.hpp"
+
+#include <condition_variable>
+#include <exception>
+#include <mutex>
+#include <utility>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// run_loop
+namespace __loop
+{
+class run_loop;
+
+struct __task : __immovable
+{
+    __task* __next_ = this;
+
+    union
+    {
+        __task* __tail_ = nullptr;
+        void (*__execute_)(__task*) noexcept;
+    };
+
+    void __execute() noexcept
+    {
+        (*__execute_)(this);
+    }
+};
+
+template <class _ReceiverId>
+struct __operation
+{
+    using _Receiver = stdexec::__t<_ReceiverId>;
+
+    struct __t : __task
+    {
+        using __id = __operation;
+
+        run_loop* __loop_;
+        STDEXEC_ATTRIBUTE((no_unique_address))
+        _Receiver __rcvr_;
+
+        static void __execute_impl(__task* __p) noexcept
+        {
+            auto& __rcvr = static_cast<__t*>(__p)->__rcvr_;
+            try
+            {
+                if (stdexec::get_stop_token(stdexec::get_env(__rcvr))
+                        .stop_requested())
+                {
+                    stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
+                }
+                else
+                {
+                    stdexec::set_value(static_cast<_Receiver&&>(__rcvr));
+                }
+            }
+            catch (...)
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                   std::current_exception());
+            }
+        }
+
+        explicit __t(__task* __tail) noexcept : __task{{}, this, __tail} {}
+
+        __t(__task* __next, run_loop* __loop, _Receiver __rcvr) :
+            __task{{}, __next, {}}, __loop_{__loop},
+            __rcvr_{static_cast<_Receiver&&>(__rcvr)}
+        {
+            __execute_ = &__execute_impl;
+        }
+
+        void start() & noexcept;
+    };
+};
+
+class run_loop
+{
+    template <class>
+    friend struct __operation;
+
+  public:
+    struct __scheduler
+    {
+      private:
+        struct __schedule_task
+        {
+            using __t = __schedule_task;
+            using __id = __schedule_task;
+            using sender_concept = sender_t;
+            using completion_signatures =
+                stdexec::completion_signatures<set_value_t(),
+                                               set_error_t(std::exception_ptr),
+                                               set_stopped_t()>;
+
+            template <class _Receiver>
+            using __operation =
+                stdexec::__t<__operation<stdexec::__id<_Receiver>>>;
+
+            template <class _Receiver>
+            auto connect(_Receiver __rcvr) const -> __operation<_Receiver>
+            {
+                return {&__loop_->__head_, __loop_,
+                        static_cast<_Receiver&&>(__rcvr)};
+            }
+
+          private:
+            friend __scheduler;
+
+            struct __env
+            {
+                using __t = __env;
+                using __id = __env;
+
+                run_loop* __loop_;
+
+                template <class _CPO>
+                auto query(get_completion_scheduler_t<_CPO>) const noexcept
+                    -> __scheduler
+                {
+                    return __loop_->get_scheduler();
+                }
+            };
+
+            explicit __schedule_task(run_loop* __loop) noexcept :
+                __loop_(__loop)
+            {}
+
+            run_loop* const __loop_;
+
+          public:
+            auto get_env() const noexcept -> __env
+            {
+                return __env{__loop_};
+            }
+        };
+
+        friend run_loop;
+
+        explicit __scheduler(run_loop* __loop) noexcept : __loop_(__loop) {}
+
+        run_loop* __loop_;
+
+      public:
+        using __t = __scheduler;
+        using __id = __scheduler;
+        auto operator==(const __scheduler&) const noexcept -> bool = default;
+
+        [[nodiscard]] auto schedule() const noexcept -> __schedule_task
+        {
+            return __schedule_task{__loop_};
+        }
+
+        auto query(get_forward_progress_guarantee_t) const noexcept
+            -> stdexec::forward_progress_guarantee
+        {
+            return stdexec::forward_progress_guarantee::parallel;
+        }
+
+        // BUGBUG NOT TO SPEC
+        auto query(execute_may_block_caller_t) const noexcept -> bool
+        {
+            return false;
+        }
+    };
+
+    auto get_scheduler() noexcept -> __scheduler
+    {
+        return __scheduler{this};
+    }
+
+    void run();
+
+    void finish();
+
+  private:
+    void __push_back_(__task* __task);
+    auto __pop_front_() -> __task*;
+
+    std::mutex __mutex_;
+    std::condition_variable __cv_;
+    __task __head_{{}, &__head_, {&__head_}};
+    bool __stop_ = false;
+};
+
+template <class _ReceiverId>
+inline void __operation<_ReceiverId>::__t::start() & noexcept
+{
+    try
+    {
+        __loop_->__push_back_(this);
+    }
+    catch (...)
+    {
+        stdexec::set_error(static_cast<_Receiver&&>(__rcvr_),
+                           std::current_exception());
+    }
+}
+
+inline void run_loop::run()
+{
+    for (__task* __task; (__task = __pop_front_()) != &__head_;)
+    {
+        __task->__execute();
+    }
+}
+
+inline void run_loop::finish()
+{
+    std::unique_lock __lock{__mutex_};
+    __stop_ = true;
+    __cv_.notify_all();
+}
+
+inline void run_loop::__push_back_(__task* __task)
+{
+    std::unique_lock __lock{__mutex_};
+    __task->__next_ = &__head_;
+    __head_.__tail_ = __head_.__tail_->__next_ = __task;
+    __cv_.notify_one();
+}
+
+inline auto run_loop::__pop_front_() -> __task*
+{
+    std::unique_lock __lock{__mutex_};
+    __cv_.wait(__lock,
+               [this] { return __head_.__next_ != &__head_ || __stop_; });
+    if (__head_.__tail_ == __head_.__next_)
+        __head_.__tail_ = &__head_;
+    return std::exchange(__head_.__next_, __head_.__next_->__next_);
+}
+} // namespace __loop
+
+// NOT TO SPEC
+using run_loop = __loop::run_loop;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp b/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp
new file mode 100644
index 0000000..9d0da1e
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__schedule_from.hpp
@@ -0,0 +1,285 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__operation_states.hpp"
+#include "__schedulers.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__tuple.hpp"
+#include "__variant.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.schedule_from]
+namespace __schfr
+{
+template <class... _Ts>
+using __tuple_t = __tuple_for<__decay_t<_Ts>...>;
+
+template <class... _Ts>
+using __variant_t = __variant_for<__monostate, _Ts...>;
+
+// Compute a variant type that is capable of storing the results of the
+// input sender when it completes. The variant has type:
+//   variant<
+//     monostate,
+//     tuple<set_stopped_t>,
+//     tuple<set_value_t, __decay_t<_Values1>...>,
+//     tuple<set_value_t, __decay_t<_Values2>...>,
+//        ...
+//     tuple<set_error_t, __decay_t<_Error1>>,
+//     tuple<set_error_t, __decay_t<_Error2>>,
+//        ...
+//   >
+template <class _CvrefSender, class _Env>
+using __variant_for = //
+    __for_each_completion_signature<
+        __completion_signatures_of_t<_CvrefSender, _Env>, __tuple_t,
+        __munique<__qq<__variant_for>>::__f>;
+
+template <class... _Values>
+using __decay_value_sig = set_value_t (*)(__decay_t<_Values>...);
+
+template <class _Error>
+using __decay_error_sig = set_error_t (*)(__decay_t<_Error>);
+
+template <class... _Ts>
+using __all_nothrow_decay_copyable =
+    __mbool<(__nothrow_decay_copyable<_Ts> && ...)>;
+
+template <class _CvrefSender, class... _Env>
+using __all_nothrow_decay_copyable_results = //
+    __for_each_completion_signature<
+        __completion_signatures_of_t<_CvrefSender, _Env...>,
+        __all_nothrow_decay_copyable, __mand_t>;
+
+template <class _Scheduler, class _CvrefSender, class... _Env>
+using __completions_t = //
+    __mtry_q<__concat_completion_signatures>::__f<
+        __transform_completion_signatures<
+            __completion_signatures_of_t<_CvrefSender, _Env...>,
+            __decay_value_sig, __decay_error_sig, set_stopped_t (*)(),
+            __completion_signature_ptrs>,
+        transform_completion_signatures<
+            __completion_signatures_of_t<schedule_result_t<_Scheduler>,
+                                         _Env...>,
+            __eptr_completion_if_t<
+                __all_nothrow_decay_copyable_results<_CvrefSender, _Env...>>,
+            __mconst<completion_signatures<>>::__f>>;
+
+template <class _SchedulerId>
+struct __environ
+{
+    using _Scheduler = stdexec::__t<_SchedulerId>;
+
+    struct __t
+    {
+        using __id = __environ;
+
+        _Scheduler __sched_;
+
+        template <__one_of<set_value_t, set_stopped_t> _Tag>
+        auto query(get_completion_scheduler_t<_Tag>) const noexcept
+        {
+            return __sched_;
+        }
+
+        auto query(get_domain_t) const noexcept
+        {
+            return query_or(get_domain, __sched_, default_domain());
+        }
+    };
+};
+
+template <class _Scheduler, class _Sexpr, class _Receiver>
+struct __state;
+
+template <class _State>
+STDEXEC_ATTRIBUTE((always_inline))
+auto __make_visitor_fn(_State* __state) noexcept
+{
+    return [__state]<class _Tup>(_Tup& __tupl) noexcept -> void {
+        if constexpr (__same_as<_Tup, __monostate>)
+        {
+            std::terminate(); // reaching this indicates a bug in schedule_from
+        }
+        else
+        {
+            __tupl.apply(
+                [&]<class... _Args>(auto __tag,
+                                    _Args&... __args) noexcept -> void {
+                __tag(std::move(__state->__receiver()),
+                      static_cast<_Args&&>(__args)...);
+            },
+                __tupl);
+        }
+    };
+}
+
+// This receiver is to be completed on the execution context associated with the
+// scheduler. When the source sender completes, the completion information is
+// saved off in the operation state so that when this receiver completes, it can
+// read the completion out of the operation state and forward it to the output
+// receiver after transitioning to the scheduler's context.
+template <class _Scheduler, class _Sexpr, class _Receiver>
+struct __receiver2
+{
+    using receiver_concept = receiver_t;
+
+    void set_value() noexcept
+    {
+        __state_->__data_.visit(__schfr::__make_visitor_fn(__state_),
+                                __state_->__data_);
+    }
+
+    template <class _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        stdexec::set_error(static_cast<_Receiver&&>(__state_->__receiver()),
+                           static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+    {
+        stdexec::set_stopped(static_cast<_Receiver&&>(__state_->__receiver()));
+    }
+
+    auto get_env() const noexcept -> env_of_t<_Receiver>
+    {
+        return stdexec::get_env(__state_->__receiver());
+    }
+
+    __state<_Scheduler, _Sexpr, _Receiver>* __state_;
+};
+
+template <class _Scheduler, class _Sexpr, class _Receiver>
+struct __state : __enable_receiver_from_this<_Sexpr, _Receiver>, __immovable
+{
+    using __variant_t = __variant_for<__child_of<_Sexpr>, env_of_t<_Receiver>>;
+    using __receiver2_t = __receiver2<_Scheduler, _Sexpr, _Receiver>;
+
+    __variant_t __data_;
+    connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t> __state2_;
+    STDEXEC_APPLE_CLANG(__state* __self_;)
+
+    explicit __state(_Scheduler __sched) :
+        __data_(), __state2_(connect(schedule(__sched), __receiver2_t{this}))
+                       STDEXEC_APPLE_CLANG(, __self_(this))
+    {}
+};
+
+struct schedule_from_t
+{
+    template <scheduler _Scheduler, sender _Sender>
+    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
+        -> __well_formed_sender auto
+    {
+        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __env = _Env{{static_cast<_Scheduler&&>(__sched)}};
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<schedule_from_t>(
+                          std::move(__env), static_cast<_Sender&&>(__sndr)));
+    }
+
+    using _Sender = __1;
+    using _Env = __0;
+    using __legacy_customizations_t = __types<tag_invoke_t(
+        schedule_from_t, get_completion_scheduler_t<set_value_t>(_Env&),
+        _Sender)>;
+};
+
+struct __schedule_from_impl : __sexpr_defaults
+{
+    template <class _Sender>
+    using __scheduler_t =
+        __decay_t<__call_result_t<get_completion_scheduler_t<set_value_t>,
+                                  env_of_t<_Sender>>>;
+
+    static constexpr auto get_attrs = //
+        []<class _Data, class _Child>(const _Data& __data,
+                                      const _Child& __child) noexcept {
+        return __env::__join(__data, stdexec::get_env(__child));
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
+        -> __completions_t<__scheduler_t<_Sender>, __child_of<_Sender>,
+                           _Env...> {
+        static_assert(sender_expr_for<_Sender, schedule_from_t>);
+        return {};
+    };
+
+    static constexpr auto get_state =
+        []<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver&) {
+        static_assert(sender_expr_for<_Sender, schedule_from_t>);
+        auto __sched =
+            get_completion_scheduler<set_value_t>(stdexec::get_env(__sndr));
+        using _Scheduler = decltype(__sched);
+        return __state<_Scheduler, _Sender, _Receiver>{__sched};
+    };
+
+    static constexpr auto complete = //
+        []<class _State, class _Receiver, class _Tag, class... _Args>(
+            __ignore, _State& __state, _Receiver& __rcvr, _Tag __tag,
+            _Args&&... __args) noexcept -> void {
+        STDEXEC_APPLE_CLANG(__state.__self_ == &__state ? void()
+                                                        : std::terminate());
+        // Write the tag and the args into the operation state so that we can
+        // forward the completion from within the scheduler's execution context.
+        if constexpr (__nothrow_callable<__tup::__mktuple_t, _Tag, _Args...>)
+        {
+            __state.__data_.emplace_from(__tup::__mktuple, __tag,
+                                         static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            try
+            {
+                __state.__data_.emplace_from(__tup::__mktuple, __tag,
+                                             static_cast<_Args&&>(__args)...);
+            }
+            catch (...)
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                   std::current_exception());
+                return;
+            }
+        }
+
+        // Enqueue the schedule operation so the completion happens on the
+        // scheduler's execution context.
+        stdexec::start(__state.__state2_);
+    };
+};
+} // namespace __schfr
+
+using __schfr::schedule_from_t;
+inline constexpr schedule_from_t schedule_from{};
+
+template <>
+struct __sexpr_impl<schedule_from_t> : __schfr::__schedule_from_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp b/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp
new file mode 100644
index 0000000..d29c080
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__schedulers.hpp
@@ -0,0 +1,161 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__cpo.hpp"
+#include "__env.hpp"
+#include "__senders.hpp"
+#include "__tag_invoke.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.schedule]
+namespace __sched
+{
+struct schedule_t
+{
+    template <__same_as<schedule_t> _Self, class _Scheduler>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    friend auto tag_invoke(_Self, _Scheduler&& __sched) //
+        noexcept(noexcept(static_cast<_Scheduler&&>(__sched).schedule()))
+            -> decltype(static_cast<_Scheduler&&>(__sched).schedule())
+    {
+        static_assert(
+            sender<decltype(static_cast<_Scheduler&&>(__sched).schedule())>,
+            "schedule() member functions must return a sender");
+        return static_cast<_Scheduler&&>(__sched).schedule();
+    }
+
+    template <class _Scheduler>
+        requires tag_invocable<schedule_t, _Scheduler>
+    STDEXEC_ATTRIBUTE((host, device)) auto
+        operator()(_Scheduler&& __sched) const
+        noexcept(nothrow_tag_invocable<schedule_t, _Scheduler>)
+    {
+        static_assert(sender<tag_invoke_result_t<schedule_t, _Scheduler>>);
+        return tag_invoke(schedule_t{}, static_cast<_Scheduler&&>(__sched));
+    }
+
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return false;
+    }
+};
+} // namespace __sched
+
+using __sched::schedule_t;
+inline constexpr schedule_t schedule{};
+
+template <class _Scheduler>
+concept __has_schedule = //
+    requires(_Scheduler&& __sched) {
+        {
+            schedule(static_cast<_Scheduler&&>(__sched))
+        } -> sender;
+    };
+
+template <class _Scheduler>
+concept __sender_has_completion_scheduler =
+    requires(_Scheduler&& __sched) {
+        {
+            stdexec::__decay_copy(get_completion_scheduler<set_value_t>(
+                get_env(schedule(static_cast<_Scheduler&&>(__sched)))))
+        } -> same_as<__decay_t<_Scheduler>>;
+    };
+
+template <class _Scheduler>
+concept scheduler =                                  //
+    __has_schedule<_Scheduler>                       //
+    && __sender_has_completion_scheduler<_Scheduler> //
+    && equality_comparable<__decay_t<_Scheduler>>    //
+    && copy_constructible<__decay_t<_Scheduler>>;
+
+template <scheduler _Scheduler>
+using schedule_result_t = __call_result_t<schedule_t, _Scheduler>;
+
+template <class _SchedulerProvider>
+concept __scheduler_provider = //
+    requires(const _SchedulerProvider& __sp) {
+        {
+            get_scheduler(__sp)
+        } -> scheduler;
+    };
+
+namespace __queries
+{
+template <class _Env>
+    requires tag_invocable<get_scheduler_t, const _Env&>
+inline auto get_scheduler_t::operator()(const _Env& __env) const noexcept
+    -> tag_invoke_result_t<get_scheduler_t, const _Env&>
+{
+    static_assert(nothrow_tag_invocable<get_scheduler_t, const _Env&>);
+    static_assert(scheduler<tag_invoke_result_t<get_scheduler_t, const _Env&>>);
+    return tag_invoke(get_scheduler_t{}, __env);
+}
+
+template <class _Env>
+    requires tag_invocable<get_delegatee_scheduler_t, const _Env&>
+inline auto
+    get_delegatee_scheduler_t::operator()(const _Env& __env) const noexcept
+    -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>
+{
+    static_assert(
+        nothrow_tag_invocable<get_delegatee_scheduler_t, const _Env&>);
+    static_assert(
+        scheduler<tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>>);
+    return tag_invoke(get_delegatee_scheduler_t{}, __env);
+}
+
+template <__completion_tag _Tag>
+template <__has_completion_scheduler_for<_Tag> _Env>
+auto get_completion_scheduler_t<_Tag>::operator()(
+    const _Env& __env) const noexcept
+    -> tag_invoke_result_t<get_completion_scheduler_t<_Tag>, const _Env&>
+{
+    static_assert(
+        nothrow_tag_invocable<get_completion_scheduler_t<_Tag>, const _Env&>,
+        "get_completion_scheduler<_Tag> should be noexcept");
+    static_assert(
+        scheduler<tag_invoke_result_t<get_completion_scheduler_t<_Tag>,
+                                      const _Env&>>);
+    return tag_invoke(*this, __env);
+}
+} // namespace __queries
+
+namespace __detail
+{
+// A handy utility for augmenting an environment with a scheduler.
+template <class _Env, class _Scheduler>
+STDEXEC_ATTRIBUTE((always_inline))
+auto __mkenv_sched(_Env&& __env, _Scheduler __sched)
+{
+    auto __env2 =
+        __env::__join(prop{get_scheduler, __sched},
+                      __env::__without(static_cast<_Env&&>(__env), get_domain));
+    using _Env2 = decltype(__env2);
+
+    struct __env_t : _Env2
+    {};
+
+    return __env_t{static_cast<_Env2&&>(__env2)};
+}
+} // namespace __detail
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp b/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp
new file mode 100644
index 0000000..5a7fa8d
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__sender_adaptor_closure.hpp
@@ -0,0 +1,143 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__execution_fwd.hpp"
+#include "__senders_core.hpp"
+#include "__tuple.hpp"
+#include "__type_traits.hpp"
+
+namespace stdexec
+{
+// NOT TO SPEC:
+namespace __closure
+{
+template <__class _Dp>
+struct sender_adaptor_closure;
+} // namespace __closure
+
+using __closure::sender_adaptor_closure;
+
+template <class _Tp>
+concept __sender_adaptor_closure =
+    derived_from<__decay_t<_Tp>, sender_adaptor_closure<__decay_t<_Tp>>> &&
+    move_constructible<__decay_t<_Tp>> //
+    && constructible_from<__decay_t<_Tp>, _Tp>;
+
+template <class _Tp, class _Sender>
+concept __sender_adaptor_closure_for =     //
+    __sender_adaptor_closure<_Tp>          //
+    && sender<__decay_t<_Sender>>          //
+    && __callable<_Tp, __decay_t<_Sender>> //
+    && sender<__call_result_t<_Tp, __decay_t<_Sender>>>;
+
+namespace __closure
+{
+template <class _T0, class _T1>
+struct __compose : sender_adaptor_closure<__compose<_T0, _T1>>
+{
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _T0 __t0_;
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _T1 __t1_;
+
+    template <sender _Sender>
+        requires __callable<_T0, _Sender> &&
+                 __callable<_T1, __call_result_t<_T0, _Sender>>
+    STDEXEC_ATTRIBUTE((always_inline))
+        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
+        operator()(_Sender&& __sndr) &&
+    {
+        return static_cast<_T1&&>(__t1_)(
+            static_cast<_T0&&>(__t0_)(static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <sender _Sender>
+        requires __callable<const _T0&, _Sender> &&
+                 __callable<const _T1&, __call_result_t<const _T0&, _Sender>>
+    STDEXEC_ATTRIBUTE((always_inline))
+        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
+        operator()(_Sender&& __sndr) const&
+    {
+        return __t1_(__t0_(static_cast<_Sender&&>(__sndr)));
+    }
+};
+
+template <__class _Dp>
+struct sender_adaptor_closure
+{};
+
+template <sender _Sender, __sender_adaptor_closure_for<_Sender> _Closure>
+STDEXEC_ATTRIBUTE((always_inline))
+__call_result_t<_Closure, _Sender> operator|(_Sender&& __sndr,
+                                             _Closure&& __clsur)
+{
+    return static_cast<_Closure&&>(__clsur)(static_cast<_Sender&&>(__sndr));
+}
+
+template <__sender_adaptor_closure _T0, __sender_adaptor_closure _T1>
+STDEXEC_ATTRIBUTE((always_inline))
+__compose<__decay_t<_T0>, __decay_t<_T1>> operator|(_T0&& __t0, _T1&& __t1)
+{
+    return {{}, static_cast<_T0&&>(__t0), static_cast<_T1&&>(__t1)};
+}
+
+template <class _Fun, class... _As>
+struct __binder_back :
+    __tuple_for<_As...>,
+    sender_adaptor_closure<__binder_back<_Fun, _As...>>
+{
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Fun __fun_{};
+
+    template <sender _Sender>
+        requires __callable<_Fun, _Sender, _As...>
+    STDEXEC_ATTRIBUTE((host, device,
+                       always_inline)) __call_result_t<_Fun, _Sender, _As...>
+        operator()(_Sender&& __sndr) && noexcept(
+            __nothrow_callable<_Fun, _Sender, _As...>)
+    {
+        return this->apply(
+            [&__sndr, this](_As&... __as) noexcept(
+                __nothrow_callable<_Fun, _Sender, _As...>)
+                -> __call_result_t<_Fun, _Sender, _As...> {
+            return static_cast<_Fun&&>(__fun_)(static_cast<_Sender&&>(__sndr),
+                                               static_cast<_As&&>(__as)...);
+        },
+            *this);
+    }
+
+    template <sender _Sender>
+        requires __callable<const _Fun&, _Sender, const _As&...>
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) auto
+        operator()(_Sender&& __sndr) const& //
+        noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
+            -> __call_result_t<const _Fun&, _Sender, const _As&...>
+    {
+        return this->apply(
+            [&__sndr, this](const _As&... __as) noexcept(
+                __nothrow_callable<_Fun, _Sender, const _As&...>)
+                -> __call_result_t<const _Fun&, _Sender, const _As&...> {
+            return __fun_(static_cast<_Sender&&>(__sndr), __as...);
+        },
+            *this);
+    }
+};
+} // namespace __closure
+
+using __closure::__binder_back;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__sender_introspection.hpp b/include/sdbusplus/async/stdexec/__detail/__sender_introspection.hpp
new file mode 100644
index 0000000..1c76e81
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__sender_introspection.hpp
@@ -0,0 +1,116 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+namespace stdexec
+{
+namespace __detail
+{
+// A function object that is to senders what std::apply is to tuples:
+struct __sexpr_apply_t
+{
+    template <class _Sender, class _ApplyFn>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Sender&& __sndr, _ApplyFn&& __fun) const            //
+        noexcept(noexcept(__sndr.apply(static_cast<_Sender&&>(__sndr),
+                                       static_cast<_ApplyFn&&>(__fun)))) //
+        -> decltype(__sndr.apply(static_cast<_Sender&&>(__sndr),
+                                 static_cast<_ApplyFn&&>(__fun)))
+    {
+        return __sndr.apply(static_cast<_Sender&&>(__sndr),
+                            static_cast<_ApplyFn&&>(__fun)); //
+    }
+};
+
+// A type that describes a sender's metadata
+template <class _Tag, class _Data, class... _Child>
+struct __desc
+{
+    using __tag = _Tag;
+    using __data = _Data;
+    using __children = __types<_Child...>;
+
+    template <class _Fn>
+    using __f = __minvoke<_Fn, _Tag, _Data, _Child...>;
+};
+
+template <class _Fn>
+struct __sexpr_uncurry_fn
+{
+    template <class _Tag, class _Data, class... _Child>
+    constexpr auto operator()(_Tag, _Data&&, _Child&&...) const noexcept
+        -> __minvoke<_Fn, _Tag, _Data, _Child...>;
+};
+
+template <class _CvrefSender, class _Fn>
+using __sexpr_uncurry =
+    __call_result_t<__sexpr_apply_t, _CvrefSender, __sexpr_uncurry_fn<_Fn>>;
+
+template <class _Sender>
+using __desc_of = __sexpr_uncurry<_Sender, __q<__desc>>;
+
+using __get_desc = __sexpr_uncurry_fn<__q<__desc>>;
+} // namespace __detail
+
+using __detail::__sexpr_apply_t;
+inline constexpr __sexpr_apply_t __sexpr_apply{};
+
+template <class _Sender, class _ApplyFn>
+using __sexpr_apply_result_t =
+    __call_result_t<__sexpr_apply_t, _Sender, _ApplyFn>;
+
+template <class _Sender>
+using tag_of_t = typename __detail::__desc_of<_Sender>::__tag;
+
+template <class _Sender>
+using __data_of = typename __detail::__desc_of<_Sender>::__data;
+
+template <class _Sender, class _Continuation = __q<__types>>
+using __children_of = //
+    __mapply<_Continuation, typename __detail::__desc_of<_Sender>::__children>;
+
+template <class _Ny, class _Sender>
+using __nth_child_of = __children_of<_Sender, __mbind_front_q<__m_at, _Ny>>;
+
+template <std::size_t _Ny, class _Sender>
+using __nth_child_of_c =
+    __children_of<_Sender, __mbind_front_q<__m_at, __msize_t<_Ny>>>;
+
+template <class _Sender>
+using __child_of = __children_of<_Sender, __q<__mfront>>;
+
+template <class _Sender>
+inline constexpr std::size_t __nbr_children_of =
+    __v<__children_of<_Sender, __msize>>;
+
+template <class _Tp>
+    requires __mvalid<tag_of_t, _Tp>
+struct __muncurry_<_Tp>
+{
+    template <class _Fn>
+    using __f = __detail::__sexpr_uncurry<_Tp, _Fn>;
+};
+
+template <class _Sender>
+concept sender_expr = //
+    __mvalid<tag_of_t, _Sender>;
+
+template <class _Sender, class _Tag>
+concept sender_expr_for = //
+    sender_expr<_Sender> && same_as<tag_of_t<_Sender>, _Tag>;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__senders.hpp b/include/sdbusplus/async/stdexec/__detail/__senders.hpp
new file mode 100644
index 0000000..02d9ef2
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__senders.hpp
@@ -0,0 +1,420 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__awaitable.hpp"
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__connect_awaitable.hpp"
+#include "__debug.hpp"
+#include "__env.hpp"
+#include "__operation_states.hpp"
+#include "__receivers.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.get_completion_signatures]
+namespace __detail
+{
+struct __dependent_completions
+{};
+
+template <class _Completions>
+concept __well_formed_sender =
+    __valid_completion_signatures<_Completions> ||
+    __same_as<_Completions, _ERROR_<__dependent_completions>>;
+} // namespace __detail
+
+using dependent_completions = _ERROR_<__detail::__dependent_completions>;
+
+namespace __sigs
+{
+template <class _Sender, class _Env>
+using __tfx_sender =
+    transform_sender_result_t<__late_domain_of_t<_Sender, _Env>, _Sender, _Env>;
+
+template <class _Sender, class... _Env>
+using __member_result_t =
+    decltype(__declval<_Sender>().get_completion_signatures(
+        __declval<_Env>()...));
+
+template <class _Sender, class... _Env>
+using __static_member_result_t =               //
+    decltype(STDEXEC_REMOVE_REFERENCE(_Sender) //
+             ::get_completion_signatures(__declval<_Sender>(),
+                                         __declval<_Env>()...));
+
+template <class _Sender, class... _Env>
+concept __with_member = __mvalid<__member_result_t, _Sender, _Env...>;
+
+template <class _Sender, class... _Env>
+concept __with_static_member =
+    __mvalid<__static_member_result_t, _Sender, _Env...>;
+
+template <class _Sender, class... _Env>
+concept __with_tag_invoke = //
+    tag_invocable<get_completion_signatures_t, _Sender, _Env...>;
+
+template <class _Sender, class... _Env>
+concept __with_legacy_tag_invoke = //
+    (sizeof...(_Env) == 0) &&
+    tag_invocable<get_completion_signatures_t, _Sender, empty_env>;
+
+template <class _Sender>
+using __member_alias_t = //
+    typename __decay_t<_Sender>::completion_signatures;
+
+template <class _Sender>
+concept __with_member_alias = __mvalid<__member_alias_t, _Sender>;
+
+struct get_completion_signatures_t
+{
+    template <class _Sender, class... _Env>
+    static auto __impl()
+    {
+        // Compute the type of the transformed sender:
+        using __tfx_fn =
+            __if_c<sizeof...(_Env) == 0, __mconst<_Sender>, __q<__tfx_sender>>;
+        using _TfxSender = __minvoke<__tfx_fn, _Sender, _Env...>;
+
+        if constexpr (__merror<_TfxSender>)
+        {
+            // Computing the type of the transformed sender returned an error
+            // type. Propagate it.
+            return static_cast<_TfxSender (*)()>(nullptr);
+        }
+        else if constexpr (__with_member_alias<_TfxSender>)
+        {
+            using _Result = __member_alias_t<_TfxSender>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else if constexpr (__with_static_member<_TfxSender, _Env...>)
+        {
+            using _Result = __static_member_result_t<_TfxSender, _Env...>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else if constexpr (__with_member<_TfxSender, _Env...>)
+        {
+            using _Result = __member_result_t<_TfxSender, _Env...>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else if constexpr (__with_tag_invoke<_TfxSender, _Env...>)
+        {
+            using _Result = tag_invoke_result_t<get_completion_signatures_t,
+                                                _TfxSender, _Env...>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else if constexpr (__with_legacy_tag_invoke<_TfxSender, _Env...>)
+        {
+            // This branch is strictly for backwards compatibility
+            using _Result = tag_invoke_result_t<get_completion_signatures_t,
+                                                _Sender, empty_env>;
+            return static_cast<_Result (*)()>(nullptr);
+            // [WAR] The explicit cast to bool below is to work around a bug in
+            // nvc++ (nvbug#4707793)
+        }
+        else if constexpr (bool(__awaitable<_TfxSender,
+                                            __env::__promise<_Env>...>))
+        {
+            using _AwaitResult =
+                __await_result_t<_TfxSender, __env::__promise<_Env>...>;
+            using _Result = completion_signatures<
+                // set_value_t() or set_value_t(T)
+                __minvoke<__mremove<void, __qf<set_value_t>>, _AwaitResult>,
+                set_error_t(std::exception_ptr), set_stopped_t()>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else if constexpr (sizeof...(_Env) == 0)
+        {
+            // It's possible this is a dependent sender.
+            return static_cast<dependent_completions (*)()>(nullptr);
+        }
+        else if constexpr ((__is_debug_env<_Env> || ...))
+        {
+            using __tag_invoke::tag_invoke;
+            // This ought to cause a hard error that indicates where the problem
+            // is.
+            using _Completions [[maybe_unused]] =
+                tag_invoke_result_t<get_completion_signatures_t, _Sender,
+                                    _Env...>;
+            return static_cast<__debug::__completion_signatures (*)()>(nullptr);
+        }
+        else
+        {
+            using _Result = __mexception<_UNRECOGNIZED_SENDER_TYPE_<>,
+                                         _WITH_SENDER_<_Sender>,
+                                         _WITH_ENVIRONMENT_<_Env>...>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+    }
+
+    // NOT TO SPEC: if we're unable to compute the completion signatures,
+    // return an error type instead of SFINAE.
+    template <class _Sender, class... _Env>
+        requires(sizeof...(_Env) <= 1)
+    constexpr auto operator()(_Sender&&, _Env&&...) const noexcept //
+        -> decltype(__impl<_Sender, _Env...>()())
+    {
+        return {};
+    }
+};
+} // namespace __sigs
+
+using __sigs::get_completion_signatures_t;
+inline constexpr get_completion_signatures_t get_completion_signatures{};
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.connect]
+namespace __connect
+{
+template <class _Sender, class _Receiver>
+using __tfx_sender = //
+    transform_sender_result_t<__late_domain_of_t<_Sender, env_of_t<_Receiver>>,
+                              _Sender, env_of_t<_Receiver>>;
+
+template <class _Sender, class _Receiver>
+using __member_result_t =
+    decltype(__declval<_Sender>().connect(__declval<_Receiver>()));
+
+template <class _Sender, class _Receiver>
+using __static_member_result_t =
+    decltype(STDEXEC_REMOVE_REFERENCE(_Sender) //
+             ::connect(__declval<_Sender>(), __declval<_Receiver>()));
+
+template <class _Sender, class _Receiver>
+concept __with_member = __mvalid<__member_result_t, _Sender, _Receiver>;
+
+template <class _Sender, class _Receiver>
+concept __with_static_member =
+    __mvalid<__static_member_result_t, _Sender, _Receiver>;
+
+template <class _Sender, class _Receiver>
+concept __with_tag_invoke = tag_invocable<connect_t, _Sender, _Receiver>;
+
+template <class _Sender, class _Receiver>
+concept __with_co_await = __callable<__connect_awaitable_t, _Sender, _Receiver>;
+
+struct connect_t
+{
+    template <class _Sender, class _Env>
+    static constexpr auto __check_signatures() -> bool
+    {
+        if constexpr (sender_in<_Sender, _Env>)
+        {
+            // Instantiate __debug_sender via completion_signatures_of_t to
+            // check that the actual completions match the expected completions.
+            //
+            // Instantiate completion_signatures_of_t only if sender_in is true
+            // to workaround Clang not implementing CWG#2369 yet (connect() does
+            // not have a constraint for _Sender satisfying sender_in).
+            using __checked_signatures
+                [[maybe_unused]] = completion_signatures_of_t<_Sender, _Env>;
+        }
+        return true;
+    }
+
+    template <class _Sender, class _Receiver>
+    static constexpr auto __select_impl() noexcept
+    {
+        using _Domain = __late_domain_of_t<_Sender, env_of_t<_Receiver>>;
+        using _TfxSender = __tfx_sender<_Sender, _Receiver>;
+        constexpr bool _NothrowTfxSender =
+            __nothrow_callable<transform_sender_t, _Domain, _Sender,
+                               env_of_t<_Receiver>>;
+
+#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
+        static_assert(__check_signatures<_TfxSender, env_of_t<_Receiver>>());
+#endif
+
+        if constexpr (__with_static_member<_TfxSender, _Receiver>)
+        {
+            using _Result = __static_member_result_t<_TfxSender, _Receiver>;
+            constexpr bool _Nothrow = //
+                _NothrowTfxSender&& noexcept(__declval<_TfxSender>().connect(
+                    __declval<_TfxSender>(), __declval<_Receiver>()));
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else if constexpr (__with_member<_TfxSender, _Receiver>)
+        {
+            using _Result = __member_result_t<_TfxSender, _Receiver>;
+            constexpr bool _Nothrow = //
+                _NothrowTfxSender&& noexcept(
+                    __declval<_TfxSender>().connect(__declval<_Receiver>()));
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else if constexpr (__with_tag_invoke<_TfxSender, _Receiver>)
+        {
+            using _Result =
+                tag_invoke_result_t<connect_t, _TfxSender, _Receiver>;
+            constexpr bool _Nothrow = //
+                _NothrowTfxSender &&
+                nothrow_tag_invocable<connect_t, _TfxSender, _Receiver>;
+            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
+        }
+        else if constexpr (__with_co_await<_TfxSender, _Receiver>)
+        {
+            using _Result =
+                __call_result_t<__connect_awaitable_t, _TfxSender, _Receiver>;
+            return static_cast<_Result (*)()>(nullptr);
+        }
+        else
+        {
+            using _Result = __debug::__debug_operation;
+            return static_cast<_Result (*)() noexcept(_NothrowTfxSender)>(
+                nullptr);
+        }
+    }
+
+    template <class _Sender, class _Receiver>
+    using __select_impl_t = decltype(__select_impl<_Sender, _Receiver>());
+
+    template <sender _Sender, receiver _Receiver>
+        requires __with_static_member<__tfx_sender<_Sender, _Receiver>,
+                                      _Receiver> ||
+                 __with_member<__tfx_sender<_Sender, _Receiver>, _Receiver> ||
+                 __with_tag_invoke<__tfx_sender<_Sender, _Receiver>,
+                                   _Receiver> ||
+                 __with_co_await<__tfx_sender<_Sender, _Receiver>, _Receiver> ||
+                 __is_debug_env<env_of_t<_Receiver>>
+    auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
+        noexcept(__nothrow_callable<__select_impl_t<_Sender, _Receiver>>)
+            -> __call_result_t<__select_impl_t<_Sender, _Receiver>>
+    {
+        using _TfxSender = __tfx_sender<_Sender, _Receiver>;
+        auto&& __env = get_env(__rcvr);
+        auto __domain = __get_late_domain(__sndr, __env);
+
+        if constexpr (__with_static_member<_TfxSender, _Receiver>)
+        {
+            static_assert(
+                operation_state<
+                    __static_member_result_t<_TfxSender, _Receiver>>,
+                "Sender::connect(sender, receiver) must return a type that "
+                "satisfies the operation_state concept");
+            auto&& __tfx_sndr = transform_sender(
+                __domain, static_cast<_Sender&&>(__sndr), __env);
+            return __tfx_sndr.connect(static_cast<_TfxSender&&>(__tfx_sndr),
+                                      static_cast<_Receiver&&>(__rcvr));
+        }
+        else if constexpr (__with_member<_TfxSender, _Receiver>)
+        {
+            static_assert(
+                operation_state<__member_result_t<_TfxSender, _Receiver>>,
+                "sender.connect(receiver) must return a type that "
+                "satisfies the operation_state concept");
+            return transform_sender(__domain, static_cast<_Sender&&>(__sndr),
+                                    __env)
+                .connect(static_cast<_Receiver&&>(__rcvr));
+        }
+        else if constexpr (__with_tag_invoke<_TfxSender, _Receiver>)
+        {
+            static_assert(
+                operation_state<
+                    tag_invoke_result_t<connect_t, _TfxSender, _Receiver>>,
+                "stdexec::connect(sender, receiver) must return a type that "
+                "satisfies the operation_state concept");
+            return tag_invoke(connect_t(),
+                              transform_sender(__domain,
+                                               static_cast<_Sender&&>(__sndr),
+                                               __env),
+                              static_cast<_Receiver&&>(__rcvr));
+        }
+        else if constexpr (__with_co_await<_TfxSender, _Receiver>)
+        {
+            return __connect_awaitable( //
+                transform_sender(__domain, static_cast<_Sender&&>(__sndr),
+                                 __env),
+                static_cast<_Receiver&&>(__rcvr));
+        }
+        else
+        {
+            // This should generate an instantiation backtrace that contains
+            // useful debugging information.
+            using __tag_invoke::tag_invoke;
+            tag_invoke(*this,
+                       transform_sender(__domain,
+                                        static_cast<_Sender&&>(__sndr), __env),
+                       static_cast<_Receiver&&>(__rcvr));
+        }
+    }
+
+    static constexpr auto query(forwarding_query_t) noexcept -> bool
+    {
+        return false;
+    }
+};
+} // namespace __connect
+
+using __connect::connect_t;
+inline constexpr __connect::connect_t connect{};
+
+/////////////////////////////////////////////////////////////////////////////
+// [exec.snd]
+template <class _Sender, class _Receiver>
+concept sender_to =                            //
+    receiver<_Receiver>                        //
+    && sender_in<_Sender, env_of_t<_Receiver>> //
+    && __receiver_from<_Receiver, _Sender>     //
+    && requires(_Sender&& __sndr, _Receiver&& __rcvr) {
+           connect(static_cast<_Sender&&>(__sndr),
+                   static_cast<_Receiver&&>(__rcvr));
+       };
+
+template <class _Tag, class... _Args>
+auto __tag_of_sig_(_Tag (*)(_Args...)) -> _Tag;
+template <class _Sig>
+using __tag_of_sig_t =
+    decltype(stdexec::__tag_of_sig_(static_cast<_Sig*>(nullptr)));
+
+template <class _Sender, class _SetSig, class _Env = empty_env>
+concept sender_of =          //
+    sender_in<_Sender, _Env> //
+    &&
+    same_as<
+        __types<_SetSig>,
+        __gather_completions_of<
+            __tag_of_sig_t<_SetSig>, _Sender, _Env,
+            __mcompose_q<__types, __qf<__tag_of_sig_t<_SetSig>>::template __f>,
+            __mconcat<__qq<__types>>>>;
+
+template <class _Error>
+    requires false
+using __nofail_t = _Error;
+
+template <class _Sender, class _Env = empty_env>
+concept __nofail_sender =
+    sender_in<_Sender, _Env> &&
+    requires {
+        typename __gather_completion_signatures<
+            __completion_signatures_of_t<_Sender, _Env>, set_error_t,
+            __nofail_t, __sigs::__default_completion, __types>;
+    };
+
+/////////////////////////////////////////////////////////////////////////////
+// early sender type-checking
+template <class _Sender>
+concept __well_formed_sender = __detail::__well_formed_sender<__minvoke<
+    __with_default_q<__completion_signatures_of_t, dependent_completions>,
+    _Sender>>;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__senders_core.hpp b/include/sdbusplus/async/stdexec/__detail/__senders_core.hpp
new file mode 100644
index 0000000..e711b06
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__senders_core.hpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__awaitable.hpp"
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__receivers.hpp"
+#include "__type_traits.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders]
+struct sender_t
+{
+    using sender_concept = sender_t;
+};
+
+namespace __detail
+{
+template <class _Sender>
+concept __enable_sender =                     //
+    derived_from<typename _Sender::sender_concept, sender_t> ||
+    requires { typename _Sender::is_sender; } // NOT TO SPEC back compat
+    || __awaitable<_Sender, __env::__promise<empty_env>>;
+} // namespace __detail
+
+template <class _Sender>
+inline constexpr bool enable_sender = __detail::__enable_sender<_Sender>;
+
+template <class _Sender>
+concept sender =                                          //
+    enable_sender<__decay_t<_Sender>>                     //
+    && environment_provider<__cref_t<_Sender>>            //
+    && __detail::__consistent_completion_domains<_Sender> //
+    && move_constructible<__decay_t<_Sender>>             //
+    && constructible_from<__decay_t<_Sender>, _Sender>;
+
+template <class _Sender, class... _Env>
+concept sender_in =
+    (sizeof...(_Env) <= 1) //
+    && sender<_Sender>     //
+    && requires(_Sender&& __sndr, _Env&&... __env) {
+           {
+               get_completion_signatures(static_cast<_Sender&&>(__sndr),
+                                         static_cast<_Env&&>(__env)...)
+           } -> __valid_completion_signatures;
+       };
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__shared.hpp b/include/sdbusplus/async/stdexec/__detail/__shared.hpp
new file mode 100644
index 0000000..49f9473
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__shared.hpp
@@ -0,0 +1,543 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "../functional.hpp"
+#include "../stop_token.hpp"
+#include "__basic_sender.hpp"
+#include "__cpo.hpp"
+#include "__env.hpp"
+#include "__intrusive_ptr.hpp"
+#include "__intrusive_slist.hpp"
+#include "__meta.hpp"
+#include "__optional.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__tuple.hpp"
+#include "__variant.hpp"
+
+#include <exception>
+#include <mutex>
+
+namespace stdexec
+{
+////////////////////////////////////////////////////////////////////////////
+// shared components of split and ensure_started
+//
+// The split and ensure_started algorithms are very similar in implementation.
+// The salient differences are:
+//
+// split: the input async operation is always connected. It is only
+//   started when one of the split senders is connected and started.
+//   split senders are copyable, so there are multiple operation states
+//   to be notified on completion. These are stored in an instrusive
+//   linked list.
+//
+// ensure_started: the input async operation is always started, so
+//   the internal receiver will always be completed. The ensure_started
+//   sender is move-only and single-shot, so there will only ever be one
+//   operation state to be notified on completion.
+//
+// The shared state should add-ref itself when the input async
+// operation is started and release itself when its completion
+// is notified.
+namespace __shared
+{
+template <class _BaseEnv>
+using __env_t =                //
+    __env::__join_t<prop<get_stop_token_t, inplace_stop_token>,
+                    _BaseEnv>; // BUGBUG NOT TO SPEC
+
+template <class _Receiver>
+auto __make_notify_visitor(_Receiver& __rcvr) noexcept
+{
+    return [&]<class _Tuple>(_Tuple&& __tupl) noexcept -> void {
+        __tupl.apply(
+            [&](auto __tag, auto&&... __args) noexcept -> void {
+            __tag(static_cast<_Receiver&&>(__rcvr),
+                  __forward_like<_Tuple>(__args)...);
+        },
+            __tupl);
+    };
+}
+
+struct __local_state_base : __immovable
+{
+    using __notify_fn = void(__local_state_base*) noexcept;
+
+    __notify_fn* __notify_{};
+    __local_state_base* __next_{};
+};
+
+template <class _CvrefSender, class _Env>
+struct __shared_state;
+
+// The operation state of ensure_started, and each operation state of split, has
+// one of these, created when the sender is connected. There are 0 or more of
+// them for each underlying async operation. It is what ensure_started- and
+// split-sender's `get_state` fn returns. It holds a ref count to the shared
+// state.
+template <class _CvrefSender, class _Receiver>
+struct __local_state :
+    __local_state_base,
+    __enable_receiver_from_this<_CvrefSender, _Receiver>
+{
+    using __tag_t = tag_of_t<_CvrefSender>;
+    using __stok_t = stop_token_of_t<env_of_t<_Receiver>>;
+    static_assert(__one_of<__tag_t, __split::__split_t,
+                           __ensure_started::__ensure_started_t>);
+
+    explicit __local_state(_CvrefSender&& __sndr) noexcept :
+        __local_state::__local_state_base{{},
+                                          &__notify<tag_of_t<_CvrefSender>>},
+        __sh_state_(__get_sh_state(__sndr))
+    {}
+
+    ~__local_state()
+    {
+        __sh_state_t::__detach(__sh_state_);
+    }
+
+    // Stop request callback:
+    void operator()() noexcept
+    {
+        // We reach here when a split/ensure_started sender has received a stop
+        // request from the receiver to which it is connected.
+        if (std::unique_lock __lock{__sh_state_->__mutex_})
+        {
+            // Remove this operation from the waiters list. Removal can fail if:
+            //   1. It was already removed by another thread, or
+            //   2. It hasn't been added yet (see `start` below), or
+            //   3. The underlying operation has already completed.
+            //
+            // In each case, the right thing to do is nothing. If (1) then we
+            // raced with another thread and lost. In that case, the other
+            // thread will take care of it. If (2) then `start` will take care
+            // of it. If (3) then this stop request is safe to ignore.
+            if (!__sh_state_->__waiters_.remove(this))
+                return;
+        }
+
+        // The following code and the __notify function cannot both execute.
+        // This is because the
+        // __notify function is called from the shared state's __notify_waiters
+        // function, which first sets __waiters_ to the completed state. As a
+        // result, the attempt to remove `this` from the waiters list above will
+        // fail and this stop request is ignored.
+        __sh_state_t::__detach(__sh_state_);
+        stdexec::set_stopped(static_cast<_Receiver&&>(this->__receiver()));
+    }
+
+    // This is called from __shared_state::__notify_waiters when the input async
+    // operation completes; or, if it has already completed when start is
+    // called, it is called from start:
+    // __notify cannot race with __on_stop_request. See comment in
+    // __on_stop_request.
+    template <class _Tag>
+    static void __notify(__local_state_base* __base) noexcept
+    {
+        auto* const __self = static_cast<__local_state*>(__base);
+
+        // The split algorithm sends by T const&. ensure_started sends by T&&.
+        constexpr bool __is_split = same_as<__split::__split_t, _Tag>;
+        using __variant_t = decltype(__self->__sh_state_->__results_);
+        using __cv_variant_t =
+            __if_c<__is_split, const __variant_t&, __variant_t>;
+
+        __self->__on_stop_.reset();
+
+        auto __visitor = __make_notify_visitor(__self->__receiver());
+        __variant_t::visit(__visitor, static_cast<__cv_variant_t&&>(
+                                          __self->__sh_state_->__results_));
+    }
+
+    static auto __get_sh_state(_CvrefSender& __sndr) noexcept
+    {
+        return __sndr
+            .apply(static_cast<_CvrefSender&&>(__sndr), __detail::__get_data())
+            .__sh_state_;
+    }
+
+    using __sh_state_ptr_t = __result_of<__get_sh_state, _CvrefSender&>;
+    using __sh_state_t = typename __sh_state_ptr_t::element_type;
+
+    __optional<stop_callback_for_t<__stok_t, __local_state&>> __on_stop_{};
+    __sh_state_ptr_t __sh_state_;
+};
+
+template <class _CvrefSenderId, class _EnvId>
+struct __receiver
+{
+    using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
+    using _Env = stdexec::__t<_EnvId>;
+
+    struct __t
+    {
+        using receiver_concept = receiver_t;
+        using __id = __receiver;
+
+        template <class... _As>
+        STDEXEC_ATTRIBUTE((always_inline))
+        void set_value(_As&&... __as) noexcept
+        {
+            __sh_state_->__complete(set_value_t(), static_cast<_As&&>(__as)...);
+        }
+
+        template <class _Error>
+        STDEXEC_ATTRIBUTE((always_inline))
+        void set_error(_Error&& __err) noexcept
+        {
+            __sh_state_->__complete(set_error_t(),
+                                    static_cast<_Error&&>(__err));
+        }
+
+        STDEXEC_ATTRIBUTE((always_inline))
+        void set_stopped() noexcept
+        {
+            __sh_state_->__complete(set_stopped_t());
+        }
+
+        auto get_env() const noexcept -> const __env_t<_Env>&
+        {
+            return __sh_state_->__env_;
+        }
+
+        // The receiver does not hold a reference to the shared state.
+        __shared_state<_CvrefSender, _Env>* __sh_state_;
+    };
+};
+
+inline __local_state_base* __get_tombstone() noexcept
+{
+    static __local_state_base __tombstone_{{}, nullptr, nullptr};
+    return &__tombstone_;
+}
+
+template <class _CvrefSender, class _Env>
+struct __shared_state :
+    private __enable_intrusive_from_this<__shared_state<_CvrefSender, _Env>, 2>
+{
+    using __receiver_t = __t<__receiver<__cvref_id<_CvrefSender>, __id<_Env>>>;
+    using __waiters_list_t = __intrusive_slist<&__local_state_base::__next_>;
+
+    using __variant_t = //
+        __transform_completion_signatures<
+            __completion_signatures_of_t<_CvrefSender, _Env>,
+            __mbind_front_q<__decayed_tuple, set_value_t>::__f,
+            __mbind_front_q<__decayed_tuple, set_error_t>::__f,
+            __tuple_for<set_error_t, std::exception_ptr>,
+            __munique<__mbind_front_q<__variant_for,
+                                      __tuple_for<set_stopped_t>>>::__f,
+            __tuple_for<set_error_t, std::exception_ptr>>;
+
+    static constexpr std::size_t __started_bit = 0;
+    static constexpr std::size_t __completed_bit = 1;
+
+    inplace_stop_source __stop_source_{};
+    __env_t<_Env> __env_;
+    __variant_t __results_{}; // Defaults to the "set_stopped" state
+    std::mutex __mutex_;      // This mutex guards access to __waiters_.
+    __waiters_list_t __waiters_{};
+    connect_result_t<_CvrefSender, __receiver_t> __shared_op_;
+
+    explicit __shared_state(_CvrefSender&& __sndr, _Env __env) :
+        __env_(__env::__join(prop{get_stop_token, __stop_source_.get_token()},
+                             static_cast<_Env&&>(__env))),
+        __shared_op_(
+            connect(static_cast<_CvrefSender&&>(__sndr), __receiver_t{this}))
+    {
+        // add one ref count to account for the case where there are no watchers
+        // left but the shared op is still running.
+        this->__inc_ref();
+    }
+
+    // The caller of this wants to release their reference to the shared state.
+    // The ref count must be at least 2 at this point: one owned by the caller,
+    // and one added in the
+    // __shared_state ctor.
+    static void __detach(__intrusive_ptr<__shared_state, 2>& __ptr) noexcept
+    {
+        // Ask the intrusive ptr to stop managing the reference count so we can
+        // manage it manually.
+        if (auto* __self = __ptr.__release_())
+        {
+            auto __old = __self->__dec_ref();
+            STDEXEC_ASSERT(__count(__old) >= 2);
+
+            if (__count(__old) == 2)
+            {
+                // The last watcher has released its reference. Asked the shared
+                // op to stop.
+                static_cast<__shared_state*>(__self)
+                    ->__stop_source_.request_stop();
+
+                // Additionally, if the shared op was never started, or if it
+                // has already completed, then the shared state is no longer
+                // needed. Decrement the ref count to 0 here, which will delete
+                // __self.
+                if (!__bit<__started_bit>(__old) ||
+                    __bit<__completed_bit>(__old))
+                {
+                    __self->__dec_ref();
+                }
+            }
+        }
+    }
+
+    /// @post The started bit is set in the shared state's ref count, OR the
+    /// __waiters_ list is set to the known "tombstone" value indicating
+    /// completion.
+    void __try_start() noexcept
+    {
+        // With the split algorithm, multiple split senders can be started
+        // simultaneously, but only one should start the shared async operation.
+        // If the "started" bit is set, then someone else has already started
+        // the shared operation. Do nothing.
+        if (this->template __is_set<__started_bit>())
+        {
+            return;
+        }
+        else if (__bit<__started_bit>(
+                     this->template __set_bit<__started_bit>()))
+        {
+            return;
+        }
+        else if (__stop_source_.stop_requested())
+        {
+            // Stop has already been requested. Rather than starting the
+            // operation, complete with set_stopped immediately.
+            // 1. Sets __waiters_ to a known "tombstone" value
+            // 2. Notifies all the waiters that the operation has stopped
+            // 3. Sets the "completed" bit in the ref count.
+            __notify_waiters();
+            return;
+        }
+        else
+        {
+            stdexec::start(__shared_op_);
+        }
+    }
+
+    template <class _StopToken>
+    bool __try_add_waiter(__local_state_base* __waiter,
+                          _StopToken __stok) noexcept
+    {
+        std::unique_lock __lock{__mutex_};
+        if (__waiters_.front() == __get_tombstone())
+        {
+            // The work has already completed. Notify the waiter immediately.
+            __lock.unlock();
+            __waiter->__notify_(__waiter);
+            return true;
+        }
+        else if (__stok.stop_requested())
+        {
+            // Stop has been requested. Do not add the waiter.
+            return false;
+        }
+        else
+        {
+            // Add the waiter to the list.
+            __waiters_.push_front(__waiter);
+            return true;
+        }
+    }
+
+    /// @brief This is called when the shared async operation completes.
+    /// @post __waiters_ is set to a known "tombstone" value.
+    template <class _Tag, class... _As>
+    void __complete(_Tag, _As&&... __as) noexcept
+    {
+        try
+        {
+            using __tuple_t = __decayed_tuple<_Tag, _As...>;
+            __results_.template emplace<__tuple_t>(_Tag(),
+                                                   static_cast<_As&&>(__as)...);
+        }
+        catch (...)
+        {
+            using __tuple_t = __decayed_tuple<set_error_t, std::exception_ptr>;
+            __results_.template emplace<__tuple_t>(set_error,
+                                                   std::current_exception());
+        }
+
+        __notify_waiters();
+    }
+
+    /// @brief This is called when the shared async operation completes.
+    /// @post __waiters_ is set to a known "tombstone" value.
+    void __notify_waiters() noexcept
+    {
+        __waiters_list_t __waiters_copy{__get_tombstone()};
+
+        // Set the waiters list to a known "tombstone" value that we can check
+        // later.
+        {
+            std::lock_guard __lock{__mutex_};
+            __waiters_.swap(__waiters_copy);
+        }
+
+        STDEXEC_ASSERT(__waiters_copy.front() != __get_tombstone());
+        for (auto __itr = __waiters_copy.begin();
+             __itr != __waiters_copy.end();)
+        {
+            __local_state_base* __item = *__itr;
+
+            // We must increment the iterator before calling notify, since
+            // notify may end up triggering *__item to be destructed on another
+            // thread, and the intrusive slist's iterator increment relies on
+            // __item.
+            ++__itr;
+
+            __item->__notify_(__item);
+        }
+
+        // Set the "completed" bit in the ref count. If the ref count is 1, then
+        // there are no more waiters. Release the final reference.
+        if (__count(this->template __set_bit<__completed_bit>()) == 1)
+        {
+            this->__dec_ref(); // release the extra ref count, deletes this
+        }
+    }
+};
+
+template <class _Cvref, class _CvrefSender, class _Env>
+using __make_completions = //
+    __try_make_completion_signatures<
+        // NOT TO SPEC:
+        // See https://github.com/cplusplus/sender-receiver/issues/23
+        _CvrefSender, __env_t<_Env>,
+        completion_signatures<set_error_t(
+                                  __minvoke<_Cvref, std::exception_ptr>),
+                              set_stopped_t()>, // NOT TO SPEC
+        __mtransform<_Cvref,
+                     __mcompose<__q<completion_signatures>, __qf<set_value_t>>>,
+        __mtransform<
+            _Cvref, __mcompose<__q<completion_signatures>, __qf<set_error_t>>>>;
+
+// split completes with const T&. ensure_started completes with T&&.
+template <class _Tag>
+using __cvref_results_t = //
+    __mcompose<__if_c<same_as<_Tag, __split::__split_t>, __cpclr, __cp>,
+               __q<__decay_t>>;
+
+// NOTE: the use of __mapply in the return type below takes advantage of the
+// fact that _ShState denotes an instance of the __shared_state template, which
+// is parameterized on the cvref-qualified sender and the environment.
+template <class _Tag, class _ShState>
+using __completions = //
+    __mapply<__mbind_front_q<__make_completions, __cvref_results_t<_Tag>>,
+             _ShState>;
+
+template <class _CvrefSender, class _Env, bool _Copyable = true>
+struct __box
+{
+    using __tag_t = __if_c<_Copyable, __split::__split_t,
+                           __ensure_started::__ensure_started_t>;
+    using __sh_state_t = __shared_state<_CvrefSender, _Env>;
+
+    __box(__tag_t, __intrusive_ptr<__sh_state_t, 2> __sh_state) noexcept :
+        __sh_state_(std::move(__sh_state))
+    {}
+
+    __box(__box&&) noexcept = default;
+    __box(const __box&) noexcept
+        requires _Copyable
+    = default;
+
+    ~__box()
+    {
+        __sh_state_t::__detach(__sh_state_);
+    }
+
+    __intrusive_ptr<__sh_state_t, 2> __sh_state_;
+};
+
+template <class _CvrefSender, class _Env>
+__box(__split::__split_t,
+      __intrusive_ptr<__shared_state<_CvrefSender, _Env>, 2>) //
+    ->__box<_CvrefSender, _Env, true>;
+
+template <class _CvrefSender, class _Env>
+__box(__ensure_started::__ensure_started_t,
+      __intrusive_ptr<__shared_state<_CvrefSender, _Env>, 2>)
+    -> __box<_CvrefSender, _Env, false>;
+
+template <class _Tag>
+struct __shared_impl : __sexpr_defaults
+{
+    static constexpr auto get_state = //
+        []<class _CvrefSender, class _Receiver>(
+            _CvrefSender&& __sndr,
+            _Receiver&) noexcept -> __local_state<_CvrefSender, _Receiver> {
+        static_assert(sender_expr_for<_CvrefSender, _Tag>);
+        return __local_state<_CvrefSender, _Receiver>{
+            static_cast<_CvrefSender&&>(__sndr)};
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Self>(const _Self&, auto&&...) noexcept
+        -> __completions<_Tag, typename __data_of<_Self>::__sh_state_t> {
+        static_assert(sender_expr_for<_Self, _Tag>);
+        return {};
+    };
+
+    static constexpr auto start = //
+        []<class _Sender, class _Receiver>(
+            __local_state<_Sender, _Receiver>& __self,
+            _Receiver& __rcvr) noexcept -> void {
+        using __sh_state_t =
+            typename __local_state<_Sender, _Receiver>::__sh_state_t;
+        // Scenario: there are no more split senders, this is the only operation
+        // state, the underlying operation has not yet been started, and the
+        // receiver's stop token is already in the "stop requested" state. Then
+        // registering the stop callback will call
+        // __on_stop_request on __self synchronously. It may also be called
+        // asynchronously at any point after the callback is registered. Beware.
+        // We are guaranteed, however, that
+        // __on_stop_request will not complete the operation or decrement the
+        // shared state's ref count until after __self has been added to the
+        // waiters list.
+        const auto __stok = stdexec::get_stop_token(stdexec::get_env(__rcvr));
+        __self.__on_stop_.emplace(__stok, __self);
+
+        // We haven't put __self in the waiters list yet and we are holding a
+        // ref count to
+        // __sh_state_, so nothing can happen to the __sh_state_ here.
+
+        // Start the shared op. As an optimization, skip it if the receiver's
+        // stop token has already been signaled.
+        if (!__stok.stop_requested())
+        {
+            __self.__sh_state_->__try_start();
+            if (__self.__sh_state_->__try_add_waiter(&__self, __stok))
+            {
+                // successfully added the waiter
+                return;
+            }
+        }
+
+        // Otherwise, failed to add the waiter because of a stop-request.
+        // Complete synchronously with set_stopped().
+        __self.__on_stop_.reset();
+        __sh_state_t::__detach(__self.__sh_state_);
+        stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
+    };
+};
+} // namespace __shared
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp b/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp
new file mode 100644
index 0000000..7cae36f
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023 Maikel Nadolski
+ * Copyright (c) 2023 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 "../../stdexec/__detail/__config.hpp"
+
+// The below code for spin_loop_pause is taken from
+// https://github.com/max0x7ba/atomic_queue/blob/master/include/atomic_queue/defs.h
+// Copyright (c) 2019 Maxim Egorushkin. MIT License.
+
+#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) ||             \
+    defined(_M_IX86)
+#if STDEXEC_MSVC()
+#include <intrin.h>
+#endif
+namespace stdexec
+{
+STDEXEC_ATTRIBUTE((always_inline))
+static void __spin_loop_pause() noexcept
+{
+#if STDEXEC_MSVC()
+    _mm_pause();
+#else
+    __builtin_ia32_pause();
+#endif
+}
+} // namespace stdexec
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64)
+namespace stdexec
+{
+STDEXEC_ATTRIBUTE((always_inline))
+static void __spin_loop_pause() noexcept
+{
+#if (defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) ||                   \
+     defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ||                 \
+     defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||                    \
+     defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ||                   \
+     defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) ||                   \
+     defined(__aarch64__))
+    asm volatile("yield" ::: "memory");
+#elif defined(_M_ARM64)
+    __yield();
+#else
+    asm volatile("nop" ::: "memory");
+#endif
+}
+} // namespace stdexec
+#else
+namespace stdexec
+{
+STDEXEC_ATTRIBUTE((always_inline))
+static void __spin_loop_pause() noexcept {}
+} // namespace stdexec
+#endif
diff --git a/include/sdbusplus/async/stdexec/__detail/__split.hpp b/include/sdbusplus/async/stdexec/__detail/__split.hpp
new file mode 100644
index 0000000..371bb82
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__split.hpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__intrusive_ptr.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__shared.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <utility>
+
+namespace stdexec
+{
+////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.split]
+namespace __split
+{
+using namespace __shared;
+
+struct __split_t
+{};
+
+struct split_t
+{
+    template <sender _Sender, class _Env = empty_env>
+        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
+    auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = __get_late_domain(__sndr, __env);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<split_t>(static_cast<_Env&&>(__env),
+                                            static_cast<_Sender&&>(__sndr)));
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()() const noexcept -> __binder_back<split_t>
+    {
+        return {{}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(split_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(split_t, _Sender)>;
+
+    template <class _CvrefSender, class _Env>
+    using __receiver_t =
+        __t<__meval<__receiver, __cvref_id<_CvrefSender>, __id<_Env>>>;
+
+    template <class _Sender>
+    static auto transform_sender(_Sender&& __sndr)
+    {
+        using _Receiver =
+            __receiver_t<__child_of<_Sender>, __decay_t<__data_of<_Sender>>>;
+        static_assert(sender_to<__child_of<_Sender>, _Receiver>);
+
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             [&]<class _Env, class _Child>(
+                                 __ignore, _Env&& __env, _Child&& __child) {
+            // The shared state starts life with a ref-count of one.
+            auto __sh_state =
+                __make_intrusive<__shared_state<_Child, __decay_t<_Env>>, 2>(
+                    static_cast<_Child&&>(__child), static_cast<_Env&&>(__env));
+
+            return __make_sexpr<__split_t>(
+                __box{__split_t(), std::move(__sh_state)});
+        });
+    }
+};
+} // namespace __split
+
+using __split::split_t;
+inline constexpr split_t split{};
+
+template <>
+struct __sexpr_impl<__split::__split_t> :
+    __shared::__shared_impl<__split::__split_t>
+{};
+
+template <>
+struct __sexpr_impl<split_t> : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {};
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__start_detached.hpp b/include/sdbusplus/async/stdexec/__detail/__start_detached.hpp
new file mode 100644
index 0000000..f22bf39
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__start_detached.hpp
@@ -0,0 +1,111 @@
+/*
+ * 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 "__cpo.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__senders.hpp"
+#include "__submit.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.consumer.start_detached]
+namespace __start_detached
+{
+template <class _EnvId>
+struct __detached_receiver
+{
+    using _Env = stdexec::__t<_EnvId>;
+
+    struct __t
+    {
+        using receiver_concept = receiver_t;
+        using __id = __detached_receiver;
+        STDEXEC_ATTRIBUTE((no_unique_address))
+        _Env __env_;
+
+        template <class... _As>
+        void set_value(_As&&...) noexcept
+        {}
+
+        template <class _Error>
+        [[noreturn]] void set_error(_Error&&) noexcept
+        {
+            std::terminate();
+        }
+
+        void set_stopped() noexcept {}
+
+        auto get_env() const noexcept -> const _Env&
+        {
+            // BUGBUG NOT TO SPEC
+            return __env_;
+        }
+    };
+};
+
+template <class _Env = empty_env>
+using __detached_receiver_t = __t<__detached_receiver<__id<__decay_t<_Env>>>>;
+
+struct start_detached_t
+{
+    template <sender_in<__root_env> _Sender>
+        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
+                            start_detached_t, _Sender>
+    void operator()(_Sender&& __sndr) const
+    {
+        auto __domain = __get_early_domain(__sndr);
+        stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr));
+    }
+
+    template <class _Env, sender_in<__as_root_env_t<_Env>> _Sender>
+        requires __callable<apply_sender_t,
+                            __late_domain_of_t<_Sender, __as_root_env_t<_Env>>,
+                            start_detached_t, _Sender, __as_root_env_t<_Env>>
+    void operator()(_Sender&& __sndr, _Env&& __env) const
+    {
+        auto __domain = __get_late_domain(__sndr, __env);
+        stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr),
+                              __as_root_env(static_cast<_Env&&>(__env)));
+    }
+
+    using _Sender = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(start_detached_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(const _Sender&)),
+                             _Sender),
+                tag_invoke_t(start_detached_t, _Sender)>;
+
+    template <class _Sender, class _Env = __root_env>
+        requires sender_to<_Sender, __detached_receiver_t<_Env>>
+    void apply_sender(_Sender&& __sndr, _Env&& __env = {}) const
+    {
+        __submit(static_cast<_Sender&&>(__sndr),
+                 __detached_receiver_t<_Env>{static_cast<_Env&&>(__env)});
+    }
+};
+} // namespace __start_detached
+
+using __start_detached::start_detached_t;
+inline constexpr start_detached_t start_detached{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__start_on.hpp b/include/sdbusplus/async/stdexec/__detail/__start_on.hpp
new file mode 100644
index 0000000..7eb8425
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__start_on.hpp
@@ -0,0 +1,120 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__let.hpp"
+#include "__meta.hpp"
+#include "__schedulers.hpp"
+#include "__senders_core.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+namespace __detail
+{
+template <class _Ty, class = __name_of<__decay_t<_Ty>>>
+struct __always
+{
+    _Ty __val_;
+
+    auto operator()() noexcept -> _Ty
+    {
+        return static_cast<_Ty&&>(__val_);
+    }
+};
+
+template <class _Ty>
+__always(_Ty) -> __always<_Ty>;
+} // namespace __detail
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.start_on]
+namespace __start_on
+{
+struct start_on_t
+{
+    using _Sender = __1;
+    using _Scheduler = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(start_on_t, _Scheduler, _Sender)>;
+
+    template <scheduler _Scheduler, sender _Sender>
+    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<start_on_t>(static_cast<_Scheduler&&>(__sched),
+                                     static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, auto __sched, __ignore) noexcept {
+            return __detail::__mkenv_sched(static_cast<_Env&&>(__env), __sched);
+        };
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__sndr,
+                             __transform_env_fn(static_cast<_Env&&>(__env)));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             []<class _Data, class _Child>(
+                                 __ignore, _Data&& __data, _Child&& __child) {
+            return let_value(
+                schedule(__data),
+                __detail::__always{static_cast<_Child&&>(__child)});
+        });
+    }
+};
+} // namespace __start_on
+
+using __start_on::start_on_t;
+inline constexpr start_on_t start_on{};
+
+using on_t = start_on_t;
+inline constexpr on_t on{};
+
+template <>
+struct __sexpr_impl<start_on_t> : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {
+        return {};
+    };
+};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__stop_token.hpp b/include/sdbusplus/async/stdexec/__detail/__stop_token.hpp
new file mode 100644
index 0000000..7f5cacc
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__stop_token.hpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021-2022 Facebook, Inc. and its affiliates
+ * 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 "__concepts.hpp"
+#include "__execution_fwd.hpp"
+
+namespace stdexec
+{
+namespace __stok
+{
+template <template <class> class>
+struct __check_type_alias_exists;
+} // namespace __stok
+
+template <class _Token, class _Callback>
+using stop_callback_for_t = typename _Token::template callback_type<_Callback>;
+
+template <class _Token>
+concept stoppable_token = __nothrow_copy_constructible<_Token>    //
+                          && __nothrow_move_constructible<_Token> //
+                          && equality_comparable<_Token>          //
+                          && requires(const _Token& __token) {
+                                 {
+                                     __token.stop_requested()
+                                 } noexcept -> __boolean_testable_;
+                                 {
+                                     __token.stop_possible()
+                                 } noexcept -> __boolean_testable_;
+    // workaround ICE in appleclang 13.1
+#if !defined(__clang__)
+                                 typename __stok::__check_type_alias_exists<
+                                     _Token::template callback_type>;
+#endif
+                             };
+
+template <class _Token, typename _Callback, typename _Initializer = _Callback>
+concept stoppable_token_for =
+    stoppable_token<_Token>  //
+    && __callable<_Callback> //
+    && requires { typename stop_callback_for_t<_Token, _Callback>; } &&
+    constructible_from<_Callback, _Initializer> &&
+    constructible_from<stop_callback_for_t<_Token, _Callback>, const _Token&,
+                       _Initializer>;
+
+template <class _Token>
+concept unstoppable_token =    //
+    stoppable_token<_Token> && //
+    requires {
+        {
+            _Token::stop_possible()
+        } -> __boolean_testable_;
+    } && (!_Token::stop_possible());
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__stopped_as_error.hpp b/include/sdbusplus/async/stdexec/__detail/__stopped_as_error.hpp
new file mode 100644
index 0000000..7476f29
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__stopped_as_error.hpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__just.hpp"
+#include "__let.hpp"
+#include "__sender_adaptor_closure.hpp"
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.stopped_as_error]
+namespace __sae
+{
+struct stopped_as_error_t
+{
+    template <sender _Sender, __movable_value _Error>
+    auto operator()(_Sender&& __sndr, _Error __err) const
+    {
+        return let_stopped(
+            static_cast<_Sender&&>(__sndr),
+            [__err2 = static_cast<_Error&&>(__err)]() mutable noexcept(
+                __nothrow_move_constructible<_Error>) {
+            return just_error(static_cast<_Error&&>(__err2));
+        });
+    }
+
+    template <__movable_value _Error>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Error __err) const
+        -> __binder_back<stopped_as_error_t, _Error>
+    {
+        return {{static_cast<_Error&&>(__err)}, {}, {}};
+    }
+};
+} // namespace __sae
+
+using __sae::stopped_as_error_t;
+inline constexpr stopped_as_error_t stopped_as_error{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__stopped_as_optional.hpp b/include/sdbusplus/async/stdexec/__detail/__stopped_as_optional.hpp
new file mode 100644
index 0000000..c84d59e
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__stopped_as_optional.hpp
@@ -0,0 +1,125 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__env.hpp"
+#include "__receivers.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__type_traits.hpp"
+
+#include <exception>
+#include <optional>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.stopped_as_optional]
+namespace __sao
+{
+struct stopped_as_optional_t
+{
+    template <sender _Sender>
+    auto operator()(_Sender&& __sndr) const
+    {
+        return __make_sexpr<stopped_as_optional_t>(
+            __(), static_cast<_Sender&&>(__sndr));
+    }
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()() const noexcept -> __binder_back<stopped_as_optional_t>
+    {
+        return {{}, {}, {}};
+    }
+};
+
+struct __stopped_as_optional_impl : __sexpr_defaults
+{
+    template <class... _Tys>
+        requires(sizeof...(_Tys) == 1)
+    using __set_value_t =
+        completion_signatures<set_value_t(std::optional<__decay_t<_Tys>>...)>;
+
+    template <class _Ty>
+    using __set_error_t = completion_signatures<set_error_t(_Ty)>;
+
+    static constexpr auto get_completion_signatures =               //
+        []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept //
+        -> transform_completion_signatures<
+            __completion_signatures_of_t<__child_of<_Self>, _Env...>,
+            completion_signatures<set_error_t(std::exception_ptr)>,
+            __set_value_t, __set_error_t, completion_signatures<>> {
+        static_assert(sender_expr_for<_Self, stopped_as_optional_t>);
+        return {};
+    };
+
+    static constexpr auto get_state = //
+        []<class _Self, class _Receiver>(_Self&&, _Receiver&) noexcept
+        requires __single_value_sender<__child_of<_Self>, env_of_t<_Receiver>>
+    {
+        static_assert(sender_expr_for<_Self, stopped_as_optional_t>);
+        using _Value = __decay_t<
+            __single_sender_value_t<__child_of<_Self>, env_of_t<_Receiver>>>;
+        return __mtype<_Value>();
+    };
+
+    static constexpr auto complete = //
+        []<class _State, class _Receiver, class _Tag, class... _Args>(
+            __ignore, _State&, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Tag, set_value_t>)
+        {
+            try
+            {
+                static_assert(constructible_from<__t<_State>, _Args...>);
+                stdexec::set_value(static_cast<_Receiver&&>(__rcvr),
+                                   std::optional<__t<_State>>{
+                                       static_cast<_Args&&>(__args)...});
+            }
+            catch (...)
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                                   std::current_exception());
+            }
+        }
+        else if constexpr (__same_as<_Tag, set_error_t>)
+        {
+            stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
+                               static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            stdexec::set_value(static_cast<_Receiver&&>(__rcvr),
+                               std::optional<__t<_State>>{std::nullopt});
+        }
+    };
+};
+} // namespace __sao
+
+using __sao::stopped_as_optional_t;
+inline constexpr stopped_as_optional_t stopped_as_optional{};
+
+template <>
+struct __sexpr_impl<stopped_as_optional_t> : __sao::__stopped_as_optional_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__submit.hpp b/include/sdbusplus/async/stdexec/__detail/__submit.hpp
new file mode 100644
index 0000000..8f91ee9
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__submit.hpp
@@ -0,0 +1,167 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__env.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__senders.hpp"
+#include "__type_traits.hpp"
+
+#include <memory>
+
+namespace stdexec
+{
+namespace
+{
+inline constexpr auto __ref = []<class _Ty>(_Ty& __ty) noexcept {
+    return [__ty = &__ty]() noexcept -> decltype(auto) { return (*__ty); };
+};
+} // namespace
+
+template <class _Ty>
+using __ref_t = decltype(__ref(__declval<_Ty&>()));
+
+/////////////////////////////////////////////////////////////////////////////
+// NOT TO SPEC: __submit
+namespace __submit_
+{
+template <class _OpRef>
+struct __receiver
+{
+    using receiver_concept = receiver_t;
+    using __t = __receiver;
+    using __id = __receiver;
+
+    using _Operation = __decay_t<__call_result_t<_OpRef>>;
+    using _Receiver = stdexec::__t<__mapply<__q<__msecond>, _Operation>>;
+
+    _OpRef __opref_;
+
+    void __delete_op() noexcept
+    {
+        _Operation* __op = &__opref_();
+        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
+        {
+            auto&& __env = stdexec::get_env(__op->__rcvr_);
+            auto __alloc = stdexec::get_allocator(__env);
+            using _Alloc = decltype(__alloc);
+            using _OpAlloc = typename std::allocator_traits<
+                _Alloc>::template rebind_alloc<_Operation>;
+            _OpAlloc __op_alloc{__alloc};
+            std::allocator_traits<_OpAlloc>::destroy(__op_alloc, __op);
+            std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op, 1);
+        }
+        else
+        {
+            delete __op;
+        }
+    }
+
+    // Forward all the receiver ops, and delete the operation state.
+    template <class... _As>
+    void set_value(_As&&... __as) noexcept
+    {
+        stdexec::set_value(static_cast<_Receiver&&>(__opref_().__rcvr_),
+                           static_cast<_As&&>(__as)...);
+        __delete_op();
+    }
+
+    template <class _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        stdexec::set_error(static_cast<_Receiver&&>(__opref_().__rcvr_),
+                           static_cast<_Error&&>(__err));
+        __delete_op();
+    }
+
+    void set_stopped() noexcept
+    {
+        stdexec::set_stopped(__opref_().__rcvr_);
+        __delete_op();
+    }
+
+    // Forward all receiever queries.
+    auto get_env() const noexcept -> env_of_t<_Receiver&>
+    {
+        return stdexec::get_env(__opref_().__rcvr_);
+    }
+};
+
+template <class _SenderId, class _ReceiverId>
+struct __operation
+{
+    using _Sender = stdexec::__t<_SenderId>;
+    using _Receiver = stdexec::__t<_ReceiverId>;
+    using __receiver_t = __receiver<__ref_t<__operation>>;
+
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _Receiver __rcvr_;
+    connect_result_t<_Sender, __receiver_t> __op_state_;
+
+    __operation(_Sender&& __sndr, _Receiver __rcvr) :
+        __rcvr_(static_cast<_Receiver&&>(__rcvr)),
+        __op_state_(
+            connect(static_cast<_Sender&&>(__sndr), __receiver_t{__ref(*this)}))
+    {}
+};
+
+struct __submit_t
+{
+    template <receiver _Receiver, sender_to<_Receiver> _Sender>
+    void operator()(_Sender&& __sndr, _Receiver __rcvr) const noexcept(false)
+    {
+        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
+        {
+            auto&& __env = get_env(__rcvr);
+            auto __alloc = get_allocator(__env);
+            using _Alloc = decltype(__alloc);
+            using _Op = __operation<__id<_Sender>, __id<_Receiver>>;
+            using _OpAlloc = typename std::allocator_traits<
+                _Alloc>::template rebind_alloc<_Op>;
+            _OpAlloc __op_alloc{__alloc};
+            auto __op = std::allocator_traits<_OpAlloc>::allocate(__op_alloc,
+                                                                  1);
+            try
+            {
+                std::allocator_traits<_OpAlloc>::construct(
+                    __op_alloc, __op, static_cast<_Sender&&>(__sndr),
+                    static_cast<_Receiver&&>(__rcvr));
+                stdexec::start(__op->__op_state_);
+            }
+            catch (...)
+            {
+                std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op,
+                                                            1);
+                throw;
+            }
+        }
+        else
+        {
+            start((new __operation<__id<_Sender>, __id<_Receiver>>{
+                       static_cast<_Sender&&>(__sndr),
+                       static_cast<_Receiver&&>(__rcvr)})
+                      ->__op_state_);
+        }
+    }
+};
+} // namespace __submit_
+
+using __submit_::__submit_t;
+inline constexpr __submit_t __submit{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp b/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp
new file mode 100644
index 0000000..427594a
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__sync_wait.hpp
@@ -0,0 +1,392 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__concepts.hpp"
+#include "__cpo.hpp"
+#include "__debug.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__into_variant.hpp"
+#include "__meta.hpp"
+#include "__receivers.hpp"
+#include "__run_loop.hpp"
+#include "__senders.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+#include "__type_traits.hpp"
+
+#include <exception>
+#include <optional>
+#include <system_error>
+#include <tuple>
+#include <variant>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.consumers.sync_wait]
+// [execution.senders.consumers.sync_wait_with_variant]
+namespace __sync_wait
+{
+struct __env
+{
+    run_loop* __loop_ = nullptr;
+
+    auto query(get_scheduler_t) const noexcept -> run_loop::__scheduler
+    {
+        return __loop_->get_scheduler();
+    }
+
+    auto query(get_delegatee_scheduler_t) const noexcept
+        -> run_loop::__scheduler
+    {
+        return __loop_->get_scheduler();
+    }
+
+    // static constexpr auto query(__debug::__is_debug_env_t) noexcept -> bool {
+    //   return true;
+    // }
+};
+
+// What should sync_wait(just_stopped()) return?
+template <class _Sender, class _Continuation>
+using __sync_wait_result_impl = //
+    __value_types_of_t<_Sender, __env,
+                       __mtransform<__q<__decay_t>, _Continuation>,
+                       __q<__msingle>>;
+
+template <class _Sender>
+using __sync_wait_result_t =
+    __mtry_eval<__sync_wait_result_impl, _Sender, __qq<std::tuple>>;
+
+template <class _Sender>
+using __sync_wait_with_variant_result_t =
+    __mtry_eval<__sync_wait_result_impl, __result_of<into_variant, _Sender>,
+                __q<__midentity>>;
+
+struct __state
+{
+    std::exception_ptr __eptr_;
+    run_loop __loop_;
+};
+
+template <class... _Values>
+struct __receiver
+{
+    struct __t
+    {
+        using receiver_concept = receiver_t;
+        using __id = __receiver;
+        __state* __state_;
+        std::optional<std::tuple<_Values...>>* __values_;
+
+        template <class... _As>
+            requires constructible_from<std::tuple<_Values...>, _As...>
+        void set_value(_As&&... __as) noexcept
+        {
+            try
+            {
+                __values_->emplace(static_cast<_As&&>(__as)...);
+            }
+            catch (...)
+            {
+                __state_->__eptr_ = std::current_exception();
+            }
+            __state_->__loop_.finish();
+        }
+
+        template <class _Error>
+        void set_error(_Error __err) noexcept
+        {
+            if constexpr (__same_as<_Error, std::exception_ptr>)
+            {
+                STDEXEC_ASSERT(__err !=
+                               nullptr); // std::exception_ptr must not be null.
+                __state_->__eptr_ = static_cast<_Error&&>(__err);
+            }
+            else if constexpr (__same_as<_Error, std::error_code>)
+            {
+                __state_->__eptr_ =
+                    std::make_exception_ptr(std::system_error(__err));
+            }
+            else
+            {
+                __state_->__eptr_ =
+                    std::make_exception_ptr(static_cast<_Error&&>(__err));
+            }
+            __state_->__loop_.finish();
+        }
+
+        void set_stopped() noexcept
+        {
+            __state_->__loop_.finish();
+        }
+
+        auto get_env() const noexcept -> __env
+        {
+            return __env{&__state_->__loop_};
+        }
+    };
+};
+
+template <class _Sender>
+using __receiver_t = __t<__sync_wait_result_impl<_Sender, __q<__receiver>>>;
+
+// These are for hiding the metaprogramming in diagnostics
+template <class _Sender>
+struct __sync_receiver_for
+{
+    using __t = __receiver_t<_Sender>;
+};
+template <class _Sender>
+using __sync_receiver_for_t = __t<__sync_receiver_for<_Sender>>;
+
+template <class _Sender>
+struct __value_tuple_for
+{
+    using __t = __sync_wait_result_t<_Sender>;
+};
+template <class _Sender>
+using __value_tuple_for_t = __t<__value_tuple_for<_Sender>>;
+
+template <class _Sender>
+struct __variant_for
+{
+    using __t = __sync_wait_with_variant_result_t<_Sender>;
+};
+template <class _Sender>
+using __variant_for_t = __t<__variant_for<_Sender>>;
+
+inline constexpr __mstring __sync_wait_context_diag = //
+    "In stdexec::sync_wait()..."_mstr;
+inline constexpr __mstring __too_many_successful_completions_diag =
+    "The argument to stdexec::sync_wait() is a sender that can complete successfully in more "
+    "than one way. Use stdexec::sync_wait_with_variant() instead."_mstr;
+
+template <__mstring _Context, __mstring _Diagnostic>
+struct _INVALID_ARGUMENT_TO_SYNC_WAIT_;
+
+template <__mstring _Diagnostic>
+using __invalid_argument_to_sync_wait =
+    _INVALID_ARGUMENT_TO_SYNC_WAIT_<__sync_wait_context_diag, _Diagnostic>;
+
+template <__mstring _Diagnostic, class _Sender, class _Env = __env>
+using __sync_wait_error =
+    __mexception<__invalid_argument_to_sync_wait<_Diagnostic>,
+                 _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
+
+template <class _Sender, class>
+using __too_many_successful_completions_error =
+    __sync_wait_error<__too_many_successful_completions_diag, _Sender>;
+
+template <class _Sender>
+concept __valid_sync_wait_argument =
+    __ok<__minvoke<__mtry_catch_q<__single_value_variant_sender_t,
+                                  __q<__too_many_successful_completions_error>>,
+                   _Sender, __env>>;
+
+#if STDEXEC_NVHPC()
+// It requires some hoop-jumping to get the NVHPC compiler to report a
+// meaningful diagnostic for SFINAE failures.
+template <class _Sender>
+auto __diagnose_error()
+{
+    if constexpr (!sender_in<_Sender, __env>)
+    {
+        using _Completions = __completion_signatures_of_t<_Sender, __env>;
+        if constexpr (__merror<_Completions>)
+        {
+            return _Completions();
+        }
+        else
+        {
+            constexpr __mstring __diag =
+                "The stdexec::sender_in<Sender, Environment> concept check has failed."_mstr;
+            return __sync_wait_error<__diag, _Sender>();
+        }
+    }
+    else if constexpr (!__valid_sync_wait_argument<_Sender>)
+    {
+        return __sync_wait_error<__too_many_successful_completions_diag,
+                                 _Sender>();
+    }
+    else if constexpr (!sender_to<_Sender, __sync_receiver_for_t<_Sender>>)
+    {
+        constexpr __mstring __diag =
+            "Failed to connect the given sender to sync_wait's internal receiver. "
+            "The stdexec::connect(Sender, Receiver) expression is ill-formed."_mstr;
+        return __sync_wait_error<__diag, _Sender>();
+    }
+    else
+    {
+        constexpr __mstring __diag = "Unknown concept check failure."_mstr;
+        return __sync_wait_error<__diag, _Sender>();
+    }
+}
+
+template <class _Sender>
+using __error_description_t =
+    decltype(__sync_wait::__diagnose_error<_Sender>());
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// [execution.senders.consumers.sync_wait]
+struct sync_wait_t
+{
+    template <sender_in<__env> _Sender>
+        requires __valid_sync_wait_argument<_Sender> &&
+                 __has_implementation_for<sync_wait_t,
+                                          __early_domain_of_t<_Sender>, _Sender>
+    auto operator()(_Sender&& __sndr) const
+        -> std::optional<__value_tuple_for_t<_Sender>>
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::apply_sender(__domain, *this,
+                                     static_cast<_Sender&&>(__sndr));
+    }
+
+#if STDEXEC_NVHPC()
+    // This is needed to get sensible diagnostics from nvc++
+    template <class _Sender, class _Error = __error_description_t<_Sender>>
+    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
+        -> std::optional<std::tuple<int>> = delete;
+#endif
+
+    using _Sender = __0;
+    using __legacy_customizations_t = __types<
+        // For legacy reasons:
+        tag_invoke_t(
+            sync_wait_t,
+            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
+            _Sender),
+        tag_invoke_t(sync_wait_t, _Sender)>;
+
+    // clang-format off
+      /// @brief Synchronously wait for the result of a sender, blocking the
+      ///         current thread.
+      ///
+      /// `sync_wait` connects and starts the given sender, and then drives a
+      ///         `run_loop` instance until the sender completes. Additional work
+      ///         can be delegated to the `run_loop` by scheduling work on the
+      ///         scheduler returned by calling `get_delegatee_scheduler` on the
+      ///         receiver's environment.
+      ///
+      /// @pre The sender must have a exactly one value completion signature. That
+      ///         is, it can only complete successfully in one way, with a single
+      ///         set of values.
+      ///
+      /// @retval success Returns an engaged `std::optional` containing the result
+      ///         values in a `std::tuple`.
+      /// @retval canceled Returns an empty `std::optional`.
+      /// @retval error Throws the error.
+      ///
+      /// @throws std::rethrow_exception(error) if the error has type
+      ///         `std::exception_ptr`.
+      /// @throws std::system_error(error) if the error has type
+      ///         `std::error_code`.
+      /// @throws error otherwise
+    // clang-format on
+    template <sender_in<__env> _Sender>
+    auto apply_sender(_Sender&& __sndr) const
+        -> std::optional<__sync_wait_result_t<_Sender>>
+    {
+        __state __local{};
+        std::optional<__sync_wait_result_t<_Sender>> __result{};
+
+        // Launch the sender with a continuation that will fill in the __result
+        // optional or set the exception_ptr in __local.
+        auto __op_state = connect(static_cast<_Sender&&>(__sndr),
+                                  __receiver_t<_Sender>{&__local, &__result});
+        stdexec::start(__op_state);
+
+        // Wait for the variant to be filled in.
+        __local.__loop_.run();
+
+        if (__local.__eptr_)
+        {
+            std::rethrow_exception(
+                static_cast<std::exception_ptr&&>(__local.__eptr_));
+        }
+
+        return __result;
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////
+// [execution.senders.consumers.sync_wait_with_variant]
+struct sync_wait_with_variant_t
+{
+    struct __impl;
+
+    template <sender_in<__env> _Sender>
+        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
+                            sync_wait_with_variant_t, _Sender>
+    auto operator()(_Sender&& __sndr) const -> decltype(auto)
+    {
+        using __result_t =
+            __call_result_t<apply_sender_t, __early_domain_of_t<_Sender>,
+                            sync_wait_with_variant_t, _Sender>;
+        static_assert(__is_instance_of<__result_t, std::optional>);
+        using __variant_t = typename __result_t::value_type;
+        static_assert(__is_instance_of<__variant_t, std::variant>);
+
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::apply_sender(__domain, *this,
+                                     static_cast<_Sender&&>(__sndr));
+    }
+
+#if STDEXEC_NVHPC()
+    template <class _Sender, class _Error = __error_description_t<
+                                 __result_of<into_variant, _Sender>>>
+    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
+        -> std::optional<std::tuple<std::variant<std::tuple<>>>> = delete;
+#endif
+
+    using _Sender = __0;
+    using __legacy_customizations_t = __types<
+        // For legacy reasons:
+        tag_invoke_t(
+            sync_wait_with_variant_t,
+            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
+            _Sender),
+        tag_invoke_t(sync_wait_with_variant_t, _Sender)>;
+
+    template <class _Sender>
+        requires __callable<sync_wait_t, __result_of<into_variant, _Sender>>
+    auto apply_sender(_Sender&& __sndr) const
+        -> std::optional<__variant_for_t<_Sender>>
+    {
+        if (auto __opt_values =
+                sync_wait_t()(into_variant(static_cast<_Sender&&>(__sndr))))
+        {
+            return std::move(std::get<0>(*__opt_values));
+        }
+        return std::nullopt;
+    }
+};
+} // namespace __sync_wait
+
+using __sync_wait::sync_wait_t;
+inline constexpr sync_wait_t sync_wait{};
+
+using __sync_wait::sync_wait_with_variant_t;
+inline constexpr sync_wait_with_variant_t sync_wait_with_variant{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__tag_invoke.hpp b/include/sdbusplus/async/stdexec/__detail/__tag_invoke.hpp
new file mode 100644
index 0000000..0f78273
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__tag_invoke.hpp
@@ -0,0 +1,141 @@
+/*
+ * 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 "__concepts.hpp"
+#include "__meta.hpp"
+
+namespace stdexec::__std_concepts
+{
+#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
+using std::invocable;
+#else
+template <class _Fun, class... _As>
+concept invocable = //
+    requires(_Fun&& __f, _As&&... __as) {
+        std::invoke(static_cast<_Fun&&>(__f), static_cast<_As&&>(__as)...);
+    };
+#endif
+} // namespace stdexec::__std_concepts
+
+namespace std
+{
+using namespace stdexec::__std_concepts;
+} // namespace std
+
+namespace stdexec
+{
+// [func.tag_invoke], tag_invoke
+namespace __tag_invoke
+{
+void tag_invoke();
+
+// For handling queryables with a static constexpr query member function:
+template <class _Tag, class _Env>
+    requires true // so this overload is preferred over the one below
+STDEXEC_ATTRIBUTE((always_inline)) constexpr auto tag_invoke(
+    _Tag, const _Env&) noexcept -> __mconstant<_Env::query(_Tag())>
+{
+    return {};
+}
+
+// For handling queryables with a query member function:
+template <class _Tag, class _Env>
+STDEXEC_ATTRIBUTE((always_inline))
+constexpr auto tag_invoke(_Tag, const _Env& __env) noexcept(
+    noexcept(__env.query(_Tag()))) -> decltype(__env.query(_Tag()))
+{
+    return __env.query(_Tag());
+}
+
+// NOT TO SPEC: Don't require tag_invocable to subsume invocable.
+// std::invoke is more expensive at compile time than necessary,
+// and results in diagnostics that are more verbose than necessary.
+template <class _Tag, class... _Args>
+concept tag_invocable = //
+    requires(_Tag __tag, _Args&&... __args) {
+        tag_invoke(static_cast<_Tag&&>(__tag), static_cast<_Args&&>(__args)...);
+    };
+
+template <class _Ret, class _Tag, class... _Args>
+concept __tag_invocable_r = //
+    requires(_Tag __tag, _Args&&... __args) {
+        {
+            static_cast<_Ret>(tag_invoke(static_cast<_Tag&&>(__tag),
+                                         static_cast<_Args&&>(__args)...))
+        };
+    };
+
+// NOT TO SPEC: nothrow_tag_invocable subsumes tag_invocable
+template <class _Tag, class... _Args>
+concept nothrow_tag_invocable =
+    tag_invocable<_Tag, _Args...> && //
+    requires(_Tag __tag, _Args&&... __args) {
+        {
+            tag_invoke(static_cast<_Tag&&>(__tag),
+                       static_cast<_Args&&>(__args)...)
+        } noexcept;
+    };
+
+template <class _Tag, class... _Args>
+using tag_invoke_result_t =
+    decltype(tag_invoke(__declval<_Tag>(), __declval<_Args>()...));
+
+template <class _Tag, class... _Args>
+struct tag_invoke_result
+{};
+
+template <class _Tag, class... _Args>
+    requires tag_invocable<_Tag, _Args...>
+struct tag_invoke_result<_Tag, _Args...>
+{
+    using type = tag_invoke_result_t<_Tag, _Args...>;
+};
+
+struct tag_invoke_t
+{
+    template <class _Tag, class... _Args>
+        requires tag_invocable<_Tag, _Args...>
+    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 __tag_invoke
+
+using __tag_invoke::tag_invoke_t;
+
+namespace __ti
+{
+inline constexpr tag_invoke_t tag_invoke{};
+} // namespace __ti
+
+using namespace __ti;
+
+template <auto& _Tag>
+using tag_t = __decay_t<decltype(_Tag)>;
+
+using __tag_invoke::__tag_invocable_r;
+using __tag_invoke::nothrow_tag_invocable;
+using __tag_invoke::tag_invocable;
+using __tag_invoke::tag_invoke_result;
+using __tag_invoke::tag_invoke_result_t;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__then.hpp b/include/sdbusplus/async/stdexec/__detail/__then.hpp
new file mode 100644
index 0000000..946fcd9
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__then.hpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "__basic_sender.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+
+// include these after __execution_fwd.hpp
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.then]
+namespace __then
+{
+inline constexpr __mstring __then_context =
+    "In stdexec::then(Sender, Function)..."_mstr;
+using __on_not_callable = __callable_error<__then_context>;
+
+template <class _Fun, class _CvrefSender, class... _Env>
+using __completions_t = //
+    transform_completion_signatures<
+        __completion_signatures_of_t<_CvrefSender, _Env...>,
+        __with_error_invoke_t<__on_not_callable, set_value_t, _Fun,
+                              _CvrefSender, _Env...>,
+        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
+                      _Fun>::template __f>;
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct then_t
+{
+    template <sender _Sender, __movable_value _Fun>
+    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
+        auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<then_t>(static_cast<_Fun&&>(__fun),
+                                           static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <__movable_value _Fun>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Fun __fun) const -> __binder_back<then_t, _Fun>
+    {
+        return {{static_cast<_Fun&&>(__fun)}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(then_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(then_t, _Sender, _Fun)>;
+};
+
+struct __then_impl : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
+        -> __completions_t<__decay_t<__data_of<_Sender>>, __child_of<_Sender>,
+                           _Env...> {
+        static_assert(sender_expr_for<_Sender, then_t>);
+        return {};
+    };
+
+    static constexpr auto complete = //
+        []<class _Tag, class _State, class _Receiver, class... _Args>(
+            __ignore, _State& __state, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Tag, set_value_t>)
+        {
+            stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr),
+                                        static_cast<_State&&>(__state),
+                                        static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            _Tag()(static_cast<_Receiver&&>(__rcvr),
+                   static_cast<_Args&&>(__args)...);
+        }
+    };
+};
+} // namespace __then
+
+using __then::then_t;
+
+/// @brief The then sender adaptor, which invokes a function with the result of
+///        a sender, making the result available to the next receiver.
+/// @hideinitializer
+inline constexpr then_t then{};
+
+template <>
+struct __sexpr_impl<then_t> : __then::__then_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp b/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp
new file mode 100644
index 0000000..3566bc6
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__transfer_just.hpp
@@ -0,0 +1,140 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__continue_on.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__just.hpp"
+#include "__meta.hpp"
+#include "__schedule_from.hpp"
+#include "__schedulers.hpp"
+#include "__sender_introspection.hpp"
+#include "__tag_invoke.hpp"
+#include "__transform_sender.hpp"
+#include "__tuple.hpp"
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.transfer_just]
+namespace __transfer_just
+{
+// This is a helper for finding legacy cusutomizations of transfer_just.
+inline auto __transfer_just_tag_invoke()
+{
+    return []<class... _Ts>(
+               _Ts&&... __ts) -> tag_invoke_result_t<transfer_just_t, _Ts...> {
+        return tag_invoke(transfer_just, static_cast<_Ts&&>(__ts)...);
+    };
+}
+
+template <class _Env>
+auto __make_transform_fn(const _Env&)
+{
+    return [&]<class _Scheduler, class... _Values>(_Scheduler&& __sched,
+                                                   _Values&&... __vals) {
+        return continue_on(just(static_cast<_Values&&>(__vals)...),
+                           static_cast<_Scheduler&&>(__sched));
+    };
+}
+
+template <class _Env>
+auto __transform_sender_fn(const _Env& __env)
+{
+    return [&]<class _Data>(__ignore, _Data&& __data) {
+        return __data.apply(__make_transform_fn(__env),
+                            static_cast<_Data&&>(__data));
+    };
+}
+
+struct __legacy_customization_fn
+{
+    template <class _Data>
+    auto operator()(_Data&& __data) const
+        -> decltype(__data.apply(__transfer_just_tag_invoke(),
+                                 static_cast<_Data&&>(__data)))
+    {
+        return __data.apply(__transfer_just_tag_invoke(),
+                            static_cast<_Data&&>(__data));
+    }
+};
+
+struct transfer_just_t
+{
+    using _Data = __0;
+    using __legacy_customizations_t = //
+        __types<__legacy_customization_fn(_Data)>;
+
+    template <scheduler _Scheduler, __movable_value... _Values>
+    auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
+        -> __well_formed_sender auto
+    {
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<transfer_just_t>(
+                          __tuple{static_cast<_Scheduler&&>(__sched),
+                                  static_cast<_Values&&>(__vals)...}));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
+    {
+        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                             __transform_sender_fn(__env));
+    }
+};
+
+inline auto __make_env_fn() noexcept
+{
+    return []<class _Scheduler>(const _Scheduler& __sched,
+                                const auto&...) noexcept {
+        using _Env = __t<__schfr::__environ<__id<_Scheduler>>>;
+        return _Env{__sched};
+    };
+}
+
+struct __transfer_just_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Data>(const _Data& __data) noexcept {
+        return __data.apply(__make_env_fn(), __data);
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {};
+};
+} // namespace __transfer_just
+
+using __transfer_just::transfer_just_t;
+inline constexpr transfer_just_t transfer_just{};
+
+template <>
+struct __sexpr_impl<transfer_just_t> : __transfer_just::__transfer_just_impl
+{};
+} // namespace stdexec
+
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__transform_completion_signatures.hpp b/include/sdbusplus/async/stdexec/__detail/__transform_completion_signatures.hpp
new file mode 100644
index 0000000..631a9c9
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__transform_completion_signatures.hpp
@@ -0,0 +1,478 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__completion_signatures.hpp"
+#include "__concepts.hpp"
+#include "__debug.hpp"
+#include "__diagnostics.hpp"
+#include "__meta.hpp"
+#include "__senders_core.hpp"
+
+#include <tuple>
+#include <variant>
+
+namespace stdexec
+{
+#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
+// __checked_completion_signatures is for catching logic bugs in a sender's
+// metadata. If sender<S> and sender_in<S, Ctx> are both true, then they had
+// better report the same metadata. This completion signatures wrapper enforces
+// that at compile time.
+template <class _Sender, class... _Env>
+auto __checked_completion_signatures(_Sender&& __sndr, _Env&&... __env) noexcept
+{
+    using __completions_t = __completion_signatures_of_t<_Sender, _Env...>;
+    stdexec::__debug_sender(static_cast<_Sender&&>(__sndr), __env...);
+    return __completions_t{};
+}
+
+template <class _Sender, class... _Env>
+    requires sender_in<_Sender, _Env...>
+using completion_signatures_of_t =
+    decltype(stdexec::__checked_completion_signatures(__declval<_Sender>(),
+                                                      __declval<_Env>()...));
+#else
+template <class _Sender, class... _Env>
+    requires sender_in<_Sender, _Env...>
+using completion_signatures_of_t =
+    __completion_signatures_of_t<_Sender, _Env...>;
+#endif
+
+struct __not_a_variant
+{
+    __not_a_variant() = delete;
+};
+
+template <class... _Ts>
+using __std_variant = //
+    __minvoke_if_c<sizeof...(_Ts) != 0,
+                   __mtransform<__q1<__decay_t>, __munique<__qq<std::variant>>>,
+                   __mconst<__not_a_variant>, _Ts...>;
+
+template <class... _Ts>
+using __nullable_std_variant =
+    __mcall<__munique<__mbind_front<__qq<std::variant>, std::monostate>>,
+            __decay_t<_Ts>...>;
+
+template <class... _Ts>
+using __decayed_std_tuple = __meval<std::tuple, __decay_t<_Ts>...>;
+
+namespace __sigs
+{
+// The following code is used to normalize completion signatures.
+// "Normalization" means that that rvalue-references are stripped from the types
+// in the completion signatures. For example, the completion signature
+// `set_value_t(int &&)` would be normalized to `set_value_t(int)`, but
+// `set_value_t(int)` and `set_value_t(int &)` would remain unchanged.
+template <class _Tag, class... _Args>
+auto __normalize_sig_impl(_Args&&...) -> _Tag (*)(_Args...);
+
+template <class _Tag, class... _Args>
+auto __normalize_sig(_Tag (*)(_Args...))
+    -> decltype(__sigs::__normalize_sig_impl<_Tag>(__declval<_Args>()...));
+
+template <class... _Sigs>
+auto __repack_completions(_Sigs*...) -> completion_signatures<_Sigs...>;
+
+template <class... _Sigs>
+auto __normalize_completions(completion_signatures<_Sigs...>*)
+    -> decltype(__sigs::__repack_completions(
+        __sigs::__normalize_sig(static_cast<_Sigs*>(nullptr))...));
+
+template <class _Completions>
+using __normalize_completions_t = decltype(__sigs::__normalize_completions(
+    static_cast<_Completions*>(nullptr)));
+} // namespace __sigs
+
+template <class... _SigPtrs>
+using __completion_signature_ptrs = //
+    decltype(__sigs::__repack_completions(static_cast<_SigPtrs>(nullptr)...));
+
+template <class... _Sigs>
+using __concat_completion_signatures = //
+    __mconcat<__qq<completion_signatures>>::__f<
+        __mconcat<__qq<__mmake_set>>::__f<_Sigs...>>;
+
+namespace __sigs
+{
+//////////////////////////////////////////////////////////////////////////////////////////////////
+template <template <class...> class _Tuple, class _Tag, class... _Args>
+auto __for_each_sig(_Tag (*)(_Args...)) -> _Tuple<_Tag, _Args...>;
+
+template <class _Sig, template <class...> class _Tuple>
+using __for_each_sig_t =
+    decltype(__sigs::__for_each_sig<_Tuple>(static_cast<_Sig*>(nullptr)));
+
+template <template <class...> class _Tuple, template <class...> class _Variant,
+          class... _More, class _What, class... _With>
+auto __for_each_completion_signature_fn(_ERROR_<_What, _With...>**)
+    -> _ERROR_<_What, _With...>;
+
+template <template <class...> class _Tuple, template <class...> class _Variant,
+          class... _More, class... _Sigs>
+auto __for_each_completion_signature_fn(completion_signatures<_Sigs...>**)
+    -> _Variant<__for_each_sig_t<_Sigs, _Tuple>..., _More...>;
+} // namespace __sigs
+
+template <class _Sigs, template <class...> class _Tuple,
+          template <class...> class _Variant, class... _More>
+using __for_each_completion_signature =
+    decltype(__sigs::__for_each_completion_signature_fn<_Tuple, _Variant,
+                                                        _More...>(
+        static_cast<_Sigs**>(nullptr)));
+
+namespace __sigs
+{
+////////////////////////////////////////////////////////////////////////////////////////////////
+template <template <class...> class _SetVal, template <class...> class _SetErr,
+          class _SetStp, class... _Values>
+auto __transform_sig(set_value_t (*)(_Values...)) -> _SetVal<_Values...>;
+
+template <template <class...> class _SetVal, template <class...> class _SetErr,
+          class _SetStp, class _Error>
+auto __transform_sig(set_error_t (*)(_Error)) -> _SetErr<_Error>;
+
+template <template <class...> class _SetVal, template <class...> class _SetErr,
+          class _SetStp>
+auto __transform_sig(set_stopped_t (*)()) -> _SetStp;
+
+template <class _Sig, template <class...> class _SetVal,
+          template <class...> class _SetErr, class _SetStp>
+using __transform_sig_t =
+    decltype(__sigs::__transform_sig<_SetVal, _SetErr, _SetStp>(
+        static_cast<_Sig*>(nullptr)));
+
+template <template <class...> class _SetVal, template <class...> class _SetErr,
+          class _SetStp, template <class...> class _Variant, class... _More,
+          class _What, class... _With>
+auto __transform_sigs_fn(_ERROR_<_What, _With...>**)
+    -> _ERROR_<_What, _With...>;
+
+template <template <class...> class _SetVal, template <class...> class _SetErr,
+          class _SetStp, template <class...> class _Variant, class... _More,
+          class... _Sigs>
+auto __transform_sigs_fn(completion_signatures<_Sigs...>**) //
+    -> _Variant<__transform_sig_t<_Sigs, _SetVal, _SetErr, _SetStp>...,
+                _More...>;
+} // namespace __sigs
+
+template <class _Sigs, template <class...> class _SetVal,
+          template <class...> class _SetErr, class _SetStp,
+          template <class...> class _Variant,
+          class... _More>
+using __transform_completion_signatures = //
+    decltype(__sigs::__transform_sigs_fn<_SetVal, _SetErr, _SetStp, _Variant,
+                                         _More...>(
+        static_cast<_Sigs**>(nullptr)));
+
+namespace __sigs
+{
+////////////////////////////////////////////////////////////////////////////////////////////////
+template <class _WantedTag>
+struct __gather_sigs_fn;
+
+template <>
+struct __gather_sigs_fn<set_value_t>
+{
+    template <class _Sigs, template <class...> class _Then,
+              template <class...> class _Else,
+              template <class...> class _Variant, class... _More>
+    using __f = __transform_completion_signatures<
+        _Sigs, _Then, __mbind_front_q<_Else, set_error_t>::template __f,
+        _Else<set_stopped_t>, _Variant, _More...>;
+};
+
+template <>
+struct __gather_sigs_fn<set_error_t>
+{
+    template <class _Sigs, template <class...> class _Then,
+              template <class...> class _Else,
+              template <class...> class _Variant, class... _More>
+    using __f = __transform_completion_signatures<
+        _Sigs, __mbind_front_q<_Else, set_value_t>::template __f, _Then,
+        _Else<set_stopped_t>, _Variant, _More...>;
+};
+
+template <>
+struct __gather_sigs_fn<set_stopped_t>
+{
+    template <class _Sigs, template <class...> class _Then,
+              template <class...> class _Else,
+              template <class...> class _Variant, class... _More>
+    using __f = __transform_completion_signatures<
+        _Sigs, __mbind_front_q<_Else, set_value_t>::template __f,
+        __mbind_front_q<_Else, set_error_t>::template __f, _Then<>, _Variant,
+        _More...>;
+};
+
+template <class... _Values>
+using __default_set_value = completion_signatures<set_value_t(_Values...)>;
+
+template <class... _Error>
+using __default_set_error = completion_signatures<set_error_t(_Error...)>;
+
+template <class _Tag, class... _Args>
+using __default_completion = completion_signatures<_Tag(_Args...)>;
+} // namespace __sigs
+
+template <class _Sigs, class _WantedTag, template <class...> class _Then,
+          template <class...> class _Else, template <class...> class _Variant,
+          class... _More>
+using __gather_completion_signatures = typename __sigs::__gather_sigs_fn<
+    _WantedTag>::template __f<_Sigs, _Then, _Else, _Variant, _More...>;
+
+/////////////////////////////////////////////////////////////////////////////
+// transform_completion_signatures
+// ==========================
+//
+// `transform_completion_signatures` takes a sender, and environment, and a
+// bunch of other template arguments for munging the completion signatures of a
+// sender in interesting ways.
+//
+//  ```c++
+//  template <class... Args>
+//    using __default_set_value = completion_signatures<set_value_t(Args...)>;
+//
+//  template <class Err>
+//    using __default_set_error = completion_signatures<set_error_t(Err)>;
+//
+//  template <
+//    class Completions,
+//    class AdditionalSigs = completion_signatures<>,
+//    template <class...> class SetValue = __default_set_value,
+//    template <class> class SetError = __default_set_error,
+//    class SetStopped = completion_signatures<set_stopped_t()>>
+//  using transform_completion_signatures =
+//    completion_signatures< ... >;
+//  ```
+//
+//  * `SetValue` : an alias template that accepts a set of value types and
+//  returns an instance of
+//    `completion_signatures`.
+//
+//  * `SetError` : an alias template that accepts an error types and returns a
+//  an instance of
+//    `completion_signatures`.
+//
+//  * `SetStopped` : an instantiation of `completion_signatures` with a list of
+//  completion
+//    signatures `Sigs...` to the added to the list if the sender can complete
+//    with a stopped signal.
+//
+//  * `AdditionalSigs` : an instantiation of `completion_signatures` with a list
+//  of completion
+//    signatures `Sigs...` to the added to the list unconditionally.
+//
+//  `transform_completion_signatures` does the following:
+//
+//  * Let `VCs...` be a pack of the `completion_signatures` types in the
+//  `__typelist` named by
+//    `value_types_of_t<Sndr, Env, SetValue, __typelist>`, and let `Vs...` be
+//    the concatenation of the packs that are template arguments to each
+//    `completion_signature` in `VCs...`.
+//
+//  * Let `ECs...` be a pack of the `completion_signatures` types in the
+//  `__typelist` named by
+//    `error_types_of_t<Sndr, Env, __errorlist>`, where `__errorlist` is an
+//    alias template such that `__errorlist<Ts...>` names
+//    `__typelist<SetError<Ts>...>`, and let `Es...` be the concatenation of the
+//    packs that are the template arguments to each `completion_signature` in
+//    `ECs...`.
+//
+//  * Let `Ss...` be an empty pack if `sends_stopped<Sndr, Env>` is `false`;
+//  otherwise, a pack
+//    containing the template arguments of the `completion_signatures`
+//    instantiation named by `SetStopped`.
+//
+//  * Let `MoreSigs...` be a pack of the template arguments of the
+//  `completion_signatures`
+//    instantiation named by `AdditionalSigs`.
+//
+//  Then `transform_completion_signatures<Completions, AdditionalSigs, SetValue,
+//  SetError, SendsStopped>` names the type `completion_signatures< Sigs... >`
+//  where `Sigs...` is the unique set of types in `[Vs..., Es..., Ss...,
+//  MoreSigs...]`.
+//
+//  If any of the above type computations are ill-formed,
+//  `transform_completion_signatures<Sndr, Env, AdditionalSigs, SetValue,
+//  SetError, SendsStopped>` is ill-formed.
+template <
+    class _Sigs, class _MoreSigs = completion_signatures<>,
+    template <class...> class _ValueTransform = __sigs::__default_set_value,
+    template <class...> class _ErrorTransform = __sigs::__default_set_error,
+    class _StoppedSigs = completion_signatures<set_stopped_t()>>
+using transform_completion_signatures = //
+    __transform_completion_signatures<
+        _Sigs, _ValueTransform, _ErrorTransform, _StoppedSigs,
+        __mtry_q<__concat_completion_signatures>::__f, _MoreSigs>;
+
+template <
+    class _Sndr, class _Env = empty_env,
+    class _MoreSigs = completion_signatures<>,
+    template <class...> class _ValueTransform = __sigs::__default_set_value,
+    template <class...> class _ErrorTransform = __sigs::__default_set_error,
+    class _StoppedSigs = completion_signatures<set_stopped_t()>>
+using transform_completion_signatures_of = //
+    transform_completion_signatures<completion_signatures_of_t<_Sndr, _Env>,
+                                    _MoreSigs, _ValueTransform, _ErrorTransform,
+                                    _StoppedSigs>;
+
+using __eptr_completion =
+    completion_signatures<set_error_t(std::exception_ptr)>;
+
+template <class _NoExcept>
+using __eptr_completion_if_t =
+    __if<_NoExcept, completion_signatures<>, __eptr_completion>;
+
+template <bool _NoExcept>
+using __eptr_completion_if = __eptr_completion_if_t<__mbool<_NoExcept>>;
+
+template <                                                      //
+    class _Sender,                                              //
+    class _Env = empty_env,                                     //
+    class _More = completion_signatures<>,                      //
+    class _SetValue = __qq<__sigs::__default_set_value>,        //
+    class _SetError = __qq<__sigs::__default_set_error>,        //
+    class _SetStopped = completion_signatures<set_stopped_t()>> //
+using __try_make_completion_signatures =                        //
+    __transform_completion_signatures<
+        __completion_signatures_of_t<_Sender, _Env>, _SetValue::template __f,
+        _SetError::template __f, _SetStopped,
+        __mtry_q<__concat_completion_signatures>::__f, _More>;
+
+template <class _SetTag, class _Completions, class _Tuple,
+          class _Variant>
+using __gather_completions = //
+    __gather_completion_signatures<
+        _Completions, _SetTag,
+        __mcompose_q<__types, _Tuple::template __f>::template __f,
+        __mconst<__types<>>::__f, __mconcat<_Variant>::template __f>;
+
+template <class _SetTag, class _Sender, class _Env, class _Tuple,
+          class _Variant>
+using __gather_completions_of = //
+    __gather_completions<_SetTag, __completion_signatures_of_t<_Sender, _Env>,
+                         _Tuple, _Variant>;
+
+template <                                                             //
+    class _Sender,                                                     //
+    class _Env = empty_env,                                            //
+    class _Sigs = completion_signatures<>,                             //
+    template <class...> class _SetValue = __sigs::__default_set_value, //
+    template <class...> class _SetError = __sigs::__default_set_error, //
+    class _SetStopped = completion_signatures<set_stopped_t()>>
+using make_completion_signatures =
+    transform_completion_signatures_of<_Sender, _Env, _Sigs, _SetValue,
+                                       _SetError, _SetStopped>;
+
+template <                                   //
+    class _Sigs,                             //
+    class _Tuple = __q<__decayed_std_tuple>, //
+    class _Variant = __q<__std_variant>>
+using __value_types_t =                      //
+    __gather_completions<set_value_t, _Sigs, _Tuple, _Variant>;
+
+template <                                   //
+    class _Sender,                           //
+    class _Env = empty_env,                  //
+    class _Tuple = __q<__decayed_std_tuple>, //
+    class _Variant = __q<__std_variant>>
+using __value_types_of_t =                   //
+    __value_types_t<__completion_signatures_of_t<_Sender, _Env>, _Tuple,
+                    _Variant>;
+
+template <class _Sigs, class _Variant = __q<__std_variant>>
+using __error_types_t =
+    __gather_completions<set_error_t, _Sigs, __q<__midentity>, _Variant>;
+
+template <class _Sender, class _Env = empty_env,
+          class _Variant = __q<__std_variant>>
+using __error_types_of_t =
+    __error_types_t<__completion_signatures_of_t<_Sender, _Env>, _Variant>;
+
+template <                                                  //
+    class _Sender,                                          //
+    class _Env = empty_env,                                 //
+    template <class...> class _Tuple = __decayed_std_tuple, //
+    template <class...> class _Variant = __std_variant>
+using value_types_of_t =
+    __value_types_of_t<_Sender, _Env, __q<_Tuple>, __q<_Variant>>;
+
+template <class _Sender, class _Env = empty_env,
+          template <class...> class _Variant = __std_variant>
+using error_types_of_t = __error_types_of_t<_Sender, _Env, __q<_Variant>>;
+
+template <class _Tag, class _Sender, class... _Env>
+using __count_of = //
+    __gather_completion_signatures<
+        __completion_signatures_of_t<_Sender, _Env...>, _Tag,
+        __mconst<__msize_t<1>>::__f, __mconst<__msize_t<0>>::__f, __mplus_t>;
+
+template <class _Tag, class _Sender, class... _Env>
+    requires sender_in<_Sender, _Env...>
+inline constexpr bool __sends = //
+    __v<__gather_completion_signatures<
+        __completion_signatures_of_t<_Sender, _Env...>, _Tag,
+        __mconst<__mtrue>::__f, __mconst<__mfalse>::__f, __mor_t>>;
+
+template <class _Sender, class... _Env>
+concept sends_stopped = //
+    sender_in<_Sender, _Env...> && __sends<set_stopped_t, _Sender, _Env...>;
+
+template <class _Sender, class... _Env>
+using __single_sender_value_t =
+    __value_types_t<__completion_signatures_of_t<_Sender, _Env...>,
+                    __msingle_or<void>, __q<__msingle>>;
+
+template <class _Sender, class... _Env>
+concept __single_value_sender =    //
+    sender_in<_Sender, _Env...> && //
+    requires { typename __single_sender_value_t<_Sender, _Env...>; };
+
+template <class _Sender, class... _Env>
+using __single_value_variant_sender_t =
+    __value_types_t<__completion_signatures_of_t<_Sender, _Env...>,
+                    __qq<__types>, __q<__msingle>>;
+
+template <class _Sender, class... _Env>
+concept __single_value_variant_sender = //
+    sender_in<_Sender, _Env...> &&      //
+    requires { typename __single_value_variant_sender_t<_Sender, _Env...>; };
+
+// The following utilities are needed fairly often:
+template <class _Fun, class... _Args>
+    requires __invocable<_Fun, _Args...>
+using __nothrow_invocable_t = __mbool<__nothrow_invocable<_Fun, _Args...>>;
+
+template <class _Catch, class _Tag, class _Fun, class _Sender, class... _Env>
+using __with_error_invoke_t = //
+    __if<__gather_completion_signatures<
+             __completion_signatures_of_t<_Sender, _Env...>, _Tag,
+             __mbind_front<__mtry_catch_q<__nothrow_invocable_t, _Catch>,
+                           _Fun>::template __f,
+             __mconst<__mbool<true>>::__f, __mand>,
+         completion_signatures<>, __eptr_completion>;
+
+template <class _Fun, class... _Args>
+    requires __invocable<_Fun, _Args...>
+using __set_value_invoke_t = //
+    completion_signatures<__minvoke<__mremove<void, __qf<set_value_t>>,
+                                    __invoke_result_t<_Fun, _Args...>>>;
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__transform_sender.hpp b/include/sdbusplus/async/stdexec/__detail/__transform_sender.hpp
new file mode 100644
index 0000000..9de95ba
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__transform_sender.hpp
@@ -0,0 +1,311 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__meta.hpp"
+#include "__sender_introspection.hpp"
+#include "__type_traits.hpp"
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_EDG(type_qualifiers_ignored_on_reference)
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// dependent_domain
+struct dependent_domain
+{
+    template <class _Sender, class _Env>
+    static constexpr auto __is_nothrow_transform_sender() noexcept -> bool;
+
+    template <sender_expr _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    STDEXEC_ATTRIBUTE((always_inline)) decltype(auto)
+        transform_sender(_Sender&& __sndr, const _Env& __env) const
+        noexcept(__is_nothrow_transform_sender<_Sender, _Env>());
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.transform_sender]
+namespace __domain
+{
+struct __transform_env
+{
+    template <class _Domain, class _Sender, class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/
+    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
+                              _Env&& __env) const noexcept
+    {
+        if constexpr (__domain::__has_transform_env<_Domain, _Sender, _Env>)
+        {
+            return __dom.transform_env(static_cast<_Sender&&>(__sndr),
+                                       static_cast<_Env&&>(__env));
+        }
+        else
+        {
+            return default_domain().transform_env(
+                static_cast<_Sender&&>(__sndr), static_cast<_Env&&>(__env));
+        }
+    }
+};
+
+struct __transform_sender_1
+{
+    template <class _Domain, class _Sender, class... _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static constexpr bool __is_nothrow() noexcept
+    {
+        if constexpr (__domain::__has_transform_sender<_Domain, _Sender,
+                                                       _Env...>)
+        {
+            return noexcept(__declval<_Domain&>().transform_sender(
+                __declval<_Sender>(), __declval<const _Env&>()...));
+        }
+        else
+        {
+            return //
+                noexcept(default_domain().transform_sender(
+                    __declval<_Sender>(), __declval<const _Env&>()...));
+        }
+    }
+
+    template <class _Domain, class _Sender, class... _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/
+    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
+                              const _Env&... __env) const
+        noexcept(__is_nothrow<_Domain, _Sender, const _Env&...>())
+    {
+        if constexpr (__domain::__has_transform_sender<_Domain, _Sender,
+                                                       _Env...>)
+        {
+            return __dom.transform_sender(static_cast<_Sender&&>(__sndr),
+                                          __env...);
+        }
+        else
+        {
+            return default_domain().transform_sender(
+                static_cast<_Sender&&>(__sndr), __env...);
+        }
+    }
+};
+
+template <class _Ty, class _Uy>
+concept __decay_same_as = same_as<__decay_t<_Ty>, __decay_t<_Uy>>;
+
+struct __transform_sender
+{
+    template <class _Self = __transform_sender, class _Domain, class _Sender,
+              class... _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    /*constexpr*/
+    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
+                              const _Env&... __env) const
+        noexcept(__nothrow_callable<__transform_sender_1, _Domain, _Sender,
+                                    const _Env&...>)
+    {
+        using _Sender2 = __call_result_t<__transform_sender_1, _Domain, _Sender,
+                                         const _Env&...>;
+        // If the transformation doesn't change the sender's type, then do not
+        // apply the transform recursively.
+        if constexpr (__decay_same_as<_Sender, _Sender2>)
+        {
+            return __transform_sender_1()(__dom, static_cast<_Sender&&>(__sndr),
+                                          __env...);
+        }
+        else
+        {
+            // We transformed the sender and got back a different sender.
+            // Transform that one too.
+            return _Self()(__dom,
+                           __transform_sender_1()(
+                               __dom, static_cast<_Sender&&>(__sndr), __env...),
+                           __env...);
+        }
+    }
+};
+
+struct __transform_dependent_sender
+{
+    // If we are doing a lazy customization of a type whose domain is
+    // value-dependent (e.g., let_value), first transform the sender to
+    // determine the domain. Then continue transforming the sender with the
+    // requested domain.
+    template <class _Domain, sender_expr _Sender, class _Env>
+        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+    /*constexpr*/ auto operator()(_Domain __dom, _Sender&& __sndr,
+                                  const _Env& __env) const
+        noexcept(noexcept(__transform_sender()(
+            __dom,
+            dependent_domain().transform_sender(static_cast<_Sender&&>(__sndr),
+                                                __env),
+            __env))) -> decltype(auto)
+    {
+        static_assert(__none_of<_Domain, dependent_domain>);
+        return __transform_sender()(__dom,
+                                    dependent_domain().transform_sender(
+                                        static_cast<_Sender&&>(__sndr), __env),
+                                    __env);
+    }
+};
+} // namespace __domain
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.transform_sender]
+inline constexpr struct transform_sender_t :
+    __domain::__transform_sender,
+    __domain::__transform_dependent_sender
+{
+    using __domain::__transform_sender::operator();
+    using __domain::__transform_dependent_sender::operator();
+} transform_sender{};
+
+template <class _Domain, class _Sender, class... _Env>
+using transform_sender_result_t =
+    __call_result_t<transform_sender_t, _Domain, _Sender, _Env...>;
+
+inline constexpr __domain::__transform_env transform_env{};
+
+struct _CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_
+{};
+
+template <class _Sender, class _Env>
+constexpr auto dependent_domain::__is_nothrow_transform_sender() noexcept
+    -> bool
+{
+    using _Env2 = __call_result_t<__domain::__transform_env, dependent_domain&,
+                                  _Sender, _Env>;
+    return __v<decltype(__sexpr_apply(
+        __declval<_Sender>(), []<class _Tag, class _Data, class... _Childs>(
+                                  _Tag, _Data&&, _Childs&&...) {
+        constexpr bool __first_transform_is_nothrow =
+            noexcept(__make_sexpr<_Tag>(
+                __declval<_Data>(),
+                __domain::__transform_sender()(__declval<dependent_domain&>(),
+                                               __declval<_Childs>(),
+                                               __declval<const _Env2&>())...));
+        using _Sender2 = decltype(__make_sexpr<_Tag>(
+            __declval<_Data>(),
+            __domain::__transform_sender()(__declval<dependent_domain&>(),
+                                           __declval<_Childs>(),
+                                           __declval<const _Env2&>())...));
+        using _Domain2 = decltype(__sexpr_apply(
+            __declval<_Sender2&>(), __domain::__common_domain_fn()));
+        constexpr bool __second_transform_is_nothrow =
+            noexcept(__domain::__transform_sender()(__declval<_Domain2&>(),
+                                                    __declval<_Sender2>(),
+                                                    __declval<const _Env&>()));
+        return __mbool < __first_transform_is_nothrow &&
+               __second_transform_is_nothrow > ();
+    }))>;
+}
+
+template <sender_expr _Sender, class _Env>
+    requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
+auto dependent_domain::transform_sender(_Sender&& __sndr,
+                                        const _Env& __env) const
+    noexcept(__is_nothrow_transform_sender<_Sender, _Env>()) -> decltype(auto)
+{
+    // apply any algorithm-specific transformation to the environment
+    const auto& __env2 = transform_env(*this, static_cast<_Sender&&>(__sndr),
+                                       __env);
+
+    // recursively transform the sender to determine the domain
+    return __sexpr_apply(static_cast<_Sender&&>(__sndr),
+                         [&]<class _Tag, class _Data, class... _Childs>(
+                             _Tag, _Data&& __data, _Childs&&... __childs) {
+        // TODO: propagate meta-exceptions here:
+        auto __sndr2 = __make_sexpr<_Tag>(
+            static_cast<_Data&&>(__data),
+            __domain::__transform_sender()(
+                *this, static_cast<_Childs&&>(__childs), __env2)...);
+        using _Sender2 = decltype(__sndr2);
+
+        auto __domain2 = __sexpr_apply(__sndr2, __domain::__common_domain_fn());
+        using _Domain2 = decltype(__domain2);
+
+        if constexpr (same_as<_Domain2, __none_such>)
+        {
+            return __mexception<_CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_,
+                                _WITH_SENDER_<_Sender2>>();
+        }
+        else
+        {
+            return __domain::__transform_sender()(__domain2, std::move(__sndr2),
+                                                  __env);
+        }
+    });
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template <class _Tag, class _Domain, class _Sender, class... _Args>
+concept __has_implementation_for =
+    __domain::__has_apply_sender<_Domain, _Tag, _Sender, _Args...> ||
+    __domain::__has_apply_sender<default_domain, _Tag, _Sender, _Args...>;
+
+/////////////////////////////////////////////////////////////////////////////
+// [execution.apply_sender]
+inline constexpr struct apply_sender_t
+{
+    template <class _Domain, class _Tag, class _Sender, class... _Args>
+        requires __has_implementation_for<_Tag, _Domain, _Sender, _Args...>
+    STDEXEC_ATTRIBUTE((always_inline))
+        /*constexpr*/
+        decltype(auto)
+            operator()(_Domain __dom, _Tag, _Sender&& __sndr,
+                       _Args&&... __args) const
+    {
+        if constexpr (__domain::__has_apply_sender<_Domain, _Tag, _Sender,
+                                                   _Args...>)
+        {
+            return __dom.apply_sender(_Tag(), static_cast<_Sender&&>(__sndr),
+                                      static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            return default_domain().apply_sender(
+                _Tag(), static_cast<_Sender&&>(__sndr),
+                static_cast<_Args&&>(__args)...);
+        }
+    }
+} apply_sender{};
+
+template <class _Domain, class _Tag, class _Sender, class... _Args>
+using apply_sender_result_t =
+    __call_result_t<apply_sender_t, _Domain, _Tag, _Sender, _Args...>;
+
+/////////////////////////////////////////////////////////////////////////////
+template <class _Sender, class _Scheduler, class _Tag = set_value_t>
+concept __completes_on = __decays_to<
+    __call_result_t<get_completion_scheduler_t<_Tag>, env_of_t<_Sender>>,
+    _Scheduler>;
+
+/////////////////////////////////////////////////////////////////////////////
+template <class _Sender, class _Scheduler, class _Env>
+concept __starts_on =
+    __decays_to<__call_result_t<get_scheduler_t, _Env>, _Scheduler>;
+} // namespace stdexec
+
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
index b1239a7..902a6e5 100644
--- a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
@@ -29,98 +29,169 @@
 template <class _Ty, std::size_t _Idx>
 struct __box
 {
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Ty __value;
+    // See https://github.com/llvm/llvm-project/issues/93563
+    // STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
+    _Ty __value;
 };
 
-template <class _Idx, class... _Ts>
+template <class _Ty>
+concept __empty = //
+    STDEXEC_IS_EMPTY(_Ty) && STDEXEC_IS_TRIVIALLY_CONSTRUCTIBLE(_Ty);
+
+template <__empty _Ty>
+inline _Ty __value{};
+
+// A specialization for empty types so that they don't take up space.
+template <__empty _Ty, std::size_t _Idx>
+struct __box<_Ty, _Idx>
+{
+    __box() = default;
+
+    constexpr __box(__not_decays_to<__box> auto&&) noexcept {}
+
+    static constexpr _Ty& __value = __tup::__value<_Ty>;
+};
+
+template <auto _Idx, class... _Ts>
 struct __tuple;
 
-template <std::size_t... _Idx, class... _Ts>
-struct __tuple<__indices<_Idx...>, _Ts...> : __box<_Ts, _Idx>...
-{};
+template <std::size_t... _Is, __indices<_Is...> _Idx, class... _Ts>
+struct __tuple<_Idx, _Ts...> : __box<_Ts, _Is>...
+{
+    template <class _Fn, class _Self, class... _Us>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    static auto apply(_Fn&& __fn, _Self&& __self, _Us&&... __us) //
+        noexcept(noexcept(static_cast<_Fn&&>(__fn)(
+            static_cast<_Us&&>(__us)...,
+            static_cast<_Self&&>(__self).__box<_Ts, _Is>::__value...)))
+            -> decltype(static_cast<_Fn&&>(__fn)(
+                static_cast<_Us&&>(__us)...,
+                static_cast<_Self&&>(__self).__box<_Ts, _Is>::__value...))
+    {
+        return static_cast<_Fn&&>(__fn)(
+            static_cast<_Us&&>(__us)...,
+            static_cast<_Self&&>(__self).__box<_Ts, _Is>::__value...);
+    }
+
+    template <class _Fn, class _Self, class... _Us>
+        requires(__callable<_Fn, _Us..., __copy_cvref_t<_Self, _Ts>> && ...)
+    STDEXEC_ATTRIBUTE((host, device, always_inline)) static auto for_each(
+        _Fn&& __fn, _Self&& __self, _Us&&... __us) //
+        noexcept((__nothrow_callable<_Fn, _Us..., __copy_cvref_t<_Self, _Ts>> &&
+                  ...)) -> void
+    {
+        return (static_cast<_Fn&&>(__fn)(
+                    static_cast<_Us&&>(__us)...,
+                    static_cast<_Self&&>(__self).__box<_Ts, _Is>::__value),
+                ...);
+    }
+};
 
 template <class... _Ts>
 STDEXEC_ATTRIBUTE((host, device))
-__tuple(_Ts...) -> __tuple<__indices_for<_Ts...>, _Ts...>;
+__tuple(_Ts...) -> __tuple<__indices_for<_Ts...>{}, _Ts...>;
+
+template <class _Fn, class _Tuple, class... _Us>
+using __apply_result_t = //
+    decltype(__declval<_Tuple>().apply(__declval<_Fn>(), __declval<_Tuple>(),
+                                       __declval<_Us>()...));
+
+template <class _Fn, class _Tuple, class... _Us>
+concept __applicable =
+    requires { typename __apply_result_t<_Fn, _Tuple, _Us...>; };
+
+template <class _Fn, class _Tuple, class... _Us>
+concept __nothrow_applicable =
+    __applicable<_Fn, _Tuple, _Us...>&& noexcept(__declval<_Tuple>().apply(
+        __declval<_Fn>(), __declval<_Tuple>(), __declval<_Us>()...));
 
 #if STDEXEC_GCC()
 template <class... _Ts>
 struct __mk_tuple
 {
-    using __t = __tuple<__indices_for<_Ts...>, _Ts...>;
+    using __t = __tuple<__indices_for<_Ts...>{}, _Ts...>;
 };
-template <class... _Ts>
-using __tuple_for = __t<__mk_tuple<_Ts...>>;
-#else
-template <class... _Ts>
-using __tuple_for = __tuple<__indices_for<_Ts...>, _Ts...>;
 #endif
 
 template <std::size_t _Idx, class _Ty>
-STDEXEC_ATTRIBUTE((always_inline))
-constexpr _Ty&& __get(__box<_Ty, _Idx>&& __self) noexcept
+STDEXEC_ATTRIBUTE((host, device, always_inline))
+constexpr _Ty&& get(__box<_Ty, _Idx>&& __self) noexcept
 {
     return static_cast<_Ty&&>(__self.__value);
 }
 
 template <std::size_t _Idx, class _Ty>
-STDEXEC_ATTRIBUTE((always_inline))
-constexpr _Ty& __get(__box<_Ty, _Idx>& __self) noexcept
+STDEXEC_ATTRIBUTE((host, device, always_inline))
+constexpr _Ty& get(__box<_Ty, _Idx>& __self) noexcept
 {
     return __self.__value;
 }
 
 template <std::size_t _Idx, class _Ty>
-STDEXEC_ATTRIBUTE((always_inline))
-constexpr const _Ty& __get(const __box<_Ty, _Idx>& __self) noexcept
+STDEXEC_ATTRIBUTE((host, device, always_inline))
+constexpr const _Ty& get(const __box<_Ty, _Idx>& __self) noexcept
 {
     return __self.__value;
 }
 
-template <std::size_t... _Idx, class... _Ts>
-void __tuple_like_(const __tuple<__indices<_Idx...>, _Ts...>&);
-
-template <class _Tup>
-concept __tuple_like = requires(_Tup& __tup) { __tup::__tuple_like_(__tup); };
-
-struct __apply_
+template <class _Fn, class _Tuple>
+STDEXEC_ATTRIBUTE((host, device, always_inline))
+auto operator<<(_Tuple&& __tup,
+                _Fn __fn) noexcept(__nothrow_move_constructible<_Fn>)
 {
-    template <class _Fun, class _Tuple, std::size_t... _Idx, class... _Ts>
-        requires __callable<_Fun, __copy_cvref_t<_Tuple, _Ts>...>
-    constexpr auto operator()(
-        _Fun&& __fun, _Tuple&& __tup,
-        const __tuple<
-            __indices<_Idx...>,
-            _Ts...>*) noexcept(__nothrow_callable<_Fun, __copy_cvref_t<_Tuple,
-                                                                       _Ts>...>)
-        -> __call_result_t<_Fun, __copy_cvref_t<_Tuple, _Ts>...>
-    {
-        return static_cast<_Fun&&>(__fun)(
-            static_cast<__copy_cvref_t<_Tuple, __box<_Ts, _Idx>>&&>(__tup)
-                .__value...);
-    }
-};
-
-template <class _Fun, __tuple_like _Tuple>
-STDEXEC_ATTRIBUTE((always_inline))
-constexpr auto __apply(_Fun&& __fun, _Tuple&& __tup) noexcept(
-    noexcept(__apply_()(static_cast<_Fun&&>(__fun),
-                        static_cast<_Tuple&&>(__tup), &__tup)))
-    -> decltype(__apply_()(static_cast<_Fun&&>(__fun),
-                           static_cast<_Tuple&&>(__tup), &__tup))
-{
-    return __apply_()(static_cast<_Fun&&>(__fun), static_cast<_Tuple&&>(__tup),
-                      &__tup);
+    return [&__tup, __fn]<class... _Us>(_Us&&... __us) //
+           noexcept(__nothrow_applicable<_Fn, _Tuple, _Us...>)
+               -> __apply_result_t<_Fn, _Tuple, _Us...> {
+        return __tup.apply(__fn, static_cast<_Tuple&&>(__tup),
+                           static_cast<_Us&&>(__us)...);
+    };
 }
+
+template <class _Fn, class... _Tuples>
+auto __cat_apply(_Fn __fn, _Tuples&&... __tups)                           //
+    noexcept(noexcept((static_cast<_Tuples&&>(__tups) << ... << __fn)())) //
+    -> decltype((static_cast<_Tuples&&>(__tups) << ... << __fn)())
+{
+    return (static_cast<_Tuples&&>(__tups) << ... << __fn)();
+}
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
+
+inline constexpr struct __mktuple_t
+{
+    template <class... _Ts>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    auto operator()(_Ts&&... __ts) const
+        noexcept(noexcept(__tuple{static_cast<_Ts&&>(__ts)...}))
+            -> decltype(__tuple{static_cast<_Ts&&>(__ts)...})
+    {
+        return __tuple{static_cast<_Ts&&>(__ts)...};
+    }
+} __mktuple{};
+
+STDEXEC_PRAGMA_POP()
+
 } // namespace __tup
 
 using __tup::__tuple;
 
-// So we can use __tuple as a typelist and ignore the first template parameter
-template <class _Fn, class _Idx, class... _Ts>
-    requires __minvocable<_Fn, _Ts...>
-struct __uncurry_<_Fn, __tuple<_Idx, _Ts...>>
+#if STDEXEC_GCC()
+template <class... _Ts>
+using __tuple_for = __t<__tup::__mk_tuple<_Ts...>>;
+#else
+template <class... _Ts>
+using __tuple_for = __tuple<__indices_for<_Ts...>{}, _Ts...>;
+#endif
+
+template <class... _Ts>
+using __decayed_tuple = __tuple_for<__decay_t<_Ts>...>;
+
+// So we can use __tuple as a typelist
+template <auto _Idx, class... _Ts>
+struct __muncurry_<__tuple<_Idx, _Ts...>>
 {
-    using __t = __minvoke<_Fn, _Ts...>;
+    template <class _Fn>
+    using __f = __minvoke<_Fn, _Ts...>;
 };
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
index 8b134ed..41a17c7 100644
--- a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
@@ -17,13 +17,15 @@
 
 #include "__config.hpp"
 
+#include <type_traits>
+
 namespace stdexec
 {
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // A very simple std::declval replacement that doesn't handle void
 template <class _Tp>
-auto __declval() noexcept -> _Tp&&;
+extern auto (*__declval)() noexcept -> _Tp&&;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // __decay_t: An efficient implementation for std::decay
@@ -179,12 +181,10 @@
 template <class _From, class _To>
 using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>;
 
-#if !STDEXEC_HAS_BUILTIN(__is_const)
 template <class>
-inline constexpr bool __is_const = false;
+inline constexpr bool __is_const_ = false;
 template <class _Up>
-inline constexpr bool __is_const<const _Up> = true;
-#endif
+inline constexpr bool __is_const_<const _Up> = true;
 
 namespace __tt
 {
@@ -196,4 +196,13 @@
 using __remove_rvalue_reference_t =
     decltype(__tt::__remove_rvalue_reference_fn(__declval<_Ty>()));
 
+// Implemented as a class instead of a free function
+// because of a bizarre nvc++ compiler bug:
+struct __cref_fn
+{
+    template <class _Ty>
+    auto operator()(const _Ty&) -> const _Ty&;
+};
+template <class _Ty>
+using __cref_t = decltype(__cref_fn{}(__declval<_Ty>()));
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__upon_error.hpp b/include/sdbusplus/async/stdexec/__detail/__upon_error.hpp
new file mode 100644
index 0000000..eb71faa
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__upon_error.hpp
@@ -0,0 +1,116 @@
+/*
+ * 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 "__basic_sender.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+
+// include these after __execution_fwd.hpp
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.upon_error]
+namespace __upon_error
+{
+inline constexpr __mstring __upon_error_context =
+    "In stdexec::upon_error(Sender, Function)..."_mstr;
+using __on_not_callable = __callable_error<__upon_error_context>;
+
+template <class _Fun, class _CvrefSender, class... _Env>
+using __completion_signatures_t = //
+    transform_completion_signatures<
+        __completion_signatures_of_t<_CvrefSender, _Env...>,
+        __with_error_invoke_t<__on_not_callable, set_error_t, _Fun,
+                              _CvrefSender, _Env...>,
+        __sigs::__default_set_value,
+        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
+                      _Fun>::template __f>;
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct upon_error_t
+{
+    template <sender _Sender, __movable_value _Fun>
+    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
+        auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<upon_error_t>(static_cast<_Fun&&>(__fun),
+                                       static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <__movable_value _Fun>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Fun __fun) const -> __binder_back<upon_error_t, _Fun>
+    {
+        return {{static_cast<_Fun&&>(__fun)}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(upon_error_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(upon_error_t, _Sender, _Fun)>;
+};
+
+struct __upon_error_impl : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
+        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
+                                     __child_of<_Sender>, _Env...> {
+        static_assert(sender_expr_for<_Sender, upon_error_t>);
+        return {};
+    };
+
+    static constexpr auto complete = //
+        []<class _Tag, class _State, class _Receiver, class... _Args>(
+            __ignore, _State& __state, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Tag, set_error_t>)
+        {
+            stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr),
+                                        static_cast<_State&&>(__state),
+                                        static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            _Tag()(static_cast<_Receiver&&>(__rcvr),
+                   static_cast<_Args&&>(__args)...);
+        }
+    };
+};
+} // namespace __upon_error
+
+using __upon_error::upon_error_t;
+inline constexpr upon_error_t upon_error{};
+
+template <>
+struct __sexpr_impl<upon_error_t> : __upon_error::__upon_error_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__upon_stopped.hpp b/include/sdbusplus/async/stdexec/__detail/__upon_stopped.hpp
new file mode 100644
index 0000000..bb588da
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__upon_stopped.hpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "__basic_sender.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__execution_fwd.hpp"
+#include "__meta.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__senders_core.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+
+// include these after __execution_fwd.hpp
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.upon_stopped]
+namespace __upon_stopped
+{
+inline constexpr __mstring __upon_stopped_context =
+    "In stdexec::upon_stopped(Sender, Function)..."_mstr;
+using __on_not_callable = __callable_error<__upon_stopped_context>;
+
+template <class _Fun, class _CvrefSender, class... _Env>
+using __completion_signatures_t = //
+    transform_completion_signatures<
+        __completion_signatures_of_t<_CvrefSender, _Env...>,
+        __with_error_invoke_t<__on_not_callable, set_stopped_t, _Fun,
+                              _CvrefSender, _Env...>,
+        __sigs::__default_set_value, __sigs::__default_set_error,
+        __set_value_invoke_t<_Fun>>;
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+struct upon_stopped_t
+{
+    template <sender _Sender, __movable_value _Fun>
+        requires __callable<_Fun>
+    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
+        auto
+    {
+        auto __domain = __get_early_domain(__sndr);
+        return stdexec::transform_sender(
+            __domain,
+            __make_sexpr<upon_stopped_t>(static_cast<_Fun&&>(__fun),
+                                         static_cast<_Sender&&>(__sndr)));
+    }
+
+    template <__movable_value _Fun>
+        requires __callable<_Fun>
+    STDEXEC_ATTRIBUTE((always_inline)) auto operator()(_Fun __fun) const
+        -> __binder_back<upon_stopped_t, _Fun>
+    {
+        return {{static_cast<_Fun&&>(__fun)}, {}, {}};
+    }
+
+    using _Sender = __1;
+    using _Fun = __0;
+    using __legacy_customizations_t =
+        __types<tag_invoke_t(upon_stopped_t,
+                             get_completion_scheduler_t<set_value_t>(
+                                 get_env_t(_Sender&)),
+                             _Sender, _Fun),
+                tag_invoke_t(upon_stopped_t, _Sender, _Fun)>;
+};
+
+struct __upon_stopped_impl : __sexpr_defaults
+{
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender, class... _Env>(_Sender&&, _Env&&...) noexcept
+        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
+                                     __child_of<_Sender>, _Env...> {
+        static_assert(sender_expr_for<_Sender, upon_stopped_t>);
+        return {};
+    };
+
+    static constexpr auto complete = //
+        []<class _Tag, class _State, class _Receiver, class... _Args>(
+            __ignore, _State& __state, _Receiver& __rcvr, _Tag,
+            _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Tag, set_stopped_t>)
+        {
+            stdexec::__set_value_invoke(static_cast<_Receiver&&>(__rcvr),
+                                        static_cast<_State&&>(__state),
+                                        static_cast<_Args&&>(__args)...);
+        }
+        else
+        {
+            _Tag()(static_cast<_Receiver&&>(__rcvr),
+                   static_cast<_Args&&>(__args)...);
+        }
+    };
+};
+} // namespace __upon_stopped
+
+using __upon_stopped::upon_stopped_t;
+inline constexpr upon_stopped_t upon_stopped{};
+
+template <>
+struct __sexpr_impl<upon_stopped_t> : __upon_stopped::__upon_stopped_impl
+{};
+
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__utility.hpp b/include/sdbusplus/async/stdexec/__detail/__utility.hpp
index 5f3f68a..3af21b7 100644
--- a/include/sdbusplus/async/stdexec/__detail/__utility.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__utility.hpp
@@ -15,13 +15,110 @@
  */
 #pragma once
 
+#include "__concepts.hpp"
 #include "__config.hpp"
 #include "__type_traits.hpp"
 
+#include <initializer_list>
+#include <memory> // for addressof
 #include <type_traits>
 
 namespace stdexec
 {
+constexpr std::size_t __npos = ~0UL;
+
+template <class...>
+struct __undefined;
+
+struct __
+{};
+
+struct __ignore
+{
+    __ignore() = default;
+
+    STDEXEC_ATTRIBUTE((always_inline))
+    constexpr __ignore(auto&&...) noexcept {}
+};
+
+#if STDEXEC_MSVC()
+// MSVCBUG
+// https://developercommunity.visualstudio.com/t/Incorrect-function-template-argument-sub/10437827
+
+template <std::size_t>
+struct __ignore_t
+{
+    __ignore_t() = default;
+
+    constexpr __ignore_t(auto&&...) noexcept {}
+};
+#else
+template <std::size_t>
+using __ignore_t = __ignore;
+#endif
+
+struct __none_such
+{};
+
+namespace
+{
+struct __anon
+{};
+} // namespace
+
+struct __immovable
+{
+    __immovable() = default;
+
+  private:
+    STDEXEC_IMMOVABLE(__immovable);
+};
+
+struct __move_only
+{
+    __move_only() = default;
+
+    __move_only(__move_only&&) noexcept = default;
+    auto operator=(__move_only&&) noexcept -> __move_only& = default;
+
+    __move_only(const __move_only&) = delete;
+    auto operator=(const __move_only&) -> __move_only& = delete;
+};
+
+inline constexpr std::size_t
+    __umax(std::initializer_list<std::size_t> __il) noexcept
+{
+    std::size_t __m = 0;
+    for (std::size_t __i : __il)
+    {
+        if (__i > __m)
+        {
+            __m = __i;
+        }
+    }
+    return __m;
+}
+
+inline constexpr std::size_t __pos_of(const bool* const __first,
+                                      const bool* const __last) noexcept
+{
+    for (const bool* __where = __first; __where != __last; ++__where)
+    {
+        if (*__where)
+        {
+            return static_cast<std::size_t>(__where - __first);
+        }
+    }
+    return __npos;
+}
+
+template <class _Ty, class... _Ts>
+inline constexpr std::size_t __index_of() noexcept
+{
+    constexpr bool __same[] = {STDEXEC_IS_SAME(_Ty, _Ts)..., false};
+    return __pos_of(__same, __same + sizeof...(_Ts));
+}
+
 namespace __detail
 {
 template <class _Cpcvref>
@@ -35,4 +132,68 @@
 template <class _Ty>
 inline constexpr const auto& __forward_like =
     __detail::__forward_like<__copy_cvref_fn<_Ty&&>>;
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wold-style-cast")
+
+// A derived-to-base cast that works even when the base is not accessible from
+// derived.
+template <class _Tp, class _Up>
+STDEXEC_ATTRIBUTE((host, device))
+auto __c_upcast(_Up&& u) noexcept -> __copy_cvref_t<_Up&&, _Tp>
+    requires __decays_to<_Tp, _Tp>
+{
+    static_assert(STDEXEC_IS_BASE_OF(_Tp, __decay_t<_Up>));
+    return (__copy_cvref_t<_Up&&, _Tp>)static_cast<_Up&&>(u);
+}
+
+// A base-to-derived cast that works even when the base is not accessible from
+// derived.
+template <class _Tp, class _Up>
+STDEXEC_ATTRIBUTE((host, device))
+auto __c_downcast(_Up&& u) noexcept -> __copy_cvref_t<_Up&&, _Tp>
+    requires __decays_to<_Tp, _Tp>
+{
+    static_assert(STDEXEC_IS_BASE_OF(__decay_t<_Up>, _Tp));
+    return (__copy_cvref_t<_Up&&, _Tp>)static_cast<_Up&&>(u);
+}
+
+STDEXEC_PRAGMA_POP()
+
+template <class _Ty>
+_Ty __decay_copy(_Ty) noexcept;
+
+template <class _Ty>
+struct __indestructible
+{
+    template <class... _Us>
+    constexpr __indestructible(_Us&&... __us) noexcept(
+        __nothrow_constructible_from<_Ty, _Us...>) :
+        __value(static_cast<_Us&&>(__us)...)
+    {}
+
+    constexpr ~__indestructible() {}
+
+    _Ty& get() noexcept
+    {
+        return __value;
+    }
+
+    const _Ty& get() const noexcept
+    {
+        return __value;
+    }
+
+    union
+    {
+        _Ty __value;
+    };
+};
 } // namespace stdexec
+
+#if defined(__cpp_auto_cast) && (__cpp_auto_cast >= 202110UL)
+#define STDEXEC_DECAY_COPY(...) auto(__VA_ARGS__)
+#else
+#define STDEXEC_DECAY_COPY(...)                                                \
+    (true ? (__VA_ARGS__) : stdexec::__decay_copy(__VA_ARGS__))
+#endif
diff --git a/include/sdbusplus/async/stdexec/__detail/__variant.hpp b/include/sdbusplus/async/stdexec/__detail/__variant.hpp
new file mode 100644
index 0000000..a3ea4bd
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__variant.hpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 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 "__meta.hpp"
+#include "__type_traits.hpp"
+#include "__utility.hpp"
+
+#include <cstddef>
+#include <memory>
+#include <new>
+#include <type_traits>
+
+/********************************************************************************/
+/* NB: The variant type implemented here default-constructs into the valueless
+ */
+/* state. This is different from std::variant which default-constructs into the
+ */
+/* first alternative. This is done to simplify the implementation and to avoid
+ */
+/* the need for a default constructor for each alternative type. */
+/********************************************************************************/
+
+STDEXEC_PRAGMA_PUSH()
+STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
+
+namespace stdexec
+{
+inline constexpr std::size_t __variant_npos = ~0UL;
+
+struct __monostate
+{};
+
+namespace __var
+{
+template <auto _Idx, class... _Ts>
+class __variant;
+
+template <>
+class __variant<__indices<>{}>
+{
+  public:
+    template <class _Fn, class... _Us>
+    STDEXEC_ATTRIBUTE((host, device))
+    void visit(_Fn&&, _Us&&...) const noexcept
+    {
+        STDEXEC_ASSERT(false);
+    }
+
+    STDEXEC_ATTRIBUTE((host, device))
+    static constexpr std::size_t index() noexcept
+    {
+        return __variant_npos;
+    }
+
+    STDEXEC_ATTRIBUTE((host, device))
+    static constexpr bool is_valueless() noexcept
+    {
+        return true;
+    }
+};
+
+template <std::size_t... _Is, __indices<_Is...> _Idx, class... _Ts>
+class __variant<_Idx, _Ts...>
+{
+    static constexpr std::size_t __max_size = stdexec::__umax({sizeof(_Ts)...});
+    static_assert(__max_size != 0);
+    std::size_t __index_{__variant_npos};
+    alignas(_Ts...) unsigned char __storage_[__max_size];
+
+    STDEXEC_ATTRIBUTE((host, device))
+    void __destroy() noexcept
+    {
+        auto __index = std::exchange(__index_, __variant_npos);
+        if (__variant_npos != __index)
+        {
+            ((_Is == __index ? std::destroy_at(static_cast<_Ts*>(__get_ptr()))
+                             : void(0)),
+             ...);
+        }
+    }
+
+    template <std::size_t _Ny>
+    using __at = __m_at_c<_Ny, _Ts...>;
+
+  public:
+    // immovable:
+    __variant(__variant&&) = delete;
+
+    STDEXEC_ATTRIBUTE((host, device))
+    __variant() noexcept {}
+
+    STDEXEC_ATTRIBUTE((host, device))
+    ~__variant()
+    {
+        __destroy();
+    }
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    void* __get_ptr() noexcept
+    {
+        return __storage_;
+    }
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    std::size_t index() const noexcept
+    {
+        return __index_;
+    }
+
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    bool is_valueless() const noexcept
+    {
+        return __index_ == __variant_npos;
+    }
+
+    template <class _Ty, class... _As>
+    STDEXEC_ATTRIBUTE((host, device))
+    _Ty& emplace(_As&&... __as) //
+        noexcept(__nothrow_constructible_from<_Ty, _As...>)
+    {
+        constexpr std::size_t __new_index = stdexec::__index_of<_Ty, _Ts...>();
+        static_assert(__new_index != __variant_npos, "Type not in variant");
+
+        __destroy();
+        ::new (__storage_) _Ty{static_cast<_As&&>(__as)...};
+        __index_ = __new_index;
+        return *reinterpret_cast<_Ty*>(__storage_);
+    }
+
+    template <std::size_t _Ny, class... _As>
+    STDEXEC_ATTRIBUTE((host, device))
+    __at<_Ny>& emplace(_As&&... __as) //
+        noexcept(__nothrow_constructible_from<__at<_Ny>, _As...>)
+    {
+        static_assert(_Ny < sizeof...(_Ts), "variant index is too large");
+
+        __destroy();
+        ::new (__storage_) __at<_Ny>{static_cast<_As&&>(__as)...};
+        __index_ = _Ny;
+        return *reinterpret_cast<__at<_Ny>*>(__storage_);
+    }
+
+    template <class _Fn, class... _As>
+    STDEXEC_ATTRIBUTE((host, device))
+    auto emplace_from(_Fn&& __fn, _As&&... __as) //
+        noexcept(__nothrow_callable<_Fn, _As...>)
+            -> __call_result_t<_Fn, _As...>&
+    {
+        using __result_t = __call_result_t<_Fn, _As...>;
+        constexpr std::size_t __new_index =
+            stdexec::__index_of<__result_t, _Ts...>();
+        static_assert(__new_index != __variant_npos, "Type not in variant");
+
+        __destroy();
+        ::new (__storage_)
+            __result_t(static_cast<_Fn&&>(__fn)(static_cast<_As&&>(__as)...));
+        __index_ = __new_index;
+        return *reinterpret_cast<__result_t*>(__storage_);
+    }
+
+    template <class _Fn, class _Self, class... _As>
+    STDEXEC_ATTRIBUTE((host, device))
+    static void visit(_Fn&& __fn, _Self&& __self, _As&&... __as) //
+        noexcept((__nothrow_callable<_Fn, _As..., __copy_cvref_t<_Self, _Ts>> &&
+                  ...))
+    {
+        STDEXEC_ASSERT(__self.__index_ != __variant_npos);
+        auto __index = __self.__index_; // make it local so we don't access it
+                                        // after it's deleted.
+        ((_Is == __index ? static_cast<_Fn&&>(__fn)(
+                               static_cast<_As&&>(__as)...,
+                               static_cast<_Self&&>(__self).template get<_Is>())
+                         : void()),
+         ...);
+    }
+
+    template <std::size_t _Ny>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    decltype(auto) get() && noexcept
+    {
+        STDEXEC_ASSERT(_Ny == __index_);
+        return static_cast<__at<_Ny>&&>(
+            *reinterpret_cast<__at<_Ny>*>(__storage_));
+    }
+
+    template <std::size_t _Ny>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    decltype(auto) get() & noexcept
+    {
+        STDEXEC_ASSERT(_Ny == __index_);
+        return *reinterpret_cast<__at<_Ny>*>(__storage_);
+    }
+
+    template <std::size_t _Ny>
+    STDEXEC_ATTRIBUTE((host, device, always_inline))
+    decltype(auto) get() const& noexcept
+    {
+        STDEXEC_ASSERT(_Ny == __index_);
+        return *reinterpret_cast<const __at<_Ny>*>(__storage_);
+    }
+};
+} // namespace __var
+
+using __var::__variant;
+
+template <class... _Ts>
+using __variant_for = __variant<__indices_for<_Ts...>{}, _Ts...>;
+
+template <class... Ts>
+using __uniqued_variant_for =
+    __mcall<__munique<__qq<__variant_for>>, __decay_t<Ts>...>;
+
+// So we can use __variant as a typelist
+template <auto _Idx, class... _Ts>
+struct __muncurry_<__variant<_Idx, _Ts...>>
+{
+    template <class _Fn>
+    using __f = __minvoke<_Fn, _Ts...>;
+};
+} // namespace stdexec
+
+STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/__detail/__when_all.hpp b/include/sdbusplus/async/stdexec/__detail/__when_all.hpp
new file mode 100644
index 0000000..d3a778b
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__when_all.hpp
@@ -0,0 +1,640 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "../stop_token.hpp"
+#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__continue_on.hpp"
+#include "__diagnostics.hpp"
+#include "__domain.hpp"
+#include "__env.hpp"
+#include "__into_variant.hpp"
+#include "__meta.hpp"
+#include "__optional.hpp"
+#include "__schedulers.hpp"
+#include "__senders.hpp"
+#include "__transform_completion_signatures.hpp"
+#include "__transform_sender.hpp"
+#include "__tuple.hpp"
+#include "__type_traits.hpp"
+#include "__utility.hpp"
+#include "__variant.hpp"
+
+#include <atomic>
+#include <exception>
+
+namespace stdexec
+{
+/////////////////////////////////////////////////////////////////////////////
+// [execution.senders.adaptors.when_all]
+// [execution.senders.adaptors.when_all_with_variant]
+namespace __when_all
+{
+enum __state_t
+{
+    __started,
+    __error,
+    __stopped
+};
+
+struct __on_stop_request
+{
+    inplace_stop_source& __stop_source_;
+
+    void operator()() noexcept
+    {
+        __stop_source_.request_stop();
+    }
+};
+
+template <class _Env>
+auto __mkenv(_Env&& __env, const inplace_stop_source& __stop_source) noexcept
+{
+    return __env::__join(prop{get_stop_token, __stop_source.get_token()},
+                         static_cast<_Env&&>(__env));
+}
+
+template <class _Env>
+using __env_t = //
+    decltype(__when_all::__mkenv(__declval<_Env>(),
+                                 __declval<inplace_stop_source&>()));
+
+template <class _Sender, class _Env>
+concept __max1_sender = sender_in<_Sender, _Env> &&
+                        __mvalid<__value_types_of_t, _Sender, _Env,
+                                 __mconst<int>, __msingle_or<void>>;
+
+template <
+    __mstring _Context = "In stdexec::when_all()..."_mstr,
+    __mstring _Diagnostic =
+        "The given sender can complete successfully in more that one way. "
+        "Use stdexec::when_all_with_variant() instead."_mstr>
+struct _INVALID_WHEN_ALL_ARGUMENT_;
+
+template <class _Sender, class... _Env>
+using __too_many_value_completions_error =
+    __mexception<_INVALID_WHEN_ALL_ARGUMENT_<>, _WITH_SENDER_<_Sender>,
+                 _WITH_ENVIRONMENT_<_Env>...>;
+
+template <class... _Args>
+using __all_nothrow_decay_copyable =
+    __mbool<(__nothrow_decay_copyable<_Args> && ...)>;
+
+template <class _Error>
+using __set_error_t = completion_signatures<set_error_t(__decay_t<_Error>)>;
+
+template <class _Sender, class... _Env>
+using __nothrow_decay_copyable_results = //
+    __for_each_completion_signature<
+        __completion_signatures_of_t<_Sender, _Env...>,
+        __all_nothrow_decay_copyable, __mand_t>;
+
+template <class... _Env>
+struct __completions_t
+{
+    template <class... _Senders>
+    using __all_nothrow_decay_copyable_results = //
+        __mand<__nothrow_decay_copyable_results<_Senders, _Env...>...>;
+
+    template <class _Sender, class _ValueTuple, class... _Rest>
+    using __value_tuple_t =
+        __minvoke<__if_c<(0 == sizeof...(_Rest)), __mconst<_ValueTuple>,
+                         __q<__too_many_value_completions_error>>,
+                  _Sender, _Env...>;
+
+    template <class _Sender>
+    using __single_values_of_t = //
+        __value_types_t<__completion_signatures_of_t<_Sender, _Env...>,
+                        __mtransform<__q<__decay_t>, __q<__types>>,
+                        __mbind_front_q<__value_tuple_t, _Sender>>;
+
+    template <class... _Senders>
+    using __set_values_sig_t = //
+        __meval<completion_signatures,
+                __minvoke<__mconcat<__qf<set_value_t>>,
+                          __single_values_of_t<_Senders>...>>;
+
+    template <class... _Senders>
+    using __f =  //
+        __meval< //
+            __concat_completion_signatures,
+            __meval<__eptr_completion_if_t,
+                    __all_nothrow_decay_copyable_results<_Senders...>>,
+            completion_signatures<set_stopped_t()>,
+            __minvoke<__with_default<__qq<__set_values_sig_t>,
+                                     completion_signatures<>>,
+                      _Senders...>,
+            __transform_completion_signatures<
+                __completion_signatures_of_t<_Senders, _Env...>,
+                __mconst<completion_signatures<>>::__f, __set_error_t,
+                completion_signatures<>, __concat_completion_signatures>...>;
+};
+
+template <class _Tag, class _Receiver>
+auto __complete_fn(_Tag, _Receiver& __rcvr) noexcept
+{
+    return [&]<class... _Ts>(_Ts&... __ts) noexcept {
+        _Tag()(static_cast<_Receiver&&>(__rcvr), static_cast<_Ts&&>(__ts)...);
+    };
+}
+
+template <class _Receiver, class _ValuesTuple>
+void __set_values(_Receiver& __rcvr, _ValuesTuple& __values) noexcept
+{
+    __values.apply(
+        [&](auto&... __opt_vals) noexcept -> void {
+        __tup::__cat_apply(__when_all::__complete_fn(set_value, __rcvr),
+                           *__opt_vals...);
+    },
+        __values);
+}
+
+template <class _Env, class _Sender>
+using __values_opt_tuple_t = //
+    value_types_of_t<_Sender, __env_t<_Env>, __decayed_tuple, __optional>;
+
+template <class _Env, __max1_sender<__env_t<_Env>>... _Senders>
+struct __traits
+{
+    // tuple<optional<tuple<Vs1...>>, optional<tuple<Vs2...>>, ...>
+    using __values_tuple = //
+        __minvoke<__with_default<
+                      __mtransform<__mbind_front_q<__values_opt_tuple_t, _Env>,
+                                   __q<__tuple_for>>,
+                      __ignore>,
+                  _Senders...>;
+
+    using __collect_errors = __mbind_front_q<__mset_insert, __mset<>>;
+
+    using __errors_list = //
+        __minvoke<
+            __mconcat<>,
+            __if<__mand<__nothrow_decay_copyable_results<_Senders, _Env>...>,
+                 __types<>, __types<std::exception_ptr>>,
+            __error_types_of_t<_Senders, __env_t<_Env>, __q<__types>>...>;
+
+    using __errors_variant =
+        __mapply<__q<__uniqued_variant_for>, __errors_list>;
+};
+
+struct _INVALID_ARGUMENTS_TO_WHEN_ALL_
+{};
+
+template <class _ErrorsVariant, class _ValuesTuple, class _StopToken>
+struct __when_all_state
+{
+    using __stop_callback_t =
+        stop_callback_for_t<_StopToken, __on_stop_request>;
+
+    template <class _Receiver>
+    void __arrive(_Receiver& __rcvr) noexcept
+    {
+        if (0 == --__count_)
+        {
+            __complete(__rcvr);
+        }
+    }
+
+    template <class _Receiver>
+    void __complete(_Receiver& __rcvr) noexcept
+    {
+        // Stop callback is no longer needed. Destroy it.
+        __on_stop_.reset();
+        // All child operations have completed and arrived at the barrier.
+        switch (__state_.load(std::memory_order_relaxed))
+        {
+            case __started:
+                if constexpr (!same_as<_ValuesTuple, __ignore>)
+                {
+                    // All child operations completed successfully:
+                    __when_all::__set_values(__rcvr, __values_);
+                }
+                break;
+            case __error:
+                if constexpr (!__same_as<_ErrorsVariant, __variant_for<>>)
+                {
+                    // One or more child operations completed with an error:
+                    __errors_.visit(__complete_fn(set_error, __rcvr),
+                                    __errors_);
+                }
+                break;
+            case __stopped:
+                stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
+                break;
+            default:;
+        }
+    }
+
+    std::atomic<std::size_t> __count_;
+    inplace_stop_source __stop_source_{};
+    // Could be non-atomic here and atomic_ref everywhere except __completion_fn
+    std::atomic<__state_t> __state_{__started};
+    _ErrorsVariant __errors_{};
+    STDEXEC_ATTRIBUTE((no_unique_address))
+    _ValuesTuple __values_{};
+    __optional<__stop_callback_t> __on_stop_{};
+};
+
+template <class _Env>
+static auto __mk_state_fn(const _Env&) noexcept
+{
+    return []<__max1_sender<__env_t<_Env>>... _Child>(__ignore, __ignore,
+                                                      _Child&&...) {
+        using _Traits = __traits<_Env, _Child...>;
+        using _ErrorsVariant = typename _Traits::__errors_variant;
+        using _ValuesTuple = typename _Traits::__values_tuple;
+        using _State = __when_all_state<_ErrorsVariant, _ValuesTuple,
+                                        stop_token_of_t<_Env>>;
+        return _State{sizeof...(_Child)};
+    };
+}
+
+template <class _Env>
+using __mk_state_fn_t = decltype(__when_all::__mk_state_fn(__declval<_Env>()));
+
+struct when_all_t
+{
+    // Used by the default_domain to find legacy customizations:
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(when_all_t, _Sender...)>;
+
+    template <sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Senders&&... __sndrs) const -> __well_formed_sender auto
+    {
+        auto __domain = __domain::__common_domain_t<_Senders...>();
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<when_all_t>(
+                          __(), static_cast<_Senders&&>(__sndrs)...));
+    }
+};
+
+struct __when_all_impl : __sexpr_defaults
+{
+    template <class _Self, class _Env>
+    using __error_t = __mexception<_INVALID_ARGUMENTS_TO_WHEN_ALL_,
+                                   __children_of<_Self, __q<_WITH_SENDERS_>>,
+                                   _WITH_ENVIRONMENT_<_Env>>;
+
+    template <class _Self, class... _Env>
+    using __completions =
+        __children_of<_Self, __completions_t<__env_t<_Env>...>>;
+
+    static constexpr auto get_attrs = //
+        []<class... _Child>(__ignore, const _Child&...) noexcept {
+        using _Domain = __domain::__common_domain_t<_Child...>;
+        if constexpr (__same_as<_Domain, default_domain>)
+        {
+            return env();
+        }
+        else
+        {
+            return prop{get_domain, _Domain()};
+        }
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept {
+        static_assert(sender_expr_for<_Self, when_all_t>);
+        return __minvoke<__mtry_catch<__q<__completions>, __q<__error_t>>,
+                         _Self, _Env...>();
+    };
+
+    static constexpr auto get_env =                                         //
+        []<class _State, class _Receiver>(__ignore, _State& __state,
+                                          const _Receiver& __rcvr) noexcept //
+        -> __env_t<env_of_t<const _Receiver&>> {
+        return __mkenv(stdexec::get_env(__rcvr), __state.__stop_source_);
+    };
+
+    static constexpr auto get_state = //
+        []<class _Self, class _Receiver>(_Self&& __self, _Receiver& __rcvr)
+        -> __sexpr_apply_result_t<_Self, __mk_state_fn_t<env_of_t<_Receiver>>> {
+        return __sexpr_apply(
+            static_cast<_Self&&>(__self),
+            __when_all::__mk_state_fn(stdexec::get_env(__rcvr)));
+    };
+
+    static constexpr auto start = //
+        []<class _State, class _Receiver, class... _Operations>(
+            _State& __state, _Receiver& __rcvr,
+            _Operations&... __child_ops) noexcept -> void {
+        // register stop callback:
+        __state.__on_stop_.emplace(get_stop_token(stdexec::get_env(__rcvr)),
+                                   __on_stop_request{__state.__stop_source_});
+        if (__state.__stop_source_.stop_requested())
+        {
+            // Stop has already been requested. Don't bother starting
+            // the child operations.
+            stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
+        }
+        else
+        {
+            (stdexec::start(__child_ops), ...);
+            if constexpr (sizeof...(__child_ops) == 0)
+            {
+                __state.__complete(__rcvr);
+            }
+        }
+    };
+
+    template <class _State, class _Receiver, class _Error>
+    static void __set_error(_State& __state, _Receiver&,
+                            _Error&& __err) noexcept
+    {
+        // TODO: What memory orderings are actually needed here?
+        if (__error != __state.__state_.exchange(__error))
+        {
+            __state.__stop_source_.request_stop();
+            // We won the race, free to write the error into the operation
+            // state without worry.
+            if constexpr (__nothrow_decay_copyable<_Error>)
+            {
+                __state.__errors_.template emplace<__decay_t<_Error>>(
+                    static_cast<_Error&&>(__err));
+            }
+            else
+            {
+                try
+                {
+                    __state.__errors_.template emplace<__decay_t<_Error>>(
+                        static_cast<_Error&&>(__err));
+                }
+                catch (...)
+                {
+                    __state.__errors_.template emplace<std::exception_ptr>(
+                        std::current_exception());
+                }
+            }
+        }
+    }
+
+    static constexpr auto complete = //
+        []<class _Index, class _State, class _Receiver, class _Set,
+           class... _Args>(_Index, _State& __state, _Receiver& __rcvr, _Set,
+                           _Args&&... __args) noexcept -> void {
+        if constexpr (__same_as<_Set, set_error_t>)
+        {
+            __set_error(__state, __rcvr, static_cast<_Args&&>(__args)...);
+        }
+        else if constexpr (__same_as<_Set, set_stopped_t>)
+        {
+            __state_t __expected = __started;
+            // Transition to the "stopped" state if and only if we're in the
+            // "started" state. (If this fails, it's because we're in an
+            // error state, which trumps cancellation.)
+            if (__state.__state_.compare_exchange_strong(__expected, __stopped))
+            {
+                __state.__stop_source_.request_stop();
+            }
+        }
+        else if constexpr (!__same_as<decltype(_State::__values_), __ignore>)
+        {
+            // We only need to bother recording the completion values
+            // if we're not already in the "error" or "stopped" state.
+            if (__state.__state_ == __started)
+            {
+                auto& __opt_values = __tup::get<__v<_Index>>(__state.__values_);
+                using _Tuple = __decayed_tuple<_Args...>;
+                static_assert(
+                    __same_as<decltype(*__opt_values), _Tuple&>,
+                    "One of the senders in this when_all() is fibbing about what types it sends");
+                if constexpr ((__nothrow_decay_copyable<_Args> && ...))
+                {
+                    __opt_values.emplace(
+                        _Tuple{{static_cast<_Args&&>(__args)}...});
+                }
+                else
+                {
+                    try
+                    {
+                        __opt_values.emplace(
+                            _Tuple{{static_cast<_Args&&>(__args)}...});
+                    }
+                    catch (...)
+                    {
+                        __set_error(__state, __rcvr, std::current_exception());
+                    }
+                }
+            }
+        }
+
+        __state.__arrive(__rcvr);
+    };
+};
+
+struct when_all_with_variant_t
+{
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(when_all_with_variant_t, _Sender...)>;
+
+    template <sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Senders&&... __sndrs) const -> __well_formed_sender auto
+    {
+        auto __domain = __domain::__common_domain_t<_Senders...>();
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<when_all_with_variant_t>(
+                          __(), static_cast<_Senders&&>(__sndrs)...));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        // transform the when_all_with_variant into a regular when_all (looking
+        // for early when_all customizations), then transform it again to look
+        // for late customizations.
+        return __sexpr_apply(
+            static_cast<_Sender&&>(__sndr),
+            [&]<class... _Child>(__ignore, __ignore, _Child&&... __child) {
+            return when_all_t()(
+                into_variant(static_cast<_Child&&>(__child))...);
+        });
+    }
+};
+
+struct __when_all_with_variant_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class... _Child>(__ignore, const _Child&...) noexcept {
+        using _Domain = __domain::__common_domain_t<_Child...>;
+        if constexpr (same_as<_Domain, default_domain>)
+        {
+            return env();
+        }
+        else
+        {
+            return prop{get_domain, _Domain()};
+        }
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {
+        return {};
+    };
+};
+
+struct transfer_when_all_t
+{
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(
+            transfer_when_all_t,
+            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
+
+    template <scheduler _Scheduler, sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
+        -> __well_formed_sender auto
+    {
+        using _Env = __t<__schfr::__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<transfer_when_all_t>(
+                          _Env{static_cast<_Scheduler&&>(__sched)},
+                          static_cast<_Senders&&>(__sndrs)...));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        // transform the transfer_when_all into a regular transform | when_all
+        // (looking for early customizations), then transform it again to look
+        // for late customizations.
+        return __sexpr_apply(
+            static_cast<_Sender&&>(__sndr),
+            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
+                                              _Child&&... __child) {
+            return continue_on(when_all_t()(static_cast<_Child&&>(__child)...),
+                               get_completion_scheduler<set_value_t>(__data));
+        });
+    }
+};
+
+struct __transfer_when_all_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Data>(const _Data& __data,
+                        const auto&...) noexcept -> const _Data& {
+        return __data;
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {
+        return {};
+    };
+};
+
+struct transfer_when_all_with_variant_t
+{
+    using _Env = __0;
+    using _Sender = __1;
+    using __legacy_customizations_t = //
+        __types<tag_invoke_t(
+            transfer_when_all_with_variant_t,
+            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
+
+    template <scheduler _Scheduler, sender... _Senders>
+        requires __domain::__has_common_domain<_Senders...>
+    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
+        -> __well_formed_sender auto
+    {
+        using _Env = __t<__schfr::__environ<__id<__decay_t<_Scheduler>>>>;
+        auto __domain = query_or(get_domain, __sched, default_domain());
+        return stdexec::transform_sender(
+            __domain, __make_sexpr<transfer_when_all_with_variant_t>(
+                          _Env{{static_cast<_Scheduler&&>(__sched)}},
+                          static_cast<_Senders&&>(__sndrs)...));
+    }
+
+    template <class _Sender, class _Env>
+    static auto transform_sender(_Sender&& __sndr, const _Env&)
+    {
+        // transform the transfer_when_all_with_variant into regular
+        // transform_when_all and into_variant calls/ (looking for early
+        // customizations), then transform it again to look for late
+        // customizations.
+        return __sexpr_apply(
+            static_cast<_Sender&&>(__sndr),
+            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
+                                              _Child&&... __child) {
+            return transfer_when_all_t()(
+                get_completion_scheduler<set_value_t>(
+                    static_cast<_Data&&>(__data)),
+                into_variant(static_cast<_Child&&>(__child))...);
+        });
+    }
+};
+
+struct __transfer_when_all_with_variant_impl : __sexpr_defaults
+{
+    static constexpr auto get_attrs = //
+        []<class _Data>(const _Data& __data,
+                        const auto&...) noexcept -> const _Data& {
+        return __data;
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Sender>(_Sender&&) noexcept         //
+        -> __completion_signatures_of_t<              //
+            transform_sender_result_t<default_domain, _Sender, empty_env>> {
+        return {};
+    };
+};
+} // namespace __when_all
+
+using __when_all::when_all_t;
+inline constexpr when_all_t when_all{};
+
+using __when_all::when_all_with_variant_t;
+inline constexpr when_all_with_variant_t when_all_with_variant{};
+
+using __when_all::transfer_when_all_t;
+inline constexpr transfer_when_all_t transfer_when_all{};
+
+using __when_all::transfer_when_all_with_variant_t;
+inline constexpr transfer_when_all_with_variant_t
+    transfer_when_all_with_variant{};
+
+template <>
+struct __sexpr_impl<when_all_t> : __when_all::__when_all_impl
+{};
+
+template <>
+struct __sexpr_impl<when_all_with_variant_t> :
+    __when_all::__when_all_with_variant_impl
+{};
+
+template <>
+struct __sexpr_impl<transfer_when_all_t> : __when_all::__transfer_when_all_impl
+{};
+
+template <>
+struct __sexpr_impl<transfer_when_all_with_variant_t> :
+    __when_all::__transfer_when_all_with_variant_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__with_awaitable_senders.hpp b/include/sdbusplus/async/stdexec/__detail/__with_awaitable_senders.hpp
new file mode 100644
index 0000000..c522394
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__with_awaitable_senders.hpp
@@ -0,0 +1,153 @@
+/*
+ * 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 "__as_awaitable.hpp"
+#include "__concepts.hpp"
+#include "__execution_fwd.hpp"
+
+#include <exception>
+
+namespace stdexec
+{
+#if !STDEXEC_STD_NO_COROUTINES()
+namespace __was
+{
+template <class _Promise = void>
+class __continuation_handle;
+
+template <>
+class __continuation_handle<void>
+{
+  public:
+    __continuation_handle() = default;
+
+    template <class _Promise>
+    __continuation_handle(__coro::coroutine_handle<_Promise> __coro) noexcept :
+        __coro_(__coro)
+    {
+        if constexpr (requires(_Promise& __promise) {
+                          __promise.unhandled_stopped();
+                      })
+        {
+            __stopped_callback_ =
+                [](void* __address) noexcept -> __coro::coroutine_handle<> {
+                // This causes the rest of the coroutine (the part after the
+                // co_await of the sender) to be skipped and invokes the calling
+                // coroutine's stopped handler.
+                return __coro::coroutine_handle<_Promise>::from_address(
+                           __address)
+                    .promise()
+                    .unhandled_stopped();
+            };
+        }
+        // If _Promise doesn't implement unhandled_stopped(), then if a
+        // "stopped" unwind reaches this point, it's considered an unhandled
+        // exception and terminate() is called.
+    }
+
+    [[nodiscard]] auto handle() const noexcept -> __coro::coroutine_handle<>
+    {
+        return __coro_;
+    }
+
+    [[nodiscard]] auto unhandled_stopped() const noexcept
+        -> __coro::coroutine_handle<>
+    {
+        return __stopped_callback_(__coro_.address());
+    }
+
+  private:
+    using __stopped_callback_t = __coro::coroutine_handle<> (*)(void*) noexcept;
+
+    __coro::coroutine_handle<> __coro_{};
+    __stopped_callback_t __stopped_callback_ =
+        [](void*) noexcept -> __coro::coroutine_handle<> { std::terminate(); };
+};
+
+template <class _Promise>
+class __continuation_handle
+{
+  public:
+    __continuation_handle() = default;
+
+    __continuation_handle(__coro::coroutine_handle<_Promise> __coro) noexcept :
+        __continuation_{__coro}
+    {}
+
+    auto handle() const noexcept -> __coro::coroutine_handle<_Promise>
+    {
+        return __coro::coroutine_handle<_Promise>::from_address(
+            __continuation_.handle().address());
+    }
+
+    [[nodiscard]] auto unhandled_stopped() const noexcept
+        -> __coro::coroutine_handle<>
+    {
+        return __continuation_.unhandled_stopped();
+    }
+
+  private:
+    __continuation_handle<> __continuation_{};
+};
+
+struct __with_awaitable_senders_base
+{
+    template <class _OtherPromise>
+    void set_continuation(
+        __coro::coroutine_handle<_OtherPromise> __hcoro) noexcept
+    {
+        static_assert(!__same_as<_OtherPromise, void>);
+        __continuation_ = __hcoro;
+    }
+
+    void set_continuation(__continuation_handle<> __continuation) noexcept
+    {
+        __continuation_ = __continuation;
+    }
+
+    [[nodiscard]] auto continuation() const noexcept -> __continuation_handle<>
+    {
+        return __continuation_;
+    }
+
+    auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>
+    {
+        return __continuation_.unhandled_stopped();
+    }
+
+  private:
+    __continuation_handle<> __continuation_{};
+};
+
+template <class _Promise>
+struct with_awaitable_senders : __with_awaitable_senders_base
+{
+    template <class _Value>
+    auto await_transform(_Value&& __val)
+        -> __call_result_t<as_awaitable_t, _Value, _Promise&>
+    {
+        static_assert(derived_from<_Promise, with_awaitable_senders>);
+        return as_awaitable(static_cast<_Value&&>(__val),
+                            static_cast<_Promise&>(*this));
+    }
+};
+} // namespace __was
+
+using __was::__continuation_handle;
+using __was::with_awaitable_senders;
+#endif
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__write_env.hpp b/include/sdbusplus/async/stdexec/__detail/__write_env.hpp
new file mode 100644
index 0000000..3afb894
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__write_env.hpp
@@ -0,0 +1,93 @@
+/*
+ * 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 "__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__basic_sender.hpp"
+#include "__env.hpp"
+#include "__sender_adaptor_closure.hpp"
+#include "__senders.hpp"
+#include "__transform_sender.hpp"
+#include "__utility.hpp"
+
+namespace stdexec
+{
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// __write adaptor
+namespace __write_
+{
+struct __write_env_t
+{
+    template <sender _Sender, class _Env>
+    auto operator()(_Sender&& __sndr, _Env __env) const
+    {
+        return __make_sexpr<__write_env_t>(static_cast<_Env&&>(__env),
+                                           static_cast<_Sender&&>(__sndr));
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    auto operator()(_Env __env) const -> __binder_back<__write_env_t, _Env>
+    {
+        return {{static_cast<_Env&&>(__env)}, {}, {}};
+    }
+
+    template <class _Env>
+    STDEXEC_ATTRIBUTE((always_inline))
+    static auto __transform_env_fn(_Env&& __env) noexcept
+    {
+        return [&](__ignore, const auto& __state, __ignore) noexcept {
+            return __env::__join(__state, static_cast<_Env&&>(__env));
+        };
+    }
+
+    template <sender_expr_for<__write_env_t> _Self, class _Env>
+    static auto transform_env(const _Self& __self, _Env&& __env) noexcept
+    {
+        return __sexpr_apply(__self,
+                             __transform_env_fn(static_cast<_Env&&>(__env)));
+    }
+};
+
+struct __write_env_impl : __sexpr_defaults
+{
+    static constexpr auto get_env = //
+        [](__ignore, const auto& __state, const auto& __rcvr) noexcept {
+        return __env::__join(__state, stdexec::get_env(__rcvr));
+    };
+
+    static constexpr auto get_completion_signatures = //
+        []<class _Self, class... _Env>(_Self&&, _Env&&...) noexcept
+        -> __completion_signatures_of_t<
+            __child_of<_Self>,
+            __meval<__env::__join_t, const __decay_t<__data_of<_Self>>&,
+                    _Env...>> {
+        static_assert(sender_expr_for<_Self, __write_env_t>);
+        return {};
+    };
+};
+} // namespace __write_
+
+using __write_::__write_env_t;
+inline constexpr __write_env_t __write{};
+inline constexpr __write_env_t __write_env{};
+
+template <>
+struct __sexpr_impl<__write_env_t> : __write_::__write_env_impl
+{};
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/any_sender_of.hpp b/include/sdbusplus/async/stdexec/any_sender_of.hpp
index e65118c..e7658a8 100644
--- a/include/sdbusplus/async/stdexec/any_sender_of.hpp
+++ b/include/sdbusplus/async/stdexec/any_sender_of.hpp
@@ -92,12 +92,11 @@
     }
 };
 
-template <class>
+template <class _Queryable, bool _IsEnvProvider = true>
 struct __query_vfun_fn;
 
 template <class _EnvProvider>
-    requires __callable<get_env_t, const _EnvProvider&>
-struct __query_vfun_fn<_EnvProvider>
+struct __query_vfun_fn<_EnvProvider, true>
 {
     template <class _Tag, class _Ret, class... _As>
         requires __callable<_Tag, env_of_t<const _EnvProvider&>, _As...>
@@ -105,9 +104,9 @@
                         const noexcept)(void*, _As...)
     {
         return +[](void* __env_provider, _As... __as) -> _Ret {
-            return _Tag{}(
-                get_env(*static_cast<const _EnvProvider*>(__env_provider)),
-                static_cast<_As&&>(__as)...);
+            return _Tag{}(stdexec::get_env(*static_cast<const _EnvProvider*>(
+                              __env_provider)),
+                          static_cast<_As&&>(__as)...);
         };
     }
 
@@ -120,16 +119,15 @@
             static_assert(
                 __nothrow_callable<_Tag, const env_of_t<_EnvProvider>&,
                                    _As...>);
-            return _Tag{}(
-                get_env(*static_cast<const _EnvProvider*>(__env_provider)),
-                static_cast<_As&&>(__as)...);
+            return _Tag{}(stdexec::get_env(*static_cast<const _EnvProvider*>(
+                              __env_provider)),
+                          static_cast<_As&&>(__as)...);
         };
     }
 };
 
 template <class _Queryable>
-    requires(!__callable<get_env_t, const _Queryable&>)
-struct __query_vfun_fn<_Queryable>
+struct __query_vfun_fn<_Queryable, false>
 {
     template <class _Tag, class _Ret, class... _As>
         requires __callable<_Tag, const _Queryable&, _As...>
@@ -227,12 +225,9 @@
     template <class _Storage, class _Tp>
         requires tag_invocable<__copy_construct_t, __mtype<_Tp>, _Storage&,
                                const _Storage&>
-    void operator()(
-        __mtype<_Tp>, _Storage& __self,
-        const _Storage&
-            __from) noexcept(nothrow_tag_invocable<__copy_construct_t,
-                                                   __mtype<_Tp>, _Storage&,
-                                                   const _Storage&>)
+    void operator()(__mtype<_Tp>, _Storage& __self, const _Storage& __from) //
+        noexcept(nothrow_tag_invocable<__copy_construct_t, __mtype<_Tp>,
+                                       _Storage&, const _Storage&>)
     {
         stdexec::tag_invoke(__copy_construct_t{}, __mtype<_Tp>{}, __self,
                             __from);
@@ -299,16 +294,16 @@
         static_cast<_StorageCPOs*>(nullptr))}...};
 
 template <class _Vtable, class _Allocator, bool _Copyable = false,
-          std::size_t _Alignment = alignof(std::max_align_t),
-          std::size_t _InlineSize = 3 * sizeof(void*)>
+          std::size_t _InlineSize = 3 * sizeof(void*),
+          std::size_t _Alignment = alignof(std::max_align_t)>
 struct __storage
 {
     class __t;
 };
 
 template <class _Vtable, class _Allocator,
-          std::size_t _Alignment = alignof(std::max_align_t),
-          std::size_t _InlineSize = 3 * sizeof(void*)>
+          std::size_t _InlineSize = 3 * sizeof(void*),
+          std::size_t _Alignment = alignof(std::max_align_t)>
 struct __immovable_storage
 {
     class __t : __immovable
@@ -430,7 +425,8 @@
         }
 
         template <class _Tp>
-        friend void tag_invoke(__delete_t, __mtype<_Tp>, __t& __self) noexcept
+        STDEXEC_MEMFN_DECL(void __delete)
+        (this __mtype<_Tp>, __t& __self) noexcept
         {
             if (!__self.__object_pointer_)
             {
@@ -460,8 +456,8 @@
 };
 
 template <class _Vtable, class _Allocator, bool _Copyable,
-          std::size_t _Alignment, std::size_t _InlineSize>
-class __storage<_Vtable, _Allocator, _Copyable, _Alignment, _InlineSize>::__t :
+          std::size_t _InlineSize, std::size_t _Alignment>
+class __storage<_Vtable, _Allocator, _Copyable, _InlineSize, _Alignment>::__t :
     __if_c<_Copyable, __, __move_only>
 {
     static_assert(STDEXEC_IS_CONVERTIBLE_TO(
@@ -625,7 +621,8 @@
     }
 
     template <class _Tp>
-    friend void tag_invoke(__delete_t, __mtype<_Tp>, __t& __self) noexcept
+    STDEXEC_MEMFN_DECL(void __delete)
+    (this __mtype<_Tp>, __t& __self) noexcept
     {
         if (!__self.__object_pointer_)
         {
@@ -644,8 +641,8 @@
     }
 
     template <class _Tp>
-    friend void tag_invoke(__move_construct_t, __mtype<_Tp>, __t& __self,
-                           __t&& __other) noexcept
+    STDEXEC_MEMFN_DECL(void __move_construct)
+    (this __mtype<_Tp>, __t& __self, __t&& __other) noexcept
     {
         if (!__other.__object_pointer_)
         {
@@ -674,8 +671,8 @@
 
     template <class _Tp>
         requires _Copyable
-    friend void tag_invoke(__copy_construct_t, __mtype<_Tp>, __t& __self,
-                           const __t& __other)
+    STDEXEC_MEMFN_DECL(void __copy_construct)(this __mtype<_Tp>, __t& __self,
+                                              const __t& __other)
     {
         if (!__other.__object_pointer_)
         {
@@ -705,8 +702,9 @@
 struct __empty_vtable
 {
     template <class _Sender>
-    friend auto tag_invoke(__create_vtable_t, __mtype<__empty_vtable>,
-                           __mtype<_Sender>) noexcept -> const __empty_vtable*
+    STDEXEC_MEMFN_DECL(auto __create_vtable)
+    (this __mtype<__empty_vtable>, __mtype<_Sender>) noexcept
+        -> const __empty_vtable*
     {
         static const __empty_vtable __vtable_{};
         return &__vtable_;
@@ -720,8 +718,10 @@
 template <class _VTable, class _Allocator = std::allocator<std::byte>>
 using __unique_storage_t = __t<__storage<_VTable, _Allocator>>;
 
-template <class _VTable, class _Allocator = std::allocator<std::byte>>
-using __copyable_storage_t = __t<__storage<_VTable, _Allocator, true>>;
+template <class _VTable, std::size_t _InlineSize = 3 * sizeof(void*),
+          class _Allocator = std::allocator<std::byte>>
+using __copyable_storage_t =
+    __t<__storage<_VTable, _Allocator, true, _InlineSize>>;
 
 template <class _Tag, class... _As>
 auto __tag_type(_Tag (*)(_As...)) -> _Tag;
@@ -744,9 +744,6 @@
 
 namespace __rec
 {
-template <class _Sig>
-struct __rcvr_vfun;
-
 template <class _Sigs, class... _Queries>
 struct __vtable
 {
@@ -756,30 +753,12 @@
 template <class _Sigs, class... _Queries>
 struct __ref;
 
-template <class _Tag, class... _As>
-struct __rcvr_vfun<_Tag(_As...)>
-{
-    void (*__fn_)(void*, _As...) noexcept;
-};
-
-template <class _Rcvr>
-struct __rcvr_vfun_fn
-{
-    template <class _Tag, class... _As>
-    constexpr void (*operator()(_Tag (*)(_As...))
-                        const noexcept)(void*, _As...) noexcept
-    {
-        return +[](void* __rcvr, _As... __as) noexcept -> void {
-            _Tag{}(static_cast<_Rcvr&&>(*static_cast<_Rcvr*>(__rcvr)),
-                   static_cast<_As&&>(__as)...);
-        };
-    }
-};
-
 template <class... _Sigs, class... _Queries>
 struct __vtable<completion_signatures<_Sigs...>, _Queries...>
 {
-    class __t : public __rcvr_vfun<_Sigs>..., public __query_vfun<_Queries>...
+    class __t :
+        public __any_::__rcvr_vfun<_Sigs>...,
+        public __query_vfun<_Queries>...
     {
       public:
         using __query_vfun<_Queries>::operator()...;
@@ -788,11 +767,13 @@
         template <class _Rcvr>
             requires receiver_of<_Rcvr, completion_signatures<_Sigs...>> &&
                      (__callable<__query_vfun_fn<_Rcvr>, _Queries> && ...)
-        friend auto tag_invoke(__create_vtable_t, __mtype<__t>,
-                               __mtype<_Rcvr>) noexcept -> const __t*
+        STDEXEC_MEMFN_DECL(auto __create_vtable)(this __mtype<__t>,
+                                                 __mtype<_Rcvr>) noexcept
+            -> const __t*
         {
             static const __t __vtable_{
-                {__rcvr_vfun_fn<_Rcvr>{}(static_cast<_Sigs*>(nullptr))}...,
+                {__any_::__rcvr_vfun_fn(static_cast<_Rcvr*>(nullptr),
+                                        static_cast<_Sigs*>(nullptr))}...,
                 {__query_vfun_fn<_Rcvr>{}(static_cast<_Queries>(nullptr))}...};
             return &__vtable_;
         }
@@ -816,23 +797,20 @@
     {
         const __vtable_t* __vtable_;
         void* __rcvr_;
-        in_place_stop_token __token_;
+        inplace_stop_token __token_;
 
         template <class _Tag, class... _As>
             requires __callable<const __vtable_t&, _Tag, void*, _As...>
-        friend auto
-            tag_invoke(_Tag, const __env_t& __self, _As&&... __as) noexcept(
-                __nothrow_callable<const __vtable_t&, _Tag, void*, _As...>)
+        auto query(_Tag, _As&&... __as) const //
+            noexcept(__nothrow_callable<const __vtable_t&, _Tag, void*, _As...>)
                 -> __call_result_t<const __vtable_t&, _Tag, void*, _As...>
         {
-            return (*__self.__vtable_)(_Tag{}, __self.__rcvr_,
-                                       static_cast<_As&&>(__as)...);
+            return (*__vtable_)(_Tag{}, __rcvr_, static_cast<_As&&>(__as)...);
         }
 
-        friend auto tag_invoke(get_stop_token_t, const __env_t& __self) noexcept
-            -> in_place_stop_token
+        auto query(get_stop_token_t) const noexcept -> inplace_stop_token
         {
-            return __self.__token_;
+            return __token_;
         }
     } __env_;
 
@@ -849,20 +827,34 @@
                &__rcvr, stdexec::get_stop_token(stdexec::get_env(__rcvr))}
     {}
 
-    template <__completion_tag _Tag, __decays_to<__ref> _Self, class... _As>
-        requires __one_of<_Tag(_As...), _Sigs...>
-    friend void tag_invoke(_Tag, _Self&& __self, _As&&... __as) noexcept
+    template <class... _As>
+        requires __one_of<set_value_t(_As...), _Sigs...>
+    void set_value(_As&&... __as) noexcept
     {
-        (*static_cast<const __rcvr_vfun<_Tag(_As...)>*>(__self.__env_.__vtable_)
-              ->__fn_)(static_cast<_Self&&>(__self).__env_.__rcvr_,
-                       static_cast<_As&&>(__as)...);
+        const __any_::__rcvr_vfun<set_value_t(_As...)>* __vfun =
+            __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_, static_cast<_As&&>(__as)...);
     }
 
-    template <std::same_as<__ref> Self>
-    friend auto tag_invoke(get_env_t, const Self& __self) noexcept
-        -> const __env_t&
+    template <class _Error>
+        requires __one_of<set_error_t(_Error), _Sigs...>
+    void set_error(_Error&& __err) noexcept
     {
-        return __self.__env_;
+        const __any_::__rcvr_vfun<set_error_t(_Error)>* __vfun =
+            __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_, static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+        requires __one_of<set_stopped_t(), _Sigs...>
+    {
+        const __any_::__rcvr_vfun<set_stopped_t()>* __vfun = __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_);
+    }
+
+    auto get_env() const noexcept -> const __env_t&
+    {
+        return __env_;
     }
 };
 
@@ -891,7 +883,7 @@
   private:
 #endif
     using _FilteredQueries =
-        __minvoke<__remove_if<__q<__is_never_stop_token_query>>, _Queries...>;
+        __minvoke<__mremove_if<__q<__is_never_stop_token_query>>, _Queries...>;
     using __vtable_t = stdexec::__t<
         __mapply<__mbind_front_q<__vtable, completion_signatures<_Sigs...>>,
                  _FilteredQueries>>;
@@ -903,13 +895,11 @@
 
         template <class _Tag, class... _As>
             requires __callable<const __vtable_t&, _Tag, void*, _As...>
-        friend auto
-            tag_invoke(_Tag, const __env_t& __self, _As&&... __as) noexcept(
-                __nothrow_callable<const __vtable_t&, _Tag, void*, _As...>)
+        auto query(_Tag, _As&&... __as) const //
+            noexcept(__nothrow_callable<const __vtable_t&, _Tag, void*, _As...>)
                 -> __call_result_t<const __vtable_t&, _Tag, void*, _As...>
         {
-            return (*__self.__vtable_)(_Tag{}, __self.__rcvr_,
-                                       static_cast<_As&&>(__as)...);
+            return (*__vtable_)(_Tag{}, __rcvr_, static_cast<_As&&>(__as)...);
         }
     } __env_;
 
@@ -926,20 +916,34 @@
                &__rcvr}
     {}
 
-    template <__completion_tag _Tag, __decays_to<__ref> _Self, class... _As>
-        requires __one_of<_Tag(_As...), _Sigs...>
-    friend void tag_invoke(_Tag, _Self&& __self, _As&&... __as) noexcept
+    template <class... _As>
+        requires __one_of<set_value_t(_As...), _Sigs...>
+    void set_value(_As&&... __as) noexcept
     {
-        (*static_cast<const __rcvr_vfun<_Tag(_As...)>*>(__self.__env_.__vtable_)
-              ->__fn_)(static_cast<_Self&&>(__self).__env_.__rcvr_,
-                       static_cast<_As&&>(__as)...);
+        const __any_::__rcvr_vfun<set_value_t(_As...)>* __vfun =
+            __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_, static_cast<_As&&>(__as)...);
     }
 
-    template <std::same_as<__ref> Self>
-    friend auto tag_invoke(get_env_t, const Self& __self) noexcept
-        -> const __env_t&
+    template <class _Error>
+        requires __one_of<set_error_t(_Error), _Sigs...>
+    void set_error(_Error&& __err) noexcept
     {
-        return __self.__env_;
+        const __any_::__rcvr_vfun<set_error_t(_Error)>* __vfun =
+            __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_, static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+        requires __one_of<set_stopped_t(), _Sigs...>
+    {
+        const __any_::__rcvr_vfun<set_stopped_t()>* __vfun = __env_.__vtable_;
+        (*__vfun->__complete_)(__env_.__rcvr_);
+    }
+
+    auto get_env() const noexcept -> const __env_t&
+    {
+        return __env_;
     }
 };
 } // namespace __rec
@@ -951,15 +955,16 @@
 
   private:
     template <class _Op>
-    friend auto tag_invoke(__create_vtable_t, __mtype<__operation_vtable>,
-                           __mtype<_Op>) noexcept -> const __operation_vtable*
+    STDEXEC_MEMFN_DECL(auto __create_vtable)
+    (this __mtype<__operation_vtable>, __mtype<_Op>) noexcept
+        -> const __operation_vtable*
     {
         static __operation_vtable __vtable{
             [](void* __object_pointer) noexcept -> void {
             STDEXEC_ASSERT(__object_pointer);
             _Op& __op = *static_cast<_Op*>(__object_pointer);
             static_assert(operation_state<_Op>);
-            start(__op);
+            stdexec::start(__op);
         }};
         return &__vtable;
     }
@@ -973,7 +978,7 @@
 
 struct __on_stop_t
 {
-    stdexec::in_place_stop_source& __source_;
+    stdexec::inplace_stop_source& __source_;
 
     void operator()() const noexcept
     {
@@ -986,7 +991,7 @@
 {
     STDEXEC_ATTRIBUTE((no_unique_address))
     _Receiver __rcvr_;
-    stdexec::in_place_stop_source __stop_source_{};
+    stdexec::inplace_stop_source __stop_source_{};
     using __stop_callback = typename stdexec::stop_token_of_t<
         stdexec::env_of_t<_Receiver>>::template callback_type<__on_stop_t>;
     std::optional<__stop_callback> __on_stop_{};
@@ -994,7 +999,7 @@
 
 template <class _Env>
 using __env_t =
-    __env::__join_t<__env::__with<in_place_stop_token, get_stop_token_t>, _Env>;
+    __env::__join_t<prop<get_stop_token_t, inplace_stop_token>, _Env>;
 
 template <class _ReceiverId>
 struct __stoppable_receiver
@@ -1006,52 +1011,46 @@
         using receiver_concept = stdexec::receiver_t;
         __operation_base<_Receiver>* __op_;
 
-        template <same_as<set_next_t> _SetNext, same_as<__t> _Self, class _Item>
-            requires __callable<_SetNext, _Receiver&, _Item>
-        friend auto tag_invoke(_SetNext, _Self& __self, _Item&& __item)
+        template <same_as<__t> _Self, class _Item>
+            requires __callable<set_next_t, _Receiver&, _Item>
+        STDEXEC_MEMFN_DECL(auto set_next)(this _Self& __self,
+                                          _Item&& __item) noexcept
+            -> __call_result_t<set_next_t, _Receiver&, _Item>
         {
-            return _SetNext{}(__self.__op_->__rcvr_,
-                              static_cast<_Item&&>(__item));
+            return exec::set_next(__self.__op_->__rcvr_,
+                                  static_cast<_Item&&>(__item));
         }
 
-        template <same_as<set_value_t> _SetValue, same_as<__t> _Self,
-                  class... _Args>
-            requires __callable<_SetValue, _Receiver&&, _Args...>
-        friend void tag_invoke(_SetValue, _Self&& __self,
-                               _Args&&... __args) noexcept
+        template <class... _Args>
+            requires __callable<set_value_t, _Receiver, _Args...>
+        void set_value(_Args&&... __args) noexcept
         {
-            __self.__op_->__on_stop_.reset();
-            _SetValue{}(static_cast<_Receiver&&>(__self.__op_->__rcvr_),
-                        static_cast<_Args&&>(__args)...);
+            __op_->__on_stop_.reset();
+            stdexec::set_value(static_cast<_Receiver&&>(__op_->__rcvr_),
+                               static_cast<_Args&&>(__args)...);
         }
 
-        template <same_as<set_error_t> _SetError, same_as<__t> _Self,
-                  class _Error>
-            requires __callable<_SetError, _Receiver&&, _Error>
-        friend void tag_invoke(_SetError, _Self&& __self,
-                               _Error&& __err) noexcept
+        template <class _Error>
+            requires __callable<set_error_t, _Receiver, _Error>
+        void set_error(_Error&& __err) noexcept
         {
-            __self.__op_->__on_stop_.reset();
-            _SetError{}(static_cast<_Receiver&&>(__self.__op_->__rcvr_),
-                        static_cast<_Error&&>(__err));
+            __op_->__on_stop_.reset();
+            stdexec::set_error(static_cast<_Receiver&&>(__op_->__rcvr_),
+                               static_cast<_Error&&>(__err));
         }
 
-        template <same_as<set_stopped_t> _SetStopped, same_as<__t> _Self>
-            requires __callable<_SetStopped, _Receiver&&>
-        friend void tag_invoke(_SetStopped, _Self&& __self) noexcept
+        void set_stopped() noexcept
+            requires __callable<set_stopped_t, _Receiver>
         {
-            __self.__op_->__on_stop_.reset();
-            _SetStopped{}(static_cast<_Receiver&&>(__self.__op_->__rcvr_));
+            __op_->__on_stop_.reset();
+            stdexec::set_stopped(static_cast<_Receiver&&>(__op_->__rcvr_));
         }
 
-        template <same_as<get_env_t> _GetEnv, same_as<__t> _Self>
-        friend auto tag_invoke(_GetEnv, const _Self& __self) noexcept
-            -> __env_t<env_of_t<_Receiver>>
+        auto get_env() const noexcept -> __env_t<env_of_t<_Receiver>>
         {
             return __env::__join(
-                __env::__with(__self.__op_->__stop_source_.get_token(),
-                              get_stop_token),
-                get_env(__self.__op_->__rcvr_));
+                prop{get_stop_token, __op_->__stop_source_.get_token()},
+                stdexec::get_env(__op_->__rcvr_));
         }
     };
 };
@@ -1075,19 +1074,19 @@
             __rec_{this}, __storage_{__sender.__connect(__rec_)}
         {}
 
+        void start() & noexcept
+        {
+            this->__on_stop_.emplace(
+                stdexec::get_stop_token(stdexec::get_env(this->__rcvr_)),
+                __on_stop_t{this->__stop_source_});
+            STDEXEC_ASSERT(__storage_.__get_vtable()->__start_);
+            __storage_.__get_vtable()->__start_(
+                __storage_.__get_object_pointer());
+        }
+
       private:
         __stoppable_receiver_t<_ReceiverId> __rec_;
         __immovable_operation_storage __storage_{};
-
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            __self.__on_stop_.emplace(
-                stdexec::get_stop_token(stdexec::get_env(__self.__rcvr_)),
-                __on_stop_t{__self.__stop_source_});
-            STDEXEC_ASSERT(__self.__storage_.__get_vtable()->__start_);
-            __self.__storage_.__get_vtable()->__start_(
-                __self.__storage_.__get_object_pointer());
-        }
     };
 };
 
@@ -1107,38 +1106,43 @@
             __storage_{__sender.__connect(__rec_)}
         {}
 
+        void start() & noexcept
+        {
+            STDEXEC_ASSERT(__storage_.__get_vtable()->__start_);
+            __storage_.__get_vtable()->__start_(
+                __storage_.__get_object_pointer());
+        }
+
       private:
         STDEXEC_ATTRIBUTE((no_unique_address))
         _Receiver __rec_;
         __immovable_operation_storage __storage_{};
-
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            STDEXEC_ASSERT(__self.__storage_.__get_vtable()->__start_);
-            __self.__storage_.__get_vtable()->__start_(
-                __self.__storage_.__get_object_pointer());
-        }
     };
 };
 
-template <class _Queries>
+template <class _Queries, bool _IsEnvProvider = true>
 class __query_vtable;
 
-template <template <class...> class _List, typename... _Queries>
-class __query_vtable<_List<_Queries...>> : public __query_vfun<_Queries>...
+template <template <class...> class _List, class... _Queries,
+          bool _IsEnvProvider>
+class __query_vtable<_List<_Queries...>, _IsEnvProvider> :
+    public __query_vfun<_Queries>...
 {
   public:
     using __query_vfun<_Queries>::operator()...;
 
   private:
-    template <class _EnvProvider>
-        requires(__callable<__query_vfun_fn<_EnvProvider>, _Queries> && ...)
-    friend auto tag_invoke(__create_vtable_t, __mtype<__query_vtable>,
-                           __mtype<_EnvProvider>) noexcept
+    template <class _Queryable>
+        requires(
+            __callable<__query_vfun_fn<_Queryable, _IsEnvProvider>, _Queries> &&
+            ...)
+    STDEXEC_MEMFN_DECL(auto __create_vtable)(this __mtype<__query_vtable>,
+                                             __mtype<_Queryable>) noexcept
         -> const __query_vtable*
     {
-        static const __query_vtable __vtable{{__query_vfun_fn<_EnvProvider>{}(
-            static_cast<_Queries>(nullptr))}...};
+        static const __query_vtable __vtable{
+            {__query_vfun_fn<_Queryable, _IsEnvProvider>{}(
+                static_cast<_Queries>(nullptr))}...};
         return &__vtable;
     }
 };
@@ -1148,7 +1152,7 @@
 struct __sender
 {
     using __receiver_ref_t = __receiver_ref<_Sigs, _ReceiverQueries>;
-    static constexpr bool __with_in_place_stop_token =
+    static constexpr bool __with_inplace_stop_token =
         __v<__mapply<__mall_of<__q<__is_not_stop_token_query_v>>,
                      _ReceiverQueries>>;
 
@@ -1166,8 +1170,8 @@
 
       private:
         template <sender_to<__receiver_ref_t> _Sender>
-        friend auto tag_invoke(__create_vtable_t, __mtype<__vtable>,
-                               __mtype<_Sender>) noexcept -> const __vtable*
+        STDEXEC_MEMFN_DECL(auto __create_vtable)
+        (this __mtype<__vtable>, __mtype<_Sender>) noexcept -> const __vtable*
         {
             static const __vtable __vtable_{
                 {*__create_vtable(__mtype<__query_vtable<_SenderQueries>>{},
@@ -1178,7 +1182,7 @@
                 using __op_state_t =
                     connect_result_t<_Sender, __receiver_ref_t>;
                 return __immovable_operation_storage{
-                    std::in_place_type<__op_state_t>, __conv{[&] {
+                    std::in_place_type<__op_state_t>, __emplace_from{[&] {
                     return stdexec::connect(
                         static_cast<_Sender&&>(__sender),
                         static_cast<__receiver_ref_t&&>(__receiver));
@@ -1188,35 +1192,27 @@
         }
     };
 
-    class __env_t
+    struct __env_t
     {
-      public:
-        __env_t(const __vtable* __vtable, void* __sender) noexcept :
-            __vtable_{__vtable}, __sender_{__sender}
-        {}
-
-      private:
         const __vtable* __vtable_;
         void* __sender_;
 
         template <class _Tag, class... _As>
             requires __callable<const __query_vtable<_SenderQueries>&, _Tag,
                                 void*, _As...>
-        friend auto
-            tag_invoke(_Tag, const __env_t& __self, _As&&... __as) noexcept(
-                __nothrow_callable<const __query_vtable<_SenderQueries>&, _Tag,
-                                   void*, _As...>)
+        auto query(_Tag, _As&&... __as) const //
+            noexcept(__nothrow_callable<const __query_vtable<_SenderQueries>&,
+                                        _Tag, void*, _As...>)
                 -> __call_result_t<const __query_vtable<_SenderQueries>&, _Tag,
                                    void*, _As...>
         {
-            return __self.__vtable_->__queries()(_Tag{}, __self.__sender_,
-                                                 static_cast<_As&&>(__as)...);
+            return __vtable_->__queries()(_Tag{}, __sender_,
+                                          static_cast<_As&&>(__as)...);
         }
     };
 
-    class __t
+    struct __t
     {
-      public:
         using __id = __sender;
         using completion_signatures = _Sigs;
         using sender_concept = stdexec::sender_t;
@@ -1245,62 +1241,102 @@
             return __get_object_pointer(__storage_) != nullptr;
         }
 
-      private:
-        __unique_storage_t<__vtable> __storage_;
+        auto get_env() const noexcept -> __env_t
+        {
+            return {__storage_.__get_vtable(),
+                    __storage_.__get_object_pointer()};
+        }
 
         template <receiver_of<_Sigs> _Rcvr>
-        friend auto tag_invoke(connect_t, __t&& __self, _Rcvr&& __rcvr)
-            -> stdexec::__t<__operation<stdexec::__id<__decay_t<_Rcvr>>,
-                                        __with_in_place_stop_token>>
+        auto connect(_Rcvr __rcvr) && //
+            -> stdexec::__t<
+                __operation<stdexec::__id<_Rcvr>, __with_inplace_stop_token>>
         {
-            return {static_cast<__t&&>(__self), static_cast<_Rcvr&&>(__rcvr)};
+            return {static_cast<__t&&>(*this), static_cast<_Rcvr&&>(__rcvr)};
         }
 
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> __env_t
-        {
-            return {__self.__storage_.__get_vtable(),
-                    __self.__storage_.__get_object_pointer()};
-        }
+      private:
+        __unique_storage_t<__vtable> __storage_;
     };
 };
 
 template <class _ScheduleSender, class _SchedulerQueries = __types<>>
 class __scheduler
 {
+    static constexpr std::size_t __buffer_size = 4 * sizeof(void*);
+    template <class _Ty>
+    static constexpr bool __is_small = sizeof(_Ty) <= __buffer_size &&
+                                       alignof(_Ty) <=
+                                           alignof(std::max_align_t);
+
   public:
     template <class _Scheduler>
         requires(!__decays_to<_Scheduler, __scheduler>) && scheduler<_Scheduler>
     __scheduler(_Scheduler&& __scheduler) :
         __storage_{static_cast<_Scheduler&&>(__scheduler)}
-    {}
+    {
+        static_assert(
+            __is_small<_Scheduler>,
+            "any_scheduler<> must have a nothrow copy constructor, so the scheduler object must be "
+            "small enough to be stored in the internal buffer to avoid dynamic allocation.");
+    }
+
+    __scheduler(__scheduler&&) noexcept = default;
+    __scheduler(const __scheduler&) noexcept = default;
+    __scheduler& operator=(__scheduler&&) noexcept = default;
+    __scheduler& operator=(const __scheduler&) noexcept = default;
 
     using __sender_t = _ScheduleSender;
 
+    auto schedule() const noexcept -> __sender_t
+    {
+        STDEXEC_ASSERT(__storage_.__get_vtable()->__schedule_);
+        return __storage_.__get_vtable()->__schedule_(
+            __storage_.__get_object_pointer());
+    }
+
+    template <class _Tag, class... _As>
+        requires __callable<const __query_vtable<_SchedulerQueries, false>&,
+                            _Tag, void*, _As...>
+    auto query(_Tag, _As&&... __as) const //
+        noexcept(
+            __nothrow_callable<const __query_vtable<_SchedulerQueries, false>&,
+                               _Tag, void*, _As...>)
+            -> __call_result_t<const __query_vtable<_SchedulerQueries, false>&,
+                               _Tag, void*, _As...>
+    {
+        return __storage_.__get_vtable()->__queries()(
+            _Tag{}, __storage_.__get_object_pointer(),
+            static_cast<_As&&>(__as)...);
+    }
+
   private:
-    class __vtable : public __query_vtable<_SchedulerQueries>
+    class __vtable : public __query_vtable<_SchedulerQueries, false>
     {
       public:
         __sender_t (*__schedule_)(void*) noexcept;
         bool (*__equal_to_)(const void*, const void* other) noexcept;
 
         auto __queries() const noexcept
-            -> const __query_vtable<_SchedulerQueries>&
+            -> const __query_vtable<_SchedulerQueries, false>&
         {
             return *this;
         }
 
       private:
         template <scheduler _Scheduler>
-        friend auto tag_invoke(__create_vtable_t, __mtype<__vtable>,
-                               __mtype<_Scheduler>) noexcept -> const __vtable*
+        STDEXEC_MEMFN_DECL(auto __create_vtable)
+        (this __mtype<__vtable>, __mtype<_Scheduler>) noexcept
+            -> const __vtable*
         {
             static const __vtable __vtable_{
-                {*__create_vtable(__mtype<__query_vtable<_SchedulerQueries>>{},
-                                  __mtype<_Scheduler>{})},
+                {*__create_vtable(
+                    __mtype<__query_vtable<_SchedulerQueries, false>>{},
+                    __mtype<_Scheduler>{})},
                 [](void* __object_pointer) noexcept -> __sender_t {
                 const _Scheduler& __scheduler =
                     *static_cast<const _Scheduler*>(__object_pointer);
-                return __sender_t{schedule(__scheduler)};
+                return __sender_t{stdexec::schedule(__scheduler)};
             },
                 [](const void* __self, const void* __other) noexcept -> bool {
                 static_assert(noexcept(__declval<const _Scheduler&>() ==
@@ -1316,29 +1352,6 @@
         }
     };
 
-    template <same_as<__scheduler> _Self>
-    friend auto tag_invoke(schedule_t, const _Self& __self) noexcept
-        -> __sender_t
-    {
-        STDEXEC_ASSERT(__self.__storage_.__get_vtable()->__schedule_);
-        return __self.__storage_.__get_vtable()->__schedule_(
-            __self.__storage_.__get_object_pointer());
-    }
-
-    template <class _Tag, same_as<__scheduler> _Self, class... _As>
-        requires __callable<const __query_vtable<_SchedulerQueries>&, _Tag,
-                            void*, _As...>
-    friend auto tag_invoke(_Tag, const _Self& __self, _As&&... __as) noexcept(
-        __nothrow_callable<const __query_vtable<_SchedulerQueries>&, _Tag,
-                           void*, _As...>)
-        -> __call_result_t<const __query_vtable<_SchedulerQueries>&, _Tag,
-                           void*, _As...>
-    {
-        return __self.__storage_.__get_vtable()->__queries()(
-            _Tag{}, __self.__storage_.__get_object_pointer(),
-            static_cast<_As&&>(__as)...);
-    }
-
     friend auto operator==(const __scheduler& __self,
                            const __scheduler& __other) noexcept -> bool
     {
@@ -1347,6 +1360,7 @@
         {
             return false;
         }
+
         void* __p = __self.__storage_.__get_object_pointer();
         void* __o = __other.__storage_.__get_object_pointer();
         // if both object pointers are not null, use the virtual equal_to
@@ -1363,7 +1377,7 @@
         return !(__self == __other);
     }
 
-    __copyable_storage_t<__vtable> __storage_{};
+    __copyable_storage_t<__vtable, __buffer_size> __storage_{};
 };
 } // namespace __any
 
@@ -1378,19 +1392,6 @@
     using __env_t = stdexec::env_of_t<__receiver_base>;
     __receiver_base __receiver_;
 
-    template <class _Tag, stdexec::__decays_to<any_receiver_ref> Self,
-              class... _As>
-        requires stdexec::tag_invocable<
-            _Tag, stdexec::__copy_cvref_t<Self, __receiver_base>, _As...>
-    friend auto tag_invoke(_Tag, Self&& __self, _As&&... __as) noexcept(
-        std::is_nothrow_invocable_v<
-            _Tag, stdexec::__copy_cvref_t<Self, __receiver_base>, _As...>)
-    {
-        return stdexec::tag_invoke(_Tag{},
-                                   static_cast<Self&&>(__self).__receiver_,
-                                   static_cast<_As&&>(__as)...);
-    }
-
   public:
     using receiver_concept = stdexec::receiver_t;
     using __t = any_receiver_ref;
@@ -1400,11 +1401,44 @@
                                  __env_t, const __env_t>
                   _Receiver>
         requires stdexec::receiver_of<_Receiver, _Completions>
-    any_receiver_ref(_Receiver& __receiver) noexcept(
-        stdexec::__nothrow_constructible_from<__receiver_base, _Receiver>) :
+    any_receiver_ref(_Receiver& __receiver) //
+        noexcept(
+            stdexec::__nothrow_constructible_from<__receiver_base, _Receiver>) :
         __receiver_(__receiver)
     {}
 
+    template <class... _As>
+        requires stdexec::tag_invocable<stdexec::set_value_t, __receiver_base,
+                                        _As...>
+    void set_value(_As&&... __as) noexcept
+    {
+        stdexec::tag_invoke(stdexec::set_value,
+                            static_cast<__receiver_base&&>(__receiver_),
+                            static_cast<_As&&>(__as)...);
+    }
+
+    template <class _Error>
+        requires stdexec::tag_invocable<stdexec::set_error_t, __receiver_base,
+                                        _Error>
+    void set_error(_Error&& __err) noexcept
+    {
+        stdexec::tag_invoke(stdexec::set_error,
+                            static_cast<__receiver_base&&>(__receiver_),
+                            static_cast<_Error&&>(__err));
+    }
+
+    void set_stopped() noexcept
+        requires stdexec::tag_invocable<stdexec::set_stopped_t, __receiver_base>
+    {
+        stdexec::tag_invoke(stdexec::set_stopped,
+                            static_cast<__receiver_base&&>(__receiver_));
+    }
+
+    auto get_env() const noexcept -> stdexec::env_of_t<__receiver_base>
+    {
+        return stdexec::get_env(__receiver_);
+    }
+
     template <auto... _SenderQueries>
     class any_sender
     {
@@ -1417,9 +1451,10 @@
                   class... _As>
             requires stdexec::tag_invocable<
                 _Tag, stdexec::__copy_cvref_t<Self, __sender_base>, _As...>
-        friend auto tag_invoke(_Tag, Self&& __self, _As&&... __as) noexcept(
-            std::is_nothrow_invocable_v<
-                _Tag, stdexec::__copy_cvref_t<Self, __sender_base>, _As...>)
+        friend auto tag_invoke(_Tag, Self&& __self, _As&&... __as) //
+            noexcept(
+                stdexec::nothrow_tag_invocable<
+                    _Tag, stdexec::__copy_cvref_t<Self, __sender_base>, _As...>)
         {
             return stdexec::tag_invoke(_Tag{},
                                        static_cast<Self&&>(__self).__sender_,
@@ -1433,16 +1468,25 @@
 
         template <stdexec::__not_decays_to<any_sender> _Sender>
             requires stdexec::sender_to<_Sender, __receiver_base>
-        any_sender(_Sender&& __sender) noexcept(
-            stdexec::__nothrow_constructible_from<__sender_base, _Sender>) :
+        any_sender(_Sender&& __sender) //
+            noexcept(
+                stdexec::__nothrow_constructible_from<__sender_base, _Sender>) :
             __sender_(static_cast<_Sender&&>(__sender))
         {}
 
+        template <stdexec::receiver_of<_Completions> _Receiver>
+        auto connect(_Receiver __rcvr) && -> stdexec::connect_result_t<
+            __sender_base, _Receiver>
+        {
+            return static_cast<__sender_base&&>(__sender_).connect(
+                static_cast<_Receiver&&>(__rcvr));
+        }
+
         template <auto... _SchedulerQueries>
         class any_scheduler
         {
             using __schedule_completions =
-                stdexec::__concat_completion_signatures_t<
+                stdexec::__concat_completion_signatures<
                     _Completions,
                     stdexec::completion_signatures<stdexec::set_value_t()>>;
             using __schedule_receiver =
@@ -1460,7 +1504,7 @@
             };
 
             using schedule_sender_queries = stdexec::__minvoke<
-                stdexec::__remove_if<__ret_equals_to<
+                stdexec::__mremove_if<__ret_equals_to<
                     stdexec::get_completion_scheduler_t<stdexec::set_value_t>>>,
                 decltype(_SenderQueries)...>;
 
@@ -1493,31 +1537,31 @@
             using __t = any_scheduler;
             using __id = any_scheduler;
 
-            template <class _Scheduler>
-                requires(!stdexec::__decays_to<_Scheduler, any_scheduler> &&
-                         stdexec::scheduler<_Scheduler>)
-            any_scheduler(_Scheduler&& __scheduler) :
+            template <stdexec::__none_of<any_scheduler> _Scheduler>
+                requires stdexec::scheduler<_Scheduler>
+            any_scheduler(_Scheduler __scheduler) :
                 __scheduler_{static_cast<_Scheduler&&>(__scheduler)}
             {}
 
-          private:
-            template <class _Tag, stdexec::__decays_to<any_scheduler> Self,
-                      class... _As>
-                requires stdexec::tag_invocable<
-                    _Tag, stdexec::__copy_cvref_t<Self, __scheduler_base>,
-                    _As...>
-            friend auto tag_invoke(_Tag, Self&& __self, _As&&... __as) noexcept(
-                std::is_nothrow_invocable_v<
-                    _Tag, stdexec::__copy_cvref_t<Self, __scheduler_base>,
-                    _As...>)
+            auto schedule() const noexcept -> __schedule_sender
             {
-                return stdexec::tag_invoke(
-                    _Tag{}, static_cast<Self&&>(__self).__scheduler_,
-                    static_cast<_As&&>(__as)...);
+                return __scheduler_.schedule();
             }
 
-            friend auto operator==(const any_scheduler& __self,
-                                   const any_scheduler& __other) noexcept
+            template <class _Tag, class... _As>
+                requires stdexec::tag_invocable<_Tag, const __scheduler_base&,
+                                                _As...>
+            auto query(_Tag, _As&&... __as) const noexcept(
+                stdexec::nothrow_tag_invocable<_Tag, const __scheduler_base&,
+                                               _As...>)
+                -> stdexec::tag_invoke_result_t<_Tag, const __scheduler_base&,
+                                                _As...>
+            {
+                return stdexec::tag_invoke(_Tag(), __scheduler_,
+                                           static_cast<_As&&>(__as)...);
+            }
+
+            auto operator==(const any_scheduler&) const noexcept
                 -> bool = default;
         };
     };
diff --git a/include/sdbusplus/async/stdexec/async_scope.hpp b/include/sdbusplus/async/stdexec/async_scope.hpp
index 63f38d6..d48ef41 100644
--- a/include/sdbusplus/async/stdexec/async_scope.hpp
+++ b/include/sdbusplus/async/stdexec/async_scope.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -33,6 +33,13 @@
 struct __impl;
 struct async_scope;
 
+template <class _A>
+concept __async_scope = requires(_A& __a) {
+                            {
+                                __a.nest(stdexec::just())
+                            } -> sender_of<stdexec::set_value_t()>;
+                        };
+
 struct __task : __immovable
 {
     const __impl* __scope_;
@@ -42,11 +49,11 @@
 
 template <class _BaseEnv>
 using __env_t =
-    make_env_t<_BaseEnv, with_t<get_stop_token_t, in_place_stop_token>>;
+    make_env_t<_BaseEnv, prop<get_stop_token_t, inplace_stop_token>>;
 
 struct __impl
 {
-    in_place_stop_source __stop_source_{};
+    inplace_stop_source __stop_source_{};
     mutable std::mutex __lock_{};
     mutable std::ptrdiff_t __active_ = 0;
     mutable __intrusive_queue<&__task::__next_> __waiters_{};
@@ -78,13 +85,7 @@
                                    static_cast<_Receiver&&>(__rcvr)))
         {}
 
-      private:
-        static void __notify_waiter(__task* __self) noexcept
-        {
-            start(static_cast<__t*>(__self)->__op_);
-        }
-
-        void __start_() noexcept
+        void start() & noexcept
         {
             std::unique_lock __guard{this->__scope_->__lock_};
             auto& __active = this->__scope_->__active_;
@@ -95,12 +96,13 @@
                 return;
             }
             __guard.unlock();
-            start(this->__op_);
+            stdexec::start(this->__op_);
         }
 
-        friend void tag_invoke(start_t, __t& __self) noexcept
+      private:
+        static void __notify_waiter(__task* __self) noexcept
         {
-            return __self.__start_();
+            stdexec::start(static_cast<__t*>(__self)->__op_);
         }
 
         STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
@@ -125,8 +127,7 @@
 
         template <__decays_to<__t> _Self, receiver _Receiver>
             requires sender_to<__copy_cvref_t<_Self, _Constrained>, _Receiver>
-        [[nodiscard]] friend auto tag_invoke(connect_t, _Self&& __self,
-                                             _Receiver __rcvr)
+        [[nodiscard]] static auto connect(_Self&& __self, _Receiver __rcvr) //
             -> __when_empty_op_t<_Self, _Receiver>
         {
             return __when_empty_op_t<_Self, _Receiver>{
@@ -134,15 +135,10 @@
                 static_cast<_Receiver&&>(__rcvr)};
         }
 
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
-                                          __env_t<_Env>>
-        {
-            return {};
-        }
-
-        friend auto tag_invoke(get_env_t, const __t&) noexcept -> empty_env
+        template <__decays_to<__t> _Self, class... _Env>
+        static auto get_completion_signatures(_Self&&, _Env&&...)
+            -> __completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
+                                            __env_t<_Env>...>
         {
             return {};
         }
@@ -198,25 +194,46 @@
             }
         }
 
-        template <__completion_tag _Tag, class... _As>
-            requires __callable<_Tag, _Receiver, _As...>
-        friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
+        template <class... _As>
+            requires __callable<set_value_t, _Receiver, _As...>
+        void set_value(_As&&... __as) noexcept
         {
-            auto __scope = __self.__op_->__scope_;
-            _Tag{}(std::move(__self.__op_->__rcvr_),
-                   static_cast<_As&&>(__as)...);
+            auto __scope = __op_->__scope_;
+            stdexec::set_value(std::move(__op_->__rcvr_),
+                               static_cast<_As&&>(__as)...);
             // do not access __op_
             // do not access this
             __complete(__scope);
         }
 
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> __env_t<env_of_t<_Receiver>>
+        template <class _Error>
+            requires __callable<set_error_t, _Receiver, _Error>
+        void set_error(_Error&& __err) noexcept
+        {
+            auto __scope = __op_->__scope_;
+            stdexec::set_error(std::move(__op_->__rcvr_),
+                               static_cast<_Error&&>(__err));
+            // do not access __op_
+            // do not access this
+            __complete(__scope);
+        }
+
+        void set_stopped() noexcept
+            requires __callable<set_stopped_t, _Receiver>
+        {
+            auto __scope = __op_->__scope_;
+            stdexec::set_stopped(std::move(__op_->__rcvr_));
+            // do not access __op_
+            // do not access this
+            __complete(__scope);
+        }
+
+        auto get_env() const noexcept -> __env_t<env_of_t<_Receiver>>
         {
             return make_env(
-                get_env(__self.__op_->__rcvr_),
-                with(get_stop_token,
-                     __self.__op_->__scope_->__stop_source_.get_token()));
+                stdexec::get_env(__op_->__rcvr_),
+                stdexec::prop{get_stop_token,
+                              __op_->__scope_->__stop_source_.get_token()});
         }
     };
 };
@@ -243,20 +260,14 @@
                                    __nest_rcvr_t{this}))
         {}
 
-      private:
-        void __start_() noexcept
+        void start() & noexcept
         {
             STDEXEC_ASSERT(this->__scope_);
             std::unique_lock __guard{this->__scope_->__lock_};
             auto& __active = this->__scope_->__active_;
             ++__active;
             __guard.unlock();
-            start(__op_);
-        }
-
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            return __self.__start_();
+            stdexec::start(__op_);
         }
     };
 };
@@ -278,6 +289,7 @@
         template <class _Receiver>
         using __nest_operation_t =
             stdexec::__t<__nest_op<_ConstrainedId, stdexec::__id<_Receiver>>>;
+
         template <class _Receiver>
         using __nest_receiver_t =
             stdexec::__t<__nest_rcvr<stdexec::__id<_Receiver>>>;
@@ -285,8 +297,7 @@
         template <__decays_to<__t> _Self, receiver _Receiver>
             requires sender_to<__copy_cvref_t<_Self, _Constrained>,
                                __nest_receiver_t<_Receiver>>
-        [[nodiscard]] friend auto tag_invoke(connect_t, _Self&& __self,
-                                             _Receiver __rcvr)
+        [[nodiscard]] static auto connect(_Self&& __self, _Receiver __rcvr)
             -> __nest_operation_t<_Receiver>
         {
             return __nest_operation_t<_Receiver>{
@@ -294,15 +305,10 @@
                 static_cast<_Receiver&&>(__rcvr)};
         }
 
-        template <__decays_to<__t> _Self, class _Env>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-            -> completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
-                                          __env_t<_Env>>
-        {
-            return {};
-        }
-
-        friend auto tag_invoke(get_env_t, const __t&) noexcept -> empty_env
+        template <__decays_to<__t> _Self, class... _Env>
+        static auto get_completion_signatures(_Self&&, _Env&&...)
+            -> __completion_signatures_of_t<__copy_cvref_t<_Self, _Constrained>,
+                                            __env_t<_Env>...>
         {
             return {};
         }
@@ -329,7 +335,7 @@
 
 struct __forward_stopped
 {
-    in_place_stop_source* __stop_source_;
+    inplace_stop_source* __stop_source_;
 
     void operator()() noexcept
     {
@@ -361,11 +367,6 @@
         using __forward_consumer = typename stop_token_of_t<
             env_of_t<_Receiver>>::template callback_type<__forward_stopped>;
 
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            __self.__start_();
-        }
-
         void __complete_() noexcept
         {
             try
@@ -384,7 +385,7 @@
                 else if (get_stop_token(get_env(__rcvr_)).stop_requested())
                 {
                     __guard.unlock();
-                    set_stopped(static_cast<_Receiver&&>(__rcvr_));
+                    stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr_));
                     __guard.lock();
                 }
                 else
@@ -413,33 +414,8 @@
             }
             catch (...)
             {
-                set_error(static_cast<_Receiver&&>(__rcvr_),
-                          std::current_exception());
-            }
-        }
-
-        void __start_() noexcept
-        {
-            try
-            {
-                if (!!__state_)
-                {
-                    std::unique_lock __guard{__state_->__mutex_};
-                    if (__state_->__data_.index() != 0)
-                    {
-                        __guard.unlock();
-                        __complete_();
-                    }
-                    else
-                    {
-                        __state_->__subscribers_.push_back(this);
-                    }
-                }
-            }
-            catch (...)
-            {
-                set_error(static_cast<_Receiver&&>(__rcvr_),
-                          std::current_exception());
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr_),
+                                   std::current_exception());
             }
         }
 
@@ -482,6 +458,31 @@
             __forward_consumer_(get_stop_token(get_env(__rcvr_)),
                                 __forward_stopped{&__state_->__stop_source_})
         {}
+
+        void start() & noexcept
+        {
+            try
+            {
+                if (!!__state_)
+                {
+                    std::unique_lock __guard{__state_->__mutex_};
+                    if (__state_->__data_.index() != 0)
+                    {
+                        __guard.unlock();
+                        __complete_();
+                    }
+                    else
+                    {
+                        __state_->__subscribers_.push_back(this);
+                    }
+                }
+            }
+            catch (...)
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__rcvr_),
+                                   std::current_exception());
+            }
+        }
     };
 };
 
@@ -490,7 +491,7 @@
 struct __completion_as_tuple2_;
 
 template <class _Tag, class... _Ts>
-struct __completion_as_tuple2_<_Tag(_Ts&&...)>
+struct __completion_as_tuple2_<_Tag(_Ts...)>
 {
     using __t = std::tuple<_Tag, _Ts...>;
 };
@@ -500,31 +501,30 @@
 #else
 
 template <class _Tag, class... _Ts>
-auto __completion_as_tuple_(_Tag (*)(_Ts&&...)) -> std::tuple<_Tag, _Ts...>;
+auto __completion_as_tuple_(_Tag (*)(_Ts...)) -> std::tuple<_Tag, _Ts...>;
+
 template <class _Fn>
 using __completion_as_tuple_t =
     decltype(__scope::__completion_as_tuple_(static_cast<_Fn*>(nullptr)));
 #endif
 
 template <class... _Ts>
-using __decay_values_t =
-    completion_signatures<set_value_t(__decay_t<_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>&&)>;
+using __decay_error_t = completion_signatures<set_error_t(__decay_t<_Ty>)>;
 
 template <class _Sender, class _Env>
 using __future_completions_t = //
-    make_completion_signatures<
+    transform_completion_signatures_of<
         _Sender, __env_t<_Env>,
-        completion_signatures<set_stopped_t(),
-                              set_error_t(std::exception_ptr&&)>,
+        completion_signatures<set_stopped_t(), set_error_t(std::exception_ptr)>,
         __decay_values_t, __decay_error_t>;
 
 template <class _Completions>
 using __completions_as_variant = //
-    __mapply<__transform<__q<__completion_as_tuple_t>,
-                         __mbind_front_q<std::variant, std::monostate>>,
+    __mapply<__mtransform<__q<__completion_as_tuple_t>,
+                          __mbind_front_q<std::variant, std::monostate>>,
              _Completions>;
 
 template <class _Ty>
@@ -560,9 +560,9 @@
     __future_state_base(_Env __env, const __impl* __scope) :
         __forward_scope_{std::in_place, __scope->__stop_source_.get_token(),
                          __forward_stopped{&__stop_source_}},
-        __env_(
-            make_env(static_cast<_Env&&>(__env),
-                     with(get_stop_token, __scope->__stop_source_.get_token())))
+        __env_(make_env(
+            static_cast<_Env&&>(__env),
+            stdexec::prop{get_stop_token, __scope->__stop_source_.get_token()}))
     {}
 
     ~__future_state_base()
@@ -591,8 +591,8 @@
         STDEXEC_ASSERT(actual == __from);
     }
 
-    in_place_stop_source __stop_source_;
-    std::optional<in_place_stop_callback<__forward_stopped>> __forward_scope_;
+    inplace_stop_source __stop_source_;
+    std::optional<inplace_stop_callback<__forward_stopped>> __forward_scope_;
     std::mutex __mutex_;
     __future_step __step_ = __future_step::__created;
     std::unique_ptr<__future_state_base, __dynamic_delete<__future_state_base>>
@@ -638,31 +638,56 @@
             }
         }
 
-        template <__completion_tag _Tag, __movable_value... _As>
-        friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept
+        template <class _Tag, class... _As>
+        bool __save_completion(_Tag, _As&&... __as) noexcept
         {
-            auto& __state = *__self.__state_;
+            auto& __state = *__state_;
             try
             {
                 std::unique_lock __guard{__state.__mutex_};
-                using _Tuple = __decayed_tuple<_Tag, _As...>;
+                using _Tuple = __decayed_std_tuple<_Tag, _As...>;
                 __state.__data_.template emplace<_Tuple>(
-                    _Tag{}, static_cast<_As&&>(__as)...);
-                __guard.unlock();
-                __self.__dispatch_result_();
+                    _Tag(), static_cast<_As&&>(__as)...);
+                return true;
             }
             catch (...)
             {
                 using _Tuple = std::tuple<set_error_t, std::exception_ptr>;
                 __state.__data_.template emplace<_Tuple>(
-                    set_error_t{}, std::current_exception());
+                    set_error_t(), std::current_exception());
+            }
+            return false;
+        }
+
+        template <__movable_value... _As>
+        void set_value(_As&&... __as) noexcept
+        {
+            if (__save_completion(set_value_t(), static_cast<_As&&>(__as)...))
+            {
+                __dispatch_result_();
             }
         }
 
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> const __env_t<_Env>&
+        template <__movable_value _Error>
+        void set_error(_Error&& __err) noexcept
         {
-            return __self.__state_->__env_;
+            if (__save_completion(set_error_t(), static_cast<_Error&&>(__err)))
+            {
+                __dispatch_result_();
+            }
+        }
+
+        void set_stopped() noexcept
+        {
+            if (__save_completion(set_stopped_t()))
+            {
+                __dispatch_result_();
+            }
+        }
+
+        auto get_env() const noexcept -> const __env_t<_Env>&
+        {
+            return __state_->__env_;
         }
     };
 };
@@ -694,8 +719,17 @@
     using _Sender = stdexec::__t<_SenderId>;
     using _Env = stdexec::__t<_EnvId>;
 
-    struct __t
+    class __t
     {
+        template <class _Self>
+        using __completions_t =
+            __future_completions_t<__mfront<_Sender, _Self>, _Env>;
+
+        template <class _Receiver>
+        using __future_op_t = stdexec::__t<
+            __future_op<_SenderId, _EnvId, stdexec::__id<_Receiver>>>;
+
+      public:
         using __id = __future;
         using sender_concept = stdexec::sender_t;
 
@@ -720,15 +754,25 @@
             }
         }
 
+        template <__decays_to<__t> _Self, receiver _Receiver>
+            requires receiver_of<_Receiver, __completions_t<_Self>>
+        static auto connect(_Self&& __self, _Receiver __rcvr)
+            -> __future_op_t<_Receiver>
+        {
+            return __future_op_t<_Receiver>{
+                static_cast<_Receiver&&>(__rcvr),
+                static_cast<_Self&&>(__self).__state_};
+        }
+
+        template <__decays_to<__t> _Self, class... _OtherEnv>
+        static auto get_completion_signatures(_Self&&, _OtherEnv&&...)
+            -> __completions_t<_Self>
+        {
+            return {};
+        }
+
       private:
         friend struct async_scope;
-        template <class _Self>
-        using __completions_t =
-            __future_completions_t<__mfront<_Sender, _Self>, _Env>;
-
-        template <class _Receiver>
-        using __future_op_t = stdexec::__t<
-            __future_op<_SenderId, _EnvId, stdexec::__id<_Receiver>>>;
 
         explicit __t(
             std::unique_ptr<__future_state<_Sender, _Env>> __state) noexcept :
@@ -739,27 +783,6 @@
                                       __future_step::__future);
         }
 
-        template <__decays_to<__t> _Self, receiver _Receiver>
-            requires receiver_of<_Receiver, __completions_t<_Self>>
-        friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr)
-            -> __future_op_t<_Receiver>
-        {
-            return __future_op_t<_Receiver>{static_cast<_Receiver&&>(__rcvr),
-                                            std::move(__self.__state_)};
-        }
-
-        template <__decays_to<__t> _Self, class _OtherEnv>
-        friend auto tag_invoke(get_completion_signatures_t, _Self&&,
-                               _OtherEnv&&) -> __completions_t<_Self>
-        {
-            return {};
-        }
-
-        friend auto tag_invoke(get_env_t, const __t&) noexcept -> empty_env
-        {
-            return {};
-        }
-
         std::unique_ptr<__future_state<_Sender, _Env>> __state_;
     };
 };
@@ -770,10 +793,23 @@
 
 ////////////////////////////////////////////////////////////////////////////
 // async_scope::spawn implementation
+struct __spawn_env_
+{
+    inplace_stop_token __token_;
+
+    auto query(get_stop_token_t) const noexcept -> inplace_stop_token
+    {
+        return __token_;
+    }
+
+    auto query(get_scheduler_t) const noexcept -> __inln::__scheduler
+    {
+        return {};
+    }
+};
+
 template <class _Env>
-using __spawn_env_t =
-    __env::__join_t<_Env, __env::__with<in_place_stop_token, get_stop_token_t>,
-                    __env::__with<__inln::__scheduler, get_scheduler_t>>;
+using __spawn_env_t = __env::__join_t<_Env, __spawn_env_>;
 
 template <class _EnvId>
 struct __spawn_op_base
@@ -794,24 +830,25 @@
         using receiver_concept = stdexec::receiver_t;
         __spawn_op_base<_EnvId>* __op_;
 
-        template <__one_of<set_value_t, set_stopped_t> _Tag>
-        friend void tag_invoke(_Tag, __t&& __self) noexcept
+        void set_value() noexcept
         {
-            __self.__op_->__delete_(__self.__op_);
+            __op_->__delete_(__op_);
         }
 
         // BUGBUG NOT TO SPEC spawn shouldn't accept senders that can fail.
-        template <same_as<set_error_t> _Tag>
-        [[noreturn]] friend void tag_invoke(_Tag, __t&&,
-                                            std::exception_ptr __eptr) noexcept
+        [[noreturn]] void set_error(std::exception_ptr __eptr) noexcept
         {
             std::rethrow_exception(std::move(__eptr));
         }
 
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> const __spawn_env_t<_Env>&
+        void set_stopped() noexcept
         {
-            return __self.__op_->__env_;
+            __op_->__delete_(__op_);
+        }
+
+        auto get_env() const noexcept -> const __spawn_env_t<_Env>&
+        {
+            return __op_->__env_;
         }
     };
 };
@@ -832,9 +869,7 @@
             __spawn_op_base<_EnvId>{
                 __env::__join(
                     static_cast<_Env&&>(__env),
-                    __env::__with(__scope->__stop_source_.get_token(),
-                                  get_stop_token),
-                    __env::__with(__inln::__scheduler{}, get_scheduler)),
+                    __spawn_env_{__scope->__stop_source_.get_token()}),
                 [](__spawn_op_base<_EnvId>* __op) {
             delete static_cast<__t*>(__op);
         }},
@@ -842,14 +877,9 @@
                                    __spawn_receiver_t<_Env>{this}))
         {}
 
-        void __start_() noexcept
+        void start() & noexcept
         {
-            start(__op_);
-        }
-
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            return __self.__start_();
+            stdexec::start(__op_);
         }
 
         connect_result_t<_Sender, __spawn_receiver_t<_Env>> __op_;
@@ -914,12 +944,12 @@
         return __future_t<_Sender, _Env>{std::move(__state)};
     }
 
-    auto get_stop_source() noexcept -> in_place_stop_source&
+    auto get_stop_source() noexcept -> inplace_stop_source&
     {
         return __impl_.__stop_source_;
     }
 
-    auto get_stop_token() const noexcept -> in_place_stop_token
+    auto get_stop_token() const noexcept -> inplace_stop_token
     {
         return __impl_.__stop_source_.get_token();
     }
@@ -935,4 +965,8 @@
 } // namespace __scope
 
 using __scope::async_scope;
+
+template <class _AsyncScope, class _Sender>
+using nest_result_t = decltype(stdexec::__declval<_AsyncScope&>().nest(
+    stdexec::__declval<_Sender&&>()));
 } // namespace exec
diff --git a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
index 6bb5318..a9ad470 100644
--- a/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
+++ b/include/sdbusplus/async/stdexec/at_coroutine_exit.hpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) Facebook, Inc. and its affiliates.
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -48,39 +48,44 @@
             using __id = __receiver_id;
             _Receiver __receiver_;
 
-            template <__one_of<set_value_t, set_error_t> _Tag,
-                      __decays_to<__t> _Self, class... _Args>
-                requires __callable<_Tag, _Receiver, _Args...>
-            friend void tag_invoke(_Tag, _Self&& __self,
-                                   _Args&&... __args) noexcept
+            template <class... _Args>
+                requires __callable<set_value_t, _Receiver, _Args...>
+            void set_value(_Args&&... __args) noexcept
             {
-                _Tag{}(static_cast<_Receiver&&>(__self.__receiver_),
-                       static_cast<_Args&&>(__args)...);
+                stdexec::set_value(static_cast<_Receiver&&>(__receiver_),
+                                   static_cast<_Args&&>(__args)...);
             }
 
-            template <same_as<set_stopped_t> _Tag>
-            [[noreturn]] friend void tag_invoke(_Tag, __t&&) noexcept
+            template <class _Error>
+                requires __callable<set_error_t, _Receiver, _Error>
+            void set_error(_Error&& __err) noexcept
+            {
+                stdexec::set_error(static_cast<_Receiver&&>(__receiver_),
+                                   static_cast<_Error&&>(__err));
+            }
+
+            [[noreturn]] void set_stopped() noexcept
             {
                 std::terminate();
             }
 
-            friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-                -> env_of_t<_Receiver>
+            auto get_env() const noexcept -> env_of_t<_Receiver>
             {
-                return get_env(__self.__receiver_);
+                return stdexec::get_env(__receiver_);
             }
         };
     };
+
     template <class _Rec>
     using __receiver = __t<__receiver_id<_Rec>>;
 
     template <class _Sender>
     struct __sender_id
     {
-        template <class _Env>
+        template <class... _Env>
         using __completion_signatures = //
-            __mapply<__remove<set_stopped_t(), __q<completion_signatures>>,
-                     completion_signatures_of_t<_Sender, _Env>>;
+            __mapply<__mremove<set_stopped_t(), __q<completion_signatures>>,
+                     __completion_signatures_of_t<_Sender, _Env...>>;
 
         struct __t
         {
@@ -91,26 +96,24 @@
 
             template <receiver _Receiver>
                 requires sender_to<_Sender, __receiver<_Receiver>>
-            friend auto tag_invoke(connect_t, __t&& __self,
-                                   _Receiver&& __rcvr) noexcept
+            auto connect(_Receiver __rcvr) && noexcept
                 -> connect_result_t<_Sender, __receiver<_Receiver>>
             {
                 return stdexec::connect(
-                    static_cast<_Sender&&>(__self.__sender_),
+                    static_cast<_Sender&&>(__sender_),
                     __receiver<_Receiver>{static_cast<_Receiver&&>(__rcvr)});
             }
 
-            template <__decays_to<__t> _Self, class _Env>
-            friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&)
-                -> __completion_signatures<_Env>
+            template <class... _Env>
+            auto get_completion_signatures(_Env&&...)
+                -> __completion_signatures<_Env...>
             {
                 return {};
             }
 
-            friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-                -> env_of_t<_Sender>
+            auto get_env() const noexcept -> env_of_t<_Sender>
             {
-                return get_env(__self.__sender_);
+                return stdexec::get_env(__sender_);
             }
         };
     };
@@ -207,10 +210,9 @@
     {
         const __promise& __promise_;
 
-        friend auto tag_invoke(get_scheduler_t, __env __self) noexcept
-            -> __any_scheduler
+        auto query(get_scheduler_t) const noexcept -> __any_scheduler
         {
-            return __self.__promise_.__scheduler_;
+            return __promise_.__scheduler_;
         }
     };
 
@@ -257,10 +259,9 @@
                 __die_on_stop(static_cast<_Awaitable&&>(__awaitable)), *this);
         }
 
-        friend auto tag_invoke(get_env_t, const __promise& __self) noexcept
-            -> __env
+        auto get_env() const noexcept -> __env
         {
-            return {__self};
+            return {*this};
         }
 
         bool __is_unhandled_stopped_{false};
diff --git a/include/sdbusplus/async/stdexec/commit.info b/include/sdbusplus/async/stdexec/commit.info
index 68da718..e3aca22 100644
--- a/include/sdbusplus/async/stdexec/commit.info
+++ b/include/sdbusplus/async/stdexec/commit.info
@@ -1 +1 @@
-af0efa96811682e26c123175746c408fa582dbb1
+439a29175f45aecdec6b124e75dc3c7bc5d8b778
diff --git a/include/sdbusplus/async/stdexec/concepts.hpp b/include/sdbusplus/async/stdexec/concepts.hpp
index 5963932..3ece504 100644
--- a/include/sdbusplus/async/stdexec/concepts.hpp
+++ b/include/sdbusplus/async/stdexec/concepts.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -15,271 +15,4 @@
  */
 #pragma once
 
-#if __cpp_concepts < 201907L
-#error This library requires support for C++20 concepts
-#endif
-
 #include "__detail/__concepts.hpp"
-#include "__detail/__config.hpp"
-#include "__detail/__meta.hpp"
-#include "__detail/__type_traits.hpp"
-
-#include <version>
-
-// Perhaps the stdlib lacks support for concepts though:
-#if __has_include(<concepts>) && __cpp_lib_concepts >= 202002
-#define STDEXEC_HAS_STD_CONCEPTS_HEADER() 1
-#else
-#define STDEXEC_HAS_STD_CONCEPTS_HEADER() 0
-#endif
-
-#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
-#include <concepts>
-#else
-#include <type_traits>
-#endif
-
-namespace stdexec::__std_concepts
-{
-// Make sure we're using a same_as concept that doesn't instantiate std::is_same
-template <class _Ap, class _Bp>
-concept same_as = __same_as<_Ap, _Bp> && __same_as<_Bp, _Ap>;
-
-#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
-
-using std::convertible_to;
-using std::derived_from;
-using std::equality_comparable;
-using std::integral;
-
-#else
-
-template <class T>
-concept integral = std::is_integral_v<T>;
-
-template <class _Ap, class _Bp>
-concept derived_from =              //
-    STDEXEC_IS_BASE_OF(_Bp, _Ap) && //
-    STDEXEC_IS_CONVERTIBLE_TO(const volatile _Ap*, const volatile _Bp*);
-
-template <class _From, class _To>
-concept convertible_to =                     //
-    STDEXEC_IS_CONVERTIBLE_TO(_From, _To) && //
-    requires(_From (&__fun)()) { static_cast<_To>(__fun()); };
-
-template <class _Ty>
-concept equality_comparable = //
-    requires(__cref_t<_Ty> __t) {
-        {
-            __t == __t
-        } -> convertible_to<bool>;
-        {
-            __t != __t
-        } -> convertible_to<bool>;
-    };
-#endif
-} // namespace stdexec::__std_concepts
-
-namespace stdexec
-{
-using namespace __std_concepts;
-
-// Avoid using libstdc++'s object concepts because they instantiate a
-// lot of templates.
-#if STDEXEC_HAS_BUILTIN(__is_nothrow_destructible)
-template <class _Ty>
-concept destructible = __is_nothrow_destructible(_Ty);
-#else
-template <class _Ty>
-inline constexpr bool __destructible_ = //
-    requires {
-        {
-            (static_cast < _Ty && (*)() noexcept > (nullptr))().~_Ty()
-        } noexcept;
-    };
-template <class _Ty>
-inline constexpr bool __destructible_<_Ty&> = true;
-template <class _Ty>
-inline constexpr bool __destructible_<_Ty&&> = true;
-template <class _Ty, std::size_t _Np>
-inline constexpr bool __destructible_<_Ty[_Np]> = __destructible_<_Ty>;
-
-template <class T>
-concept destructible = __destructible_<T>;
-#endif
-
-#if STDEXEC_HAS_BUILTIN(__is_constructible)
-template <class _Ty, class... _As>
-concept constructible_from = //
-    destructible<_Ty> &&     //
-    __is_constructible(_Ty, _As...);
-#else
-template <class _Ty, class... _As>
-concept constructible_from = //
-    destructible<_Ty> &&     //
-    std::is_constructible_v<_Ty, _As...>;
-#endif
-
-template <class _Ty>
-concept default_initializable = //
-    constructible_from<_Ty> &&  //
-    requires { _Ty{}; } &&      //
-    requires { ::new _Ty; };
-
-template <class _Ty>
-concept move_constructible = //
-    constructible_from<_Ty, _Ty>;
-
-template <class _Ty>
-concept copy_constructible = //
-    move_constructible<_Ty>  //
-    && constructible_from<_Ty, const _Ty&>;
-
-template <class _LHS, class _RHS>
-concept assignable_from =   //
-    same_as<_LHS, _LHS&> && //
-    // std::common_reference_with<
-    //   const std::remove_reference_t<_LHS>&,
-    //   const std::remove_reference_t<_RHS>&> &&
-    requires(_LHS __lhs, _RHS&& __rhs) {
-        {
-            __lhs = static_cast<_RHS&&>(__rhs)
-        } -> same_as<_LHS>;
-    };
-
-namespace __swap
-{
-using std::swap;
-
-template <class _Ty, class _Uy>
-concept swappable_with =             //
-    requires(_Ty&& __t, _Uy&& __u) { //
-        swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u));
-    };
-
-inline constexpr const auto __fn = //
-    []<class _Ty, swappable_with<_Ty> _Uy>(_Ty&& __t, _Uy&& __u) noexcept(
-        noexcept(swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u)))) {
-    swap(static_cast<_Ty&&>(__t), static_cast<_Uy&&>(__u));
-};
-} // namespace __swap
-
-using __swap::swappable_with;
-inline constexpr const auto& swap = __swap::__fn;
-
-template <class _Ty>
-concept swappable = //
-    swappable_with<_Ty, _Ty>;
-
-template <class _Ty>
-concept movable =                 //
-    std::is_object_v<_Ty> &&      //
-    move_constructible<_Ty> &&    //
-    assignable_from<_Ty&, _Ty> && //
-    swappable<_Ty>;
-
-template <class _Ty>
-concept copyable =                       //
-    copy_constructible<_Ty> &&           //
-    movable<_Ty> &&                      //
-    assignable_from<_Ty&, _Ty&> &&       //
-    assignable_from<_Ty&, const _Ty&> && //
-    assignable_from<_Ty&, const _Ty>;
-
-template <class _Ty>
-concept semiregular = //
-    copyable<_Ty> &&  //
-    default_initializable<_Ty>;
-
-template <class _Ty>
-concept regular =       //
-    semiregular<_Ty> && //
-    equality_comparable<_Ty>;
-
-// Not exactly right, but close.
-template <class _Ty>
-concept __boolean_testable_ = convertible_to<_Ty, bool>;
-
-template <class T, class U>
-concept __partially_ordered_with = //
-    requires(__cref_t<T> t, __cref_t<U> u) {
-        {
-            t < u
-        } -> __boolean_testable_;
-        {
-            t > u
-        } -> __boolean_testable_;
-        {
-            t <= u
-        } -> __boolean_testable_;
-        {
-            t >= u
-        } -> __boolean_testable_;
-        {
-            u < t
-        } -> __boolean_testable_;
-        {
-            u > t
-        } -> __boolean_testable_;
-        {
-            u <= t
-        } -> __boolean_testable_;
-        {
-            u >= t
-        } -> __boolean_testable_;
-    };
-
-template <class _Ty>
-concept totally_ordered =       //
-    equality_comparable<_Ty> && //
-    __partially_ordered_with<_Ty, _Ty>;
-
-template <class _Ty>
-concept __movable_value =                 //
-    move_constructible<__decay_t<_Ty>> && //
-    constructible_from<__decay_t<_Ty>, _Ty>;
-
-template <class _Ty>
-concept __nothrow_movable_value = //
-    __movable_value<_Ty> &&       //
-    requires(_Ty&& __t) {
-        {
-            __decay_t<_Ty>{__decay_t<_Ty>{static_cast<_Ty&&>(__t)}}
-        } noexcept;
-    };
-
-#if STDEXEC_HAS_BUILTIN(__is_nothrow_constructible)
-template <class _Ty, class... _As>
-concept __nothrow_constructible_from = constructible_from<_Ty, _As...> &&
-                                       __is_nothrow_constructible(_Ty, _As...);
-#else
-template <class _Ty, class... _As>
-concept __nothrow_constructible_from =
-    constructible_from<_Ty, _As...> &&
-    std::is_nothrow_constructible_v<_Ty, _As...>;
-#endif
-
-template <class _Ty>
-concept __nothrow_move_constructible = __nothrow_constructible_from<_Ty, _Ty>;
-
-template <class _Ty>
-concept __nothrow_copy_constructible =
-    __nothrow_constructible_from<_Ty, const _Ty&>;
-
-template <class _Ty>
-concept __decay_copyable = constructible_from<__decay_t<_Ty>, _Ty>;
-
-template <class _Ty>
-concept __nothrow_decay_copyable =
-    __nothrow_constructible_from<__decay_t<_Ty>, _Ty>;
-
-template <class _Ty, class _Up>
-concept __decays_to_derived_from = derived_from<__decay_t<_Ty>, _Up>;
-
-} // namespace stdexec
-
-// #if !STDEXEC_HAS_STD_CONCEPTS_HEADER()
-// namespace std {
-//   using namespace stdexec::__std_concepts;
-// }
-// #endif
diff --git a/include/sdbusplus/async/stdexec/coroutine.hpp b/include/sdbusplus/async/stdexec/coroutine.hpp
index 01fb2fc..2426ed3 100644
--- a/include/sdbusplus/async/stdexec/coroutine.hpp
+++ b/include/sdbusplus/async/stdexec/coroutine.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -15,156 +15,130 @@
  */
 #pragma once
 
-#include "__detail/__concepts.hpp"
+#include "__detail/__awaitable.hpp"
 #include "__detail/__config.hpp"
-#include "concepts.hpp"
 
-#include <version>
-#if __cpp_impl_coroutine >= 201902 && __cpp_lib_coroutine >= 201902
-#include <coroutine>
-namespace __coro = std;
-#elif defined(__cpp_coroutines) && __has_include(<experimental/coroutine>)
-#include <experimental/coroutine>
-namespace __coro = std::experimental;
-#else
-#define STDEXEC_STD_NO_COROUTINES_ 1
-#endif
-
+#if STDEXEC_MSVC() && _MSC_VER >= 1939
 namespace stdexec
 {
-#if !STDEXEC_STD_NO_COROUTINES_
-// Define some concepts and utilities for working with awaitables
-template <class _Tp>
-concept __await_suspend_result =
-    __one_of<_Tp, void, bool> ||
-    __is_instance_of<_Tp, __coro::coroutine_handle>;
-
-template <class _Awaiter, class _Promise>
-concept __with_await_suspend =
-    same_as<_Promise, void> || //
-    requires(_Awaiter& __awaiter, __coro::coroutine_handle<_Promise> __h) {
-        {
-            __awaiter.await_suspend(__h)
-        } -> __await_suspend_result;
-    };
-
-template <class _Awaiter, class _Promise = void>
-concept __awaiter = //
-    requires(_Awaiter& __awaiter) {
-        __awaiter.await_ready() ? 1 : 0;
-        __awaiter.await_resume();
-    } && //
-    __with_await_suspend<_Awaiter, _Promise>;
-
-#if STDEXEC_MSVC()
 // MSVCBUG
-// https://developercommunity.visualstudio.com/t/operator-co_await-not-found-in-requires/10452721
+// https://developercommunity.visualstudio.com/t/destroy-coroutine-from-final_suspend-r/10096047
 
-template <class _Awaitable>
-void __co_await_constraint(_Awaitable&& __awaitable)
-    requires requires {
-                 operator co_await(static_cast<_Awaitable&&>(__awaitable));
-             };
-#endif
+// Prior to Visual Studio 17.9 (Feb, 2024), aka MSVC 19.39, MSVC incorrectly
+// allocates the return buffer for await_suspend calls within the suspended
+// coroutine frame. When the suspended coroutine is destroyed within
+// await_suspend, the continuation coroutine handle is not only used after free,
+// but also overwritten by the debug malloc implementation when NRVO is in play.
 
-template <class _Awaitable>
-auto __get_awaiter(_Awaitable&& __awaitable, void*) -> decltype(auto)
+// This workaround delays the destruction of the suspended coroutine by wrapping
+// the continuation in another coroutine which destroys the former and transfers
+// execution to the original continuation.
+
+// The wrapping coroutine is thread-local and is reused within the thread for
+// each destroy-and-continue sequence. The wrapping coroutine itself is
+// destroyed at thread exit.
+
+namespace __destroy_and_continue_msvc
 {
-    if constexpr (requires {
-                      static_cast<_Awaitable&&>(__awaitable)
-                          .
-                          operator co_await();
-                  })
-    {
-        return static_cast<_Awaitable&&>(__awaitable).operator co_await();
-    }
-    else if constexpr (requires {
-#if STDEXEC_MSVC()
-                           __co_await_constraint(
-                               static_cast<_Awaitable&&>(__awaitable));
-#else
-                           operator co_await(
-                               static_cast<_Awaitable&&>(__awaitable));
-#endif
-                       })
-    {
-        return operator co_await(static_cast<_Awaitable&&>(__awaitable));
-    }
-    else
-    {
-        return static_cast<_Awaitable&&>(__awaitable);
-    }
-}
-
-template <class _Awaitable, class _Promise>
-auto __get_awaiter(_Awaitable&& __awaitable, _Promise* __promise)
-    -> decltype(auto)
-    requires requires {
-                 __promise->await_transform(
-                     static_cast<_Awaitable&&>(__awaitable));
-             }
+struct __task
 {
-    if constexpr (requires {
-                      __promise
-                          ->await_transform(
-                              static_cast<_Awaitable&&>(__awaitable))
-                          .
-                          operator co_await();
-                  })
+    struct promise_type
     {
-        return __promise
-            ->await_transform(static_cast<_Awaitable&&>(__awaitable))
-            .
-            operator co_await();
-    }
-    else if constexpr (requires {
-#if STDEXEC_MSVC()
-                           __co_await_constraint(__promise->await_transform(
-                               static_cast<_Awaitable&&>(__awaitable)));
-#else
-                           operator co_await(__promise->await_transform(
-                               static_cast<_Awaitable&&>(__awaitable)));
-#endif
-                       })
-    {
-        return operator co_await(
-            __promise->await_transform(static_cast<_Awaitable&&>(__awaitable)));
-    }
-    else
-    {
-        return __promise->await_transform(
-            static_cast<_Awaitable&&>(__awaitable));
-    }
-}
-
-template <class _Awaitable, class _Promise = void>
-concept __awaitable = //
-    requires(_Awaitable&& __awaitable, _Promise* __promise) {
+        __task get_return_object() noexcept
         {
-            stdexec::__get_awaiter(static_cast<_Awaitable&&>(__awaitable),
-                                   __promise)
-        } -> __awaiter<_Promise>;
+            return {
+                __coro::coroutine_handle<promise_type>::from_promise(*this)};
+        }
+
+        static std::suspend_never initial_suspend() noexcept
+        {
+            return {};
+        }
+
+        static std::suspend_never final_suspend() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+            return {};
+        }
+
+        static void return_void() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+        }
+
+        static void unhandled_exception() noexcept
+        {
+            STDEXEC_ASSERT(!"Should never get here");
+        }
     };
 
-template <class _Tp>
-auto __as_lvalue(_Tp&&) -> _Tp&;
+    __coro::coroutine_handle<> __coro_;
+};
 
-template <class _Awaitable, class _Promise = void>
-    requires __awaitable<_Awaitable, _Promise>
-using __await_result_t =
-    decltype(stdexec::__as_lvalue(
-                 stdexec::__get_awaiter(std::declval<_Awaitable>(),
-                                        static_cast<_Promise*>(nullptr)))
-                 .await_resume());
+struct __continue_t
+{
+    static constexpr bool await_ready() noexcept
+    {
+        return false;
+    }
 
-#else
+    __coro::coroutine_handle<>
+        await_suspend(__coro::coroutine_handle<>) noexcept
+    {
+        return __continue_;
+    }
 
-template <class _Awaitable, class _Promise = void>
-concept __awaitable = false;
+    static void await_resume() noexcept {}
 
-template <class _Awaitable, class _Promise = void>
-    requires __awaitable<_Awaitable, _Promise>
-using __await_result_t = void;
+    __coro::coroutine_handle<> __continue_;
+};
 
-#endif
+struct __context
+{
+    __coro::coroutine_handle<> __destroy_;
+    __coro::coroutine_handle<> __continue_;
+};
+
+inline __task __co_impl(__context& __c)
+{
+    while (true)
+    {
+        co_await __continue_t{__c.__continue_};
+        __c.__destroy_.destroy();
+    }
+}
+
+struct __context_and_coro
+{
+    __context_and_coro()
+    {
+        __context_.__continue_ = __coro::noop_coroutine();
+        __coro_ = __co_impl(__context_).__coro_;
+    }
+
+    ~__context_and_coro()
+    {
+        __coro_.destroy();
+    }
+
+    __context __context_;
+    __coro::coroutine_handle<> __coro_;
+};
+
+inline __coro::coroutine_handle<> __impl(__coro::coroutine_handle<> __destroy,
+                                         __coro::coroutine_handle<> __continue)
+{
+    static thread_local __context_and_coro __c;
+    __c.__context_.__destroy_ = __destroy;
+    __c.__context_.__continue_ = __continue;
+    return __c.__coro_;
+}
+} // namespace __destroy_and_continue_msvc
 } // namespace stdexec
+
+#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
+    (::stdexec::__destroy_and_continue_msvc::__impl(__destroy, __continue))
+#else
+#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
+    (__destroy.destroy(), __continue)
+#endif
diff --git a/include/sdbusplus/async/stdexec/env.hpp b/include/sdbusplus/async/stdexec/env.hpp
index d83948a..27590f2 100644
--- a/include/sdbusplus/async/stdexec/env.hpp
+++ b/include/sdbusplus/async/stdexec/env.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -23,7 +23,7 @@
 namespace exec
 {
 template <class _Tag, class _Value>
-using with_t = stdexec::__env::__with<_Value, _Tag>;
+using with_t = stdexec::prop<_Tag, _Value>;
 
 namespace __envs
 {
@@ -32,7 +32,7 @@
     template <class _Tag, class _Value>
     auto operator()(_Tag, _Value&& __val) const
     {
-        return stdexec::__env::__with(static_cast<_Value&&>(__val), _Tag());
+        return stdexec::prop{_Tag(), static_cast<_Value&&>(__val)};
     }
 };
 
@@ -93,24 +93,25 @@
         _Default __default_;
         _Receiver __rcvr_;
 
-        friend void tag_invoke(start_t, __t& __self) noexcept
+        void start() & noexcept
         {
             try
             {
                 if constexpr (__callable<_Tag, env_of_t<_Receiver>>)
                 {
-                    const auto& __env = get_env(__self.__rcvr_);
-                    set_value(std::move(__self.__rcvr_), _Tag{}(__env));
+                    const auto& __env = get_env(__rcvr_);
+                    stdexec::set_value(std::move(__rcvr_), _Tag{}(__env));
                 }
                 else
                 {
-                    set_value(std::move(__self.__rcvr_),
-                              std::move(__self.__default_));
+                    stdexec::set_value(std::move(__rcvr_),
+                                       std::move(__default_));
                 }
             }
             catch (...)
             {
-                set_error(std::move(__self.__rcvr_), std::current_exception());
+                stdexec::set_error(std::move(__rcvr_),
+                                   std::current_exception());
             }
         }
     };
@@ -133,6 +134,7 @@
         __with_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>),
@@ -140,7 +142,7 @@
 
     template <__decays_to<__sender> _Self, class _Receiver>
         requires receiver_of<_Receiver, __completions_t<env_of_t<_Receiver>>>
-    friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) //
+    static auto connect(_Self&& __self, _Receiver __rcvr) //
         noexcept(std::is_nothrow_move_constructible_v<_Receiver>)
             -> __operation_t<_Tag, __default_t<env_of_t<_Receiver>>, _Receiver>
     {
@@ -150,8 +152,7 @@
     }
 
     template <class _Env>
-    friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&)
-        -> __completions_t<_Env>
+    auto get_completion_signatures(_Env&&) -> __completions_t<_Env>
     {
         return {};
     }
@@ -170,7 +171,8 @@
 
 inline constexpr __read_with_default::__read_with_default_t read_with_default{};
 
-inline constexpr stdexec::__write_::__write_t write{};
+inline constexpr stdexec::__write_::__write_env_t write{};
+inline constexpr stdexec::__write_::__write_env_t write_env{};
 } // namespace exec
 
 STDEXEC_PRAGMA_POP()
diff --git a/include/sdbusplus/async/stdexec/execution.hpp b/include/sdbusplus/async/stdexec/execution.hpp
index 31cfe3f..0dc3800 100644
--- a/include/sdbusplus/async/stdexec/execution.hpp
+++ b/include/sdbusplus/async/stdexec/execution.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -15,6864 +15,62 @@
  */
 #pragma once
 
-#include "__detail/__basic_sender.hpp"
-#include "__detail/__config.hpp"
-#include "__detail/__cpo.hpp"
-#include "__detail/__domain.hpp"
-#include "__detail/__env.hpp"
 #include "__detail/__execution_fwd.hpp"
+
+// include these after __execution_fwd.hpp
+#include "__detail/__as_awaitable.hpp"
+#include "__detail/__basic_sender.hpp"
+#include "__detail/__bulk.hpp"
+#include "__detail/__completion_signatures.hpp"
+#include "__detail/__connect_awaitable.hpp"
+#include "__detail/__continue_on.hpp"
+#include "__detail/__cpo.hpp"
+#include "__detail/__debug.hpp"
+#include "__detail/__domain.hpp"
+#include "__detail/__ensure_started.hpp"
+#include "__detail/__env.hpp"
+#include "__detail/__execute.hpp"
+#include "__detail/__inline_scheduler.hpp"
+#include "__detail/__into_variant.hpp"
 #include "__detail/__intrusive_ptr.hpp"
+#include "__detail/__intrusive_slist.hpp"
+#include "__detail/__just.hpp"
+#include "__detail/__let.hpp"
 #include "__detail/__meta.hpp"
-#include "__detail/__scope.hpp"
+#include "__detail/__on.hpp"
+#include "__detail/__operation_states.hpp"
+#include "__detail/__read_env.hpp"
+#include "__detail/__receiver_adaptor.hpp"
+#include "__detail/__receivers.hpp"
+#include "__detail/__run_loop.hpp"
+#include "__detail/__schedule_from.hpp"
+#include "__detail/__schedulers.hpp"
+#include "__detail/__sender_adaptor_closure.hpp"
+#include "__detail/__senders.hpp"
+#include "__detail/__split.hpp"
+#include "__detail/__start_detached.hpp"
+#include "__detail/__start_on.hpp"
+#include "__detail/__stopped_as_error.hpp"
+#include "__detail/__stopped_as_optional.hpp"
+#include "__detail/__submit.hpp"
+#include "__detail/__sync_wait.hpp"
+#include "__detail/__then.hpp"
+#include "__detail/__transfer_just.hpp"
+#include "__detail/__transform_completion_signatures.hpp"
+#include "__detail/__transform_sender.hpp"
 #include "__detail/__type_traits.hpp"
+#include "__detail/__upon_error.hpp"
+#include "__detail/__upon_stopped.hpp"
 #include "__detail/__utility.hpp"
+#include "__detail/__when_all.hpp"
+#include "__detail/__with_awaitable_senders.hpp"
+#include "__detail/__write_env.hpp"
 #include "concepts.hpp"
 #include "coroutine.hpp"
 #include "functional.hpp"
 #include "stop_token.hpp"
 
-#include <atomic>
-#include <cassert>
-#include <concepts>
-#include <condition_variable>
-#include <cstddef>
-#include <exception>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <stdexcept>
-#include <system_error>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-#include <variant>
-
-STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE_GNU("-Wundefined-inline")
-STDEXEC_PRAGMA_IGNORE_GNU("-Wsubobject-linkage")
-STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
-
-STDEXEC_PRAGMA_IGNORE_EDG(1302)
-STDEXEC_PRAGMA_IGNORE_EDG(497)
-STDEXEC_PRAGMA_IGNORE_EDG(type_qualifiers_ignored_on_reference)
-
-namespace stdexec
-{
-/////////////////////////////////////////////////////////////////////////////
-template <class _Sender, class _Scheduler, class _Tag = set_value_t>
-concept __completes_on = __decays_to<
-    __call_result_t<get_completion_scheduler_t<_Tag>, env_of_t<_Sender>>,
-    _Scheduler>;
-
-/////////////////////////////////////////////////////////////////////////////
-template <class _Sender, class _Scheduler, class _Env>
-concept __starts_on =
-    __decays_to<__call_result_t<get_scheduler_t, _Env>, _Scheduler>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.receivers]
-namespace __receivers
-{
-struct set_value_t
-{
-    template <class _Fn, class... _Args>
-    using __f = __minvoke<_Fn, _Args...>;
-
-    template <class _Receiver, class... _As>
-        requires tag_invocable<set_value_t, _Receiver, _As...>
-    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
-        operator()(_Receiver&& __rcvr, _As&&... __as) const noexcept
-    {
-        static_assert(nothrow_tag_invocable<set_value_t, _Receiver, _As...>);
-        (void)tag_invoke(set_value_t{}, static_cast<_Receiver&&>(__rcvr),
-                         static_cast<_As&&>(__as)...);
-    }
-};
-
-struct set_error_t
-{
-    template <class _Fn, class... _Args>
-        requires(sizeof...(_Args) == 1)
-    using __f = __minvoke<_Fn, _Args...>;
-
-    template <class _Receiver, class _Error>
-        requires tag_invocable<set_error_t, _Receiver, _Error>
-    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
-        operator()(_Receiver&& __rcvr, _Error&& __err) const noexcept
-    {
-        static_assert(nothrow_tag_invocable<set_error_t, _Receiver, _Error>);
-        (void)tag_invoke(set_error_t{}, static_cast<_Receiver&&>(__rcvr),
-                         static_cast<_Error&&>(__err));
-    }
-};
-
-struct set_stopped_t
-{
-    template <class _Fn, class... _Args>
-        requires(sizeof...(_Args) == 0)
-    using __f = __minvoke<_Fn, _Args...>;
-
-    template <class _Receiver>
-        requires tag_invocable<set_stopped_t, _Receiver>
-    STDEXEC_ATTRIBUTE((host, device, always_inline)) void
-        operator()(_Receiver&& __rcvr) const noexcept
-    {
-        static_assert(nothrow_tag_invocable<set_stopped_t, _Receiver>);
-        (void)tag_invoke(set_stopped_t{}, static_cast<_Receiver&&>(__rcvr));
-    }
-};
-} // namespace __receivers
-
-using __receivers::set_error_t;
-using __receivers::set_stopped_t;
-using __receivers::set_value_t;
-inline constexpr set_value_t set_value{};
-inline constexpr set_error_t set_error{};
-inline constexpr set_stopped_t set_stopped{};
-
-inline constexpr struct __try_call_t
-{
-    template <class _Receiver, class _Fun, class... _Args>
-        requires __callable<_Fun, _Args...>
-    void operator()(_Receiver&& __rcvr, _Fun __fun,
-                    _Args&&... __args) const noexcept
-    {
-        if constexpr (__nothrow_callable<_Fun, _Args...>)
-        {
-            static_cast<_Fun&&>(__fun)(static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            try
-            {
-                static_cast<_Fun&&>(__fun)(static_cast<_Args&&>(__args)...);
-            }
-            catch (...)
-            {
-                set_error(static_cast<_Receiver&&>(__rcvr),
-                          std::current_exception());
-            }
-        }
-    }
-} __try_call{};
-
-namespace __error__
-{
-inline constexpr __mstring __unrecognized_sender_type_diagnostic =
-    "The given type cannot be used as a sender with the given environment "
-    "because the attempt to compute the completion signatures failed."_mstr;
-
-template <__mstring _Diagnostic = __unrecognized_sender_type_diagnostic>
-struct _UNRECOGNIZED_SENDER_TYPE_;
-
-template <class _Sender>
-struct _WITH_SENDER_;
-
-template <class... _Senders>
-struct _WITH_SENDERS_;
-
-template <class _Env>
-struct _WITH_ENVIRONMENT_;
-
-template <class _Ty>
-struct _WITH_TYPE_;
-
-template <class _Receiver>
-struct _WITH_RECEIVER_;
-
-template <class _Sig>
-struct _MISSING_COMPLETION_SIGNAL_;
-} // namespace __error__
-
-using __error__::_MISSING_COMPLETION_SIGNAL_;
-using __error__::_UNRECOGNIZED_SENDER_TYPE_;
-using __error__::_WITH_ENVIRONMENT_;
-using __error__::_WITH_RECEIVER_;
-using __error__::_WITH_TYPE_;
-
-template <class _Sender>
-using _WITH_SENDER_ = __error__::_WITH_SENDER_<__name_of<_Sender>>;
-
-template <class... _Senders>
-using _WITH_SENDERS_ = __error__::_WITH_SENDERS_<__name_of<_Senders>...>;
-
-/////////////////////////////////////////////////////////////////////////////
-// completion_signatures
-namespace __compl_sigs
-{
-template <class _Sig>
-inline constexpr bool __is_compl_sig = false;
-template <class... _Args>
-inline constexpr bool __is_compl_sig<set_value_t(_Args...)> = true;
-template <class _Error>
-inline constexpr bool __is_compl_sig<set_error_t(_Error)> = true;
-template <>
-inline constexpr bool __is_compl_sig<set_stopped_t()> = true;
-} // namespace __compl_sigs
-
-template <class _Sig>
-concept __completion_signature = __compl_sigs::__is_compl_sig<_Sig>;
-
-template <__completion_signature... _Sigs>
-struct completion_signatures
-{};
-
-namespace __compl_sigs
-{
-template <class _TaggedTuple, class _Tag, class... _Ts>
-auto __as_tagged_tuple_(_Tag (*)(_Ts...), _TaggedTuple*)
-    -> __mconst<__minvoke<_TaggedTuple, _Tag, _Ts...>>;
-
-template <class _Sig, class _TaggedTuple>
-using __as_tagged_tuple = decltype(__compl_sigs::__as_tagged_tuple_(
-    static_cast<_Sig*>(nullptr), static_cast<_TaggedTuple*>(nullptr)));
-
-template <class _TaggedTuple, class _Variant, class... _Sigs>
-auto __for_all_sigs_(completion_signatures<_Sigs...>*, _TaggedTuple*, _Variant*)
-    -> __mconst<__minvoke<
-        _Variant, __minvoke<__as_tagged_tuple<_Sigs, _TaggedTuple>>...>>;
-
-template <class _Completions, class _TaggedTuple, class _Variant>
-using __for_all_sigs =                          //
-    __minvoke<                                  //
-        decltype(__compl_sigs::__for_all_sigs_( //
-            static_cast<_Completions*>(nullptr),
-            static_cast<_TaggedTuple*>(nullptr),
-            static_cast<_Variant*>(nullptr)))>;
-
-template <class _Completions, class _TaggedTuple, class _Variant>
-using __maybe_for_all_sigs =
-    __meval<__for_all_sigs, _Completions, _TaggedTuple, _Variant>;
-} // namespace __compl_sigs
-
-template <class _Completions>
-concept __valid_completion_signatures = //
-    __ok<_Completions> && __is_instance_of<_Completions, completion_signatures>;
-
-template <class _Completions>
-using __invalid_completion_signatures_t = //
-    __mbool<!__valid_completion_signatures<_Completions>>;
-
-template <__mstring _Msg =
-              "Expected an instance of template completion_signatures<>"_mstr>
-struct _INVALID_COMPLETION_SIGNATURES_TYPE_
-{
-    template <class... _Completions>
-    using __f = //
-        __mexception<
-            _INVALID_COMPLETION_SIGNATURES_TYPE_<>,
-            __minvoke<__mfind_if<__q<__invalid_completion_signatures_t>,
-                                 __mcompose<__q<_WITH_TYPE_>, __q<__mfront>>>,
-                      _Completions...>>;
-};
-
-template <class... _Completions>
-using __concat_completion_signatures_impl_t = //
-    __minvoke<__if_c<(__valid_completion_signatures<_Completions> && ...),
-                     __mconcat<__munique<__q<completion_signatures>>>,
-                     _INVALID_COMPLETION_SIGNATURES_TYPE_<>>,
-              _Completions...>;
-
-template <class... _Completions>
-struct __concat_completion_signatures_
-{
-    using __t = __meval<__concat_completion_signatures_impl_t, _Completions...>;
-};
-
-template <class... _Completions>
-using __concat_completion_signatures_t =
-    __t<__concat_completion_signatures_<_Completions...>>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.receivers]
-template <class _Receiver, class _Tag, class... _Args>
-auto __try_completion(_Tag (*)(_Args...))
-    -> __mexception<_MISSING_COMPLETION_SIGNAL_<_Tag(_Args...)>,
-                    _WITH_RECEIVER_<_Receiver>>;
-
-template <class _Receiver, class _Tag, class... _Args>
-    requires nothrow_tag_invocable<_Tag, _Receiver, _Args...>
-auto __try_completion(_Tag (*)(_Args...)) -> __msuccess;
-
-template <class _Receiver, class... _Sigs>
-auto __try_completions(completion_signatures<_Sigs...>*) -> decltype((
-    __msuccess(), ...,
-    stdexec::__try_completion<_Receiver>(static_cast<_Sigs*>(nullptr))));
-
-template <class _Sender, class _Env>
-using __unrecognized_sender_error = //
-    __mexception<_UNRECOGNIZED_SENDER_TYPE_<>, _WITH_SENDER_<_Sender>,
-                 _WITH_ENVIRONMENT_<_Env>>;
-
-template <class _Sender, class _Env>
-using __completion_signatures_of_t =
-    __call_result_t<get_completion_signatures_t, _Sender, _Env>;
-
-/////////////////////////////////////////////////////////////////////////////
-// early sender type-checking
-template <class _Sender>
-concept __well_formed_sender = //
-    !__detail::__non_dependent_sender<_Sender> ||
-    __valid_completion_signatures<
-        __completion_signatures_of_t<_Sender, empty_env>>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.receivers]
-struct receiver_t
-{
-    using receiver_concept = receiver_t; // NOT TO SPEC
-};
-
-namespace __detail
-{
-template <class _Receiver>
-concept __enable_receiver =                                              //
-    (STDEXEC_NVHPC(requires { typename _Receiver::receiver_concept; }&&) //
-     derived_from<typename _Receiver::receiver_concept, receiver_t>) ||
-    requires { typename _Receiver::is_receiver; } // back-compat, NOT TO SPEC
-    || STDEXEC_IS_BASE_OF(receiver_t,
-                          _Receiver); // NOT TO SPEC, for receiver_adaptor
-} // namespace __detail
-
-template <class _Receiver>
-inline constexpr bool enable_receiver =
-    __detail::__enable_receiver<_Receiver>; // NOT TO SPEC
-
-template <class _Receiver>
-concept receiver = enable_receiver<__decay_t<_Receiver>> &&     //
-                   environment_provider<__cref_t<_Receiver>> && //
-                   move_constructible<__decay_t<_Receiver>> &&  //
-                   constructible_from<__decay_t<_Receiver>, _Receiver>;
-
-template <class _Receiver, class _Completions>
-concept receiver_of =      //
-    receiver<_Receiver> && //
-    requires(_Completions* __completions) {
-        {
-            stdexec::__try_completions<__decay_t<_Receiver>>(__completions)
-        } -> __ok;
-    };
-
-template <class _Receiver, class _Sender>
-concept __receiver_from =
-    receiver_of<_Receiver,
-                __completion_signatures_of_t<_Sender, env_of_t<_Receiver>>>;
-
-/////////////////////////////////////////////////////////////////////////////
-// Some utilities for debugging senders
-namespace __debug
-{
-struct __is_debug_env_t
-{
-    friend constexpr auto tag_invoke(forwarding_query_t,
-                                     const __is_debug_env_t&) noexcept -> bool
-    {
-        return true;
-    }
-    template <class _Env>
-        requires tag_invocable<__is_debug_env_t, const _Env&>
-    auto operator()(const _Env&) const noexcept
-        -> tag_invoke_result_t<__is_debug_env_t, const _Env&>;
-};
-template <class _Env>
-using __debug_env_t =
-    __env::__join_t<__env::__with<bool, __is_debug_env_t>, _Env>;
-
-template <class _Env>
-concept __is_debug_env = tag_invocable<__debug::__is_debug_env_t, _Env>;
-
-struct __completion_signatures
-{};
-
-#if STDEXEC_MSVC()
-// MSVCBUG
-// https://developercommunity.visualstudio.com/t/Explicit-variable-template-specialisatio/10360032
-// MSVCBUG
-// https://developercommunity.visualstudio.com/t/Non-function-type-interpreted-as-functio/10447831
-
-template <class _Sig>
-struct __normalize_sig;
-
-template <class _Tag, class... _Args>
-struct __normalize_sig<_Tag(_Args...)>
-{
-    using __type = _Tag (*)(_Args&&...);
-};
-
-template <class _Sig>
-using __normalize_sig_t = typename __normalize_sig<_Sig>::__type;
-#else
-template <class _Sig>
-extern int __normalize_sig;
-
-template <class _Tag, class... _Args>
-extern _Tag (*__normalize_sig<_Tag(_Args...)>)(_Args&&...);
-
-template <class _Sig>
-using __normalize_sig_t = decltype(__normalize_sig<_Sig>);
-#endif
-
-template <class... _Sigs>
-struct __valid_completions
-{
-    template <derived_from<__valid_completions> _Self, class _Tag,
-              class... _Args>
-        requires __one_of<_Tag (*)(_Args&&...), _Sigs...>
-    STDEXEC_ATTRIBUTE((host,
-                       device)) friend void tag_invoke(_Tag, _Self&&,
-                                                       _Args&&...) noexcept
-    {
-        STDEXEC_TERMINATE();
-    }
-};
-
-template <class _CvrefSenderId, class _Env, class _Completions>
-struct __debug_receiver
-{
-    using __t = __debug_receiver;
-    using __id = __debug_receiver;
-    using receiver_concept = receiver_t;
-};
-
-template <class _CvrefSenderId, class _Env, class... _Sigs>
-struct __debug_receiver<_CvrefSenderId, _Env,
-                        completion_signatures<_Sigs...>> //
-    : __valid_completions<__normalize_sig_t<_Sigs>...>
-{
-    using __t = __debug_receiver;
-    using __id = __debug_receiver;
-    using receiver_concept = receiver_t;
-
-    template <same_as<get_env_t> _Tag>
-    STDEXEC_ATTRIBUTE((host, device))
-    friend auto tag_invoke(_Tag, __debug_receiver) noexcept
-        -> __debug_env_t<_Env>
-    {
-        STDEXEC_TERMINATE();
-    }
-};
-
-struct _COMPLETION_SIGNATURES_MISMATCH_
-{};
-
-template <class _Sig>
-struct _COMPLETION_SIGNATURE_
-{};
-
-template <class... _Sigs>
-struct _IS_NOT_ONE_OF_
-{};
-
-template <class _Sender>
-struct _SIGNAL_SENT_BY_SENDER_
-{};
-
-template <class _Warning>
-[[deprecated(
-    "The sender claims to send a particular set of completions,"
-    " but in actual fact it completes with a result that is not"
-    " one of the declared completion signatures.")]] STDEXEC_ATTRIBUTE((host,
-                                                                        device)) void _ATTENTION_() noexcept
-{}
-
-template <class _Sig>
-struct __invalid_completion
-{
-    struct __t
-    {
-        template <class _CvrefSenderId, class _Env, class... _Sigs>
-        // BUGBUG this works around a recently (aug 2023) introduced regression
-        // in nvc++
-            requires(!__one_of<_Sig, _Sigs...>)
-        __t(__debug_receiver<_CvrefSenderId, _Env,
-                             completion_signatures<_Sigs...>>&&) noexcept
-        {
-            using _SenderId = __decay_t<_CvrefSenderId>;
-            using _Sender = stdexec::__t<_SenderId>;
-            using _What =  //
-                _WARNING_< //
-                    _COMPLETION_SIGNATURES_MISMATCH_,
-                    _COMPLETION_SIGNATURE_<_Sig>, _IS_NOT_ONE_OF_<_Sigs...>,
-                    _SIGNAL_SENT_BY_SENDER_<__name_of<_Sender>>>;
-            __debug::_ATTENTION_<_What>();
-        }
-    };
-};
-
-template <__completion_tag _Tag, class... _Args>
-STDEXEC_ATTRIBUTE((host, device))
-void tag_invoke(_Tag, __t<__invalid_completion<_Tag(_Args...)>>,
-                _Args&&...) noexcept
-{}
-
-struct __debug_operation
-{
-    template <same_as<start_t> _Tag>
-    friend void tag_invoke(_Tag, __debug_operation&) noexcept
-    {}
-};
-
-////////////////////////////////////////////////////////////////////////////
-// `__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 _Sigs, class _Env = empty_env, class _Sender>
-//   void __debug_sender(_Sender&& __sndr, _Env = {});
-//
-// template <class _Env = empty_env, 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<completion_signatures<set_value_t(int)>>(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.
-template <class _Sigs, class _Env = empty_env, class _Sender>
-void __debug_sender(_Sender&& __sndr, const _Env& = {})
-{
-    if constexpr (!__is_debug_env<_Env>)
-    {
-        if (sizeof(_Sender) == ~0u)
-        { // never true
-            using _Receiver =
-                __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>;
-            using _Operation = connect_result_t<_Sender, _Receiver>;
-            // static_assert(receiver_of<_Receiver, _Sigs>);
-            if constexpr (!same_as<_Operation, __debug_operation>)
-            {
-                auto __op = connect(static_cast<_Sender&&>(__sndr),
-                                    _Receiver{});
-                start(__op);
-            }
-        }
-    }
-}
-
-template <class _Env = empty_env, class _Sender>
-void __debug_sender(_Sender&& __sndr, const _Env& = {})
-{
-    if constexpr (!__is_debug_env<_Env>)
-    {
-        if (sizeof(_Sender) == ~0)
-        { // never true
-            using _Sigs =
-                __completion_signatures_of_t<_Sender, __debug_env_t<_Env>>;
-            if constexpr (!same_as<_Sigs, __debug::__completion_signatures>)
-            {
-                using _Receiver =
-                    __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>;
-                using _Operation = connect_result_t<_Sender, _Receiver>;
-                // static_assert(receiver_of<_Receiver, _Sigs>);
-                if constexpr (!same_as<_Operation, __debug_operation>)
-                {
-                    auto __op = connect(static_cast<_Sender&&>(__sndr),
-                                        _Receiver{});
-                    start(__op);
-                }
-            }
-        }
-    }
-}
-} // namespace __debug
-
-using __debug::__debug_sender;
-using __debug::__is_debug_env;
-
-/////////////////////////////////////////////////////////////////////////////
-// dependent_domain
-struct dependent_domain
-{
-    template <sender_expr _Sender, class _Env>
-        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
-    STDEXEC_ATTRIBUTE((always_inline)) decltype(auto)
-        transform_sender(_Sender&& __sndr, const _Env& __env) const;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.transform_sender]
-namespace __domain
-{
-struct __transform_env
-{
-    template <class _Domain, class _Sender, class _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    /*constexpr*/
-    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
-                              _Env&& __env) const noexcept
-    {
-        if constexpr (__domain::__has_transform_env<_Domain, _Sender, _Env>)
-        {
-            return __dom.transform_env(static_cast<_Sender&&>(__sndr),
-                                       static_cast<_Env&&>(__env));
-        }
-        else
-        {
-            return default_domain().transform_env(
-                static_cast<_Sender&&>(__sndr), static_cast<_Env&&>(__env));
-        }
-    }
-};
-
-struct __transform_sender_1
-{
-    template <class _Domain, class _Sender, class... _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    /*constexpr*/
-    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
-                              const _Env&... __env) const
-    {
-        if constexpr (__domain::__has_transform_sender<_Domain, _Sender,
-                                                       _Env...>)
-        {
-            return __dom.transform_sender(static_cast<_Sender&&>(__sndr),
-                                          __env...);
-        }
-        else
-        {
-            return default_domain().transform_sender(
-                static_cast<_Sender&&>(__sndr), __env...);
-        }
-    }
-};
-
-template <class _Ty, class _Uy>
-concept __decay_same_as = same_as<__decay_t<_Ty>, __decay_t<_Uy>>;
-
-struct __transform_sender
-{
-    template <class _Self = __transform_sender, class _Domain, class _Sender,
-              class... _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    /*constexpr*/
-    decltype(auto) operator()(_Domain __dom, _Sender&& __sndr,
-                              const _Env&... __env) const
-    {
-        using _Sender2 = __call_result_t<__transform_sender_1, _Domain, _Sender,
-                                         const _Env&...>;
-        // If the transformation doesn't change the sender's type, then do not
-        // apply the transform recursively.
-        if constexpr (__decay_same_as<_Sender, _Sender2>)
-        {
-            return __transform_sender_1()(__dom, static_cast<_Sender&&>(__sndr),
-                                          __env...);
-        }
-        else
-        {
-            // We transformed the sender and got back a different sender.
-            // Transform that one too.
-            return _Self()(__dom,
-                           __transform_sender_1()(
-                               __dom, static_cast<_Sender&&>(__sndr), __env...),
-                           __env...);
-        }
-    }
-};
-
-struct __transform_dependent_sender
-{
-    // If we are doing a lazy customization of a type whose domain is
-    // value-dependent (e.g., let_value), first transform the sender to
-    // determine the domain. Then continue transforming the sender with the
-    // requested domain.
-    template <class _Domain, sender_expr _Sender, class _Env>
-        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
-    /*constexpr*/ auto operator()(_Domain __dom, _Sender&& __sndr,
-                                  const _Env& __env) const -> decltype(auto)
-    {
-        static_assert(__none_of<_Domain, dependent_domain>);
-        return __transform_sender()(__dom,
-                                    dependent_domain().transform_sender(
-                                        static_cast<_Sender&&>(__sndr), __env),
-                                    __env);
-    }
-};
-} // namespace __domain
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.transform_sender]
-inline constexpr struct transform_sender_t :
-    __domain::__transform_sender,
-    __domain::__transform_dependent_sender
-{
-    using __domain::__transform_sender::operator();
-    using __domain::__transform_dependent_sender::operator();
-} transform_sender{};
-
-template <class _Domain, class _Sender, class... _Env>
-using transform_sender_result_t =
-    __call_result_t<transform_sender_t, _Domain, _Sender, _Env...>;
-
-inline constexpr __domain::__transform_env transform_env{};
-
-struct _CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_
-{};
-
-template <sender_expr _Sender, class _Env>
-    requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
-auto dependent_domain::transform_sender(_Sender&& __sndr,
-                                        const _Env& __env) const
-    -> decltype(auto)
-{
-    // apply any algorithm-specific transformation to the environment
-    const auto& __env2 = transform_env(*this, static_cast<_Sender&&>(__sndr),
-                                       __env);
-
-    // recursively transform the sender to determine the domain
-    return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                         [&]<class _Tag, class _Data, class... _Childs>(
-                             _Tag, _Data&& __data, _Childs&&... __childs) {
-        // TODO: propagate meta-exceptions here:
-        auto __sndr2 = __make_sexpr<_Tag>(
-            static_cast<_Data&&>(__data),
-            __domain::__transform_sender()(
-                *this, static_cast<_Childs&&>(__childs), __env2)...);
-        using _Sender2 = decltype(__sndr2);
-
-        auto __domain2 = __sexpr_apply(__sndr2, __domain::__common_domain_fn());
-        using _Domain2 = decltype(__domain2);
-
-        if constexpr (same_as<_Domain2, __none_such>)
-        {
-            return __mexception<_CHILD_SENDERS_WITH_DIFFERENT_DOMAINS_,
-                                _WITH_SENDER_<_Sender2>>();
-        }
-        else
-        {
-            return __domain::__transform_sender()(__domain2, std::move(__sndr2),
-                                                  __env);
-        }
-    });
-}
-
-/////////////////////////////////////////////////////////////////////////////
-template <class _Tag, class _Domain, class _Sender, class... _Args>
-concept __has_implementation_for =
-    __domain::__has_apply_sender<_Domain, _Tag, _Sender, _Args...> ||
-    __domain::__has_apply_sender<default_domain, _Tag, _Sender, _Args...>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.apply_sender]
-inline constexpr struct apply_sender_t
-{
-    template <class _Domain, class _Tag, class _Sender, class... _Args>
-        requires __has_implementation_for<_Tag, _Domain, _Sender, _Args...>
-    STDEXEC_ATTRIBUTE((always_inline))
-        /*constexpr*/
-        decltype(auto)
-            operator()(_Domain __dom, _Tag, _Sender&& __sndr,
-                       _Args&&... __args) const
-    {
-        if constexpr (__domain::__has_apply_sender<_Domain, _Tag, _Sender,
-                                                   _Args...>)
-        {
-            return __dom.apply_sender(_Tag(), static_cast<_Sender&&>(__sndr),
-                                      static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            return default_domain().apply_sender(
-                _Tag(), static_cast<_Sender&&>(__sndr),
-                static_cast<_Args&&>(__args)...);
-        }
-    }
-} apply_sender{};
-
-template <class _Domain, class _Tag, class _Sender, class... _Args>
-using apply_sender_result_t =
-    __call_result_t<apply_sender_t, _Domain, _Tag, _Sender, _Args...>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.sndtraits]
-namespace __get_completion_signatures
-{
-template <class _Sender, class _Env>
-using __tfx_sender =
-    transform_sender_result_t<__late_domain_of_t<_Sender, _Env>, _Sender, _Env>;
-
-template <class _Sender, class _Env>
-concept __with_tag_invoke = //
-    tag_invocable<get_completion_signatures_t, __tfx_sender<_Sender, _Env>,
-                  _Env>;
-
-template <class _Sender, class _Env>
-using __member_alias_t = //
-    typename __decay_t<__tfx_sender<_Sender, _Env>>::completion_signatures;
-
-template <class _Sender, class _Env = empty_env>
-concept __with_member_alias = __mvalid<__member_alias_t, _Sender, _Env>;
-
-struct get_completion_signatures_t
-{
-    template <class _Sender, class _Env>
-    static auto __impl()
-    {
-        static_assert(sizeof(_Sender),
-                      "Incomplete type used with get_completion_signatures");
-        static_assert(sizeof(_Env),
-                      "Incomplete type used with get_completion_signatures");
-
-        // Compute the type of the transformed sender:
-        using _TfxSender = __tfx_sender<_Sender, _Env>;
-
-        if constexpr (__merror<_TfxSender>)
-        {
-            // Computing the type of the transformed sender returned an error
-            // type. Propagate it.
-            return static_cast<_TfxSender (*)()>(nullptr);
-        }
-        else if constexpr (__with_tag_invoke<_Sender, _Env>)
-        {
-            using _Result = tag_invoke_result_t<get_completion_signatures_t,
-                                                _TfxSender, _Env>;
-            return static_cast<_Result (*)()>(nullptr);
-        }
-        else if constexpr (__with_member_alias<_Sender, _Env>)
-        {
-            using _Result = __member_alias_t<_Sender, _Env>;
-            return static_cast<_Result (*)()>(nullptr);
-        }
-        else if constexpr (__awaitable<_Sender, __env::__promise<_Env>>)
-        {
-            using _AwaitResult =
-                __await_result_t<_Sender, __env::__promise<_Env>>;
-            using _Result = completion_signatures<
-                // set_value_t() or set_value_t(T)
-                __minvoke<__remove<void, __qf<set_value_t>>, _AwaitResult>,
-                set_error_t(std::exception_ptr), set_stopped_t()>;
-            return static_cast<_Result (*)()>(nullptr);
-        }
-        else if constexpr (__is_debug_env<_Env>)
-        {
-            using __tag_invoke::tag_invoke;
-            // This ought to cause a hard error that indicates where the problem
-            // is.
-            using _Completions [[maybe_unused]] =
-                tag_invoke_result_t<get_completion_signatures_t, _Sender, _Env>;
-            return static_cast<__debug::__completion_signatures (*)()>(nullptr);
-        }
-        else
-        {
-            using _Result =
-                __mexception<_UNRECOGNIZED_SENDER_TYPE_<>,
-                             _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
-            return static_cast<_Result (*)()>(nullptr);
-        }
-    }
-
-    // NOT TO SPEC: if we're unable to compute the completion signatures,
-    // return an error type instead of SFINAE.
-    template <class _Sender, class _Env = empty_env>
-    constexpr auto operator()(_Sender&&, const _Env&) const noexcept
-        -> decltype(__impl<_Sender, _Env>()())
-    {
-        return {};
-    }
-};
-} // namespace __get_completion_signatures
-
-using __get_completion_signatures::get_completion_signatures_t;
-inline constexpr get_completion_signatures_t get_completion_signatures{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders]
-struct sender_t
-{
-    using sender_concept = sender_t;
-};
-
-namespace __detail
-{
-template <class _Sender>
-concept __enable_sender =                     //
-    derived_from<typename _Sender::sender_concept, sender_t> ||
-    requires { typename _Sender::is_sender; } // NOT TO SPEC back compat
-    || __awaitable<_Sender, __env::__promise<empty_env>>;
-} // namespace __detail
-
-template <class _Sender>
-inline constexpr bool enable_sender = __detail::__enable_sender<_Sender>;
-
-template <class _Sender, class _Env = empty_env>
-concept sender = enable_sender<__decay_t<_Sender>> &&                  //
-                 environment_provider<__cref_t<_Sender>> &&            //
-                 __detail::__consistent_completion_domains<_Sender> && //
-                 move_constructible<__decay_t<_Sender>> &&             //
-                 constructible_from<__decay_t<_Sender>, _Sender>;
-
-template <class _Sender, class _Env = empty_env>
-concept sender_in =    //
-    sender<_Sender> && //
-    requires(_Sender&& __sndr, _Env&& __env) {
-        {
-            get_completion_signatures(static_cast<_Sender&&>(__sndr),
-                                      static_cast<_Env&&>(__env))
-        } -> __valid_completion_signatures;
-    };
-
-#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
-// __checked_completion_signatures is for catching logic bugs in a typed
-// sender's metadata. If sender<S> and sender_in<S, Ctx> are both true, then
-// they had better report the same metadata. This completion signatures wrapper
-// enforces that at compile time.
-template <class _Sender, class _Env>
-auto __checked_completion_signatures(_Sender&& __sndr,
-                                     const _Env& __env) noexcept
-{
-    using __completions_t = __completion_signatures_of_t<_Sender, _Env>;
-    stdexec::__debug_sender<__completions_t>(static_cast<_Sender&&>(__sndr),
-                                             __env);
-    return __completions_t{};
-}
-
-template <class _Sender, class _Env = empty_env>
-    requires sender_in<_Sender, _Env>
-using completion_signatures_of_t =
-    decltype(stdexec::__checked_completion_signatures(__declval<_Sender>(),
-                                                      __declval<_Env>()));
-#else
-template <class _Sender, class _Env = empty_env>
-    requires sender_in<_Sender, _Env>
-using completion_signatures_of_t = __completion_signatures_of_t<_Sender, _Env>;
-#endif
-
-struct __not_a_variant
-{
-    __not_a_variant() = delete;
-};
-template <class... _Ts>
-using __variant = //
-    __minvoke<__if_c<sizeof...(_Ts) != 0,
-                     __transform<__q<__decay_t>, __munique<__q<std::variant>>>,
-                     __mconst<__not_a_variant>>,
-              _Ts...>;
-
-using __nullable_variant_t =
-    __munique<__mbind_front_q<std::variant, std::monostate>>;
-
-template <class... _Ts>
-using __decayed_tuple = __meval<std::tuple, __decay_t<_Ts>...>;
-
-template <class _Tag, class _Tuple>
-struct __select_completions_for
-{
-    template <same_as<_Tag> _Tag2, class... _Args>
-    using __f = __minvoke<_Tag2, _Tuple, _Args...>;
-};
-
-template <class _Tuple>
-struct __invoke_completions
-{
-    template <class _Tag, class... _Args>
-    using __f = __minvoke<_Tag, _Tuple, _Args...>;
-};
-
-template <class _Tag, class _Tuple>
-using __select_completions_for_or = //
-    __with_default<__select_completions_for<_Tag, _Tuple>, __>;
-
-template <class _Tag, class _Completions>
-using __only_gather_signal = //
-    __compl_sigs::__maybe_for_all_sigs<
-        _Completions, __select_completions_for_or<_Tag, __qf<_Tag>>,
-        __remove<__, __q<completion_signatures>>>;
-
-template <class _Tag, class _Completions, class _Tuple, class _Variant>
-using __gather_signal = //
-    __compl_sigs::__maybe_for_all_sigs<__only_gather_signal<_Tag, _Completions>,
-                                       __invoke_completions<_Tuple>, _Variant>;
-
-template <class _Tag, class _Sender, class _Env, class _Tuple, class _Variant>
-using __gather_completions_for = //
-    __meval<                     //
-        __gather_signal, _Tag, __completion_signatures_of_t<_Sender, _Env>,
-        _Tuple, _Variant>;
-
-template <                               //
-    class _Sender,                       //
-    class _Env = empty_env,              //
-    class _Tuple = __q<__decayed_tuple>, //
-    class _Variant = __q<__variant>>
-using __try_value_types_of_t =           //
-    __gather_completions_for<set_value_t, _Sender, _Env, _Tuple, _Variant>;
-
-template <                               //
-    class _Sender,                       //
-    class _Env = empty_env,              //
-    class _Tuple = __q<__decayed_tuple>, //
-    class _Variant = __q<__variant>>
-    requires sender_in<_Sender, _Env>
-using __value_types_of_t = //
-    __msuccess_or_t<__try_value_types_of_t<_Sender, _Env, _Tuple, _Variant>>;
-
-template <class _Sender, class _Env = empty_env,
-          class _Variant = __q<__variant>>
-using __try_error_types_of_t =
-    __gather_completions_for<set_error_t, _Sender, _Env, __q<__midentity>,
-                             _Variant>;
-
-template <class _Sender, class _Env = empty_env,
-          class _Variant = __q<__variant>>
-    requires sender_in<_Sender, _Env>
-using __error_types_of_t =
-    __msuccess_or_t<__try_error_types_of_t<_Sender, _Env, _Variant>>;
-
-template <                                              //
-    class _Sender,                                      //
-    class _Env = empty_env,                             //
-    template <class...> class _Tuple = __decayed_tuple, //
-    template <class...> class _Variant = __variant>
-    requires sender_in<_Sender, _Env>
-using value_types_of_t =
-    __value_types_of_t<_Sender, _Env, __q<_Tuple>, __q<_Variant>>;
-
-template <class _Sender, class _Env = empty_env,
-          template <class...> class _Variant = __variant>
-    requires sender_in<_Sender, _Env>
-using error_types_of_t = __error_types_of_t<_Sender, _Env, __q<_Variant>>;
-
-template <class _Tag, class _Sender, class _Env = empty_env>
-using __try_count_of = //
-    __compl_sigs::__maybe_for_all_sigs<
-        __completion_signatures_of_t<_Sender, _Env>, __q<__mfront>,
-        __mcount<_Tag>>;
-
-template <class _Tag, class _Sender, class _Env = empty_env>
-    requires sender_in<_Sender, _Env>
-using __count_of = __msuccess_or_t<__try_count_of<_Tag, _Sender, _Env>>;
-
-template <class _Tag, class _Sender, class _Env = empty_env>
-    requires __mvalid<__count_of, _Tag, _Sender, _Env>
-inline constexpr bool __sends = (__v<__count_of<_Tag, _Sender, _Env>> != 0);
-
-template <class _Sender, class _Env = empty_env>
-    requires __mvalid<__count_of, set_stopped_t, _Sender, _Env>
-inline constexpr bool sends_stopped = __sends<set_stopped_t, _Sender, _Env>;
-
-template <class _Sender, class _Env = empty_env>
-using __single_sender_value_t =
-    __value_types_of_t<_Sender, _Env, __msingle_or<void>, __q<__msingle>>;
-
-template <class _Sender, class _Env = empty_env>
-using __single_value_variant_sender_t =
-    value_types_of_t<_Sender, _Env, __types, __msingle>;
-
-template <class _Sender, class _Env = empty_env>
-concept __single_typed_sender =
-    sender_in<_Sender, _Env> &&
-    __mvalid<__single_sender_value_t, _Sender, _Env>;
-
-template <class _Sender, class _Env = empty_env>
-concept __single_value_variant_sender =
-    sender_in<_Sender, _Env> &&
-    __mvalid<__single_value_variant_sender_t, _Sender, _Env>;
-
-template <class... Errs>
-using __nofail = __mbool<sizeof...(Errs) == 0>;
-
-template <class _Sender, class _Env = empty_env>
-concept __nofail_sender = sender_in<_Sender, _Env> &&
-                          (__v<error_types_of_t<_Sender, _Env, __nofail>>);
-
-/////////////////////////////////////////////////////////////////////////////
-namespace __compl_sigs
-{
-template <class... _Args>
-using __default_set_value = completion_signatures<set_value_t(_Args...)>;
-
-template <class _Error>
-using __default_set_error = completion_signatures<set_error_t(_Error)>;
-
-template <__valid_completion_signatures... _Sigs>
-using __ensure_concat_ =
-    __minvoke<__mconcat<__q<completion_signatures>>, _Sigs...>;
-
-template <class... _Sigs>
-using __ensure_concat = __mtry_eval<__ensure_concat_, _Sigs...>;
-
-template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr,
-          class _SetStp>
-using __compl_sigs_impl = //
-    __concat_completion_signatures_t<
-        _Sigs,
-        __mtry_eval<__try_value_types_of_t, _Sender, _Env, _SetVal,
-                    __q<__ensure_concat>>,
-        __mtry_eval<__try_error_types_of_t, _Sender, _Env,
-                    __transform<_SetErr, __q<__ensure_concat>>>,
-        __if<__try_count_of<set_stopped_t, _Sender, _Env>, _SetStp,
-             completion_signatures<>>>;
-
-template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr,
-          class _SetStp>
-    requires __mvalid<__compl_sigs_impl, _Sender, _Env, _Sigs, _SetVal, _SetErr,
-                      _SetStp>
-extern __compl_sigs_impl<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>
-    __compl_sigs_v;
-
-template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr,
-          class _SetStp>
-using __compl_sigs_t =
-    decltype(__compl_sigs_v<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>);
-
-template <                                                      //
-    class _Sender,                                              //
-    class _Env = empty_env,                                     //
-    class _Sigs = completion_signatures<>,                      //
-    class _SetValue = __q<__default_set_value>,                 //
-    class _SetError = __q<__default_set_error>,                 //
-    class _SetStopped = completion_signatures<set_stopped_t()>> //
-using __try_make_completion_signatures =                        //
-    __meval<__compl_sigs_t, _Sender, _Env, _Sigs, _SetValue, _SetError,
-            _SetStopped>;
-} // namespace __compl_sigs
-
-using __compl_sigs::__try_make_completion_signatures;
-
-/////////////////////////////////////////////////////////////////////////////
-// NOT TO SPEC
-//
-// make_completion_signatures
-// ==========================
-//
-// `make_completion_signatures` takes a sender, and environment, and a bunch
-// of other template arguments for munging the completion signatures of a
-// sender in interesting ways.
-//
-//  ```c++
-//  template <class... Args>
-//    using __default_set_value = completion_signatures<set_value_t(Args...)>;
-//
-//  template <class Err>
-//    using __default_set_error = completion_signatures<set_error_t(Err)>;
-//
-//  template <
-//    sender Sndr,
-//    class Env = empty_env,
-//    class AddlSigs = completion_signatures<>,
-//    template <class...> class SetValue = __default_set_value,
-//    template <class> class SetError = __default_set_error,
-//    class SetStopped = completion_signatures<set_stopped_t()>>
-//      requires sender_in<Sndr, Env>
-//  using make_completion_signatures =
-//    completion_signatures< ... >;
-//  ```
-//
-//  * `SetValue` : an alias template that accepts a set of value types and
-//    returns an instance of `completion_signatures`.
-//  * `SetError` : an alias template that accepts an error types and returns a
-//    an instance of `completion_signatures`.
-//  * `SetStopped` : an instantiation of `completion_signatures` with a list
-//    of completion signatures `Sigs...` to the added to the list if the
-//    sender can complete with a stopped signal.
-//  * `AddlSigs` : an instantiation of `completion_signatures` with a list of
-//    completion signatures `Sigs...` to the added to the list
-//    unconditionally.
-//
-//  `make_completion_signatures` does the following:
-//  * Let `VCs...` be a pack of the `completion_signatures` types in the
-//    `__typelist` named by `value_types_of_t<Sndr, Env, SetValue,
-//    __typelist>`, and let `Vs...` be the concatenation of the packs that are
-//    template arguments to each `completion_signature` in `VCs...`.
-//  * Let `ECs...` be a pack of the `completion_signatures` types in the
-//    `__typelist` named by `error_types_of_t<Sndr, Env, __errorlist>`, where
-//    `__errorlist` is an alias template such that `__errorlist<Ts...>` names
-//    `__typelist<SetError<Ts>...>`, and let `Es...` by the concatenation of
-//    the packs that are the template arguments to each `completion_signature`
-//    in `ECs...`.
-//  * Let `Ss...` be an empty pack if `sends_stopped<Sndr, Env>` is
-//    `false`; otherwise, a pack containing the template arguments of the
-//    `completion_signatures` instantiation named by `SetStopped`.
-//  * Let `MoreSigs...` be a pack of the template arguments of the
-//    `completion_signatures` instantiation named by `AddlSigs`.
-//
-//  Then `make_completion_signatures<Sndr, Env, AddlSigs, SetValue, SetError,
-//  SendsStopped>` names the type `completion_signatures< Sigs... >` where
-//  `Sigs...` is the unique set of types in `[Vs..., Es..., Ss...,
-//  MoreSigs...]`.
-//
-//  If any of the above type computations are ill-formed,
-//  `make_completion_signatures<Sndr, Env, AddlSigs, SetValue, SetError,
-//  SendsStopped>` is an alias for an empty struct
-template <                                                                   //
-    class _Sender,                                                           //
-    class _Env = empty_env,                                                  //
-    __valid_completion_signatures _Sigs = completion_signatures<>,           //
-    template <class...> class _SetValue = __compl_sigs::__default_set_value, //
-    template <class> class _SetError = __compl_sigs::__default_set_error,    //
-    __valid_completion_signatures _SetStopped =
-        completion_signatures<set_stopped_t()>>
-    requires sender_in<_Sender, _Env>
-using make_completion_signatures = //
-    __msuccess_or_t<               //
-        __try_make_completion_signatures<_Sender, _Env, _Sigs, __q<_SetValue>,
-                                         __q<_SetError>, _SetStopped>>;
-
-// Needed fairly often
-using __with_exception_ptr =
-    completion_signatures<set_error_t(std::exception_ptr)>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.schedule]
-namespace __schedule
-{
-struct schedule_t
-{
-    template <class _Scheduler>
-        requires tag_invocable<schedule_t, _Scheduler>
-    STDEXEC_ATTRIBUTE((host, device)) auto
-        operator()(_Scheduler&& __sched) const
-        noexcept(nothrow_tag_invocable<schedule_t, _Scheduler>)
-    {
-        static_assert(sender<tag_invoke_result_t<schedule_t, _Scheduler>>);
-        return tag_invoke(schedule_t{}, static_cast<_Scheduler&&>(__sched));
-    }
-
-    friend constexpr auto tag_invoke(forwarding_query_t, schedule_t) -> bool
-    {
-        return false;
-    }
-};
-} // namespace __schedule
-
-using __schedule::schedule_t;
-inline constexpr schedule_t schedule{};
-
-// NOT TO SPEC
-template <class _Tag, const auto& _Predicate>
-concept tag_category = //
-    requires {
-        typename __mbool<bool{_Predicate(_Tag{})}>;
-        requires bool {
-            _Predicate(_Tag{})
-        };
-    };
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.schedulers]
-template <class _Scheduler>
-concept __has_schedule = //
-    requires(_Scheduler&& __sched) {
-        {
-            schedule(static_cast<_Scheduler&&>(__sched))
-        } -> sender;
-    };
-
-template <class _Scheduler>
-concept __sender_has_completion_scheduler =
-    requires(_Scheduler&& __sched,
-             get_completion_scheduler_t<set_value_t>&& __tag) {
-        {
-            tag_invoke(std::move(__tag),
-                       get_env(schedule(static_cast<_Scheduler&&>(__sched))))
-        } -> same_as<__decay_t<_Scheduler>>;
-    };
-
-template <class _Scheduler>
-concept scheduler =                                  //
-    __has_schedule<_Scheduler> &&                    //
-    __sender_has_completion_scheduler<_Scheduler> && //
-    equality_comparable<__decay_t<_Scheduler>> &&    //
-    copy_constructible<__decay_t<_Scheduler>>;
-
-template <scheduler _Scheduler>
-using schedule_result_t = __call_result_t<schedule_t, _Scheduler>;
-
-template <receiver _Receiver>
-using __current_scheduler_t =
-    __call_result_t<get_scheduler_t, env_of_t<_Receiver>>;
-
-template <class _SchedulerProvider>
-concept __scheduler_provider = //
-    requires(const _SchedulerProvider& __sp) {
-        {
-            get_scheduler(__sp)
-        } -> scheduler;
-    };
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.op_state]
-namespace __start
-{
-struct start_t
-{
-    template <class _Op>
-        requires tag_invocable<start_t, _Op&>
-    STDEXEC_ATTRIBUTE((always_inline)) void operator()(_Op& __op) const noexcept
-    {
-        static_assert(nothrow_tag_invocable<start_t, _Op&>);
-        (void)tag_invoke(start_t{}, __op);
-    }
-};
-} // namespace __start
-
-using __start::start_t;
-inline constexpr start_t start{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.op_state]
-template <class _Op>
-concept operation_state =    //
-    destructible<_Op> &&     //
-    std::is_object_v<_Op> && //
-    requires(_Op& __op) {    //
-        start(__op);
-    };
-
-#if !STDEXEC_STD_NO_COROUTINES_
-/////////////////////////////////////////////////////////////////////////////
-// __connect_awaitable_
-namespace __connect_awaitable_
-{
-struct __promise_base
-{
-    auto initial_suspend() noexcept -> __coro::suspend_always
-    {
-        return {};
-    }
-
-    [[noreturn]] auto final_suspend() noexcept -> __coro::suspend_always
-    {
-        std::terminate();
-    }
-
-    [[noreturn]] void unhandled_exception() noexcept
-    {
-        std::terminate();
-    }
-
-    [[noreturn]] void return_void() noexcept
-    {
-        std::terminate();
-    }
-};
-
-struct __operation_base
-{
-    __coro::coroutine_handle<> __coro_;
-
-    explicit __operation_base(__coro::coroutine_handle<> __hcoro) noexcept :
-        __coro_(__hcoro)
-    {}
-
-    __operation_base(__operation_base&& __other) noexcept :
-        __coro_(std::exchange(__other.__coro_, {}))
-    {}
-
-    ~__operation_base()
-    {
-        if (__coro_)
-        {
-#if STDEXEC_MSVC()
-            // MSVCBUG
-            // https://developercommunity.visualstudio.com/t/Double-destroy-of-a-local-in-coroutine-d/10456428
-
-            // Reassign __coro_ before calling destroy to make the mutation
-            // observable and to hopefully ensure that the compiler does not
-            // eliminate it.
-            auto __coro = __coro_;
-            __coro_ = {};
-            __coro.destroy();
-#else
-            __coro_.destroy();
-#endif
-        }
-    }
-
-    friend void tag_invoke(start_t, __operation_base& __self) noexcept
-    {
-        __self.__coro_.resume();
-    }
-};
-
-template <class _ReceiverId>
-struct __promise;
-
-template <class _ReceiverId>
-struct __operation
-{
-    struct __t : __operation_base
-    {
-        using promise_type = stdexec::__t<__promise<_ReceiverId>>;
-        using __operation_base::__operation_base;
-    };
-};
-
-template <class _ReceiverId>
-struct __promise
-{
-    using _Receiver = stdexec::__t<_ReceiverId>;
-
-    struct __t : __promise_base
-    {
-        using __id = __promise;
-
-        explicit __t(auto&, _Receiver& __rcvr) noexcept : __rcvr_(__rcvr) {}
-
-        auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>
-        {
-            set_stopped(static_cast<_Receiver&&>(__rcvr_));
-            // Returning noop_coroutine here causes the __connect_awaitable
-            // coroutine to never resume past the point where it co_await's
-            // the awaitable.
-            return __coro::noop_coroutine();
-        }
-
-        auto get_return_object() noexcept
-            -> stdexec::__t<__operation<_ReceiverId>>
-        {
-            return stdexec::__t<__operation<_ReceiverId>>{
-                __coro::coroutine_handle<__t>::from_promise(*this)};
-        }
-
-        template <class _Awaitable>
-        auto await_transform(_Awaitable&& __awaitable) noexcept -> _Awaitable&&
-        {
-            return static_cast<_Awaitable&&>(__awaitable);
-        }
-
-        template <class _Awaitable>
-            requires tag_invocable<as_awaitable_t, _Awaitable, __t&>
-        auto await_transform(_Awaitable&& __awaitable) //
-            noexcept(nothrow_tag_invocable<as_awaitable_t, _Awaitable, __t&>)
-                -> tag_invoke_result_t<as_awaitable_t, _Awaitable, __t&>
-        {
-            return tag_invoke(as_awaitable,
-                              static_cast<_Awaitable&&>(__awaitable), *this);
-        }
-
-        // Pass through the get_env receiver query
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<_Receiver>
-        {
-            return get_env(__self.__rcvr_);
-        }
-
-        _Receiver& __rcvr_;
-    };
-};
-
-template <receiver _Receiver>
-using __promise_t = __t<__promise<__id<_Receiver>>>;
-
-template <receiver _Receiver>
-using __operation_t = __t<__operation<__id<_Receiver>>>;
-
-struct __connect_awaitable_t
-{
-  private:
-    template <class _Fun, class... _Ts>
-    static auto __co_call(_Fun __fun, _Ts&&... __as) noexcept
-    {
-        auto __fn = [&, __fun]() noexcept {
-            __fun(static_cast<_Ts&&>(__as)...);
-        };
-
-        struct __awaiter
-        {
-            decltype(__fn) __fn_;
-
-            static constexpr auto await_ready() noexcept -> bool
-            {
-                return false;
-            }
-
-            void await_suspend(__coro::coroutine_handle<>) noexcept
-            {
-                __fn_();
-            }
-
-            [[noreturn]] void await_resume() noexcept
-            {
-                std::terminate();
-            }
-        };
-
-        return __awaiter{__fn};
-    }
-
-    template <class _Awaitable, class _Receiver>
-#if STDEXEC_GCC() && (__GNUC__ > 11)
-    __attribute__((__used__))
-#endif
-    static auto
-        __co_impl(_Awaitable __awaitable, _Receiver __rcvr)
-            -> __operation_t<_Receiver>
-    {
-        using __result_t = __await_result_t<_Awaitable, __promise_t<_Receiver>>;
-        std::exception_ptr __eptr;
-        try
-        {
-            if constexpr (same_as<__result_t, void>)
-                co_await (
-                    co_await static_cast<_Awaitable&&>(__awaitable),
-                    __co_call(set_value, static_cast<_Receiver&&>(__rcvr)));
-            else
-                co_await __co_call(
-                    set_value, static_cast<_Receiver&&>(__rcvr),
-                    co_await static_cast<_Awaitable&&>(__awaitable));
-        }
-        catch (...)
-        {
-            __eptr = std::current_exception();
-        }
-        co_await __co_call(set_error, static_cast<_Receiver&&>(__rcvr),
-                           static_cast<std::exception_ptr&&>(__eptr));
-    }
-
-    template <receiver _Receiver, class _Awaitable>
-    using __completions_t = //
-        completion_signatures<
-            __minvoke<      // set_value_t() or set_value_t(T)
-                __remove<void, __qf<set_value_t>>,
-                __await_result_t<_Awaitable, __promise_t<_Receiver>>>,
-            set_error_t(std::exception_ptr), set_stopped_t()>;
-
-  public:
-    template <class _Receiver, __awaitable<__promise_t<_Receiver>> _Awaitable>
-        requires receiver_of<_Receiver, __completions_t<_Receiver, _Awaitable>>
-    auto operator()(_Awaitable&& __awaitable, _Receiver __rcvr) const
-        -> __operation_t<_Receiver>
-    {
-        return __co_impl(static_cast<_Awaitable&&>(__awaitable),
-                         static_cast<_Receiver&&>(__rcvr));
-    }
-};
-} // namespace __connect_awaitable_
-
-using __connect_awaitable_::__connect_awaitable_t;
-#else
-struct __connect_awaitable_t
-{};
-#endif
-inline constexpr __connect_awaitable_t __connect_awaitable{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.connect]
-namespace __connect
-{
-struct connect_t;
-
-template <class _Sender, class _Receiver>
-using __tfx_sender = //
-    transform_sender_result_t<__late_domain_of_t<_Sender, env_of_t<_Receiver&>>,
-                              _Sender, env_of_t<_Receiver&>>;
-
-template <class _Sender, class _Receiver>
-concept __connectable_with_tag_invoke_ =       //
-    receiver<_Receiver> &&                     //
-    sender_in<_Sender, env_of_t<_Receiver>> && //
-    __receiver_from<_Receiver, _Sender> &&     //
-    tag_invocable<connect_t, _Sender, _Receiver>;
-
-template <class _Sender, class _Receiver>
-concept __connectable_with_tag_invoke = //
-    __connectable_with_tag_invoke_<__tfx_sender<_Sender, _Receiver>, _Receiver>;
-
-template <class _Sender, class _Receiver>
-concept __connectable_with_co_await = //
-    __callable<__connect_awaitable_t, __tfx_sender<_Sender, _Receiver>,
-               _Receiver>;
-
-struct connect_t
-{
-    template <class _Sender, class _Env>
-    static constexpr auto __check_signatures() -> bool
-    {
-        if constexpr (sender_in<_Sender, _Env>)
-        {
-            // Instantiate __debug_sender via completion_signatures_of_t
-            // to check that the actual completions match the expected
-            // completions.
-            //
-            // Instantiate completion_signatures_of_t only if sender_in
-            // is true to workaround Clang not implementing CWG#2369 yet
-            // (connect() does have a constraint for _Sender satisfying
-            // sender_in).
-            using __checked_signatures
-                [[maybe_unused]] = completion_signatures_of_t<_Sender, _Env>;
-        }
-        return true;
-    }
-
-    template <class _Sender, class _Receiver>
-    static constexpr auto __select_impl() noexcept
-    {
-        using _Domain = __late_domain_of_t<_Sender, env_of_t<_Receiver&>>;
-        constexpr bool _NothrowTfxSender =
-            __nothrow_callable<get_env_t, _Receiver&> &&
-            __nothrow_callable<transform_sender_t, _Domain, _Sender,
-                               env_of_t<_Receiver&>>;
-        using _TfxSender = __tfx_sender<_Sender, _Receiver&>;
-
-#if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING()
-        static_assert(__check_signatures<_TfxSender, env_of_t<_Receiver>>());
-#endif
-
-        if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>)
-        {
-            using _Result =
-                tag_invoke_result_t<connect_t, _TfxSender, _Receiver>;
-            constexpr bool _Nothrow = //
-                _NothrowTfxSender &&
-                nothrow_tag_invocable<connect_t, _TfxSender, _Receiver>;
-            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
-        }
-        else if constexpr (__connectable_with_co_await<_Sender, _Receiver>)
-        {
-            using _Result =
-                __call_result_t<__connect_awaitable_t, _TfxSender, _Receiver>;
-            return static_cast<_Result (*)()>(nullptr);
-        }
-        else
-        {
-            using _Result = __debug::__debug_operation;
-            return static_cast<_Result (*)() noexcept(_NothrowTfxSender)>(
-                nullptr);
-        }
-    }
-
-    template <class _Sender, class _Receiver>
-    using __select_impl_t = decltype(__select_impl<_Sender, _Receiver>());
-
-    template <sender _Sender, receiver _Receiver>
-        requires __connectable_with_tag_invoke<_Sender, _Receiver> ||
-                 __connectable_with_co_await<_Sender, _Receiver> ||
-                 __is_debug_env<env_of_t<_Receiver>>
-    auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
-        noexcept(__nothrow_callable<__select_impl_t<_Sender, _Receiver>>)
-            -> __call_result_t<__select_impl_t<_Sender, _Receiver>>
-    {
-        using _TfxSender = __tfx_sender<_Sender, _Receiver&>;
-        auto&& __env = get_env(__rcvr);
-        auto __domain = __get_late_domain(__sndr, __env);
-
-        if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>)
-        {
-            static_assert(
-                operation_state<
-                    tag_invoke_result_t<connect_t, _TfxSender, _Receiver>>,
-                "stdexec::connect(sender, receiver) must return a type that "
-                "satisfies the operation_state concept");
-            return tag_invoke(connect_t{},
-                              transform_sender(__domain,
-                                               static_cast<_Sender&&>(__sndr),
-                                               __env),
-                              static_cast<_Receiver&&>(__rcvr));
-        }
-        else if constexpr (__connectable_with_co_await<_Sender, _Receiver>)
-        {
-            return __connect_awaitable( //
-                transform_sender(__domain, static_cast<_Sender&&>(__sndr),
-                                 __env),
-                static_cast<_Receiver&&>(__rcvr));
-        }
-        else
-        {
-            // This should generate an instantiation backtrace that contains
-            // useful debugging information.
-            using __tag_invoke::tag_invoke;
-            tag_invoke(*this,
-                       transform_sender(__domain,
-                                        static_cast<_Sender&&>(__sndr), __env),
-                       static_cast<_Receiver&&>(__rcvr));
-        }
-    }
-
-    friend constexpr auto tag_invoke(forwarding_query_t, connect_t) noexcept
-        -> bool
-    {
-        return false;
-    }
-};
-} // namespace __connect
-
-using __connect::connect_t;
-inline constexpr __connect::connect_t connect{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [exec.snd]
-template <class _Sender, class _Receiver>
-concept sender_to = receiver<_Receiver> &&                     //
-                    sender_in<_Sender, env_of_t<_Receiver>> && //
-                    __receiver_from<_Receiver, _Sender> &&     //
-                    requires(_Sender&& __sndr, _Receiver&& __rcvr) {
-                        connect(static_cast<_Sender&&>(__sndr),
-                                static_cast<_Receiver&&>(__rcvr));
-                    };
-
-template <class _Tag, class... _Args>
-auto __tag_of_sig_(_Tag (*)(_Args...)) -> _Tag;
-template <class _Sig>
-using __tag_of_sig_t =
-    decltype(stdexec::__tag_of_sig_(static_cast<_Sig*>(nullptr)));
-
-template <class _Sender, class _SetSig, class _Env = empty_env>
-concept sender_of =
-    sender_in<_Sender, _Env> &&
-    same_as<__types<_SetSig>, __gather_completions_for<
-                                  __tag_of_sig_t<_SetSig>, _Sender, _Env,
-                                  __qf<__tag_of_sig_t<_SetSig>>, __q<__types>>>;
-
-#if !STDEXEC_STD_NO_COROUTINES_
-/////////////////////////////////////////////////////////////////////////////
-// stdexec::as_awaitable [execution.coro_utils.as_awaitable]
-namespace __as_awaitable
-{
-struct __void
-{};
-template <class _Value>
-using __value_or_void_t = __if<std::is_same<_Value, void>, __void, _Value>;
-template <class _Value>
-using __expected_t =
-    std::variant<std::monostate, __value_or_void_t<_Value>, std::exception_ptr>;
-
-template <class _Value>
-struct __receiver_base
-{
-    using receiver_concept = receiver_t;
-
-    template <same_as<set_value_t> _Tag, class... _Us>
-        requires constructible_from<__value_or_void_t<_Value>, _Us...>
-    friend void tag_invoke(_Tag, __receiver_base&& __self,
-                           _Us&&... __us) noexcept
-    {
-        try
-        {
-            __self.__result_->template emplace<1>(static_cast<_Us&&>(__us)...);
-            __self.__continuation_.resume();
-        }
-        catch (...)
-        {
-            set_error(static_cast<__receiver_base&&>(__self),
-                      std::current_exception());
-        }
-    }
-
-    template <same_as<set_error_t> _Tag, class _Error>
-    friend void tag_invoke(_Tag, __receiver_base&& __self,
-                           _Error&& __err) noexcept
-    {
-        if constexpr (__decays_to<_Error, std::exception_ptr>)
-            __self.__result_->template emplace<2>(static_cast<_Error&&>(__err));
-        else if constexpr (__decays_to<_Error, std::error_code>)
-            __self.__result_->template emplace<2>(
-                std::make_exception_ptr(std::system_error(__err)));
-        else
-            __self.__result_->template emplace<2>(
-                std::make_exception_ptr(static_cast<_Error&&>(__err)));
-        __self.__continuation_.resume();
-    }
-
-    __expected_t<_Value>* __result_;
-    __coro::coroutine_handle<> __continuation_;
-};
-
-template <class _PromiseId, class _Value>
-struct __receiver
-{
-    using _Promise = stdexec::__t<_PromiseId>;
-
-    struct __t : __receiver_base<_Value>
-    {
-        using __id = __receiver;
-
-        template <same_as<set_stopped_t> _Tag>
-        friend void tag_invoke(_Tag, __t&& __self) noexcept
-        {
-            auto __continuation =
-                __coro::coroutine_handle<_Promise>::from_address(
-                    __self.__continuation_.address());
-            __coro::coroutine_handle<> __stopped_continuation =
-                __continuation.promise().unhandled_stopped();
-            __stopped_continuation.resume();
-        }
-
-        // Forward get_env query to the coroutine promise
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> env_of_t<_Promise&>
-        {
-            auto __continuation =
-                __coro::coroutine_handle<_Promise>::from_address(
-                    __self.__continuation_.address());
-            return get_env(__continuation.promise());
-        }
-    };
-};
-
-// BUGBUG NOT TO SPEC: make senders of more-than-one-value awaitable
-// by packaging the values into a tuple.
-// See: https://github.com/cplusplus/sender-receiver/issues/182
-template <std::size_t _Count>
-extern const __q<__decayed_tuple> __as_single;
-
-template <>
-inline const __q<__midentity> __as_single<1>;
-
-template <>
-inline const __mconst<void> __as_single<0>;
-
-template <class... _Values>
-using __single_value =
-    __minvoke<decltype(__as_single<sizeof...(_Values)>), _Values...>;
-
-template <class _Sender, class _Promise>
-using __value_t =
-    __decay_t<__value_types_of_t<_Sender, env_of_t<_Promise&>,
-                                 __q<__single_value>, __msingle_or<void>>>;
-
-template <class _Sender, class _Promise>
-using __receiver_t =
-    __t<__receiver<__id<_Promise>, __value_t<_Sender, _Promise>>>;
-
-template <class _Value>
-struct __sender_awaitable_base
-{
-    [[nodiscard]] auto await_ready() const noexcept -> bool
-    {
-        return false;
-    }
-
-    auto await_resume() -> _Value
-    {
-        switch (__result_.index())
-        {
-            case 0: // receiver contract not satisfied
-                STDEXEC_ASSERT(!"_Should never get here");
-                break;
-            case 1: // set_value
-                if constexpr (!std::is_void_v<_Value>)
-                    return static_cast<_Value&&>(std::get<1>(__result_));
-                else
-                    return;
-            case 2: // set_error
-                std::rethrow_exception(std::get<2>(__result_));
-        }
-        std::terminate();
-    }
-
-  protected:
-    __expected_t<_Value> __result_;
-};
-
-template <class _PromiseId, class _SenderId>
-struct __sender_awaitable
-{
-    using _Promise = stdexec::__t<_PromiseId>;
-    using _Sender = stdexec::__t<_SenderId>;
-    using __value = __value_t<_Sender, _Promise>;
-
-    struct __t : __sender_awaitable_base<__value>
-    {
-        __t(_Sender&& sndr, __coro::coroutine_handle<_Promise> __hcoro) //
-            noexcept(__nothrow_connectable<_Sender, __receiver>) :
-            __op_state_(connect(static_cast<_Sender&&>(sndr),
-                                __receiver{{&this->__result_, __hcoro}}))
-        {}
-
-        void await_suspend(__coro::coroutine_handle<_Promise>) noexcept
-        {
-            start(__op_state_);
-        }
-
-      private:
-        using __receiver = __receiver_t<_Sender, _Promise>;
-        connect_result_t<_Sender, __receiver> __op_state_;
-    };
-};
-
-template <class _Promise, class _Sender>
-using __sender_awaitable_t =
-    __t<__sender_awaitable<__id<_Promise>, __id<_Sender>>>;
-
-template <class _Sender, class _Promise>
-concept __awaitable_sender =
-    sender_in<_Sender, env_of_t<_Promise&>> &&             //
-    __mvalid<__value_t, _Sender, _Promise> &&              //
-    sender_to<_Sender, __receiver_t<_Sender, _Promise>> && //
-    requires(_Promise& __promise) {
-        {
-            __promise.unhandled_stopped()
-        } -> convertible_to<__coro::coroutine_handle<>>;
-    };
-
-struct __unspecified
-{
-    auto get_return_object() noexcept -> __unspecified;
-    auto initial_suspend() noexcept -> __unspecified;
-    auto final_suspend() noexcept -> __unspecified;
-    void unhandled_exception() noexcept;
-    void return_void() noexcept;
-    auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>;
-};
-
-struct as_awaitable_t
-{
-    template <class _Tp, class _Promise>
-    static constexpr auto __select_impl_() noexcept
-    {
-        if constexpr (tag_invocable<as_awaitable_t, _Tp, _Promise&>)
-        {
-            using _Result = tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
-            constexpr bool _Nothrow =
-                nothrow_tag_invocable<as_awaitable_t, _Tp, _Promise&>;
-            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
-            // NOLINTNEXTLINE(bugprone-branch-clone)
-        }
-        else if constexpr (__awaitable<_Tp, __unspecified>)
-        { // NOT __awaitable<_Tp, _Promise> !!
-            using _Result = _Tp&&;
-            return static_cast<_Result (*)() noexcept>(nullptr);
-        }
-        else if constexpr (__awaitable_sender<_Tp, _Promise>)
-        {
-            using _Result = __sender_awaitable_t<_Promise, _Tp>;
-            constexpr bool _Nothrow = __nothrow_constructible_from<
-                _Result, _Tp, __coro::coroutine_handle<_Promise>>;
-            return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
-        }
-        else
-        {
-            using _Result = _Tp&&;
-            return static_cast<_Result (*)() noexcept>(nullptr);
-        }
-    }
-    template <class _Tp, class _Promise>
-    using __select_impl_t = decltype(__select_impl_<_Tp, _Promise>());
-
-    template <class _Tp, class _Promise>
-    auto operator()(_Tp&& __t, _Promise& __promise) const
-        noexcept(__nothrow_callable<__select_impl_t<_Tp, _Promise>>)
-            -> __call_result_t<__select_impl_t<_Tp, _Promise>>
-    {
-        if constexpr (tag_invocable<as_awaitable_t, _Tp, _Promise&>)
-        {
-            using _Result = tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
-            static_assert(__awaitable<_Result, _Promise>);
-            return tag_invoke(*this, static_cast<_Tp&&>(__t), __promise);
-            // NOLINTNEXTLINE(bugprone-branch-clone)
-        }
-        else if constexpr (__awaitable<_Tp, __unspecified>)
-        { // NOT __awaitable<_Tp, _Promise> !!
-            return static_cast<_Tp&&>(__t);
-        }
-        else if constexpr (__awaitable_sender<_Tp, _Promise>)
-        {
-            auto __hcoro =
-                __coro::coroutine_handle<_Promise>::from_promise(__promise);
-            return __sender_awaitable_t<_Promise, _Tp>{static_cast<_Tp&&>(__t),
-                                                       __hcoro};
-        }
-        else
-        {
-            return static_cast<_Tp&&>(__t);
-        }
-    }
-};
-} // namespace __as_awaitable
-
-using __as_awaitable::as_awaitable_t;
-inline constexpr as_awaitable_t as_awaitable{};
-
-namespace __with_awaitable_senders
-{
-
-template <class _Promise = void>
-class __continuation_handle;
-
-template <>
-class __continuation_handle<void>
-{
-  public:
-    __continuation_handle() = default;
-
-    template <class _Promise>
-    __continuation_handle(__coro::coroutine_handle<_Promise> __coro) noexcept :
-        __coro_(__coro)
-    {
-        if constexpr (requires(_Promise& __promise) {
-                          __promise.unhandled_stopped();
-                      })
-        {
-            __stopped_callback_ =
-                [](void* __address) noexcept -> __coro::coroutine_handle<> {
-                // This causes the rest of the coroutine (the part after the
-                // co_await of the sender) to be skipped and invokes the calling
-                // coroutine's stopped handler.
-                return __coro::coroutine_handle<_Promise>::from_address(
-                           __address)
-                    .promise()
-                    .unhandled_stopped();
-            };
-        }
-        // If _Promise doesn't implement unhandled_stopped(), then if a
-        // "stopped" unwind reaches this point, it's considered an unhandled
-        // exception and terminate() is called.
-    }
-
-    [[nodiscard]] auto handle() const noexcept -> __coro::coroutine_handle<>
-    {
-        return __coro_;
-    }
-
-    [[nodiscard]] auto unhandled_stopped() const noexcept
-        -> __coro::coroutine_handle<>
-    {
-        return __stopped_callback_(__coro_.address());
-    }
-
-  private:
-    __coro::coroutine_handle<> __coro_{};
-    using __stopped_callback_t = __coro::coroutine_handle<> (*)(void*) noexcept;
-    __stopped_callback_t __stopped_callback_ =
-        [](void*) noexcept -> __coro::coroutine_handle<> { std::terminate(); };
-};
-
-template <class _Promise>
-class __continuation_handle
-{
-  public:
-    __continuation_handle() = default;
-
-    __continuation_handle(__coro::coroutine_handle<_Promise> __coro) noexcept :
-        __continuation_{__coro}
-    {}
-
-    auto handle() const noexcept -> __coro::coroutine_handle<_Promise>
-    {
-        return __coro::coroutine_handle<_Promise>::from_address(
-            __continuation_.handle().address());
-    }
-
-    [[nodiscard]] auto unhandled_stopped() const noexcept
-        -> __coro::coroutine_handle<>
-    {
-        return __continuation_.unhandled_stopped();
-    }
-
-  private:
-    __continuation_handle<> __continuation_{};
-};
-
-struct __with_awaitable_senders_base
-{
-    template <class _OtherPromise>
-    void set_continuation(
-        __coro::coroutine_handle<_OtherPromise> __hcoro) noexcept
-    {
-        static_assert(!std::is_void_v<_OtherPromise>);
-        __continuation_ = __hcoro;
-    }
-
-    void set_continuation(__continuation_handle<> __continuation) noexcept
-    {
-        __continuation_ = __continuation;
-    }
-
-    [[nodiscard]] auto continuation() const noexcept -> __continuation_handle<>
-    {
-        return __continuation_;
-    }
-
-    auto unhandled_stopped() noexcept -> __coro::coroutine_handle<>
-    {
-        return __continuation_.unhandled_stopped();
-    }
-
-  private:
-    __continuation_handle<> __continuation_{};
-};
-
-template <class _Promise>
-struct with_awaitable_senders : __with_awaitable_senders_base
-{
-    template <class _Value>
-    auto await_transform(_Value&& __val)
-        -> __call_result_t<as_awaitable_t, _Value, _Promise&>
-    {
-        static_assert(derived_from<_Promise, with_awaitable_senders>);
-        return as_awaitable(static_cast<_Value&&>(__val),
-                            static_cast<_Promise&>(*this));
-    }
-};
-} // namespace __with_awaitable_senders
-
-using __with_awaitable_senders::__continuation_handle;
-using __with_awaitable_senders::with_awaitable_senders;
-#endif
-
-namespace
-{
-inline constexpr auto __ref = []<class _Ty>(_Ty& __ty) noexcept {
-    return [__ty = &__ty]() noexcept -> decltype(auto) { return (*__ty); };
-};
-} // namespace
-
-template <class _Ty>
-using __ref_t = decltype(__ref(__declval<_Ty&>()));
-
-/////////////////////////////////////////////////////////////////////////////
-// NOT TO SPEC: __submit
-namespace __submit_
-{
-template <class _OpRef>
-struct __receiver
-{
-    using receiver_concept = receiver_t;
-    using __t = __receiver;
-    using __id = __receiver;
-
-    using _Operation = __decay_t<__call_result_t<_OpRef>>;
-    using _Receiver = stdexec::__t<__mapply<__q<__msecond>, _Operation>>;
-
-    _OpRef __opref_;
-
-    // Forward all the receiver ops, and delete the operation state.
-    template <__completion_tag _Tag, class... _As>
-        requires __callable<_Tag, _Receiver, _As...>
-    friend void tag_invoke(_Tag __tag, __receiver&& __self,
-                           _As&&... __as) noexcept
-    {
-        __tag(static_cast<_Receiver&&>(__self.__opref_().__rcvr_),
-              static_cast<_As&&>(__as)...);
-        __self.__delete_op();
-    }
-
-    void __delete_op() noexcept
-    {
-        _Operation* __op = &__opref_();
-        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
-        {
-            auto&& __env = get_env(__op->__rcvr_);
-            auto __alloc = get_allocator(__env);
-            using _Alloc = decltype(__alloc);
-            using _OpAlloc = typename std::allocator_traits<
-                _Alloc>::template rebind_alloc<_Operation>;
-            _OpAlloc __op_alloc{__alloc};
-            std::allocator_traits<_OpAlloc>::destroy(__op_alloc, __op);
-            std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op, 1);
-        }
-        else
-        {
-            delete __op;
-        }
-    }
-
-    // Forward all receiver queries.
-    friend auto tag_invoke(get_env_t, const __receiver& __self) noexcept
-        -> env_of_t<_Receiver&>
-    {
-        return get_env(__self.__opref_().__rcvr_);
-    }
-};
-
-template <class _SenderId, class _ReceiverId>
-struct __operation
-{
-    using _Sender = stdexec::__t<_SenderId>;
-    using _Receiver = stdexec::__t<_ReceiverId>;
-    using __receiver_t = __receiver<__ref_t<__operation>>;
-
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _Receiver __rcvr_;
-    connect_result_t<_Sender, __receiver_t> __op_state_;
-
-    __operation(_Sender&& __sndr, _Receiver __rcvr) :
-        __rcvr_(static_cast<_Receiver&&>(__rcvr)),
-        __op_state_(
-            connect(static_cast<_Sender&&>(__sndr), __receiver_t{__ref(*this)}))
-    {}
-};
-
-struct __submit_t
-{
-    template <receiver _Receiver, sender_to<_Receiver> _Sender>
-    void operator()(_Sender&& __sndr, _Receiver __rcvr) const noexcept(false)
-    {
-        if constexpr (__callable<get_allocator_t, env_of_t<_Receiver>>)
-        {
-            auto&& __env = get_env(__rcvr);
-            auto __alloc = get_allocator(__env);
-            using _Alloc = decltype(__alloc);
-            using _Op = __operation<__id<_Sender>, __id<_Receiver>>;
-            using _OpAlloc = typename std::allocator_traits<
-                _Alloc>::template rebind_alloc<_Op>;
-            _OpAlloc __op_alloc{__alloc};
-            auto __op = std::allocator_traits<_OpAlloc>::allocate(__op_alloc,
-                                                                  1);
-            try
-            {
-                std::allocator_traits<_OpAlloc>::construct(
-                    __op_alloc, __op, static_cast<_Sender&&>(__sndr),
-                    static_cast<_Receiver&&>(__rcvr));
-                start(__op->__op_state_);
-            }
-            catch (...)
-            {
-                std::allocator_traits<_OpAlloc>::deallocate(__op_alloc, __op,
-                                                            1);
-                throw;
-            }
-        }
-        else
-        {
-            start((new __operation<__id<_Sender>, __id<_Receiver>>{
-                       static_cast<_Sender&&>(__sndr),
-                       static_cast<_Receiver&&>(__rcvr)})
-                      ->__op_state_);
-        }
-    }
-};
-} // namespace __submit_
-
-using __submit_::__submit_t;
-inline constexpr __submit_t __submit{};
-
-namespace __inln
-{
-struct __schedule_t
-{};
-
-struct __scheduler
-{
-    using __t = __scheduler;
-    using __id = __scheduler;
-
-    template <class _Tag = __schedule_t>
-    STDEXEC_ATTRIBUTE((host, device))
-    friend auto tag_invoke(schedule_t, __scheduler)
-    {
-        return __make_sexpr<_Tag>();
-    }
-
-    friend auto tag_invoke(get_forward_progress_guarantee_t,
-                           __scheduler) noexcept -> forward_progress_guarantee
-    {
-        return forward_progress_guarantee::weakly_parallel;
-    }
-
-    auto operator==(const __scheduler&) const noexcept -> bool = default;
-};
-} // namespace __inln
-
-template <>
-struct __sexpr_impl<__inln::__schedule_t> : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        [](__ignore) noexcept
-        -> __env::__with<__inln::__scheduler,
-                         get_completion_scheduler_t<set_value_t>> {
-        return __env::__with(__inln::__scheduler{},
-                             get_completion_scheduler<set_value_t>);
-    };
-
-    static constexpr auto get_completion_signatures = //
-        [](__ignore,
-           __ignore) noexcept -> completion_signatures<set_value_t()> {
-        return {};
-    };
-
-    static constexpr auto start = //
-        []<class _Receiver>(__ignore, _Receiver& __rcvr) noexcept -> void {
-        set_value(static_cast<_Receiver&&>(__rcvr));
-    };
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.consumer.start_detached]
-namespace __start_detached
-{
-template <class _EnvId>
-struct __detached_receiver
-{
-    using _Env = stdexec::__t<_EnvId>;
-
-    struct __t
-    {
-        using receiver_concept = receiver_t;
-        using __id = __detached_receiver;
-        STDEXEC_ATTRIBUTE((no_unique_address))
-        _Env __env_;
-
-        template <same_as<set_value_t> _Tag, class... _As>
-        friend void tag_invoke(_Tag, __t&&, _As&&...) noexcept
-        {}
-
-        template <same_as<set_error_t> _Tag, class _Error>
-        [[noreturn]] friend void tag_invoke(_Tag, __t&&, _Error&&) noexcept
-        {
-            std::terminate();
-        }
-
-        template <same_as<set_stopped_t> _Tag>
-        friend void tag_invoke(_Tag, __t&&) noexcept
-        {}
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> const _Env&
-        {
-            // BUGBUG NOT TO SPEC
-            return __self.__env_;
-        }
-    };
-};
-template <class _Env = empty_env>
-using __detached_receiver_t = __t<__detached_receiver<__id<__decay_t<_Env>>>>;
-
-struct start_detached_t
-{
-    template <sender_in<empty_env> _Sender>
-        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
-                            start_detached_t, _Sender>
-    void operator()(_Sender&& __sndr) const
-    {
-        auto __domain = __get_early_domain(__sndr);
-        stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr));
-    }
-
-    template <class _Env, sender_in<_Env> _Sender>
-        requires __callable<apply_sender_t, __late_domain_of_t<_Sender, _Env>,
-                            start_detached_t, _Sender, _Env>
-    void operator()(_Sender&& __sndr, _Env&& __env) const
-    {
-        auto __domain = __get_late_domain(__sndr, __env);
-        stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr),
-                              static_cast<_Env&&>(__env));
-    }
-
-    using _Sender = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(start_detached_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(const _Sender&)),
-                             _Sender),
-                tag_invoke_t(start_detached_t, _Sender)>;
-
-    template <class _Sender, class _Env = empty_env>
-        requires sender_to<_Sender, __detached_receiver_t<_Env>>
-    void apply_sender(_Sender&& __sndr, _Env&& __env = {}) const
-    {
-        __submit(static_cast<_Sender&&>(__sndr),
-                 __detached_receiver_t<_Env>{static_cast<_Env&&>(__env)});
-    }
-};
-} // namespace __start_detached
-
-using __start_detached::start_detached_t;
-inline constexpr start_detached_t start_detached{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.factories]
-namespace __just
-{
-template <class _JustTag>
-struct __impl : __sexpr_defaults
-{
-    using __tag_t = typename _JustTag::__tag_t;
-
-    static constexpr auto get_completion_signatures =
-        []<class _Sender>(_Sender&&, __ignore) noexcept {
-        static_assert(sender_expr_for<_Sender, _JustTag>);
-        return completion_signatures<
-            __mapply<__qf<__tag_t>, __decay_t<__data_of<_Sender>>>>{};
-    };
-
-    static constexpr auto start =
-        []<class _State, class _Receiver>(_State& __state,
-                                          _Receiver& __rcvr) noexcept -> void {
-        __tup::__apply(
-            [&]<class... _Ts>(_Ts&... __ts) noexcept {
-            __tag_t()(std::move(__rcvr), std::move(__ts)...);
-        },
-            __state);
-    };
-};
-
-struct just_t
-{
-    using __tag_t = set_value_t;
-
-    template <__movable_value... _Ts>
-    STDEXEC_ATTRIBUTE((host, device))
-    auto operator()(_Ts&&... __ts) const
-        noexcept((__nothrow_decay_copyable<_Ts> && ...))
-    {
-        return __make_sexpr<just_t>(__tuple{static_cast<_Ts&&>(__ts)...});
-    }
-};
-
-struct just_error_t
-{
-    using __tag_t = set_error_t;
-
-    template <__movable_value _Error>
-    STDEXEC_ATTRIBUTE((host, device))
-    auto operator()(_Error&& __err) const
-        noexcept(__nothrow_decay_copyable<_Error>)
-    {
-        return __make_sexpr<just_error_t>(
-            __tuple{static_cast<_Error&&>(__err)});
-    }
-};
-
-struct just_stopped_t
-{
-    using __tag_t = set_stopped_t;
-
-    template <class _Tag = just_stopped_t>
-    STDEXEC_ATTRIBUTE((host, device))
-    auto operator()() const noexcept
-    {
-        return __make_sexpr<_Tag>(__tuple{});
-    }
-};
-} // namespace __just
-
-using __just::just_error_t;
-using __just::just_stopped_t;
-using __just::just_t;
-
-template <>
-struct __sexpr_impl<just_t> : __just::__impl<just_t>
-{};
-
-template <>
-struct __sexpr_impl<just_error_t> : __just::__impl<just_error_t>
-{};
-
-template <>
-struct __sexpr_impl<just_stopped_t> : __just::__impl<just_stopped_t>
-{};
-
-inline constexpr just_t just{};
-inline constexpr just_error_t just_error{};
-inline constexpr just_stopped_t just_stopped{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.execute]
-namespace __execute_
-{
-template <class _Fun>
-struct __as_receiver
-{
-    using receiver_concept = receiver_t;
-    _Fun __fun_;
-
-    template <same_as<set_value_t> _Tag>
-    friend void tag_invoke(_Tag, __as_receiver&& __rcvr) noexcept
-    {
-        try
-        {
-            __rcvr.__fun_();
-        }
-        catch (...)
-        {
-            set_error(static_cast<__as_receiver&&>(__rcvr),
-                      std::exception_ptr());
-        }
-    }
-
-    template <same_as<set_error_t> _Tag>
-    [[noreturn]] friend void tag_invoke(_Tag, __as_receiver&&,
-                                        std::exception_ptr) noexcept
-    {
-        std::terminate();
-    }
-
-    template <same_as<set_stopped_t> _Tag>
-    friend void tag_invoke(_Tag, __as_receiver&&) noexcept
-    {}
-
-    friend auto tag_invoke(get_env_t, const __as_receiver&) noexcept
-        -> empty_env
-    {
-        return {};
-    }
-};
-
-struct execute_t
-{
-    template <scheduler _Scheduler, class _Fun>
-        requires __callable<_Fun&> && move_constructible<_Fun>
-    void operator()(_Scheduler&& __sched, _Fun __fun) const noexcept(false)
-    {
-        // Look for a legacy customization
-        if constexpr (tag_invocable<execute_t, _Scheduler, _Fun>)
-        {
-            tag_invoke(execute_t{}, static_cast<_Scheduler&&>(__sched),
-                       static_cast<_Fun&&>(__fun));
-        }
-        else
-        {
-            auto __domain = query_or(get_domain, __sched, default_domain());
-            stdexec::apply_sender(__domain, *this,
-                                  schedule(static_cast<_Scheduler&&>(__sched)),
-                                  static_cast<_Fun&&>(__fun));
-        }
-    }
-
-    template <sender_of<set_value_t()> _Sender, class _Fun>
-        requires __callable<_Fun&> && move_constructible<_Fun>
-    void apply_sender(_Sender&& __sndr, _Fun __fun) const noexcept(false)
-    {
-        __submit(static_cast<_Sender&&>(__sndr),
-                 __as_receiver<_Fun>{static_cast<_Fun&&>(__fun)});
-    }
-};
-} // namespace __execute_
-
-using __execute_::execute_t;
-inline constexpr execute_t execute{};
-
-// NOT TO SPEC:
-namespace __closure
-{
-template <__class _Dp>
-struct sender_adaptor_closure;
-} // namespace __closure
-
-using __closure::sender_adaptor_closure;
-
-template <class _Tp>
-concept __sender_adaptor_closure =
-    derived_from<__decay_t<_Tp>, sender_adaptor_closure<__decay_t<_Tp>>> &&
-    move_constructible<__decay_t<_Tp>> &&
-    constructible_from<__decay_t<_Tp>, _Tp>;
-
-template <class _Tp, class _Sender>
-concept __sender_adaptor_closure_for =
-    __sender_adaptor_closure<_Tp> && sender<__decay_t<_Sender>> &&
-    __callable<_Tp, __decay_t<_Sender>> &&
-    sender<__call_result_t<_Tp, __decay_t<_Sender>>>;
-
-namespace __closure
-{
-template <class _T0, class _T1>
-struct __compose : sender_adaptor_closure<__compose<_T0, _T1>>
-{
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _T0 __t0_;
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _T1 __t1_;
-
-    template <sender _Sender>
-        requires __callable<_T0, _Sender> &&
-                 __callable<_T1, __call_result_t<_T0, _Sender>>
-    STDEXEC_ATTRIBUTE((always_inline))
-        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
-        operator()(_Sender&& __sndr) &&
-    {
-        return static_cast<_T1&&>(__t1_)(
-            static_cast<_T0&&>(__t0_)(static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <sender _Sender>
-        requires __callable<const _T0&, _Sender> &&
-                 __callable<const _T1&, __call_result_t<const _T0&, _Sender>>
-    STDEXEC_ATTRIBUTE((always_inline))
-        __call_result_t<_T1, __call_result_t<_T0, _Sender>>
-        operator()(_Sender&& __sndr) const&
-    {
-        return __t1_(__t0_(static_cast<_Sender&&>(__sndr)));
-    }
-};
-
-template <__class _Dp>
-struct sender_adaptor_closure
-{};
-
-template <sender _Sender, __sender_adaptor_closure_for<_Sender> _Closure>
-STDEXEC_ATTRIBUTE((always_inline))
-__call_result_t<_Closure, _Sender> operator|(_Sender&& __sndr,
-                                             _Closure&& __clsur)
-{
-    return static_cast<_Closure&&>(__clsur)(static_cast<_Sender&&>(__sndr));
-}
-
-template <__sender_adaptor_closure _T0, __sender_adaptor_closure _T1>
-STDEXEC_ATTRIBUTE((always_inline))
-__compose<__decay_t<_T0>, __decay_t<_T1>> operator|(_T0&& __t0, _T1&& __t1)
-{
-    return {{}, static_cast<_T0&&>(__t0), static_cast<_T1&&>(__t1)};
-}
-
-template <class _Fun, class... _As>
-struct __binder_back : sender_adaptor_closure<__binder_back<_Fun, _As...>>
-{
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _Fun __fun_;
-    std::tuple<_As...> __as_;
-
-    template <sender _Sender>
-        requires __callable<_Fun, _Sender, _As...>
-    STDEXEC_ATTRIBUTE((host, device,
-                       always_inline)) __call_result_t<_Fun, _Sender, _As...>
-        operator()(_Sender&& __sndr) && noexcept(
-            __nothrow_callable<_Fun, _Sender, _As...>)
-    {
-        return __apply(
-            [&__sndr,
-             this](_As&... __as) -> __call_result_t<_Fun, _Sender, _As...> {
-            return static_cast<_Fun&&>(__fun_)(static_cast<_Sender&&>(__sndr),
-                                               static_cast<_As&&>(__as)...);
-        },
-            __as_);
-    }
-
-    template <sender _Sender>
-        requires __callable<const _Fun&, _Sender, const _As&...>
-    STDEXEC_ATTRIBUTE((host, device)) auto
-        operator()(_Sender&& __sndr) const& //
-        noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>)
-            -> __call_result_t<const _Fun&, _Sender, const _As&...>
-    {
-        return __apply(
-            [&__sndr, this](const _As&... __as)
-                -> __call_result_t<const _Fun&, _Sender, const _As&...> {
-            return __fun_(static_cast<_Sender&&>(__sndr), __as...);
-        },
-            __as_);
-    }
-};
-} // namespace __closure
-
-using __closure::__binder_back;
-
-namespace __adaptors
-{
-STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE_GNU("-Wold-style-cast")
-
-// A derived-to-base cast that works even when the base is not
-// accessible from derived.
-template <class _Tp, class _Up>
-STDEXEC_ATTRIBUTE((host, device))
-auto __c_cast(_Up&& u) noexcept -> __copy_cvref_t<_Up&&, _Tp>
-    requires __decays_to<_Tp, _Tp>
-{
-    static_assert(std::is_reference_v<__copy_cvref_t<_Up&&, _Tp>>);
-    static_assert(STDEXEC_IS_BASE_OF(_Tp, __decay_t<_Up>));
-    return (__copy_cvref_t<_Up&&, _Tp>)static_cast<_Up&&>(u);
-}
-STDEXEC_PRAGMA_POP()
-
-namespace __no
-{
-struct __nope
-{};
-
-struct __receiver : __nope
-{
-    using receiver_concept = receiver_t;
-};
-
-template <same_as<set_error_t> _Tag>
-void tag_invoke(_Tag, __receiver, std::exception_ptr) noexcept;
-template <same_as<set_stopped_t> _Tag>
-void tag_invoke(_Tag, __receiver) noexcept;
-auto tag_invoke(get_env_t, __receiver) noexcept -> empty_env;
-} // namespace __no
-
-using __not_a_receiver = __no::__receiver;
-
-template <class _Base>
-struct __adaptor_base
-{
-    template <class _T1>
-        requires constructible_from<_Base, _T1>
-    explicit __adaptor_base(_T1&& __base) : __base_(static_cast<_T1&&>(__base))
-    {}
-
-  private:
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _Base __base_;
-
-  protected:
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-
-    _Base& base() & noexcept
-    {
-        return __base_;
-    }
-
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-
-    const _Base& base() const& noexcept
-    {
-        return __base_;
-    }
-
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-
-    _Base&& base() && noexcept
-    {
-        return static_cast<_Base&&>(__base_);
-    }
-};
-
-template <derived_from<__no::__nope> _Base>
-struct __adaptor_base<_Base>
-{};
-
-// BUGBUG Not to spec: on gcc and nvc++, member functions in derived classes
-// don't shadow type aliases of the same name in base classes. :-O
-// On mingw gcc, 'bool(type::existing_member_function)' evaluates to true,
-// but 'int(type::existing_member_function)' is an error (as desired).
-#define STDEXEC_DISPATCH_MEMBER(_TAG)                                          \
-    template <class _Self, class... _Ts>                                       \
-    STDEXEC_ATTRIBUTE((host, device, always_inline))                           \
-    static auto __call_##_TAG(_Self&& __self, _Ts&&... __ts) noexcept          \
-        -> decltype((static_cast<_Self&&>(__self))                             \
-                        ._TAG(static_cast<_Ts&&>(__ts)...))                    \
-    {                                                                          \
-        static_assert(noexcept((static_cast<_Self&&>(__self))                  \
-                                   ._TAG(static_cast<_Ts&&>(__ts)...)));       \
-        return static_cast<_Self&&>(__self)._TAG(static_cast<_Ts&&>(__ts)...); \
-    } /**/
-#define STDEXEC_CALL_MEMBER(_TAG, ...) __call_##_TAG(__VA_ARGS__)
-
-#if STDEXEC_CLANG()
-// Only clang gets this right.
-#define STDEXEC_MISSING_MEMBER(_Dp, _TAG) requires { typename _Dp::_TAG; }
-#define STDEXEC_DEFINE_MEMBER(_TAG)                                            \
-    STDEXEC_DISPATCH_MEMBER(_TAG) using _TAG = void
-#else
-#define STDEXEC_MISSING_MEMBER(_Dp, _TAG) (__missing_##_TAG<_Dp>())
-#define STDEXEC_DEFINE_MEMBER(_TAG)                                            \
-    template <class _Dp>                                                       \
-    static constexpr bool __missing_##_TAG() noexcept                          \
-    {                                                                          \
-        return requires { requires bool(int(_Dp::_TAG)); };                    \
-    }                                                                          \
-    STDEXEC_DISPATCH_MEMBER(_TAG)                                              \
-    static constexpr int _TAG = 1 /**/
-#endif
-
-template <__class _Derived, class _Base = __not_a_receiver>
-struct receiver_adaptor : __adaptor_base<_Base>, receiver_t
-{
-    friend _Derived;
-    STDEXEC_DEFINE_MEMBER(set_value);
-    STDEXEC_DEFINE_MEMBER(set_error);
-    STDEXEC_DEFINE_MEMBER(set_stopped);
-    STDEXEC_DEFINE_MEMBER(get_env);
-
-    static constexpr bool __has_base = !derived_from<_Base, __no::__nope>;
-
-    template <class _Dp>
-    using __base_from_derived_t = decltype(__declval<_Dp>().base());
-
-    using __get_base_t =
-        __if_c<__has_base, __mbind_back_q<__copy_cvref_t, _Base>,
-               __q<__base_from_derived_t>>;
-
-    template <class _Dp>
-    using __base_t = __minvoke<__get_base_t, _Dp&&>;
-
-    template <class _Dp>
-    STDEXEC_ATTRIBUTE((host, device))
-    static auto __get_base(_Dp&& __self) noexcept -> __base_t<_Dp>
-    {
-        if constexpr (__has_base)
-        {
-            return __c_cast<receiver_adaptor>(static_cast<_Dp&&>(__self))
-                .base();
-        }
-        else
-        {
-            return static_cast<_Dp&&>(__self).base();
-        }
-    }
-
-    template <same_as<set_value_t> _SetValue, class... _As>
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-    friend auto tag_invoke(_SetValue, _Derived&& __self,
-                           _As&&... __as) noexcept //
-        -> __msecond<                              //
-            __if_c<same_as<set_value_t, _SetValue>>,
-            decltype(STDEXEC_CALL_MEMBER(set_value,
-                                         static_cast<_Derived&&>(__self),
-                                         static_cast<_As&&>(__as)...))>
-    {
-        static_assert(noexcept(
-            STDEXEC_CALL_MEMBER(set_value, static_cast<_Derived&&>(__self),
-                                static_cast<_As&&>(__as)...)));
-        STDEXEC_CALL_MEMBER(set_value, static_cast<_Derived&&>(__self),
-                            static_cast<_As&&>(__as)...);
-    }
-
-    template <same_as<set_value_t> _SetValue, class _Dp = _Derived,
-              class... _As>
-        requires STDEXEC_MISSING_MEMBER
-    (_Dp, set_value) &&
-        tag_invocable<_SetValue, __base_t<_Dp>, _As...> STDEXEC_ATTRIBUTE((
-            host, device,
-            always_inline)) friend void tag_invoke(_SetValue, _Derived&& __self,
-                                                   _As&&... __as) noexcept
-    {
-        stdexec::set_value(__get_base(static_cast<_Dp&&>(__self)),
-                           static_cast<_As&&>(__as)...);
-    }
-
-    template <same_as<set_error_t> _SetError, class _Error>
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-    friend auto tag_invoke(_SetError, _Derived&& __self,
-                           _Error&& __err) noexcept //
-        -> __msecond<                               //
-            __if_c<same_as<set_error_t, _SetError>>,
-            decltype(STDEXEC_CALL_MEMBER(set_error,
-                                         static_cast<_Derived&&>(__self),
-                                         static_cast<_Error&&>(__err)))>
-    {
-        static_assert(noexcept(
-            STDEXEC_CALL_MEMBER(set_error, static_cast<_Derived&&>(__self),
-                                static_cast<_Error&&>(__err))));
-        STDEXEC_CALL_MEMBER(set_error, static_cast<_Derived&&>(__self),
-                            static_cast<_Error&&>(__err));
-    }
-
-    template <same_as<set_error_t> _SetError, class _Error,
-              class _Dp = _Derived>
-        requires STDEXEC_MISSING_MEMBER
-    (_Dp, set_error) &&
-        tag_invocable<_SetError, __base_t<_Dp>, _Error> STDEXEC_ATTRIBUTE((
-            host, device,
-            always_inline)) friend void tag_invoke(_SetError, _Derived&& __self,
-                                                   _Error&& __err) noexcept
-    {
-        stdexec::set_error(__get_base(static_cast<_Derived&&>(__self)),
-                           static_cast<_Error&&>(__err));
-    }
-
-    template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived>
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-    friend auto tag_invoke(_SetStopped, _Derived&& __self) noexcept //
-        -> __msecond<                                               //
-            __if_c<same_as<set_stopped_t, _SetStopped>>,
-            decltype(STDEXEC_CALL_MEMBER(set_stopped,
-                                         static_cast<_Dp&&>(__self)))>
-    {
-        static_assert(noexcept(
-            STDEXEC_CALL_MEMBER(set_stopped, static_cast<_Derived&&>(__self))));
-        STDEXEC_CALL_MEMBER(set_stopped, static_cast<_Derived&&>(__self));
-    }
-
-    template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived>
-        requires STDEXEC_MISSING_MEMBER
-    (_Dp, set_stopped) &&
-        tag_invocable<_SetStopped, __base_t<_Dp>> STDEXEC_ATTRIBUTE(
-            (host, device,
-             always_inline)) friend void tag_invoke(_SetStopped,
-                                                    _Derived&& __self) noexcept
-    {
-        stdexec::set_stopped(__get_base(static_cast<_Derived&&>(__self)));
-    }
-
-    // Pass through the get_env receiver query
-    template <same_as<get_env_t> _GetEnv, class _Dp = _Derived>
-    STDEXEC_ATTRIBUTE((host, device, always_inline))
-    friend auto tag_invoke(_GetEnv, const _Derived& __self) noexcept
-        -> decltype(STDEXEC_CALL_MEMBER(get_env,
-                                        static_cast<const _Dp&>(__self)))
-    {
-        static_assert(noexcept(STDEXEC_CALL_MEMBER(get_env, __self)));
-        return STDEXEC_CALL_MEMBER(get_env, __self);
-    }
-
-    template <same_as<get_env_t> _GetEnv, class _Dp = _Derived>
-        requires STDEXEC_MISSING_MEMBER
-    (_Dp, get_env)
-        STDEXEC_ATTRIBUTE((host, device, always_inline)) friend auto tag_invoke(
-            _GetEnv, const _Derived& __self) noexcept
-        -> env_of_t<__base_t<const _Dp&>>
-    {
-        return stdexec::get_env(__get_base(__self));
-    }
-
-  public:
-    receiver_adaptor() = default;
-    using __adaptor_base<_Base>::__adaptor_base;
-
-    using receiver_concept = receiver_t;
-};
-} // namespace __adaptors
-
-template <__class _Derived, receiver _Base = __adaptors::__not_a_receiver>
-using receiver_adaptor = __adaptors::receiver_adaptor<_Derived, _Base>;
-
-template <class _Receiver, class _Fun, class... _As>
-concept __receiver_of_invoke_result = //
-    receiver_of<_Receiver, completion_signatures<
-                               __minvoke<__remove<void, __qf<set_value_t>>,
-                                         __invoke_result_t<_Fun, _As...>>>>;
-
-template <bool _CanThrow = false, class _Receiver, class _Fun, class... _As>
-void __set_value_invoke(_Receiver&& __rcvr, _Fun&& __fun,
-                        _As&&... __as) noexcept(!_CanThrow)
-{
-    if constexpr (_CanThrow || __nothrow_invocable<_Fun, _As...>)
-    {
-        if constexpr (same_as<void, __invoke_result_t<_Fun, _As...>>)
-        {
-            __invoke(static_cast<_Fun&&>(__fun), static_cast<_As&&>(__as)...);
-            set_value(static_cast<_Receiver&&>(__rcvr));
-        }
-        else
-        {
-            set_value(static_cast<_Receiver&&>(__rcvr),
-                      __invoke(static_cast<_Fun&&>(__fun),
-                               static_cast<_As&&>(__as)...));
-        }
-    }
-    else
-    {
-        try
-        {
-            stdexec::__set_value_invoke<true>(static_cast<_Receiver&&>(__rcvr),
-                                              static_cast<_Fun&&>(__fun),
-                                              static_cast<_As&&>(__as)...);
-        }
-        catch (...)
-        {
-            set_error(static_cast<_Receiver&&>(__rcvr),
-                      std::current_exception());
-        }
-    }
-}
-
-template <class _Fun>
-struct _WITH_FUNCTION_
-{};
-
-template <class... _Args>
-struct _WITH_ARGUMENTS_
-{};
-
-inline constexpr __mstring __not_callable_diag =
-    "The specified function is not callable with the arguments provided."_mstr;
-
-template <__mstring _Context, __mstring _Diagnostic = __not_callable_diag>
-struct _NOT_CALLABLE_
-{};
-
-template <__mstring _Context>
-struct __callable_error
-{
-    template <class _Fun, class... _Args>
-    using __f =       //
-        __mexception< //
-            _NOT_CALLABLE_<_Context>, _WITH_FUNCTION_<_Fun>,
-            _WITH_ARGUMENTS_<_Args...>>;
-};
-
-template <class _Fun, class... _Args>
-    requires __invocable<_Fun, _Args...>
-using __non_throwing_ = __mbool<__nothrow_invocable<_Fun, _Args...>>;
-
-template <class _Tag, class _Fun, class _Sender, class _Env, class _Catch>
-using __with_error_invoke_t = //
-    __if<__gather_completions_for<
-             _Tag, _Sender, _Env,
-             __mbind_front<__mtry_catch_q<__non_throwing_, _Catch>, _Fun>,
-             __q<__mand>>,
-         completion_signatures<>, __with_exception_ptr>;
-
-template <class _Fun, class... _Args>
-    requires __invocable<_Fun, _Args...>
-using __set_value_invoke_t = //
-    completion_signatures<__minvoke<__remove<void, __qf<set_value_t>>,
-                                    __invoke_result_t<_Fun, _Args...>>>;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.then]
-namespace __then
-{
-inline constexpr __mstring __then_context =
-    "In stdexec::then(Sender, Function)..."_mstr;
-using __on_not_callable = __callable_error<__then_context>;
-
-template <class _Fun, class _CvrefSender, class _Env>
-using __completion_signatures_t = //
-    __try_make_completion_signatures<
-        _CvrefSender, _Env,
-        __with_error_invoke_t<set_value_t, _Fun, _CvrefSender, _Env,
-                              __on_not_callable>,
-        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
-                      _Fun>>;
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-struct then_t
-{
-    template <sender _Sender, __movable_value _Fun>
-    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
-        auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<then_t>(static_cast<_Fun&&>(__fun),
-                                           static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <__movable_value _Fun>
-    STDEXEC_ATTRIBUTE((always_inline))
-    __binder_back<then_t, _Fun> operator()(_Fun __fun) const
-    {
-        return {{}, {}, {static_cast<_Fun&&>(__fun)}};
-    }
-
-    using _Sender = __1;
-    using _Fun = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(then_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(_Sender&)),
-                             _Sender, _Fun),
-                tag_invoke_t(then_t, _Sender, _Fun)>;
-};
-
-struct __then_impl : __sexpr_defaults
-{
-    static constexpr auto get_completion_signatures = //
-        []<class _Sender, class _Env>(_Sender&&, _Env&&) noexcept
-        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
-                                     __child_of<_Sender>, _Env> {
-        static_assert(sender_expr_for<_Sender, then_t>);
-        return {};
-    };
-
-    static constexpr auto complete = //
-        []<class _Tag, class... _Args>(__ignore, auto& __state, auto& __rcvr,
-                                       _Tag,
-                                       _Args&&... __args) noexcept -> void {
-        if constexpr (std::same_as<_Tag, set_value_t>)
-        {
-            stdexec::__set_value_invoke(std::move(__rcvr), std::move(__state),
-                                        static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-        }
-    };
-};
-} // namespace __then
-
-using __then::then_t;
-
-/// @brief The then sender adaptor, which invokes a function with the result of
-///        a sender, making the result available to the next receiver.
-/// @hideinitializer
-inline constexpr then_t then{};
-
-template <>
-struct __sexpr_impl<then_t> : __then::__then_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.upon_error]
-namespace __upon_error
-{
-inline constexpr __mstring __upon_error_context =
-    "In stdexec::upon_error(Sender, Function)..."_mstr;
-using __on_not_callable = __callable_error<__upon_error_context>;
-
-template <class _Fun, class _CvrefSender, class _Env>
-using __completion_signatures_t = //
-    __try_make_completion_signatures<
-        _CvrefSender, _Env,
-        __with_error_invoke_t<set_error_t, _Fun, _CvrefSender, _Env,
-                              __on_not_callable>,
-        __q<__compl_sigs::__default_set_value>,
-        __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>,
-                      _Fun>>;
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-struct upon_error_t
-{
-    template <sender _Sender, __movable_value _Fun>
-    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
-        auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<upon_error_t>(static_cast<_Fun&&>(__fun),
-                                       static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <__movable_value _Fun>
-    STDEXEC_ATTRIBUTE((always_inline))
-    __binder_back<upon_error_t, _Fun> operator()(_Fun __fun) const
-    {
-        return {{}, {}, {static_cast<_Fun&&>(__fun)}};
-    }
-
-    using _Sender = __1;
-    using _Fun = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(upon_error_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(_Sender&)),
-                             _Sender, _Fun),
-                tag_invoke_t(upon_error_t, _Sender, _Fun)>;
-};
-
-struct __upon_error_impl : __sexpr_defaults
-{
-    static constexpr auto get_completion_signatures = //
-        []<class _Sender, class _Env>(_Sender&&, _Env&&) noexcept
-        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
-                                     __child_of<_Sender>, _Env> {
-        static_assert(sender_expr_for<_Sender, upon_error_t>);
-        return {};
-    };
-
-    static constexpr auto complete = //
-        []<class _Tag, class... _Args>(__ignore, auto& __state, auto& __rcvr,
-                                       _Tag,
-                                       _Args&&... __args) noexcept -> void {
-        if constexpr (std::same_as<_Tag, set_error_t>)
-        {
-            stdexec::__set_value_invoke(std::move(__rcvr), std::move(__state),
-                                        static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-        }
-    };
-};
-} // namespace __upon_error
-
-using __upon_error::upon_error_t;
-inline constexpr upon_error_t upon_error{};
-
-template <>
-struct __sexpr_impl<upon_error_t> : __upon_error::__upon_error_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.upon_stopped]
-namespace __upon_stopped
-{
-inline constexpr __mstring __upon_stopped_context =
-    "In stdexec::upon_stopped(Sender, Function)..."_mstr;
-using __on_not_callable = __callable_error<__upon_stopped_context>;
-
-template <class _Fun, class _CvrefSender, class _Env>
-using __completion_signatures_t = //
-    __try_make_completion_signatures<
-        _CvrefSender, _Env,
-        __with_error_invoke_t<set_stopped_t, _Fun, _CvrefSender, _Env,
-                              __on_not_callable>,
-        __q<__compl_sigs::__default_set_value>,
-        __q<__compl_sigs::__default_set_error>, __set_value_invoke_t<_Fun>>;
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-struct upon_stopped_t
-{
-    template <sender _Sender, __movable_value _Fun>
-        requires __callable<_Fun>
-    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
-        auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<upon_stopped_t>(static_cast<_Fun&&>(__fun),
-                                         static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <__movable_value _Fun>
-        requires __callable<_Fun>
-    STDEXEC_ATTRIBUTE((always_inline)) __binder_back<upon_stopped_t, _Fun>
-        operator()(_Fun __fun) const
-    {
-        return {{}, {}, {static_cast<_Fun&&>(__fun)}};
-    }
-
-    using _Sender = __1;
-    using _Fun = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(upon_stopped_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(_Sender&)),
-                             _Sender, _Fun),
-                tag_invoke_t(upon_stopped_t, _Sender, _Fun)>;
-};
-
-struct __upon_stopped_impl : __sexpr_defaults
-{
-    static constexpr auto get_completion_signatures = //
-        []<class _Sender, class _Env>(_Sender&&, _Env&&) noexcept
-        -> __completion_signatures_t<__decay_t<__data_of<_Sender>>,
-                                     __child_of<_Sender>, _Env> {
-        static_assert(sender_expr_for<_Sender, upon_stopped_t>);
-        return {};
-    };
-
-    static constexpr auto complete = //
-        []<class _Tag, class... _Args>(__ignore, auto& __state, auto& __rcvr,
-                                       _Tag,
-                                       _Args&&... __args) noexcept -> void {
-        if constexpr (std::same_as<_Tag, set_stopped_t>)
-        {
-            stdexec::__set_value_invoke(std::move(__rcvr), std::move(__state),
-                                        static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-        }
-    };
-};
-} // namespace __upon_stopped
-
-using __upon_stopped::upon_stopped_t;
-inline constexpr upon_stopped_t upon_stopped{};
-
-template <>
-struct __sexpr_impl<upon_stopped_t> : __upon_stopped::__upon_stopped_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.bulk]
-namespace __bulk
-{
-inline constexpr __mstring __bulk_context =
-    "In stdexec::bulk(Sender, Shape, Function)..."_mstr;
-using __on_not_callable = __callable_error<__bulk_context>;
-
-template <class _Shape, class _Fun>
-struct __data
-{
-    _Shape __shape_;
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _Fun __fun_;
-    static constexpr auto __mbrs_ =
-        __mliterals<&__data::__shape_, &__data::__fun_>();
-};
-template <class _Shape, class _Fun>
-__data(_Shape, _Fun) -> __data<_Shape, _Fun>;
-
-template <class _Ty>
-using __decay_ref = __decay_t<_Ty>&;
-
-template <class _CvrefSender, class _Env, class _Shape, class _Fun,
-          class _Catch>
-using __with_error_invoke_t = //
-    __if<__try_value_types_of_t<
-             _CvrefSender, _Env,
-             __transform<__q<__decay_ref>,
-                         __mbind_front<__mtry_catch_q<__non_throwing_, _Catch>,
-                                       _Fun, _Shape>>,
-             __q<__mand>>,
-         completion_signatures<>, __with_exception_ptr>;
-
-template <class _CvrefSender, class _Env, class _Shape, class _Fun>
-using __completion_signatures = //
-    __try_make_completion_signatures<
-        _CvrefSender, _Env,
-        __with_error_invoke_t<_CvrefSender, _Env, _Shape, _Fun,
-                              __on_not_callable>>;
-
-struct bulk_t
-{
-    template <sender _Sender, integral _Shape, __movable_value _Fun>
-    STDEXEC_ATTRIBUTE((host, device))
-    auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const
-        -> __well_formed_sender auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<bulk_t>(__data{__shape, static_cast<_Fun&&>(__fun)},
-                                 static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <integral _Shape, class _Fun>
-    STDEXEC_ATTRIBUTE((always_inline))
-    __binder_back<bulk_t, _Shape, _Fun> operator()(_Shape __shape,
-                                                   _Fun __fun) const
-    {
-        return {{},
-                {},
-                {static_cast<_Shape&&>(__shape), static_cast<_Fun&&>(__fun)}};
-    }
-
-    // This describes how to use the pieces of a bulk sender to find
-    // legacy customizations of the bulk algorithm.
-    using _Sender = __1;
-    using _Shape = __nth_member<0>(__0);
-    using _Fun = __nth_member<1>(__0);
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(bulk_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(_Sender&)),
-                             _Sender, _Shape, _Fun),
-                tag_invoke_t(bulk_t, _Sender, _Shape, _Fun)>;
-};
-
-struct __bulk_impl : __sexpr_defaults
-{
-    template <class _Sender>
-    using __fun_t = decltype(__decay_t<__data_of<_Sender>>::__fun_);
-
-    template <class _Sender>
-    using __shape_t = decltype(__decay_t<__data_of<_Sender>>::__shape_);
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Sender, class _Env>(_Sender&&, _Env&&) noexcept
-        -> __completion_signatures<__child_of<_Sender>, _Env,
-                                   __shape_t<_Sender>, __fun_t<_Sender>> {
-        static_assert(sender_expr_for<_Sender, bulk_t>);
-        return {};
-    };
-
-    static constexpr auto complete = //
-        []<class _Tag, class... _Args>(__ignore, auto& __state, auto& __rcvr,
-                                       _Tag,
-                                       _Args&&... __args) noexcept -> void {
-        if constexpr (std::same_as<_Tag, set_value_t>)
-        {
-            using __shape_t = decltype(__state.__shape_);
-            if constexpr (noexcept(__state.__fun_(__shape_t{}, __args...)))
-            {
-                for (__shape_t __i{}; __i != __state.__shape_; ++__i)
-                {
-                    __state.__fun_(__i, __args...);
-                }
-                _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-            }
-            else
-            {
-                try
-                {
-                    for (__shape_t __i{}; __i != __state.__shape_; ++__i)
-                    {
-                        __state.__fun_(__i, __args...);
-                    }
-                    _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-                }
-                catch (...)
-                {
-                    set_error(std::move(__rcvr), std::current_exception());
-                }
-            }
-        }
-        else
-        {
-            _Tag()(std::move(__rcvr), static_cast<_Args&&>(__args)...);
-        }
-    };
-};
-} // namespace __bulk
-
-using __bulk::bulk_t;
-inline constexpr bulk_t bulk{};
-
-template <>
-struct __sexpr_impl<bulk_t> : __bulk::__bulk_impl
-{};
-
-////////////////////////////////////////////////////////////////////////////
-// shared components of split and ensure_started
-//
-// The split and ensure_started algorithms are very similar in implementation.
-// The salient differences are:
-//
-// split: the input async operation is always connected. It is only
-//   started when one of the split senders is connected and started.
-//   split senders are copyable, so there are multiple operation states
-//   to be notified on completion. These are stored in an instrusive
-//   linked list.
-//
-// ensure_started: the input async operation is always started, so
-//   the internal receiver will always be completed. The ensure_started
-//   sender is move-only and single-shot, so there will only ever be one
-//   operation state to be notified on completion.
-//
-// The shared state should add-ref itself when the input async
-// operation is started and release itself when its completion
-// is notified.
-namespace __shared
-{
-template <class _BaseEnv>
-using __env_t =                //
-    __env::__join_t<__env::__with<in_place_stop_token, get_stop_token_t>,
-                    _BaseEnv>; // BUGBUG NOT TO SPEC
-
-struct __on_stop_request
-{
-    in_place_stop_source& __stop_source_;
-
-    void operator()() noexcept
-    {
-        __stop_source_.request_stop();
-    }
-};
-
-template <class _Receiver>
-auto __notify_visitor(_Receiver& __rcvr) noexcept
-{
-    return [&]<class _Tuple>(_Tuple&& __tupl) noexcept -> void {
-        __apply(
-            [&](auto __tag, auto&&... __args) noexcept -> void {
-            __tag(static_cast<_Receiver&&>(__rcvr),
-                  __forward_like<_Tuple>(__args)...);
-        },
-            __tupl);
-    };
-}
-
-enum class __action_kind : bool
-{
-    __notify,
-    __detach
-};
-
-struct __local_state_base : __immovable
-{
-    using __action_fn = void(__local_state_base*, __action_kind) noexcept;
-
-    __action_fn* __action_{};
-    __local_state_base* __next_{};
-};
-
-template <class _CvrefSender, class _Env>
-struct __shared_state;
-
-// Each operation state of a split sender has one of these,
-// created when a split sender is connected. There are 0 or
-// more of them per input async operation. It is what
-// the split sender's `get_state` fn returns. It holds a
-// reference to the shared state of the input async operation.
-template <class _CvrefSender, class _Receiver>
-struct __local_state :
-    __local_state_base,
-    __enable_receiver_from_this<_CvrefSender, _Receiver>
-{
-    using __data_t = __decay_t<__data_of<_CvrefSender>>;
-    using __shared_state_t = __mapply<__q<__mfront>, __data_t>;
-    using __on_stop_cb_t = //
-        typename stop_token_of_t<env_of_t<_Receiver>&>::template callback_type<
-            __on_stop_request>;
-    using __tag_t = tag_of_t<_CvrefSender>;
-    static_assert(__one_of<__tag_t, __split::__split_t,
-                           __ensure_started::__ensure_started_t>);
-
-    explicit __local_state(_CvrefSender&& __sndr) noexcept :
-        __local_state::__local_state_base{{},
-                                          &__action<tag_of_t<_CvrefSender>>},
-        __shared_state_(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(
-                            static_cast<_CvrefSender&&>(__sndr),
-                            apply)(__detail::__get_data())
-                            .__shared_state)
-    {}
-
-    ~__local_state()
-    {
-        __action_(this, __action_kind::__detach);
-    }
-
-    // This is called when the input async operation completes; or,
-    // if it has already completed when start is called, it is called
-    // from start:
-    template <class _Tag>
-    static void __action(__local_state_base* __self,
-                         __action_kind __kind) noexcept
-    {
-        auto* const __op = static_cast<__local_state*>(__self);
-        if (__kind == __action_kind::__notify)
-        {
-            __op->__on_stop_.reset();
-
-            // The split algorithm sends by T const&. ensure_started sends by
-            // T&&.
-            if constexpr (same_as<__split::__split_t, _Tag>)
-            {
-                std::visit(__notify_visitor(__op->__receiver()),
-                           std::as_const(__op->__shared_state_->__data_));
-            }
-            else
-            {
-                std::visit(__notify_visitor(__op->__receiver()),
-                           std::move(__op->__shared_state_->__data_));
-            }
-        }
-        else
-        {
-            // This is a detach operation
-            if constexpr (same_as<__split::__split_t, _Tag>)
-            {
-                // no-op
-            }
-            else
-            {
-                __op->__shared_state_->__detach();
-            }
-        }
-    }
-
-    std::optional<__on_stop_cb_t> __on_stop_{};
-    __intrusive_ptr<__shared_state_t> __shared_state_;
-};
-
-template <class _CvrefSenderId, class _EnvId>
-struct __receiver
-{
-    using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>;
-    using _Env = stdexec::__t<_EnvId>;
-
-    struct __t
-    {
-        using receiver_concept = receiver_t;
-        using __id = __receiver;
-
-        explicit __t(
-            __shared_state<_CvrefSender, _Env>* __shared_state) noexcept :
-            __shared_state_(__shared_state)
-        {}
-
-        template <__completion_tag _Tag, class... _As>
-        friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept
-        {
-            __shared_state<_CvrefSender, _Env>& __state =
-                *__self.__shared_state_;
-
-            try
-            {
-                using __tuple_t = __decayed_tuple<_Tag, _As...>;
-                __state.__data_.template emplace<__tuple_t>(
-                    __tag, static_cast<_As&&>(__as)...);
-            }
-            catch (...)
-            {
-                using __tuple_t =
-                    __decayed_tuple<set_error_t, std::exception_ptr>;
-                __state.__data_.template emplace<__tuple_t>(
-                    set_error, std::current_exception());
-            }
-
-            __state.__notify();
-        }
-
-        friend auto tag_invoke(get_env_t, const __t& __self) noexcept
-            -> const __env_t<_Env>&
-        {
-            return __self.__shared_state_->__env_;
-        }
-
-        __shared_state<_CvrefSender, _Env>* __shared_state_;
-    };
-};
-
-template <class _CvrefSender, class _Env>
-struct __shared_state :
-    __enable_intrusive_from_this<__shared_state<_CvrefSender, _Env>>
-{
-    using __variant_t = __compl_sigs::__for_all_sigs<
-        __completion_signatures_of_t<_CvrefSender, _Env>, __q<__decayed_tuple>,
-        __mbind_front_q<__variant,
-                        std::tuple<set_stopped_t>, // Initial state of the
-                                                   // variant is set_stopped
-                        std::tuple<set_error_t, std::exception_ptr>>>;
-
-    using __receiver_t = __t<__receiver<__cvref_id<_CvrefSender>, __id<_Env>>>;
-
-    in_place_stop_source __stop_source_{};
-    __variant_t __data_;
-    std::atomic<void*> __head_{nullptr};
-    __env_t<_Env> __env_;
-    connect_result_t<_CvrefSender, __receiver_t> __op_state2_;
-
-    explicit __shared_state(_CvrefSender&& __sndr, _Env __env) :
-        __env_(__env::__join(
-            __env::__with(__stop_source_.get_token(), get_stop_token),
-            static_cast<_Env&&>(__env))),
-        __op_state2_(
-            connect(static_cast<_CvrefSender&&>(__sndr), __receiver_t{this}))
-    {}
-
-    void __start_op() noexcept
-    {
-        // the inner sender isn't running. if we reach here, then
-        // one way or the other, __shared_state::__notify() will be
-        // called, which decrements the ref count of *this.
-        // So we need to increment it here:
-        this->__inc_ref();
-
-        if (__stop_source_.stop_requested())
-        {
-            // 1. resets __head to completion state
-            // 2. notifies waiting threads
-            // 3. propagates "stopped" signal to `out_r'`
-            __notify();
-        }
-        else
-        {
-            stdexec::start(__op_state2_);
-        }
-    }
-
-    // This is called when the shared async operation completes:
-    void __notify() noexcept
-    {
-        void* const __completion_state = static_cast<void*>(this);
-        void* const __old = __head_.exchange(__completion_state,
-                                             std::memory_order_acq_rel);
-        auto* __state = static_cast<__local_state_base*>(__old);
-
-        while (__state != nullptr)
-        {
-            __local_state_base* __next = __state->__next_;
-            __state->__action_(__state, __action_kind::__notify);
-            __state = __next;
-        }
-
-        // The async operation has completed, so we can release our
-        // ref-count on it:
-        this->__dec_ref();
-    }
-
-    void __detach() noexcept
-    {
-        // Check to see if this operation was ever started. If not,
-        // detach the (potentially still running) operation:
-        if (nullptr == __head_.load(std::memory_order_acquire))
-        {
-            __stop_source_.request_stop();
-        }
-    }
-};
-
-template <class _Cvref, class _CvrefSenderId, class _EnvId>
-using __completions_t = //
-    __try_make_completion_signatures<
-        // NOT TO SPEC:
-        // See https://github.com/cplusplus/sender-receiver/issues/23
-        __cvref_t<_CvrefSenderId>, __env_t<__t<_EnvId>>,
-        completion_signatures<set_error_t(
-                                  __minvoke<_Cvref, std::exception_ptr>),
-                              set_stopped_t()>, // NOT TO SPEC
-        __transform<_Cvref,
-                    __mcompose<__q<completion_signatures>, __qf<set_value_t>>>,
-        __transform<_Cvref,
-                    __mcompose<__q<completion_signatures>, __qf<set_error_t>>>>;
-
-template <class _Ty>
-using __clref_t = const __decay_t<_Ty>&;
-
-template <class _Ty>
-using __rref_t = __decay_t<_Ty>&&;
-
-template <class _Tag>
-using __cvref_results_t = //
-    __if_c<same_as<_Tag, __split::__split_t>, __q<__clref_t>, __q<__rref_t>>;
-
-template <class _Tag>
-inline auto __get_completion_signatures_fn() noexcept
-{ //
-    return
-        []<template <class> class _Data, class _ShState>(
-            auto, const _Data<_ShState>&) //
-        -> __mapply<__mbind_front_q<__completions_t, __cvref_results_t<_Tag>>,
-                    _ShState> { return {}; };
-}
-
-template <class _Tag>
-struct __shared_impl : __sexpr_defaults
-{
-    static constexpr auto get_state = //
-        []<class _Sender, class _Receiver>(
-            _Sender&& __sndr,
-            _Receiver&) noexcept -> __local_state<_Sender, _Receiver> {
-        static_assert(sender_expr_for<_Sender, _Tag>);
-        return __local_state<_Sender, _Receiver>{
-            static_cast<_Sender&&>(__sndr)};
-    };
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Self, class _OtherEnv>(_Self&&, _OtherEnv&&) noexcept
-        -> __call_result_t<__sexpr_apply_t, _Self,
-                           __result_of<__get_completion_signatures_fn<_Tag>>> {
-        static_assert(sender_expr_for<_Self, _Tag>);
-        return {};
-    };
-
-    static constexpr auto start = //
-        []<class _Sender, class _Receiver>(
-            __local_state<_Sender, _Receiver>& __state,
-            _Receiver& __rcvr) noexcept -> void {
-        auto* __shared_state = __state.__shared_state_.get();
-        std::atomic<void*>& __head = __shared_state->__head_;
-        void* const __completion_state = static_cast<void*>(__shared_state);
-        void* __old = __head.load(std::memory_order_acquire);
-
-        if (__old != __completion_state)
-        {
-            __state.__on_stop_.emplace(
-                get_stop_token(stdexec::get_env(__rcvr)),
-                __on_stop_request{__shared_state->__stop_source_});
-
-            if constexpr (same_as<_Tag, __ensure_started::__ensure_started_t>)
-            {
-                // Check if the stop_source has requested cancellation
-                if (__shared_state->__stop_source_.stop_requested())
-                {
-                    // Stop has already been requested. Don't bother starting
-                    // the child operations.
-                    stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
-                    return;
-                }
-            }
-        }
-
-        // With the split algorithm, multiple split senders can be started
-        // simultaneously, but only one should start the async operation. The
-        // following loop atomically (re)tries to set the pointer to the head of
-        // the list to __state. When it finally succeeds, the prior value is
-        // checked. If it is nullptr, then this split sender has won the race
-        // and has the honor of starting the async operation.
-        do
-        {
-            if (__old == __completion_state)
-            {
-                __state.template __action<_Tag>(&__state,
-                                                __action_kind::__notify);
-                return;
-            }
-            __state.__next_ = static_cast<__local_state_base*>(__old);
-        } while (!__head.compare_exchange_weak(
-            __old, static_cast<void*>(&__state), std::memory_order_release,
-            std::memory_order_acquire));
-
-        if constexpr (same_as<_Tag, __split::__split_t>)
-        {
-            if (__old == nullptr)
-            {
-                __shared_state->__start_op();
-            }
-        }
-    };
-};
-} // namespace __shared
-
-////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.split]
-namespace __split
-{
-using namespace __shared;
-
-template <class _ShState>
-struct __data
-{
-    explicit __data(__intrusive_ptr<_ShState> __shared_state) noexcept :
-        __shared_state(std::move(__shared_state))
-    {}
-
-    __intrusive_ptr<_ShState> __shared_state;
-};
-
-struct __split_t
-{};
-
-struct split_t
-{
-    template <sender _Sender, class _Env = empty_env>
-        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
-    auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
-        -> __well_formed_sender auto
-    {
-        auto __domain = __get_late_domain(__sndr, __env);
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<split_t>(static_cast<_Env&&>(__env),
-                                            static_cast<_Sender&&>(__sndr)));
-    }
-
-    STDEXEC_ATTRIBUTE((always_inline))
-
-    __binder_back<split_t> operator()() const
-    {
-        return {{}, {}, {}};
-    }
-
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(split_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(const _Sender&)),
-                             _Sender),
-                tag_invoke_t(split_t, _Sender)>;
-
-    template <class _CvrefSender, class _Env>
-    using __receiver_t =
-        __t<__meval<__receiver, __cvref_id<_CvrefSender>, __id<_Env>>>;
-
-    template <class _Sender>
-    static auto transform_sender(_Sender&& __sndr)
-    {
-        using _Receiver =
-            __receiver_t<__child_of<_Sender>, __decay_t<__data_of<_Sender>>>;
-        static_assert(sender_to<__child_of<_Sender>, _Receiver>);
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             [&]<class _Env, class _Child>(
-                                 __ignore, _Env&& __env, _Child&& __child) {
-            auto __state =
-                __make_intrusive<__shared_state<_Child, __decay_t<_Env>>>(
-                    static_cast<_Child&&>(__child), static_cast<_Env&&>(__env));
-            return __make_sexpr<__split_t>(__data{std::move(__state)});
-        });
-    }
-};
-} // namespace __split
-
-using __split::split_t;
-inline constexpr split_t split{};
-
-template <>
-struct __sexpr_impl<__split::__split_t> :
-    __shared::__shared_impl<__split::__split_t>
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.ensure_started]
-namespace __ensure_started
-{
-using namespace __shared;
-
-// Each ensure_started sender has one of these, created when
-// ensure_started() is called.
-template <class _ShState>
-struct __data
-{
-    explicit __data(__intrusive_ptr<_ShState> __ptr) noexcept :
-        __shared_state(std::move(__ptr))
-    {
-        // Eagerly launch the async operation.
-        __shared_state->__start_op();
-    }
-
-    __data(__data&&) noexcept = default;
-    auto operator=(__data&&) noexcept -> __data& = default;
-
-    ~__data()
-    {
-        if (__shared_state != nullptr)
-        {
-            // detach from the still-running operation.
-            // NOT TO SPEC: This also requests cancellation.
-            __shared_state->__detach();
-        }
-    }
-
-    __intrusive_ptr<_ShState> __shared_state;
-};
-
-struct __ensure_started_t
-{};
-
-struct ensure_started_t
-{
-    template <sender _Sender, class _Env = empty_env>
-        requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
-    [[nodiscard]] auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
-        -> __well_formed_sender auto
-    {
-        if constexpr (sender_expr_for<_Sender, __ensure_started_t>)
-        {
-            return static_cast<_Sender&&>(__sndr);
-        }
-        else
-        {
-            auto __domain = __get_late_domain(__sndr, __env);
-            return stdexec::transform_sender(
-                __domain,
-                __make_sexpr<ensure_started_t>(static_cast<_Env&&>(__env),
-                                               static_cast<_Sender&&>(__sndr)));
-        }
-    }
-
-    STDEXEC_ATTRIBUTE((always_inline))
-
-    __binder_back<ensure_started_t> operator()() const
-    {
-        return {{}, {}, {}};
-    }
-
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(ensure_started_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(const _Sender&)),
-                             _Sender),
-                tag_invoke_t(ensure_started_t, _Sender)>;
-
-    template <class _CvrefSender, class _Env>
-    using __receiver_t =
-        __t<__meval<__receiver, __cvref_id<_CvrefSender>, __id<_Env>>>;
-
-    template <class _Sender>
-    static auto transform_sender(_Sender&& __sndr)
-    {
-        using _Receiver =
-            __receiver_t<__child_of<_Sender>, __decay_t<__data_of<_Sender>>>;
-        static_assert(sender_to<__child_of<_Sender>, _Receiver>);
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             [&]<class _Env, class _Child>(
-                                 __ignore, _Env&& __env, _Child&& __child) {
-            auto __state =
-                __make_intrusive<__shared_state<_Child, __decay_t<_Env>>>(
-                    static_cast<_Child&&>(__child), static_cast<_Env&&>(__env));
-            return __make_sexpr<__ensure_started_t>(__data{std::move(__state)});
-        });
-    }
-};
-} // namespace __ensure_started
-
-using __ensure_started::ensure_started_t;
-inline constexpr ensure_started_t ensure_started{};
-
-template <>
-struct __sexpr_impl<__ensure_started::__ensure_started_t> :
-    __shared::__shared_impl<__ensure_started::__ensure_started_t>
-{};
-
-STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE_EDG(not_used_in_partial_spec_arg_list)
-
-/////////////////////////////////////////////////////////////////////////////
-// a receiver adaptor that augments its environment
-namespace __detail
-{
-template <auto _ReceiverPtr, auto... _EnvFns>
-struct __receiver_with;
-
-template <class _Operation, class _Receiver,
-          _Receiver _Operation::*_ReceiverPtr, auto... _EnvFns>
-struct __receiver_with<_ReceiverPtr, _EnvFns...>
-{
-    struct __t : receiver_adaptor<__t>
-    {
-        using __id = __receiver_with;
-        using __env_t = __env::__join_t<__result_of<_EnvFns, _Operation*>...,
-                                        env_of_t<_Receiver>>;
-
-        _Operation* __op_state_;
-
-        auto base() && noexcept -> _Receiver&&
-        {
-            return static_cast<_Receiver&&>(__op_state_->*_ReceiverPtr);
-        }
-
-        auto get_env() const noexcept -> __env_t
-        {
-            return __env::__join(_EnvFns(__op_state_)...,
-                                 stdexec::get_env(__op_state_->*_ReceiverPtr));
-        }
-    };
-};
-} // namespace __detail
-
-STDEXEC_PRAGMA_POP()
-
-//////////////////////////////////////////////////////////////////////////////
-// [exec.let]
-namespace __let
-{
-template <class _Set, class _Domain = dependent_domain>
-struct __let_t;
-
-template <class _Set>
-inline constexpr __mstring __in_which_let_msg{
-    "In stdexec::let_value(Sender, Function)..."};
-
-template <>
-inline constexpr __mstring __in_which_let_msg<set_error_t>{
-    "In stdexec::let_error(Sender, Function)..."};
-
-template <>
-inline constexpr __mstring __in_which_let_msg<set_stopped_t>{
-    "In stdexec::let_stopped(Sender, Function)..."};
-
-template <class _Set>
-using __on_not_callable = __callable_error<__in_which_let_msg<_Set>>;
-
-// FUTURE: when we have a scheduler query for "always completes inline",
-// then we can use that instead of hard-coding `__inln::__scheduler` here.
-template <class _Scheduler>
-concept __unknown_context =
-    __one_of<_Scheduler, __none_such, __inln::__scheduler>;
-
-template <class _Receiver, class _Scheduler>
-struct __receiver_with_sched
-{
-    using receiver_concept = receiver_t;
-    _Receiver __rcvr_;
-    _Scheduler __sched_;
-
-    template <__completion_tag _Tag, same_as<__receiver_with_sched> _Self,
-              class... _As>
-    friend void tag_invoke(_Tag, _Self&& __self, _As&&... __as) noexcept
-    {
-        _Tag()(static_cast<_Receiver&&>(__self.__rcvr_),
-               static_cast<_As&&>(__as)...);
-    }
-
-    template <same_as<get_env_t> _Tag>
-    friend auto tag_invoke(_Tag, const __receiver_with_sched& __self) noexcept
-    {
-        return __env::__join(
-            __env::__with(__self.__sched_, get_scheduler),
-            __env::__without(get_env(__self.__rcvr_), get_domain));
-    }
-};
-
-template <class _Receiver, class _Scheduler>
-__receiver_with_sched(_Receiver, _Scheduler)
-    -> __receiver_with_sched<_Receiver, _Scheduler>;
-
-// If the input sender knows its completion scheduler, make it the current
-// scheduler in the environment seen by the result sender.
-template <class _Env, class _Scheduler>
-using __result_env_t =
-    __if_c<__unknown_context<_Scheduler>, _Env,
-           __env::__join_t<__env::__with<_Scheduler, get_scheduler_t>,
-                           __env::__without_t<_Env, get_domain_t>>>;
-
-template <class _Tp>
-using __decay_ref = __decay_t<_Tp>&;
-
-template <__mstring _Where, __mstring _What>
-struct _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_
-{};
-
-#if STDEXEC_NVHPC()
-template <class _Sender, class _Env, class _Set>
-struct __bad_result_sender_
-{
-    using __t = __mexception<
-        _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_<
-            __in_which_let_msg<_Set>,
-            "The function must return a valid sender for the current environment"_mstr>,
-        _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
-};
-template <class _Sender, class _Env, class _Set>
-using __bad_result_sender = __t<__bad_result_sender_<_Sender, _Env, _Set>>;
-#else
-template <class _Sender, class _Env, class _Set>
-using __bad_result_sender = __mexception<
-    _FUNCTION_MUST_RETURN_A_VALID_SENDER_IN_THE_CURRENT_ENVIRONMENT_<
-        __in_which_let_msg<_Set>,
-        "The function must return a valid sender for the current environment"_mstr>,
-    _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
-#endif
-
-template <class _Sender, class _Env, class _Set>
-using __ensure_sender = //
-    __minvoke_if_c<sender_in<_Sender, _Env>, __q<__midentity>,
-                   __mbind_back_q<__bad_result_sender, _Env, _Set>, _Sender>;
-
-// A metafunction that computes the result sender type for a given set of
-// argument types
-template <class _Fun, class _Set, class _Env, class _Sched>
-using __result_sender_fn = //
-    __mcompose<
-        __mbind_back_q<__ensure_sender, __result_env_t<_Env, _Sched>, _Set>,
-        __transform<__q<__decay_ref>,
-                    __mbind_front<__mtry_catch_q<__call_result_t,
-                                                 __on_not_callable<_Set>>,
-                                  _Fun>>>;
-
-// The receiver that gets connected to the result sender is the input receiver,
-// possibly augmented with the input sender's completion scheduler (which is
-// where the result sender will be started).
-template <class _Receiver, class _Scheduler>
-using __result_receiver_t =
-    __if_c<__unknown_context<_Scheduler>, _Receiver,
-           __receiver_with_sched<_Receiver, _Scheduler>>;
-
-template <class _Receiver, class _Fun, class _Set, class _Sched>
-using __op_state_for = //
-    __mcompose<__mbind_back_q<connect_result_t,
-                              __result_receiver_t<_Receiver, _Sched>>,
-               __result_sender_fn<_Fun, _Set, env_of_t<_Receiver>, _Sched>>;
-
-template <class _Set, class _Sig>
-struct __tfx_signal_fn
-{
-    template <class, class, class>
-    using __f = completion_signatures<_Sig>;
-};
-
-template <class _Set, class... _Args>
-struct __tfx_signal_fn<_Set, _Set(_Args...)>
-{
-    template <class _Env, class _Fun, class _Sched>
-    using __f = //
-        __try_make_completion_signatures<
-            __minvoke<__result_sender_fn<_Fun, _Set, _Env, _Sched>, _Args...>,
-            __result_env_t<_Env, _Sched>,
-            // because we don't know if connect-ing the result sender will
-            // throw:
-            completion_signatures<set_error_t(std::exception_ptr)>>;
-};
-
-// `_Sched` is the input sender's completion scheduler, or __none_such if it
-// doesn't have one.
-template <class _Env, class _Fun, class _Set, class _Sched, class _Sig>
-using __tfx_signal_t =
-    __minvoke<__tfx_signal_fn<_Set, _Sig>, _Env, _Fun, _Sched>;
-
-template <class _Sender, class _Set>
-using __completion_sched = __query_result_or_t<get_completion_scheduler_t<_Set>,
-                                               env_of_t<_Sender>, __none_such>;
-
-template <class _CvrefSender, class _Env, class _LetTag, class _Fun>
-using __completions = //
-    __mapply<__transform<__mbind_front_q<
-                             __tfx_signal_t, _Env, _Fun, __t<_LetTag>,
-                             __completion_sched<_CvrefSender, __t<_LetTag>>>,
-                         __q<__concat_completion_signatures_t>>,
-             __completion_signatures_of_t<_CvrefSender, _Env>>;
-
-template <__mstring _Where, __mstring _What>
-struct _NO_COMMON_DOMAIN_
-{};
-
-template <class _Set>
-using __no_common_domain_t = //
-    _NO_COMMON_DOMAIN_<
-        __in_which_let_msg<_Set>,
-        "The senders returned by Function do not all share a common domain"_mstr>;
-
-template <class _Set>
-using __try_common_domain_fn = //
-    __mtry_catch_q<
-        __domain::__common_domain_t,
-        __mcompose<__mbind_front_q<__mexception, __no_common_domain_t<_Set>>,
-                   __q<_WITH_SENDERS_>>>;
-
-// Compute all the domains of all the result senders and make sure they're all
-// the same
-template <class _Set, class _Child, class _Fun, class _Env, class _Sched>
-using __result_domain_t = //
-    __gather_completions_for<_Set, _Child, _Env,
-                             __result_sender_fn<_Fun, _Set, _Env, _Sched>,
-                             __try_common_domain_fn<_Set>>;
-
-template <class _LetTag, class _Env>
-auto __mk_transform_env_fn(const _Env& __env) noexcept
-{
-    using _Set = __t<_LetTag>;
-    return [&]<class _Fun, class _Child>(__ignore, _Fun&&,
-                                         _Child&& __child) -> decltype(auto) {
-        using __completions_t = __completion_signatures_of_t<_Child, _Env>;
-        if constexpr (__merror<__completions_t>)
-        {
-            return __completions_t();
-        }
-        else
-        {
-            using _Scheduler = __completion_sched<_Child, _Set>;
-            if constexpr (__unknown_context<_Scheduler>)
-            {
-                return (__env);
-            }
-            else
-            {
-                return __env::__join(
-                    __env::__with(get_completion_scheduler<_Set>(
-                                      stdexec::get_env(__child)),
-                                  get_scheduler),
-                    __env::__without(__env, get_domain));
-            }
-        }
-    };
-}
-
-template <class _LetTag, class _Env>
-auto __mk_transform_sender_fn(const _Env&) noexcept
-{
-    using _Set = __t<_LetTag>;
-    return
-        []<class _Fun, class _Child>(__ignore, _Fun&& __fun, _Child&& __child) {
-        using __completions_t = __completion_signatures_of_t<_Child, _Env>;
-        if constexpr (__merror<__completions_t>)
-        {
-            return __completions_t();
-        }
-        else
-        {
-            using _Sched = __completion_sched<_Child, _Set>;
-            using _Domain = __result_domain_t<_Set, _Child, _Fun, _Env, _Sched>;
-            if constexpr (__merror<_Domain>)
-            {
-                return _Domain();
-            }
-            else if constexpr (same_as<_Domain, dependent_domain>)
-            {
-                using _Domain2 = __late_domain_of_t<_Child, _Env>;
-                return __make_sexpr<__let_t<_Set, _Domain2>>(
-                    static_cast<_Fun&&>(__fun), static_cast<_Child&&>(__child));
-            }
-            else
-            {
-                static_assert(!same_as<_Domain, __none_such>);
-                return __make_sexpr<__let_t<_Set, _Domain>>(
-                    static_cast<_Fun&&>(__fun), static_cast<_Child&&>(__child));
-            }
-        }
-    };
-}
-
-template <class _Receiver, class _Fun, class _Set, class _Sched,
-          class... _Tuples>
-struct __let_state
-{
-    using __fun_t = _Fun;
-    using __sched_t = _Sched;
-
-    using __result_variant = std::variant<std::monostate, _Tuples...>;
-
-    using __op_state_variant = //
-        __minvoke<__transform<
-                      __uncurry<__op_state_for<_Receiver, _Fun, _Set, _Sched>>,
-                      __nullable_variant_t>,
-                  _Tuples...>;
-
-    auto __get_result_receiver(_Receiver&& __rcvr) -> decltype(auto)
-    {
-        if constexpr (__unknown_context<_Sched>)
-        {
-            return static_cast<_Receiver&&>(__rcvr);
-        }
-        else
-        {
-            return __receiver_with_sched{static_cast<_Receiver&&>(__rcvr),
-                                         this->__sched_};
-        }
-    }
-
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Fun __fun_;
-    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Sched __sched_;
-    __result_variant __args_;
-    __op_state_variant __op_state3_;
-};
-
-template <class _Set, class _Domain>
-struct __let_t
-{
-    using __domain_t = _Domain;
-    using __t = _Set;
-
-    template <sender _Sender, __movable_value _Fun>
-    auto operator()(_Sender&& __sndr, _Fun __fun) const -> __well_formed_sender
-        auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<__let_t<_Set>>(static_cast<_Fun&&>(__fun),
-                                        static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <class _Fun>
-    STDEXEC_ATTRIBUTE((always_inline))
-    __binder_back<__let_t, _Fun> operator()(_Fun __fun) const
-    {
-        return {{}, {}, {static_cast<_Fun&&>(__fun)}};
-    }
-
-    using _Sender = __1;
-    using _Function = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(__let_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(const _Sender&)),
-                             _Sender, _Function),
-                tag_invoke_t(__let_t, _Sender, _Function)>;
-
-    template <sender_expr_for<__let_t<_Set>> _Sender, class _Env>
-    static auto transform_env(_Sender&& __sndr, const _Env& __env)
-        -> decltype(auto)
-    {
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             __mk_transform_env_fn<__let_t<_Set>>(__env));
-    }
-
-    template <sender_expr_for<__let_t<_Set>> _Sender, class _Env>
-        requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-        -> decltype(auto)
-    {
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             __mk_transform_sender_fn<__let_t<_Set>>(__env));
-    }
-};
-
-template <class _Set, class _Domain>
-struct __let_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class _Child>(__ignore, const _Child& __child) noexcept {
-        return __env::__join(__env::__with(_Domain(), get_domain),
-                             stdexec::get_env(__child));
-    };
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Self, class _Env>(_Self&&, _Env&&) noexcept
-        -> __completions<__child_of<_Self>, _Env, __let_t<_Set, _Domain>,
-                         __data_of<_Self>> {
-        static_assert(sender_expr_for<_Self, __let_t<_Set, _Domain>>);
-        return {};
-    };
-
-    static constexpr auto get_state = //
-        []<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver&) {
-        static_assert(sender_expr_for<_Sender, __let_t<_Set, _Domain>>);
-        using _Fun = __data_of<_Sender>;
-        using _Sched = __completion_sched<_Sender, _Set>;
-        using __mk_let_state =
-            __mbind_front_q<__let_state, _Receiver, _Fun, _Set, _Sched>;
-
-        using __let_state_t =
-            __gather_completions_for<_Set, __child_of<_Sender>,
-                                     env_of_t<_Receiver>, __q<__decayed_tuple>,
-                                     __mk_let_state>;
-
-        _Sched __sched = query_or(get_completion_scheduler<_Set>,
-                                  stdexec::get_env(__sndr), __none_such());
-        return __let_state_t{
-            STDEXEC_CALL_EXPLICIT_THIS_MEMFN(static_cast<_Sender&&>(__sndr),
-                                             apply)(__detail::__get_data()),
-            __sched};
-    };
-
-    template <class _State, class _Receiver, class... _As>
-    static void __bind(_State& __state, _Receiver& __rcvr,
-                       _As&&... __as) noexcept
-    {
-        try
-        {
-            auto& __args =
-                __state.__args_.template emplace<__decayed_tuple<_As...>>(
-                    static_cast<_As&&>(__as)...);
-            auto __sndr2 = __apply(std::move(__state.__fun_), __args);
-            auto __rcvr2 =
-                __state.__get_result_receiver(static_cast<_Receiver&&>(__rcvr));
-            auto __mkop = [&] {
-                return stdexec::connect(std::move(__sndr2), std::move(__rcvr2));
-            };
-            auto& __op2 =
-                __state.__op_state3_.template emplace<decltype(__mkop())>(
-                    __conv{__mkop});
-            stdexec::start(__op2);
-        }
-        catch (...)
-        {
-            set_error(std::move(__rcvr), std::current_exception());
-        }
-    }
-
-    static constexpr auto complete = //
-        []<class _State, class _Receiver, class _Tag, class... _As>(
-            __ignore, _State& __state, _Receiver& __rcvr, _Tag,
-            _As&&... __as) noexcept -> void {
-        if constexpr (std::same_as<_Tag, _Set>)
-        {
-            __bind(__state, __rcvr, static_cast<_As&&>(__as)...);
-        }
-        else
-        {
-            _Tag()(static_cast<_Receiver&&>(__rcvr),
-                   static_cast<_As&&>(__as)...);
-        }
-    };
-};
-} // namespace __let
-
-using let_value_t = __let::__let_t<set_value_t>;
-inline constexpr let_value_t let_value{};
-
-using let_error_t = __let::__let_t<set_error_t>;
-inline constexpr let_error_t let_error{};
-
-using let_stopped_t = __let::__let_t<set_stopped_t>;
-inline constexpr let_stopped_t let_stopped{};
-
-template <class _Set, class _Domain>
-struct __sexpr_impl<__let::__let_t<_Set, _Domain>> :
-    __let::__let_impl<_Set, _Domain>
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.stopped_as_optional]
-// [execution.senders.adaptors.stopped_as_error]
-namespace __stopped_as_xxx
-{
-struct stopped_as_optional_t
-{
-    template <sender _Sender>
-    auto operator()(_Sender&& __sndr) const
-    {
-        return __make_sexpr<stopped_as_optional_t>(
-            __(), static_cast<_Sender&&>(__sndr));
-    }
-
-    STDEXEC_ATTRIBUTE((always_inline))
-
-    __binder_back<stopped_as_optional_t> operator()() const noexcept
-    {
-        return {};
-    }
-};
-
-struct __stopped_as_optional_impl : __sexpr_defaults
-{
-    template <class... _Tys>
-        requires(sizeof...(_Tys) == 1)
-    using __set_value_t =
-        completion_signatures<set_value_t(std::optional<__decay_t<_Tys>>...)>;
-
-    template <class _Ty>
-    using __set_error_t = completion_signatures<set_error_t(_Ty)>;
-
-    static constexpr auto get_completion_signatures =         //
-        []<class _Self, class _Env>(_Self&&, _Env&&) noexcept //
-        -> make_completion_signatures<
-            __child_of<_Self>, _Env,
-            completion_signatures<set_error_t(std::exception_ptr)>,
-            __set_value_t, __set_error_t, completion_signatures<>> {
-        static_assert(sender_expr_for<_Self, stopped_as_optional_t>);
-        return {};
-    };
-
-    static constexpr auto get_state = //
-        []<class _Self, class _Receiver>(_Self&&, _Receiver&) noexcept
-        requires __single_typed_sender<__child_of<_Self>, env_of_t<_Receiver>>
-    {
-        static_assert(sender_expr_for<_Self, stopped_as_optional_t>);
-        using _Value = __decay_t<
-            __single_sender_value_t<__child_of<_Self>, env_of_t<_Receiver>>>;
-        return __mtype<_Value>();
-    };
-
-    static constexpr auto complete = //
-        []<class _State, class _Receiver, __completion_tag _Tag,
-           class... _Args>(__ignore, _State&, _Receiver& __rcvr, _Tag,
-                           _Args&&... __args) noexcept -> void {
-        if constexpr (same_as<_Tag, set_value_t>)
-        {
-            try
-            {
-                static_assert(constructible_from<__t<_State>, _Args...>);
-                stdexec::set_value(static_cast<_Receiver&&>(__rcvr),
-                                   std::optional<__t<_State>>{
-                                       static_cast<_Args&&>(__args)...});
-            }
-            catch (...)
-            {
-                stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
-                                   std::current_exception());
-            }
-        }
-        else if constexpr (same_as<_Tag, set_error_t>)
-        {
-            stdexec::set_error(static_cast<_Receiver&&>(__rcvr),
-                               static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            stdexec::set_value(static_cast<_Receiver&&>(__rcvr),
-                               std::optional<__t<_State>>{std::nullopt});
-        }
-    };
-};
-
-struct stopped_as_error_t
-{
-    template <sender _Sender, __movable_value _Error>
-    auto operator()(_Sender&& __sndr, _Error __err) const
-    {
-        return static_cast<_Sender&&>(__sndr) |
-               let_stopped(
-                   [__err2 = static_cast<_Error&&>(__err)]() mutable //
-                   noexcept(std::is_nothrow_move_constructible_v<_Error>) {
-            return just_error(static_cast<_Error&&>(__err2));
-        });
-    }
-
-    template <__movable_value _Error>
-    STDEXEC_ATTRIBUTE((always_inline))
-    auto operator()(_Error __err) const
-        -> __binder_back<stopped_as_error_t, _Error>
-    {
-        return {{}, {}, {static_cast<_Error&&>(__err)}};
-    }
-};
-} // namespace __stopped_as_xxx
-
-using __stopped_as_xxx::stopped_as_optional_t;
-inline constexpr stopped_as_optional_t stopped_as_optional{};
-using __stopped_as_xxx::stopped_as_error_t;
-inline constexpr stopped_as_error_t stopped_as_error{};
-
-template <>
-struct __sexpr_impl<stopped_as_optional_t> :
-    __stopped_as_xxx::__stopped_as_optional_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// run_loop
-namespace __loop
-{
-class run_loop;
-
-struct __task : __immovable
-{
-    __task* __next_ = this;
-
-    union
-    {
-        void (*__execute_)(__task*) noexcept;
-        __task* __tail_;
-    };
-
-    void __execute() noexcept
-    {
-        (*__execute_)(this);
-    }
-};
-
-template <class _ReceiverId>
-struct __operation
-{
-    using _Receiver = stdexec::__t<_ReceiverId>;
-
-    struct __t : __task
-    {
-        using __id = __operation;
-
-        run_loop* __loop_;
-        STDEXEC_ATTRIBUTE((no_unique_address))
-        _Receiver __rcvr_;
-
-        static void __execute_impl(__task* __p) noexcept
-        {
-            auto& __rcvr = static_cast<__t*>(__p)->__rcvr_;
-            try
-            {
-                if (get_stop_token(get_env(__rcvr)).stop_requested())
-                {
-                    set_stopped(static_cast<_Receiver&&>(__rcvr));
-                }
-                else
-                {
-                    set_value(static_cast<_Receiver&&>(__rcvr));
-                }
-            }
-            catch (...)
-            {
-                set_error(static_cast<_Receiver&&>(__rcvr),
-                          std::current_exception());
-            }
-        }
-
-        explicit __t(__task* __tail) noexcept : __task{.__tail_ = __tail} {}
-
-        __t(__task* __next, run_loop* __loop, _Receiver __rcvr) :
-            __task{{}, __next, {&__execute_impl}}, __loop_{__loop},
-            __rcvr_{static_cast<_Receiver&&>(__rcvr)}
-        {}
-
-        friend void tag_invoke(start_t, __t& __self) noexcept
-        {
-            __self.__start_();
-        }
-
-        void __start_() noexcept;
-    };
-};
-
-class run_loop
-{
-    template <class... Ts>
-    using __completion_signatures_ = completion_signatures<Ts...>;
-
-    template <class>
-    friend struct __operation;
-
-  public:
-    struct __scheduler
-    {
-        using __t = __scheduler;
-        using __id = __scheduler;
-        auto operator==(const __scheduler&) const noexcept -> bool = default;
-
-      private:
-        struct __schedule_task
-        {
-            using __t = __schedule_task;
-            using __id = __schedule_task;
-            using sender_concept = sender_t;
-            using completion_signatures = //
-                __completion_signatures_<set_value_t(),
-                                         set_error_t(std::exception_ptr),
-                                         set_stopped_t()>;
-
-          private:
-            friend __scheduler;
-
-            template <class _Receiver>
-            using __operation =
-                stdexec::__t<__operation<stdexec::__id<_Receiver>>>;
-
-            template <class _Receiver>
-            friend auto tag_invoke(connect_t, const __schedule_task& __self,
-                                   _Receiver __rcvr) -> __operation<_Receiver>
-            {
-                return __self.__connect_(static_cast<_Receiver&&>(__rcvr));
-            }
-
-            template <class _Receiver>
-            auto __connect_(_Receiver&& __rcvr) const -> __operation<_Receiver>
-            {
-                return {&__loop_->__head_, __loop_,
-                        static_cast<_Receiver&&>(__rcvr)};
-            }
-
-            struct __env
-            {
-                run_loop* __loop_;
-
-                template <class _CPO>
-                friend auto tag_invoke(get_completion_scheduler_t<_CPO>,
-                                       const __env& __self) noexcept
-                    -> __scheduler
-                {
-                    return __self.__loop_->get_scheduler();
-                }
-            };
-
-            friend auto tag_invoke(get_env_t,
-                                   const __schedule_task& __self) noexcept
-                -> __env
-            {
-                return __env{__self.__loop_};
-            }
-
-            explicit __schedule_task(run_loop* __loop) noexcept :
-                __loop_(__loop)
-            {}
-
-            run_loop* const __loop_;
-        };
-
-        friend run_loop;
-
-        explicit __scheduler(run_loop* __loop) noexcept : __loop_(__loop) {}
-
-        friend auto tag_invoke(schedule_t, const __scheduler& __self) noexcept
-            -> __schedule_task
-        {
-            return __self.__schedule();
-        }
-
-        friend auto tag_invoke(get_forward_progress_guarantee_t,
-                               const __scheduler&) noexcept
-            -> stdexec::forward_progress_guarantee
-        {
-            return stdexec::forward_progress_guarantee::parallel;
-        }
-
-        // BUGBUG NOT TO SPEC
-        friend auto tag_invoke(execute_may_block_caller_t,
-                               const __scheduler&) noexcept -> bool
-        {
-            return false;
-        }
-
-        [[nodiscard]] auto __schedule() const noexcept -> __schedule_task
-        {
-            return __schedule_task{__loop_};
-        }
-
-        run_loop* __loop_;
-    };
-
-    auto get_scheduler() noexcept -> __scheduler
-    {
-        return __scheduler{this};
-    }
-
-    void run();
-
-    void finish();
-
-  private:
-    void __push_back_(__task* __task);
-    auto __pop_front_() -> __task*;
-
-    std::mutex __mutex_;
-    std::condition_variable __cv_;
-    __task __head_{.__tail_ = &__head_};
-    bool __stop_ = false;
-};
-
-template <class _ReceiverId>
-inline void __operation<_ReceiverId>::__t::__start_() noexcept
-{
-    try
-    {
-        __loop_->__push_back_(this);
-    }
-    catch (...)
-    {
-        set_error(static_cast<_Receiver&&>(__rcvr_), std::current_exception());
-    }
-}
-
-inline void run_loop::run()
-{
-    for (__task* __task; (__task = __pop_front_()) != &__head_;)
-    {
-        __task->__execute();
-    }
-}
-
-inline void run_loop::finish()
-{
-    std::unique_lock __lock{__mutex_};
-    __stop_ = true;
-    __cv_.notify_all();
-}
-
-inline void run_loop::__push_back_(__task* __task)
-{
-    std::unique_lock __lock{__mutex_};
-    __task->__next_ = &__head_;
-    __head_.__tail_ = __head_.__tail_->__next_ = __task;
-    __cv_.notify_one();
-}
-
-inline auto run_loop::__pop_front_() -> __task*
-{
-    std::unique_lock __lock{__mutex_};
-    __cv_.wait(__lock,
-               [this] { return __head_.__next_ != &__head_ || __stop_; });
-    if (__head_.__tail_ == __head_.__next_)
-        __head_.__tail_ = &__head_;
-    return std::exchange(__head_.__next_, __head_.__next_->__next_);
-}
-} // namespace __loop
-
-// NOT TO SPEC
-using run_loop = __loop::run_loop;
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.schedule_from]
-namespace __schedule_from
-{
-// Compute a variant type that is capable of storing the results of the
-// input sender when it completes. The variant has type:
-//   variant<
-//     monostate,
-//     tuple<set_stopped_t>,
-//     tuple<set_value_t, __decay_t<_Values1>...>,
-//     tuple<set_value_t, __decay_t<_Values2>...>,
-//        ...
-//     tuple<set_error_t, __decay_t<_Error1>>,
-//     tuple<set_error_t, __decay_t<_Error2>>,
-//        ...
-//   >
-template <class _CvrefSender, class _Env>
-using __variant_for_t = __compl_sigs::__maybe_for_all_sigs<
-    __completion_signatures_of_t<_CvrefSender, _Env>, __q<__decayed_tuple>,
-    __nullable_variant_t>;
-
-template <class _Tp>
-using __decay_rvalue_ref = __decay_t<_Tp>&&;
-
-template <class _Tag>
-using __decay_signature =
-    __transform<__q<__decay_rvalue_ref>,
-                __mcompose<__q<completion_signatures>, __qf<_Tag>>>;
-
-template <class... _Ts>
-using __all_nothrow_decay_copyable_ =
-    __mbool<(__nothrow_decay_copyable<_Ts> && ...)>;
-
-template <class _CvrefSender, class _Env>
-using __all_values_and_errors_nothrow_decay_copyable = //
-    __compl_sigs::__maybe_for_all_sigs<
-        __completion_signatures_of_t<_CvrefSender, _Env>,
-        __q<__all_nothrow_decay_copyable_>, __q<__mand>>;
-
-template <class _CvrefSender, class _Env>
-using __with_error_t = //
-    __if<__all_values_and_errors_nothrow_decay_copyable<_CvrefSender, _Env>,
-         completion_signatures<>, __with_exception_ptr>;
-
-template <class _Scheduler, class _CvrefSender, class _Env>
-using __completions_t = //
-    __try_make_completion_signatures<
-        _CvrefSender, _Env,
-        __try_make_completion_signatures<schedule_result_t<_Scheduler>, _Env,
-                                         __with_error_t<_CvrefSender, _Env>,
-                                         __mconst<completion_signatures<>>>,
-        __decay_signature<set_value_t>, __decay_signature<set_error_t>>;
-
-template <class _SchedulerId>
-struct __environ
-{
-    using _Scheduler = stdexec::__t<_SchedulerId>;
-
-    struct __t :
-        __env::__with<stdexec::__t<_SchedulerId>,
-                      get_completion_scheduler_t<set_value_t>,
-                      get_completion_scheduler_t<set_stopped_t>>
-    {
-        using __id = __environ;
-
-        explicit __t(_Scheduler __sched) noexcept :
-            __t::__with{std::move(__sched)}
-        {}
-
-        template <same_as<get_domain_t> _Key>
-        friend auto tag_invoke(_Key, const __t& __self) noexcept
-        {
-            return query_or(get_domain, __self.__value_, default_domain());
-        }
-    };
-};
-
-template <class _Scheduler, class _Sexpr, class _Receiver>
-struct __state;
-
-// This receiver is to be completed on the execution context
-// associated with the scheduler. When the source sender
-// completes, the completion information is saved off in the
-// operation state so that when this receiver completes, it can
-// read the completion out of the operation state and forward it
-// to the output receiver after transitioning to the scheduler's
-// context.
-template <class _Scheduler, class _Sexpr, class _Receiver>
-struct __receiver2 :
-    receiver_adaptor<__receiver2<_Scheduler, _Sexpr, _Receiver>>
-{
-    explicit __receiver2(
-        __state<_Scheduler, _Sexpr, _Receiver>* __state) noexcept :
-        __state_{__state}
-    {}
-
-    auto base() && noexcept -> _Receiver&&
-    {
-        return std::move(__state_->__receiver());
-    }
-
-    auto base() const& noexcept -> const _Receiver&
-    {
-        return __state_->__receiver();
-    }
-
-    void set_value() && noexcept
-    {
-        STDEXEC_ASSERT(!__state_->__data_.valueless_by_exception());
-        std::visit(
-            [__state = __state_]<class _Tup>(_Tup& __tupl) noexcept -> void {
-            if constexpr (same_as<_Tup, std::monostate>)
-            {
-                std::terminate(); // reaching this indicates a bug in
-                                  // schedule_from
-            }
-            else
-            {
-                __apply(
-                    [&]<class... _Args>(auto __tag,
-                                        _Args&... __args) noexcept -> void {
-                    __tag(std::move(__state->__receiver()),
-                          static_cast<_Args&&>(__args)...);
-                },
-                    __tupl);
-            }
-        },
-            __state_->__data_);
-    }
-
-    __state<_Scheduler, _Sexpr, _Receiver>* __state_;
-};
-
-template <class _Scheduler, class _Sexpr, class _Receiver>
-struct __state : __enable_receiver_from_this<_Sexpr, _Receiver>
-{
-    using __variant_t =
-        __variant_for_t<__child_of<_Sexpr>, env_of_t<_Receiver>>;
-    using __receiver2_t = __receiver2<_Scheduler, _Sexpr, _Receiver>;
-
-    __variant_t __data_;
-    connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t> __state2_;
-
-    explicit __state(_Scheduler __sched) :
-        __data_(), __state2_(connect(schedule(__sched), __receiver2_t{this}))
-    {}
-};
-
-struct schedule_from_t
-{
-    template <scheduler _Scheduler, sender _Sender>
-    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        -> __well_formed_sender auto
-    {
-        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
-        auto __env = _Env{{static_cast<_Scheduler&&>(__sched)}};
-        auto __domain = query_or(get_domain, __sched, default_domain());
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<schedule_from_t>(
-                          std::move(__env), static_cast<_Sender&&>(__sndr)));
-    }
-
-    using _Sender = __1;
-    using _Env = __0;
-    using __legacy_customizations_t = __types<tag_invoke_t(
-        schedule_from_t, get_completion_scheduler_t<set_value_t>(_Env&),
-        _Sender)>;
-};
-
-struct __schedule_from_impl : __sexpr_defaults
-{
-    template <class _Sender>
-    using __scheduler_t =
-        __decay_t<__call_result_t<get_completion_scheduler_t<set_value_t>,
-                                  env_of_t<_Sender>>>;
-
-    static constexpr auto get_attrs = //
-        []<class _Data, class _Child>(const _Data& __data,
-                                      const _Child& __child) noexcept {
-        return __env::__join(__data, stdexec::get_env(__child));
-    };
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Sender, class _Env>(_Sender&&, const _Env&) noexcept
-        -> __completions_t<__scheduler_t<_Sender>, __child_of<_Sender>, _Env> {
-        static_assert(sender_expr_for<_Sender, schedule_from_t>);
-        return {};
-    };
-
-    static constexpr auto get_state =
-        []<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver&) {
-        static_assert(sender_expr_for<_Sender, schedule_from_t>);
-        auto __sched =
-            get_completion_scheduler<set_value_t>(stdexec::get_env(__sndr));
-        using _Scheduler = decltype(__sched);
-        return __state<_Scheduler, _Sender, _Receiver>{__sched};
-    };
-
-    static constexpr auto complete =
-        []<class _Tag, class... _Args>(__ignore, auto& __state, auto& __rcvr,
-                                       _Tag,
-                                       _Args&&... __args) noexcept -> void {
-        // Write the tag and the args into the operation state so that
-        // we can forward the completion from within the scheduler's
-        // execution context.
-        using __async_result = __decayed_tuple<_Tag, _Args...>;
-        if constexpr (__nothrow_constructible_from<__async_result, _Tag,
-                                                   _Args...>)
-        {
-            __state.__data_.template emplace<__async_result>(
-                _Tag(), static_cast<_Args&&>(__args)...);
-        }
-        else
-        {
-            try
-            {
-                __state.__data_.template emplace<__async_result>(
-                    _Tag(), static_cast<_Args&&>(__args)...);
-            }
-            catch (...)
-            {
-                set_error(std::move(__rcvr), std::current_exception());
-                return;
-            }
-        }
-        // Enqueue the schedule operation so the completion happens
-        // on the scheduler's execution context.
-        stdexec::start(__state.__state2_);
-    };
-};
-} // namespace __schedule_from
-
-using __schedule_from::schedule_from_t;
-inline constexpr schedule_from_t schedule_from{};
-
-template <>
-struct __sexpr_impl<schedule_from_t> : __schedule_from::__schedule_from_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.transfer]
-namespace __transfer
-{
-using __schedule_from::__environ;
-
-template <class _Env>
-using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>;
-
-template <class _Sender>
-using __lowered_t = //
-    __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>,
-                __child_of<_Sender>>;
-
-struct transfer_t
-{
-    template <sender _Sender, scheduler _Scheduler>
-    auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const
-        -> __well_formed_sender auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<transfer_t>(_Env{{static_cast<_Scheduler&&>(__sched)}},
-                                     static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <scheduler _Scheduler>
-    STDEXEC_ATTRIBUTE((always_inline))
-    __binder_back<transfer_t, __decay_t<_Scheduler>>
-        operator()(_Scheduler&& __sched) const
-    {
-        return {{}, {}, {static_cast<_Scheduler&&>(__sched)}};
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////////////////
-    using _Env = __0;
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(transfer_t,
-                             get_completion_scheduler_t<set_value_t>(
-                                 get_env_t(const _Sender&)),
-                             _Sender,
-                             get_completion_scheduler_t<set_value_t>(_Env)),
-                tag_invoke_t(transfer_t, _Sender,
-                             get_completion_scheduler_t<set_value_t>(_Env))>;
-
-    template <class _Env>
-    static auto __transform_sender_fn(const _Env&)
-    {
-        return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
-                                              _Child&& __child) {
-            auto __sched = get_completion_scheduler<set_value_t>(__data);
-            return schedule_from(std::move(__sched),
-                                 static_cast<_Child&&>(__child));
-        };
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             __transform_sender_fn(__env));
-    }
-};
-
-struct __transfer_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class _Data, class _Child>(
-            const _Data& __data,
-            const _Child& __child) noexcept -> decltype(auto) {
-        return __env::__join(__data, stdexec::get_env(__child));
-    };
-};
-} // namespace __transfer
-
-using __transfer::transfer_t;
-inline constexpr transfer_t transfer{};
-
-template <>
-struct __sexpr_impl<transfer_t> : __transfer::__transfer_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.transfer_just]
-namespace __transfer_just
-{
-// This is a helper for finding legacy cusutomizations of transfer_just.
-inline auto __transfer_just_tag_invoke()
-{
-    return []<class... _Ts>(
-               _Ts&&... __ts) -> tag_invoke_result_t<transfer_just_t, _Ts...> {
-        return tag_invoke(transfer_just, static_cast<_Ts&&>(__ts)...);
-    };
-}
-
-template <class _Env>
-auto __make_transform_fn(const _Env& __env)
-{
-    return [&]<class _Scheduler, class... _Values>(_Scheduler&& __sched,
-                                                   _Values&&... __vals) {
-        return transfer(just(static_cast<_Values&&>(__vals)...),
-                        static_cast<_Scheduler&&>(__sched));
-    };
-}
-
-template <class _Env>
-auto __transform_sender_fn(const _Env& __env)
-{
-    return [&]<class _Data>(__ignore, _Data&& __data) {
-        return __apply(__make_transform_fn(__env),
-                       static_cast<_Data&&>(__data));
-    };
-}
-
-struct transfer_just_t
-{
-    using _Data = __0;
-    using __legacy_customizations_t = //
-        __types<__apply_t(decltype(__transfer_just_tag_invoke()), _Data)>;
-
-    template <scheduler _Scheduler, __movable_value... _Values>
-    auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
-        -> __well_formed_sender auto
-    {
-        auto __domain = query_or(get_domain, __sched, default_domain());
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<transfer_just_t>(
-                          std::tuple{static_cast<_Scheduler&&>(__sched),
-                                     static_cast<_Values&&>(__vals)...}));
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             __transform_sender_fn(__env));
-    }
-};
-
-inline auto __make_env_fn() noexcept
-{
-    return []<class _Scheduler>(const _Scheduler& __sched,
-                                const auto&...) noexcept {
-        using _Env = __t<__schedule_from::__environ<__id<_Scheduler>>>;
-        return _Env{__sched};
-    };
-}
-
-struct __transfer_just_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class _Data>(const _Data& __data) noexcept {
-        return __apply(__make_env_fn(), __data);
-    };
-};
-} // namespace __transfer_just
-
-using __transfer_just::transfer_just_t;
-inline constexpr transfer_just_t transfer_just{};
-
-template <>
-struct __sexpr_impl<transfer_just_t> : __transfer_just::__transfer_just_impl
-{};
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// __write adaptor
-namespace __write_
-{
-struct __write_t
-{
-    template <sender _Sender, class... _Envs>
-    auto operator()(_Sender&& __sndr, _Envs... __envs) const
-    {
-        return __make_sexpr<__write_t>(__env::__join(std::move(__envs)...),
-                                       static_cast<_Sender&&>(__sndr));
-    }
-
-    template <class... _Envs>
-    STDEXEC_ATTRIBUTE((always_inline))
-    auto operator()(_Envs... __envs) const -> __binder_back<__write_t, _Envs...>
-    {
-        return {{}, {}, {std::move(__envs)...}};
-    }
-
-    template <class _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    static auto __transform_env_fn(_Env&& __env) noexcept
-    {
-        return [&](__ignore, const auto& __state, __ignore) noexcept {
-            return __env::__join(__state, static_cast<_Env&&>(__env));
-        };
-    }
-
-    template <sender_expr_for<__write_t> _Self, class _Env>
-    static auto transform_env(const _Self& __self, _Env&& __env) noexcept
-    {
-        return __sexpr_apply(__self,
-                             __transform_env_fn(static_cast<_Env&&>(__env)));
-    }
-};
-
-struct __write_impl : __sexpr_defaults
-{
-    static constexpr auto get_env = //
-        [](__ignore, const auto& __state, const auto& __rcvr) noexcept {
-        return __env::__join(__state, stdexec::get_env(__rcvr));
-    };
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Self, class _Env>(_Self&&, _Env&&) noexcept
-        -> stdexec::__completion_signatures_of_t<
-            __child_of<_Self>,
-            __env::__join_t<const __decay_t<__data_of<_Self>>&, _Env>> {
-        static_assert(sender_expr_for<_Self, __write_t>);
-        return {};
-    };
-};
-} // namespace __write_
-
-using __write_::__write_t;
-inline constexpr __write_t __write{};
-
-template <>
-struct __sexpr_impl<__write_t> : __write_::__write_impl
-{};
-
-namespace __detail
-{
-template <class _Env, class _Scheduler>
-STDEXEC_ATTRIBUTE((always_inline))
-auto __mkenv_sched(_Env&& __env, _Scheduler __sched)
-{
-    auto __env2 =
-        __env::__join(__env::__with(__sched, get_scheduler),
-                      __env::__without(static_cast<_Env&&>(__env), get_domain));
-    using _Env2 = decltype(__env2);
-
-    struct __env_t : _Env2
-    {};
-
-    return __env_t{static_cast<_Env2&&>(__env2)};
-}
-
-template <class _Ty, class = __name_of<__decay_t<_Ty>>>
-struct __always
-{
-    _Ty __val_;
-
-    auto operator()() noexcept -> _Ty
-    {
-        return static_cast<_Ty&&>(__val_);
-    }
-};
-
-template <class _Ty>
-__always(_Ty) -> __always<_Ty>;
-} // namespace __detail
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.on]
-namespace __on
-{
-struct on_t
-{
-    using _Sender = __1;
-    using _Scheduler = __0;
-    using __legacy_customizations_t =
-        __types<tag_invoke_t(on_t, _Scheduler, _Sender)>;
-
-    template <scheduler _Scheduler, sender _Sender>
-    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        -> __well_formed_sender auto
-    {
-        auto __domain = query_or(get_domain, __sched, default_domain());
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<on_t>(static_cast<_Scheduler&&>(__sched),
-                                         static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <class _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    static auto __transform_env_fn(_Env&& __env) noexcept
-    {
-        return [&](__ignore, auto __sched, __ignore) noexcept {
-            return __detail::__mkenv_sched(static_cast<_Env&&>(__env), __sched);
-        };
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
-    {
-        return __sexpr_apply(__sndr,
-                             __transform_env_fn(static_cast<_Env&&>(__env)));
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env&)
-    {
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             []<class _Data, class _Child>(
-                                 __ignore, _Data&& __data, _Child&& __child) {
-            return let_value(
-                schedule(__data),
-                __detail::__always{static_cast<_Child&&>(__child)});
-        });
-    }
-};
-} // namespace __on
-
-using __on::on_t;
-inline constexpr on_t on{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.into_variant]
-namespace __into_variant
-{
-template <class _Sender, class _Env>
-    requires sender_in<_Sender, _Env>
-using __into_variant_result_t = value_types_of_t<_Sender, _Env>;
-
-template <class _Sender, class _Env>
-using __variant_t = __try_value_types_of_t<_Sender, _Env>;
-
-template <class _Variant>
-using __variant_completions =
-    completion_signatures<set_value_t(_Variant),
-                          set_error_t(std::exception_ptr)>;
-
-template <class _Sender, class _Env>
-using __compl_sigs = //
-    __try_make_completion_signatures<
-        _Sender, _Env,
-        __meval<__variant_completions, __variant_t<_Sender, _Env>>,
-        __mconst<completion_signatures<>>>;
-
-struct into_variant_t
-{
-    template <sender _Sender>
-    auto operator()(_Sender&& __sndr) const -> __well_formed_sender auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain,
-            __make_sexpr<into_variant_t>(__(), std::forward<_Sender>(__sndr)));
-    }
-
-    STDEXEC_ATTRIBUTE((always_inline))
-
-    auto operator()() const noexcept
-    {
-        return __binder_back<into_variant_t>{};
-    }
-};
-
-struct __into_variant_impl : __sexpr_defaults
-{
-    static constexpr auto get_state = //
-        []<class _Self, class _Receiver>(_Self&&, _Receiver&) noexcept {
-        using __variant_t =
-            value_types_of_t<__child_of<_Self>, env_of_t<_Receiver>>;
-        return __mtype<__variant_t>();
-    };
-
-    static constexpr auto complete = //
-        []<class _State, class _Receiver, class _Tag, class... _Args>(
-            __ignore, _State, _Receiver& __rcvr, _Tag,
-            _Args&&... __args) noexcept -> void {
-        if constexpr (same_as<_Tag, set_value_t>)
-        {
-            using __variant_t = __t<_State>;
-            try
-            {
-                set_value(static_cast<_Receiver&&>(__rcvr),
-                          __variant_t{std::tuple<_Args&&...>{
-                              static_cast<_Args&&>(__args)...}});
-            }
-            catch (...)
-            {
-                set_error(static_cast<_Receiver&&>(__rcvr),
-                          std::current_exception());
-            }
-        }
-        else
-        {
-            _Tag()(static_cast<_Receiver&&>(__rcvr),
-                   static_cast<_Args&&>(__args)...);
-        }
-    };
-
-    static constexpr auto get_completion_signatures =         //
-        []<class _Self, class _Env>(_Self&&, _Env&&) noexcept //
-        -> __compl_sigs<__child_of<_Self>, _Env> {
-        static_assert(sender_expr_for<_Self, into_variant_t>);
-        return {};
-    };
-};
-} // namespace __into_variant
-
-using __into_variant::into_variant_t;
-inline constexpr into_variant_t into_variant{};
-
-template <>
-struct __sexpr_impl<into_variant_t> : __into_variant::__into_variant_impl
-{};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.when_all]
-// [execution.senders.adaptors.when_all_with_variant]
-namespace __when_all
-{
-enum __state_t
-{
-    __started,
-    __error,
-    __stopped
-};
-
-struct __on_stop_request
-{
-    in_place_stop_source& __stop_source_;
-
-    void operator()() noexcept
-    {
-        __stop_source_.request_stop();
-    }
-};
-
-template <class _Env>
-auto __mkenv(_Env&& __env, in_place_stop_source& __stop_source) noexcept
-{
-    return __env::__join(
-        __env::__with(__stop_source.get_token(), get_stop_token),
-        static_cast<_Env&&>(__env));
-}
-
-template <class _Env>
-using __env_t = //
-    decltype(__mkenv(__declval<_Env>(), __declval<in_place_stop_source&>()));
-
-template <class _Tp>
-using __decay_rvalue_ref = __decay_t<_Tp>&&;
-
-template <class _Sender, class _Env>
-concept __max1_sender = sender_in<_Sender, _Env> &&
-                        __mvalid<__value_types_of_t, _Sender, _Env,
-                                 __mconst<int>, __msingle_or<void>>;
-
-template <
-    __mstring _Context = "In stdexec::when_all()..."_mstr,
-    __mstring _Diagnostic =
-        "The given sender can complete successfully in more that one way. "
-        "Use stdexec::when_all_with_variant() instead."_mstr>
-struct _INVALID_WHEN_ALL_ARGUMENT_;
-
-template <class _Sender, class _Env>
-using __too_many_value_completions_error =
-    __mexception<_INVALID_WHEN_ALL_ARGUMENT_<>, _WITH_SENDER_<_Sender>,
-                 _WITH_ENVIRONMENT_<_Env>>;
-
-template <class _Sender, class _Env, class _ValueTuple, class... _Rest>
-using __value_tuple_t =
-    __minvoke<__if_c<(0 == sizeof...(_Rest)), __mconst<_ValueTuple>,
-                     __q<__too_many_value_completions_error>>,
-              _Sender, _Env>;
-
-template <class _Env, class _Sender>
-using __single_values_of_t = //
-    __try_value_types_of_t<_Sender, _Env,
-                           __transform<__q<__decay_rvalue_ref>, __q<__types>>,
-                           __mbind_front_q<__value_tuple_t, _Sender, _Env>>;
-
-template <class _Env, class... _Senders>
-using __set_values_sig_t = //
-    __meval<completion_signatures,
-            __minvoke<__mconcat<__qf<set_value_t>>,
-                      __single_values_of_t<_Env, _Senders>...>>;
-
-template <class... _Args>
-using __all_nothrow_decay_copyable_ =
-    __mbool<(__nothrow_decay_copyable<_Args> && ...)>;
-
-template <class _Env, class... _Senders>
-using __all_nothrow_decay_copyable = //
-    __mand<__compl_sigs::__maybe_for_all_sigs<
-        __completion_signatures_of_t<_Senders, _Env>,
-        __q<__all_nothrow_decay_copyable_>, __q<__mand>>...>;
-
-template <class _Env, class... _Senders>
-using __completions_t = //
-    __concat_completion_signatures_t<
-        __if<__all_nothrow_decay_copyable<_Env, _Senders...>,
-             completion_signatures<set_stopped_t()>,
-             completion_signatures<set_stopped_t(),
-                                   set_error_t(std::exception_ptr&&)>>,
-        __minvoke<__with_default<__mbind_front_q<__set_values_sig_t, _Env>,
-                                 completion_signatures<>>,
-                  _Senders...>,
-        __try_make_completion_signatures<
-            _Senders, _Env, completion_signatures<>,
-            __mconst<completion_signatures<>>,
-            __mcompose<__q<completion_signatures>, __qf<set_error_t>,
-                       __q<__decay_rvalue_ref>>>...>;
-
-struct __not_an_error
-{};
-
-struct __tie_fn
-{
-    template <class... _Ty>
-    auto operator()(_Ty&... __vals) noexcept -> std::tuple<_Ty&...>
-    {
-        return std::tuple<_Ty&...>{__vals...};
-    }
-};
-
-template <class _Tag, class _Receiver>
-auto __complete_fn(_Tag, _Receiver& __rcvr) noexcept
-{
-    return [&]<class... _Ts>(_Ts&... __ts) noexcept {
-        if constexpr (!same_as<__types<_Ts...>, __types<__not_an_error>>)
-        {
-            _Tag()(static_cast<_Receiver&&>(__rcvr),
-                   static_cast<_Ts&&>(__ts)...);
-        }
-    };
-}
-
-template <class _Receiver, class _ValuesTuple>
-void __set_values(_Receiver& __rcvr, _ValuesTuple& __values) noexcept
-{
-    __tup::__apply(
-        [&](auto&... __opt_vals) noexcept -> void {
-        __apply(__complete_fn(set_value, __rcvr), //
-                std::tuple_cat(__tup::__apply(__tie_fn{}, *__opt_vals)...));
-    },
-        __values);
-}
-
-template <class... Ts>
-using __decayed_custom_tuple = __tup::__tuple_for<__decay_t<Ts>...>;
-
-template <class _Env, class _Sender>
-using __values_opt_tuple_t = //
-    value_types_of_t<_Sender, __env_t<_Env>, __decayed_custom_tuple,
-                     std::optional>;
-
-template <class _Env, __max1_sender<__env_t<_Env>>... _Senders>
-struct __traits
-{
-    // tuple<optional<tuple<Vs1...>>, optional<tuple<Vs2...>>, ...>
-    using __values_tuple = //
-        __minvoke<__with_default<
-                      __transform<__mbind_front_q<__values_opt_tuple_t, _Env>,
-                                  __q<__tup::__tuple_for>>,
-                      __ignore>,
-                  _Senders...>;
-
-    using __nullable_variant_t_ =
-        __munique<__mbind_front_q<std::variant, __not_an_error>>;
-
-    using __error_types = //
-        __minvoke<__mconcat<__transform<__q<__decay_t>, __nullable_variant_t_>>,
-                  error_types_of_t<_Senders, __env_t<_Env>, __types>...>;
-
-    using __errors_variant = //
-        __if<__all_nothrow_decay_copyable<_Env, _Senders...>, __error_types,
-             __minvoke<__push_back_unique<__q<std::variant>>, __error_types,
-                       std::exception_ptr>>;
-};
-
-struct _INVALID_ARGUMENTS_TO_WHEN_ALL_
-{};
-
-template <class _ErrorsVariant, class _ValuesTuple, class _StopToken>
-struct __when_all_state
-{
-    using __stop_callback_t =
-        typename _StopToken::template callback_type<__on_stop_request>;
-
-    template <class _Receiver>
-    void __arrive(_Receiver& __rcvr) noexcept
-    {
-        if (0 == --__count_)
-        {
-            __complete(__rcvr);
-        }
-    }
-
-    template <class _Receiver>
-    void __complete(_Receiver& __rcvr) noexcept
-    {
-        // Stop callback is no longer needed. Destroy it.
-        __on_stop_.reset();
-        // All child operations have completed and arrived at the barrier.
-        switch (__state_.load(std::memory_order_relaxed))
-        {
-            case __started:
-                if constexpr (!same_as<_ValuesTuple, __ignore>)
-                {
-                    // All child operations completed successfully:
-                    __when_all::__set_values(__rcvr, __values_);
-                }
-                break;
-            case __error:
-                if constexpr (!same_as<_ErrorsVariant,
-                                       std::variant<std::monostate>>)
-                {
-                    // One or more child operations completed with an error:
-                    std::visit(__complete_fn(set_error, __rcvr), __errors_);
-                }
-                break;
-            case __stopped:
-                stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr));
-                break;
-            default:;
-        }
-    }
-
-    std::atomic<std::size_t> __count_;
-    in_place_stop_source __stop_source_{};
-    // Could be non-atomic here and atomic_ref everywhere except __completion_fn
-    std::atomic<__state_t> __state_{__started};
-    _ErrorsVariant __errors_{};
-    STDEXEC_ATTRIBUTE((no_unique_address))
-    _ValuesTuple __values_{};
-    std::optional<__stop_callback_t> __on_stop_{};
-};
-
-template <class _Env>
-static auto __mk_state_fn(const _Env& __env) noexcept
-{
-    return [&]<__max1_sender<__env_t<_Env>>... _Child>(__ignore, __ignore,
-                                                       _Child&&...) {
-        using _Traits = __traits<_Env, _Child...>;
-        using _ErrorsVariant = typename _Traits::__errors_variant;
-        using _ValuesTuple = typename _Traits::__values_tuple;
-        using _State = __when_all_state<_ErrorsVariant, _ValuesTuple,
-                                        stop_token_of_t<_Env>>;
-        return _State{sizeof...(_Child), in_place_stop_source{}, __started,
-                      _ErrorsVariant{},  _ValuesTuple{},         std::nullopt};
-    };
-}
-
-template <class _Env>
-using __mk_state_fn_t = decltype(__when_all::__mk_state_fn(__declval<_Env>()));
-
-struct when_all_t
-{
-    // Used by the default_domain to find legacy customizations:
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(when_all_t, _Sender...)>;
-
-    template <sender... _Senders>
-        requires __domain::__has_common_domain<_Senders...>
-    auto operator()(_Senders&&... __sndrs) const -> __well_formed_sender auto
-    {
-        auto __domain = __domain::__common_domain_t<_Senders...>();
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<when_all_t>(
-                          __(), static_cast<_Senders&&>(__sndrs)...));
-    }
-};
-
-struct __when_all_impl : __sexpr_defaults
-{
-    template <class _Self, class _Env>
-    using __error_t = __mexception<_INVALID_ARGUMENTS_TO_WHEN_ALL_,
-                                   __children_of<_Self, __q<_WITH_SENDERS_>>,
-                                   _WITH_ENVIRONMENT_<_Env>>;
-
-    template <class _Self, class _Env>
-    using __completions = //
-        __children_of<_Self, __mbind_front_q<__completions_t, __env_t<_Env>>>;
-
-    static constexpr auto get_attrs = //
-        []<class... _Child>(__ignore, const _Child&...) noexcept {
-        using _Domain = __domain::__common_domain_t<_Child...>;
-        if constexpr (same_as<_Domain, default_domain>)
-        {
-            return empty_env();
-        }
-        else
-        {
-            return __env::__with(_Domain(), get_domain);
-        }
-    };
-
-    static constexpr auto get_completion_signatures = //
-        []<class _Self, class _Env>(_Self&&, _Env&&) noexcept {
-        static_assert(sender_expr_for<_Self, when_all_t>);
-        return __minvoke<__mtry_catch<__q<__completions>, __q<__error_t>>,
-                         _Self, _Env>();
-    };
-
-    static constexpr auto get_env =                                         //
-        []<class _State, class _Receiver>(__ignore, _State& __state,
-                                          const _Receiver& __rcvr) noexcept //
-        -> __env_t<env_of_t<const _Receiver&>> {
-        return __mkenv(stdexec::get_env(__rcvr), __state.__stop_source_);
-    };
-
-    static constexpr auto get_state = //
-        []<class _Self, class _Receiver>(_Self&& __self, _Receiver& __rcvr)
-        -> __sexpr_apply_result_t<_Self, __mk_state_fn_t<env_of_t<_Receiver>>> {
-        return __sexpr_apply(
-            static_cast<_Self&&>(__self),
-            __when_all::__mk_state_fn(stdexec::get_env(__rcvr)));
-    };
-
-    static constexpr auto start = //
-        []<class _State, class _Receiver, class... _Operations>(
-            _State& __state, _Receiver& __rcvr,
-            _Operations&... __child_ops) noexcept -> void {
-        // register stop callback:
-        __state.__on_stop_.emplace(get_stop_token(stdexec::get_env(__rcvr)),
-                                   __on_stop_request{__state.__stop_source_});
-        if (__state.__stop_source_.stop_requested())
-        {
-            // Stop has already been requested. Don't bother starting
-            // the child operations.
-            stdexec::set_stopped(std::move(__rcvr));
-        }
-        else
-        {
-            (stdexec::start(__child_ops), ...);
-            if constexpr (sizeof...(__child_ops) == 0)
-            {
-                __state.__complete(__rcvr);
-            }
-        }
-    };
-
-    template <class _State, class _Receiver, class _Error>
-    static void __set_error(_State& __state, _Receiver& __rcvr,
-                            _Error&& __err) noexcept
-    {
-        // TODO: What memory orderings are actually needed here?
-        if (__error != __state.__state_.exchange(__error))
-        {
-            __state.__stop_source_.request_stop();
-            // We won the race, free to write the error into the operation
-            // state without worry.
-            if constexpr (__nothrow_decay_copyable<_Error>)
-            {
-                __state.__errors_.template emplace<__decay_t<_Error>>(
-                    static_cast<_Error&&>(__err));
-            }
-            else
-            {
-                try
-                {
-                    __state.__errors_.template emplace<__decay_t<_Error>>(
-                        static_cast<_Error&&>(__err));
-                }
-                catch (...)
-                {
-                    __state.__errors_.template emplace<std::exception_ptr>(
-                        std::current_exception());
-                }
-            }
-        }
-    }
-
-    static constexpr auto complete = //
-        []<class _Index, class _State, class _Receiver, class _Set,
-           class... _Args>(_Index, _State& __state, _Receiver& __rcvr, _Set,
-                           _Args&&... __args) noexcept -> void {
-        if constexpr (same_as<_Set, set_error_t>)
-        {
-            __set_error(__state, __rcvr, static_cast<_Args&&>(__args)...);
-        }
-        else if constexpr (same_as<_Set, set_stopped_t>)
-        {
-            __state_t __expected = __started;
-            // Transition to the "stopped" state if and only if we're in the
-            // "started" state. (If this fails, it's because we're in an
-            // error state, which trumps cancellation.)
-            if (__state.__state_.compare_exchange_strong(__expected, __stopped))
-            {
-                __state.__stop_source_.request_stop();
-            }
-        }
-        else if constexpr (!same_as<decltype(_State::__values_), __ignore>)
-        {
-            // We only need to bother recording the completion values
-            // if we're not already in the "error" or "stopped" state.
-            if (__state.__state_ == __started)
-            {
-                auto& __opt_values =
-                    __tup::__get<__v<_Index>>(__state.__values_);
-                using _Tuple = __decayed_custom_tuple<_Args...>;
-                static_assert(
-                    same_as<decltype(*__opt_values), _Tuple&>,
-                    "One of the senders in this when_all() is fibbing about what types it sends");
-                if constexpr ((__nothrow_decay_copyable<_Args> && ...))
-                {
-                    __opt_values.emplace(
-                        _Tuple{{static_cast<_Args&&>(__args)}...});
-                }
-                else
-                {
-                    try
-                    {
-                        __opt_values.emplace(
-                            _Tuple{{static_cast<_Args&&>(__args)}...});
-                    }
-                    catch (...)
-                    {
-                        __set_error(__state, __rcvr, std::current_exception());
-                    }
-                }
-            }
-        }
-
-        __state.__arrive(__rcvr);
-    };
-};
-
-struct when_all_with_variant_t
-{
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(when_all_with_variant_t, _Sender...)>;
-
-    template <sender... _Senders>
-        requires __domain::__has_common_domain<_Senders...>
-    auto operator()(_Senders&&... __sndrs) const -> __well_formed_sender auto
-    {
-        auto __domain = __domain::__common_domain_t<_Senders...>();
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<when_all_with_variant_t>(
-                          __(), static_cast<_Senders&&>(__sndrs)...));
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        // transform the when_all_with_variant into a regular when_all (looking
-        // for early when_all customizations), then transform it again to look
-        // for late customizations.
-        return __sexpr_apply(
-            static_cast<_Sender&&>(__sndr),
-            [&]<class... _Child>(__ignore, __ignore, _Child&&... __child) {
-            return when_all_t()(
-                into_variant(static_cast<_Child&&>(__child))...);
-        });
-    }
-};
-
-struct __when_all_with_variant_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class... _Child>(__ignore, const _Child&...) noexcept {
-        using _Domain = __domain::__common_domain_t<_Child...>;
-        if constexpr (same_as<_Domain, default_domain>)
-        {
-            return empty_env();
-        }
-        else
-        {
-            return __env::__with(_Domain(), get_domain);
-        }
-    };
-};
-
-struct transfer_when_all_t
-{
-    using _Env = __0;
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(
-            transfer_when_all_t,
-            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
-
-    template <scheduler _Scheduler, sender... _Senders>
-        requires __domain::__has_common_domain<_Senders...>
-    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
-        -> __well_formed_sender auto
-    {
-        using _Env =
-            __t<__schedule_from::__environ<__id<__decay_t<_Scheduler>>>>;
-        auto __domain = query_or(get_domain, __sched, default_domain());
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<transfer_when_all_t>(
-                          _Env{static_cast<_Scheduler&&>(__sched)},
-                          static_cast<_Senders&&>(__sndrs)...));
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        // transform the transfer_when_all into a regular transform | when_all
-        // (looking for early customizations), then transform it again to look
-        // for late customizations.
-        return __sexpr_apply(
-            static_cast<_Sender&&>(__sndr),
-            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
-                                              _Child&&... __child) {
-            return transfer(when_all_t()(static_cast<_Child&&>(__child)...),
-                            get_completion_scheduler<set_value_t>(__data));
-        });
-    }
-};
-
-struct __transfer_when_all_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class _Data>(const _Data& __data,
-                        const auto&...) noexcept -> const _Data& {
-        return __data;
-    };
-};
-
-struct transfer_when_all_with_variant_t
-{
-    using _Env = __0;
-    using _Sender = __1;
-    using __legacy_customizations_t = //
-        __types<tag_invoke_t(
-            transfer_when_all_with_variant_t,
-            get_completion_scheduler_t<set_value_t>(const _Env&), _Sender...)>;
-
-    template <scheduler _Scheduler, sender... _Senders>
-        requires __domain::__has_common_domain<_Senders...>
-    auto operator()(_Scheduler&& __sched, _Senders&&... __sndrs) const
-        -> __well_formed_sender auto
-    {
-        using _Env =
-            __t<__schedule_from::__environ<__id<__decay_t<_Scheduler>>>>;
-        auto __domain = query_or(get_domain, __sched, default_domain());
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<transfer_when_all_with_variant_t>(
-                          _Env{{static_cast<_Scheduler&&>(__sched)}},
-                          static_cast<_Senders&&>(__sndrs)...));
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        // transform the transfer_when_all_with_variant into regular
-        // transform_when_all and into_variant calls/ (looking for early
-        // customizations), then transform it again to look for late
-        // customizations.
-        return __sexpr_apply(
-            static_cast<_Sender&&>(__sndr),
-            [&]<class _Data, class... _Child>(__ignore, _Data&& __data,
-                                              _Child&&... __child) {
-            return transfer_when_all_t()(
-                get_completion_scheduler<set_value_t>(
-                    static_cast<_Data&&>(__data)),
-                into_variant(static_cast<_Child&&>(__child))...);
-        });
-    }
-};
-
-struct __transfer_when_all_with_variant_impl : __sexpr_defaults
-{
-    static constexpr auto get_attrs = //
-        []<class _Data>(const _Data& __data,
-                        const auto&...) noexcept -> const _Data& {
-        return __data;
-    };
-};
-} // namespace __when_all
-
-using __when_all::when_all_t;
-inline constexpr when_all_t when_all{};
-
-using __when_all::when_all_with_variant_t;
-inline constexpr when_all_with_variant_t when_all_with_variant{};
-
-using __when_all::transfer_when_all_t;
-inline constexpr transfer_when_all_t transfer_when_all{};
-
-using __when_all::transfer_when_all_with_variant_t;
-inline constexpr transfer_when_all_with_variant_t
-    transfer_when_all_with_variant{};
-
-template <>
-struct __sexpr_impl<when_all_t> : __when_all::__when_all_impl
-{};
-
-template <>
-struct __sexpr_impl<when_all_with_variant_t> :
-    __when_all::__when_all_with_variant_impl
-{};
-
-template <>
-struct __sexpr_impl<transfer_when_all_t> : __when_all::__transfer_when_all_impl
-{};
-
-template <>
-struct __sexpr_impl<transfer_when_all_with_variant_t> :
-    __when_all::__transfer_when_all_with_variant_impl
-{};
-
-namespace __read
-{
-template <class _Tag, class _ReceiverId>
-using __result_t = __call_result_t<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
-
-template <class _Tag, class _ReceiverId>
-concept __nothrow_t =
-    __nothrow_callable<_Tag, env_of_t<stdexec::__t<_ReceiverId>>>;
-
-inline constexpr __mstring __query_failed_diag =
-    "The current execution environment doesn't have a value for the given query."_mstr;
-
-template <class _Tag>
-struct _WITH_QUERY_;
-
-template <class _Tag, class _Env>
-using __query_failed_error = //
-    __mexception<            //
-        _NOT_CALLABLE_<"In stdexec::read()..."_mstr, __query_failed_diag>,
-        _WITH_QUERY_<_Tag>, _WITH_ENVIRONMENT_<_Env>>;
-
-template <class _Tag, class _Env>
-    requires __callable<_Tag, _Env>
-using __completions_t = //
-    __if_c<__nothrow_callable<_Tag, _Env>,
-           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>)>,
-           completion_signatures<set_value_t(__call_result_t<_Tag, _Env>),
-                                 set_error_t(std::exception_ptr)>>;
-
-template <class _Tag, class _Ty>
-struct __state
-{
-    using __query = _Tag;
-    using __result = _Ty;
-    std::optional<_Ty> __result_;
-};
-
-template <class _Tag, class _Ty>
-    requires same_as<_Ty, _Ty&&>
-struct __state<_Tag, _Ty>
-{
-    using __query = _Tag;
-    using __result = _Ty;
-};
-
-struct __read_t
-{
-    template <class _Tag>
-    constexpr auto operator()(_Tag) const noexcept
-    {
-        return __make_sexpr<__read_t>(_Tag());
-    }
-};
-
-struct __read_impl : __sexpr_defaults
-{
-    using is_dependent = void;
-
-    template <class _Tag, class _Env>
-    using __completions_t = __minvoke<
-        __mtry_catch_q<__read::__completions_t, __q<__query_failed_error>>,
-        _Tag, _Env>;
-
-    static constexpr auto get_completion_signatures =              //
-        []<class _Self, class _Env>(const _Self&, _Env&&) noexcept //
-        -> __completions_t<__data_of<_Self>, _Env> {
-        static_assert(sender_expr_for<_Self, __read_t>);
-        return {};
-    };
-
-    static constexpr auto get_state = //
-        []<class _Self, class _Receiver>(const _Self&,
-                                         _Receiver& __rcvr) noexcept {
-        using __query = __data_of<_Self>;
-        using __result = __call_result_t<__query, env_of_t<_Receiver>>;
-        return __state<__query, __result>();
-    };
-
-    static constexpr auto start = //
-        []<class _State, class _Receiver>(_State& __state,
-                                          _Receiver& __rcvr) noexcept -> void {
-        using __query = typename _State::__query;
-        using __result = typename _State::__result;
-        if constexpr (same_as<__result, __result&&>)
-        {
-            // The query returns a reference type; pass it straight through to
-            // the receiver.
-            stdexec::__set_value_invoke(std::move(__rcvr), __query(),
-                                        stdexec::get_env(__rcvr));
-        }
-        else
-        {
-            constexpr bool _Nothrow =
-                __nothrow_callable<__query, env_of_t<_Receiver>>;
-            auto __query_fn = [&]() noexcept(_Nothrow) -> __result&& {
-                __state.__result_.emplace(__conv{[&]() noexcept(_Nothrow) {
-                    return __query()(stdexec::get_env(__rcvr));
-                }});
-                return std::move(*__state.__result_);
-            };
-            stdexec::__set_value_invoke(std::move(__rcvr), __query_fn);
-        }
-    };
-};
-} // namespace __read
-
-inline constexpr __read::__read_t read{};
-
-template <>
-struct __sexpr_impl<__read::__read_t> : __read::__read_impl
-{};
-
-namespace __queries
-{
-template <class _Tag>
-inline auto get_scheduler_t::operator()() const noexcept
-{
-    return read(get_scheduler);
-}
-
-template <class _Env>
-    requires tag_invocable<get_scheduler_t, const _Env&>
-inline auto get_scheduler_t::operator()(const _Env& __env) const noexcept
-    -> tag_invoke_result_t<get_scheduler_t, const _Env&>
-{
-    static_assert(nothrow_tag_invocable<get_scheduler_t, const _Env&>);
-    static_assert(scheduler<tag_invoke_result_t<get_scheduler_t, const _Env&>>);
-    return tag_invoke(get_scheduler_t{}, __env);
-}
-
-template <class _Tag>
-inline auto get_delegatee_scheduler_t::operator()() const noexcept
-{
-    return read(get_delegatee_scheduler);
-}
-
-template <class _Env>
-    requires tag_invocable<get_delegatee_scheduler_t, const _Env&>
-inline auto
-    get_delegatee_scheduler_t::operator()(const _Env& __t) const noexcept
-    -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>
-{
-    static_assert(
-        nothrow_tag_invocable<get_delegatee_scheduler_t, const _Env&>);
-    static_assert(
-        scheduler<tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>>);
-    return tag_invoke(get_delegatee_scheduler_t{}, std::as_const(__t));
-}
-
-template <class _Tag>
-inline auto get_allocator_t::operator()() const noexcept
-{
-    return read(get_allocator);
-}
-
-template <class _Tag>
-inline auto get_stop_token_t::operator()() const noexcept
-{
-    return read(get_stop_token);
-}
-
-template <__completion_tag _CPO>
-template <__has_completion_scheduler_for<_CPO> _Queryable>
-auto get_completion_scheduler_t<_CPO>::operator()(
-    const _Queryable& __queryable) const noexcept
-    -> tag_invoke_result_t<get_completion_scheduler_t<_CPO>, const _Queryable&>
-{
-    static_assert(nothrow_tag_invocable<get_completion_scheduler_t<_CPO>,
-                                        const _Queryable&>,
-                  "get_completion_scheduler<_CPO> should be noexcept");
-    static_assert(
-        scheduler<tag_invoke_result_t<get_completion_scheduler_t<_CPO>,
-                                      const _Queryable&>>);
-    return tag_invoke(*this, __queryable);
-}
-} // namespace __queries
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.adaptors.on]
-namespace __on_v2
-{
-inline constexpr __mstring __on_context =
-    "In stdexec::on(Scheduler, Sender)..."_mstr;
-inline constexpr __mstring __no_scheduler_diag =
-    "stdexec::on() requires a scheduler to transition back to."_mstr;
-inline constexpr __mstring __no_scheduler_details =
-    "The provided environment lacks a value for the get_scheduler() query."_mstr;
-
-template <__mstring _Context = __on_context,
-          __mstring _Diagnostic = __no_scheduler_diag,
-          __mstring _Details = __no_scheduler_details>
-struct _CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_
-{};
-
-struct on_t;
-
-STDEXEC_PRAGMA_PUSH()
-STDEXEC_PRAGMA_IGNORE_GNU("-Wunused-local-typedefs")
-
-struct __no_scheduler_in_environment
-{
-    // Issue a custom diagnostic if the environment doesn't provide a scheduler.
-    template <class _Sender, class _Env>
-    static auto transform_sender(_Sender&&, const _Env&)
-    {
-        struct __no_scheduler_in_environment
-        {
-            using sender_concept = sender_t;
-            using completion_signatures = //
-                __mexception<_CANNOT_RESTORE_EXECUTION_CONTEXT_AFTER_ON_<>,
-                             _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
-        };
-
-        return __no_scheduler_in_environment{};
-    }
-};
-
-STDEXEC_PRAGMA_POP()
-
-struct on_t : __no_scheduler_in_environment
-{
-    template <scheduler _Scheduler, sender _Sender>
-    auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const
-        -> __well_formed_sender auto
-    {
-        // BUGBUG __get_early_domain, or get_domain(__sched), or ...?
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<on_t>(static_cast<_Scheduler&&>(__sched),
-                                         static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <class _Env>
-    STDEXEC_ATTRIBUTE((always_inline))
-    static auto __transform_env_fn(_Env&& __env) noexcept
-    {
-        return [&](__ignore, auto __sched, __ignore) noexcept {
-            return __detail::__mkenv_sched(static_cast<_Env&&>(__env), __sched);
-        };
-    }
-
-    template <class _Sender, class _Env>
-    static auto transform_env(const _Sender& __sndr, _Env&& __env) noexcept
-    {
-        return __sexpr_apply(__sndr,
-                             __transform_env_fn(static_cast<_Env&&>(__env)));
-    }
-
-    using __no_scheduler_in_environment::transform_sender;
-
-    template <class _Sender, class _Env>
-        requires __callable<get_scheduler_t, const _Env&>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        return __sexpr_apply(
-            static_cast<_Sender&&>(__sndr),
-            [&]<class _Scheduler, class _Child>(__ignore, _Scheduler __sched,
-                                                _Child&& __child) {
-            auto __old = get_scheduler(__env);
-            return transfer(
-                let_value(transfer_just(std::move(__sched)),
-                          __detail::__always{static_cast<_Child&&>(__child)}),
-                std::move(__old));
-        });
-    }
-};
-
-template <class _Scheduler, class _Closure>
-struct __continue_on_data
-{
-    _Scheduler __sched_;
-    _Closure __clsur_;
-};
-template <class _Scheduler, class _Closure>
-__continue_on_data(_Scheduler, _Closure)
-    -> __continue_on_data<_Scheduler, _Closure>;
-
-template <class _Scheduler>
-struct __with_sched
-{
-    _Scheduler __sched_;
-
-    friend auto tag_invoke(get_scheduler_t, const __with_sched& __self) noexcept
-        -> _Scheduler
-    {
-        return __self.__sched_;
-    }
-
-    friend auto tag_invoke(get_domain_t, const __with_sched& __self) noexcept
-    {
-        return query_or(get_domain, __self.__sched_, default_domain());
-    }
-};
-
-template <class _Scheduler>
-__with_sched(_Scheduler) -> __with_sched<_Scheduler>;
-
-struct continue_on_t : __no_scheduler_in_environment
-{
-    template <sender _Sender, scheduler _Scheduler,
-              __sender_adaptor_closure_for<_Sender> _Closure>
-    auto operator()(_Sender&& __sndr, _Scheduler&& __sched,
-                    _Closure&& __clsur) const -> __well_formed_sender auto
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::transform_sender(
-            __domain, __make_sexpr<continue_on_t>(
-                          __continue_on_data{static_cast<_Scheduler&&>(__sched),
-                                             static_cast<_Closure&&>(__clsur)},
-                          static_cast<_Sender&&>(__sndr)));
-    }
-
-    template <scheduler _Scheduler, __sender_adaptor_closure _Closure>
-    STDEXEC_ATTRIBUTE((always_inline))
-    auto operator()(_Scheduler&& __sched, _Closure&& __clsur) const
-        -> __binder_back<continue_on_t, __decay_t<_Scheduler>,
-                         __decay_t<_Closure>>
-    {
-        return {{},
-                {},
-                {static_cast<_Scheduler&&>(__sched),
-                 static_cast<_Closure&&>(__clsur)}};
-    }
-
-    using __no_scheduler_in_environment::transform_sender;
-
-    template <class _Sender, class _Env>
-        requires __callable<get_scheduler_t, const _Env&>
-    static auto transform_sender(_Sender&& __sndr, const _Env& __env)
-    {
-        auto __old = get_scheduler(__env);
-        return __sexpr_apply(static_cast<_Sender&&>(__sndr),
-                             [&]<class _Data, class _Child>(
-                                 __ignore, _Data&& __data, _Child&& __child) {
-            auto&& [__sched, __clsur] = static_cast<_Data&&>(__data);
-            using _Closure = decltype(__clsur);
-            return __write(transfer(static_cast<_Closure&&>(__clsur)(transfer(
-                                        __write(static_cast<_Child&&>(__child),
-                                                __with_sched{__old}),
-                                        __sched)),
-                                    __old),
-                           __with_sched{__sched});
-        });
-    }
-};
-} // namespace __on_v2
-
-namespace v2
-{
-using __on_v2::on_t;
-inline constexpr on_t on{};
-
-using __on_v2::continue_on_t;
-inline constexpr continue_on_t continue_on{};
-} // namespace v2
-
-template <>
-struct __sexpr_impl<v2::on_t> : __sexpr_defaults
-{
-    using is_dependent = void;
-};
-
-template <>
-struct __sexpr_impl<v2::continue_on_t> : __sexpr_defaults
-{
-    using is_dependent = void;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// [execution.senders.consumers.sync_wait]
-// [execution.senders.consumers.sync_wait_with_variant]
-namespace __sync_wait
-{
-inline auto __make_env(run_loop& __loop) noexcept
-{
-    return __env::__with(__loop.get_scheduler(), get_scheduler,
-                         get_delegatee_scheduler);
-}
-
-struct __env : __result_of<__make_env, run_loop&>
-{
-    __env();
-
-    explicit __env(run_loop& __loop) noexcept :
-        __result_of<__make_env, run_loop&>{__sync_wait::__make_env(__loop)}
-    {}
-};
-
-// What should sync_wait(just_stopped()) return?
-template <class _Sender, class _Continuation>
-using __sync_wait_result_impl = //
-    __try_value_types_of_t<_Sender, __env,
-                           __transform<__q<__decay_t>, _Continuation>,
-                           __q<__msingle>>;
-
-template <class _Sender>
-using __sync_wait_result_t =
-    __mtry_eval<__sync_wait_result_impl, _Sender, __q<std::tuple>>;
-
-template <class _Sender>
-using __sync_wait_with_variant_result_t =
-    __mtry_eval<__sync_wait_result_impl, __result_of<into_variant, _Sender>,
-                __q<__midentity>>;
-
-template <class... _Values>
-struct __state
-{
-    using _Tuple = std::tuple<_Values...>;
-    std::variant<std::monostate, _Tuple, std::exception_ptr, set_stopped_t>
-        __data_{};
-};
-
-template <class... _Values>
-struct __receiver
-{
-    struct __t
-    {
-        using receiver_concept = receiver_t;
-        using __id = __receiver;
-        __state<_Values...>* __state_;
-        run_loop* __loop_;
-
-        template <class _Error>
-        void __set_error(_Error __err) noexcept
-        {
-            if constexpr (__decays_to<_Error, std::exception_ptr>)
-                __state_->__data_.template emplace<2>(
-                    static_cast<_Error&&>(__err));
-            else if constexpr (__decays_to<_Error, std::error_code>)
-                __state_->__data_.template emplace<2>(
-                    std::make_exception_ptr(std::system_error(__err)));
-            else
-                __state_->__data_.template emplace<2>(
-                    std::make_exception_ptr(static_cast<_Error&&>(__err)));
-            __loop_->finish();
-        }
-
-        template <same_as<set_value_t> _Tag, class... _As>
-            requires constructible_from<std::tuple<_Values...>, _As...>
-        friend void tag_invoke(_Tag, __t&& __rcvr, _As&&... __as) noexcept
-        {
-            try
-            {
-                __rcvr.__state_->__data_.template emplace<1>(
-                    static_cast<_As&&>(__as)...);
-                __rcvr.__loop_->finish();
-            }
-            catch (...)
-            {
-                __rcvr.__set_error(std::current_exception());
-            }
-        }
-
-        template <same_as<set_error_t> _Tag, class _Error>
-        friend void tag_invoke(_Tag, __t&& __rcvr, _Error __err) noexcept
-        {
-            __rcvr.__set_error(static_cast<_Error&&>(__err));
-        }
-
-        friend void tag_invoke(set_stopped_t __d, __t&& __rcvr) noexcept
-        {
-            __rcvr.__state_->__data_.template emplace<3>(__d);
-            __rcvr.__loop_->finish();
-        }
-
-        friend auto tag_invoke(get_env_t, const __t& __rcvr) noexcept -> __env
-        {
-            return __env(*__rcvr.__loop_);
-        }
-    };
-};
-
-template <class _Sender>
-using __receiver_t = __t<__sync_wait_result_impl<_Sender, __q<__receiver>>>;
-
-// These are for hiding the metaprogramming in diagnostics
-template <class _Sender>
-struct __sync_receiver_for
-{
-    using __t = __receiver_t<_Sender>;
-};
-template <class _Sender>
-using __sync_receiver_for_t = __t<__sync_receiver_for<_Sender>>;
-
-template <class _Sender>
-struct __value_tuple_for
-{
-    using __t = __sync_wait_result_t<_Sender>;
-};
-template <class _Sender>
-using __value_tuple_for_t = __t<__value_tuple_for<_Sender>>;
-
-template <class _Sender>
-struct __variant_for
-{
-    using __t = __sync_wait_with_variant_result_t<_Sender>;
-};
-template <class _Sender>
-using __variant_for_t = __t<__variant_for<_Sender>>;
-
-inline constexpr __mstring __sync_wait_context_diag = //
-    "In stdexec::sync_wait()..."_mstr;
-inline constexpr __mstring __too_many_successful_completions_diag =
-    "The argument to stdexec::sync_wait() is a sender that can complete successfully in more "
-    "than one way. Use stdexec::sync_wait_with_variant() instead."_mstr;
-
-template <__mstring _Context, __mstring _Diagnostic>
-struct _INVALID_ARGUMENT_TO_SYNC_WAIT_;
-
-template <__mstring _Diagnostic>
-using __invalid_argument_to_sync_wait =
-    _INVALID_ARGUMENT_TO_SYNC_WAIT_<__sync_wait_context_diag, _Diagnostic>;
-
-template <__mstring _Diagnostic, class _Sender, class _Env = __env>
-using __sync_wait_error =
-    __mexception<__invalid_argument_to_sync_wait<_Diagnostic>,
-                 _WITH_SENDER_<_Sender>, _WITH_ENVIRONMENT_<_Env>>;
-
-template <class _Sender, class>
-using __too_many_successful_completions_error =
-    __sync_wait_error<__too_many_successful_completions_diag, _Sender>;
-
-template <class _Sender>
-concept __valid_sync_wait_argument =
-    __ok<__minvoke<__mtry_catch_q<__single_value_variant_sender_t,
-                                  __q<__too_many_successful_completions_error>>,
-                   _Sender, __env>>;
-
-#if STDEXEC_NVHPC()
-// It requires some hoop-jumping to get the NVHPC compiler to report a
-// meaningful diagnostic for SFINAE failures.
-template <class _Sender>
-auto __diagnose_error()
-{
-    if constexpr (!sender_in<_Sender, __env>)
-    {
-        using _Completions = __completion_signatures_of_t<_Sender, __env>;
-        if constexpr (__merror<_Completions>)
-        {
-            return _Completions();
-        }
-        else
-        {
-            constexpr __mstring __diag =
-                "The stdexec::sender_in<Sender, Environment> concept check has failed."_mstr;
-            return __sync_wait_error<__diag, _Sender>();
-        }
-    }
-    else if constexpr (!__valid_sync_wait_argument<_Sender>)
-    {
-        return __sync_wait_error<__too_many_successful_completions_diag,
-                                 _Sender>();
-    }
-    else if constexpr (!sender_to<_Sender, __sync_receiver_for_t<_Sender>>)
-    {
-        constexpr __mstring __diag =
-            "Failed to connect the given sender to sync_wait's internal receiver. "
-            "The stdexec::connect(Sender, Receiver) expression is ill-formed."_mstr;
-        return __sync_wait_error<__diag, _Sender>();
-    }
-    else
-    {
-        constexpr __mstring __diag = "Unknown concept check failure."_mstr;
-        return __sync_wait_error<__diag, _Sender>();
-    }
-}
-
-template <class _Sender>
-using __error_description_t =
-    decltype(__sync_wait::__diagnose_error<_Sender>());
-#endif
-
-////////////////////////////////////////////////////////////////////////////
-// [execution.senders.consumers.sync_wait]
-struct sync_wait_t
-{
-    template <sender_in<__env> _Sender>
-        requires __valid_sync_wait_argument<_Sender> &&
-                 __has_implementation_for<sync_wait_t,
-                                          __early_domain_of_t<_Sender>, _Sender>
-    auto operator()(_Sender&& __sndr) const
-        -> std::optional<__value_tuple_for_t<_Sender>>
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::apply_sender(__domain, *this,
-                                     static_cast<_Sender&&>(__sndr));
-    }
-
-#if STDEXEC_NVHPC()
-    // This is needed to get sensible diagnostics from nvc++
-    template <class _Sender, class _Error = __error_description_t<_Sender>>
-    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
-        -> std::optional<std::tuple<int>> = delete;
-#endif
-
-    using _Sender = __0;
-    using __legacy_customizations_t = __types<
-        // For legacy reasons:
-        tag_invoke_t(
-            sync_wait_t,
-            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
-            _Sender),
-        tag_invoke_t(sync_wait_t, _Sender)>;
-
-    // The default implementation goes here:
-    template <class _Sender>
-        requires sender_to<_Sender, __sync_receiver_for_t<_Sender>>
-    auto apply_sender(_Sender&& __sndr) const
-        -> std::optional<__sync_wait_result_t<_Sender>>
-    {
-        using state_t = __sync_wait_result_impl<_Sender, __q<__state>>;
-        state_t __state{};
-        run_loop __loop;
-
-        // Launch the sender with a continuation that will fill in a variant
-        // and notify a condition variable.
-        auto __op_state = connect(static_cast<_Sender&&>(__sndr),
-                                  __receiver_t<_Sender>{&__state, &__loop});
-        start(__op_state);
-
-        // Wait for the variant to be filled in.
-        __loop.run();
-
-        if (__state.__data_.index() == 2)
-            std::rethrow_exception(std::get<2>(__state.__data_));
-
-        if (__state.__data_.index() == 3)
-            return std::nullopt;
-
-        return std::move(std::get<1>(__state.__data_));
-    }
-};
-
-////////////////////////////////////////////////////////////////////////////
-// [execution.senders.consumers.sync_wait_with_variant]
-struct sync_wait_with_variant_t
-{
-    struct __impl;
-
-    template <sender_in<__env> _Sender>
-        requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
-                            sync_wait_with_variant_t, _Sender>
-    auto operator()(_Sender&& __sndr) const
-        -> std::optional<__variant_for_t<_Sender>>
-    {
-        auto __domain = __get_early_domain(__sndr);
-        return stdexec::apply_sender(__domain, *this,
-                                     static_cast<_Sender&&>(__sndr));
-    }
-
-#if STDEXEC_NVHPC()
-    template <class _Sender, class _Error = __error_description_t<
-                                 __result_of<into_variant, _Sender>>>
-    auto operator()(_Sender&&, [[maybe_unused]] _Error __diagnostic = {}) const
-        -> std::optional<std::tuple<std::variant<std::tuple<>>>> = delete;
-#endif
-
-    using _Sender = __0;
-    using __legacy_customizations_t = __types<
-        // For legacy reasons:
-        tag_invoke_t(
-            sync_wait_with_variant_t,
-            get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)),
-            _Sender),
-        tag_invoke_t(sync_wait_with_variant_t, _Sender)>;
-
-    template <class _Sender>
-        requires __callable<sync_wait_t, __result_of<into_variant, _Sender>>
-    auto apply_sender(_Sender&& __sndr) const
-        -> std::optional<__variant_for_t<_Sender>>
-    {
-        if (auto __opt_values =
-                sync_wait_t()(into_variant(static_cast<_Sender&&>(__sndr))))
-        {
-            return std::move(std::get<0>(*__opt_values));
-        }
-        return std::nullopt;
-    }
-};
-} // namespace __sync_wait
-
-using __sync_wait::sync_wait_t;
-inline constexpr sync_wait_t sync_wait{};
-
-using __sync_wait::sync_wait_with_variant_t;
-inline constexpr sync_wait_with_variant_t sync_wait_with_variant{};
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-struct __ignore_sender
-{
-    using sender_concept = sender_t;
-
-    template <sender _Sender>
-    constexpr __ignore_sender(_Sender&&) noexcept
-    {}
-};
-
-template <auto _Reason = "You cannot pipe one sender into another."_mstr>
-struct _CANNOT_PIPE_INTO_A_SENDER_
-{};
-
-template <class _Sender>
-using __bad_pipe_sink_t =
-    __mexception<_CANNOT_PIPE_INTO_A_SENDER_<>, _WITH_SENDER_<_Sender>>;
-} // namespace stdexec
-
-#if STDEXEC_MSVC()
-namespace stdexec
-{
-// MSVCBUG
-// https://developercommunity.visualstudio.com/t/Incorrect-codegen-in-await_suspend-aroun/10454102
-
-// MSVC incorrectly allocates the return buffer for await_suspend calls within
-// the suspended coroutine frame. When the suspended coroutine is destroyed
-// within await_suspend, the continuation coroutine handle is not only used
-// after free, but also overwritten by the debug malloc implementation when NRVO
-// is in play.
-
-// This workaround delays the destruction of the suspended coroutine by wrapping
-// the continuation in another coroutine which destroys the former and transfers
-// execution to the original continuation.
-
-// The wrapping coroutine is thread-local and is reused within the thread for
-// each destroy-and-continue sequence. The wrapping coroutine itself is
-// destroyed at thread exit.
-
-namespace __destroy_and_continue_msvc
-{
-struct __task
-{
-    struct promise_type
-    {
-        __task get_return_object() noexcept
-        {
-            return {
-                __coro::coroutine_handle<promise_type>::from_promise(*this)};
-        }
-
-        static std::suspend_never initial_suspend() noexcept
-        {
-            return {};
-        }
-
-        static std::suspend_never final_suspend() noexcept
-        {
-            STDEXEC_ASSERT(!"Should never get here");
-            return {};
-        }
-
-        static void return_void() noexcept
-        {
-            STDEXEC_ASSERT(!"Should never get here");
-        }
-
-        static void unhandled_exception() noexcept
-        {
-            STDEXEC_ASSERT(!"Should never get here");
-        }
-    };
-
-    __coro::coroutine_handle<> __coro_;
-};
-
-struct __continue_t
-{
-    static constexpr bool await_ready() noexcept
-    {
-        return false;
-    }
-
-    __coro::coroutine_handle<>
-        await_suspend(__coro::coroutine_handle<>) noexcept
-    {
-        return __continue_;
-    }
-
-    static void await_resume() noexcept {}
-
-    __coro::coroutine_handle<> __continue_;
-};
-
-struct __context
-{
-    __coro::coroutine_handle<> __destroy_;
-    __coro::coroutine_handle<> __continue_;
-};
-
-inline __task __co_impl(__context& __c)
-{
-    while (true)
-    {
-        co_await __continue_t{__c.__continue_};
-        __c.__destroy_.destroy();
-    }
-}
-
-struct __context_and_coro
-{
-    __context_and_coro()
-    {
-        __context_.__continue_ = __coro::noop_coroutine();
-        __coro_ = __co_impl(__context_).__coro_;
-    }
-
-    ~__context_and_coro()
-    {
-        __coro_.destroy();
-    }
-
-    __context __context_;
-    __coro::coroutine_handle<> __coro_;
-};
-
-inline __coro::coroutine_handle<> __impl(__coro::coroutine_handle<> __destroy,
-                                         __coro::coroutine_handle<> __continue)
-{
-    static thread_local __context_and_coro __c;
-    __c.__context_.__destroy_ = __destroy;
-    __c.__context_.__continue_ = __continue;
-    return __c.__coro_;
-}
-} // namespace __destroy_and_continue_msvc
-} // namespace stdexec
-
-#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
-    (::stdexec::__destroy_and_continue_msvc::__impl(__destroy, __continue))
-#else
-#define STDEXEC_DESTROY_AND_CONTINUE(__destroy, __continue)                    \
-    (__destroy.destroy(), __continue)
-#endif
-
 // For issuing a meaningful diagnostic for the erroneous `snd1 | snd2`.
-template <stdexec::sender _Sender>
+template <stdexec::sender _Ignore, stdexec::sender _Sender>
     requires stdexec::__ok<stdexec::__bad_pipe_sink_t<_Sender>>
-auto operator|(stdexec::__ignore_sender, _Sender&&) noexcept
-    -> stdexec::__ignore_sender;
-
-#include "__detail/__p2300.hpp"
-
-STDEXEC_PRAGMA_POP()
+auto operator|(_Ignore&&, _Sender&&) noexcept;
diff --git a/include/sdbusplus/async/stdexec/functional.hpp b/include/sdbusplus/async/stdexec/functional.hpp
index 3b4c989..4dbc910 100644
--- a/include/sdbusplus/async/stdexec/functional.hpp
+++ b/include/sdbusplus/async/stdexec/functional.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -17,6 +17,7 @@
 
 #include "__detail/__config.hpp"
 #include "__detail/__meta.hpp"
+#include "__detail/__tag_invoke.hpp"
 #include "concepts.hpp"
 
 #include <cstddef>
@@ -24,59 +25,8 @@
 #include <tuple>
 #include <type_traits>
 
-namespace stdexec::__std_concepts
-{
-#if STDEXEC_HAS_STD_CONCEPTS_HEADER()
-using std::invocable;
-#else
-template <class _Fun, class... _As>
-concept invocable = //
-    requires(_Fun&& __f, _As&&... __as) {
-        std::invoke(static_cast<_Fun&&>(__f), static_cast<_As&&>(__as)...);
-    };
-#endif
-} // namespace stdexec::__std_concepts
-
-namespace std
-{
-using namespace stdexec::__std_concepts;
-} // namespace std
-
 namespace stdexec
 {
-template <auto _Fun>
-struct __function_constant
-{
-    using _FunT = decltype(_Fun);
-
-    template <class... _Args>
-        requires __callable<_FunT, _Args...>
-    STDEXEC_ATTRIBUTE((always_inline)) auto operator()(_Args&&... __args) const
-        noexcept(noexcept(_Fun(static_cast<_Args&&>(__args)...)))
-            -> decltype(_Fun(static_cast<_Args&&>(__args)...))
-    {
-        return _Fun(static_cast<_Args&&>(__args)...);
-    }
-};
-
-template <class _Ty, class _Cl, _Ty _Cl::*_MemPtr>
-struct __function_constant<_MemPtr>
-{
-    using _FunT = _Ty _Cl::*;
-
-    template <class _Arg>
-        requires requires(_Arg&& __arg) { static_cast<_Arg&&>(__arg).*_MemPtr; }
-    STDEXEC_ATTRIBUTE((always_inline)) constexpr auto
-        operator()(_Arg&& __arg) const noexcept
-        -> decltype(((static_cast<_Arg&&>(__arg)).*_MemPtr))
-    {
-        return static_cast<_Arg&&>(__arg).*_MemPtr;
-    }
-};
-
-template <auto _Fun>
-inline constexpr __function_constant<_Fun> __function_constant_v{};
-
 template <class _Fun0, class _Fun1>
 struct __composed
 {
@@ -313,11 +263,11 @@
 
 template <std::size_t... _Is, class _Fn, class _Tup>
 STDEXEC_ATTRIBUTE((always_inline))
-constexpr auto __impl(__indices<_Is...>, _Fn&& __fn, _Tup&& __tup) noexcept(
-    noexcept(__invoke(static_cast<_Fn&&>(__fn),
-                      get<_Is>(static_cast<_Tup&&>(__tup))...)))
-    -> decltype(__invoke(static_cast<_Fn&&>(__fn),
-                         get<_Is>(static_cast<_Tup&&>(__tup))...))
+constexpr auto __impl(__indices<_Is...>, _Fn&& __fn, _Tup&& __tup) //
+    noexcept(noexcept(__invoke(static_cast<_Fn&&>(__fn),
+                               get<_Is>(static_cast<_Tup&&>(__tup))...)))
+        -> decltype(__invoke(static_cast<_Fn&&>(__fn),
+                             get<_Is>(static_cast<_Tup&&>(__tup))...))
 {
     return __invoke(static_cast<_Fn&&>(__fn),
                     get<_Is>(static_cast<_Tup&&>(__tup))...);
@@ -337,8 +287,9 @@
 
 template <class _Fn, class _Tup>
 concept __nothrow_applicable = __applicable<_Fn, _Tup> //
-    && noexcept(__apply_::__impl(__apply_::__tuple_indices<_Tup>(),
-                                 __declval<_Fn>(), __declval<_Tup>()));
+    &&                                                 //
+    noexcept(__apply_::__impl(__apply_::__tuple_indices<_Tup>(),
+                              __declval<_Fn>(), __declval<_Tup>()));
 
 template <class _Fn, class _Tup>
     requires __applicable<_Fn, _Tup>
@@ -386,87 +337,4 @@
 
 template <class _Tag>
 inline constexpr __mkfield_<_Tag> __mkfield{};
-
-// [func.tag_invoke], tag_invoke
-namespace __tag_invoke
-{
-void tag_invoke();
-
-// NOT TO SPEC: Don't require tag_invocable to subsume invocable.
-// std::invoke is more expensive at compile time than necessary,
-// and results in diagnostics that are more verbose than necessary.
-template <class _Tag, class... _Args>
-concept tag_invocable = //
-    requires(_Tag __tag, _Args&&... __args) {
-        tag_invoke(static_cast<_Tag&&>(__tag), static_cast<_Args&&>(__args)...);
-    };
-
-template <class _Ret, class _Tag, class... _Args>
-concept __tag_invocable_r = //
-    requires(_Tag __tag, _Args&&... __args) {
-        {
-            static_cast<_Ret>(tag_invoke(static_cast<_Tag&&>(__tag),
-                                         static_cast<_Args&&>(__args)...))
-        };
-    };
-
-// NOT TO SPEC: nothrow_tag_invocable subsumes tag_invocable
-template <class _Tag, class... _Args>
-concept nothrow_tag_invocable =
-    tag_invocable<_Tag, _Args...> && //
-    requires(_Tag __tag, _Args&&... __args) {
-        {
-            tag_invoke(static_cast<_Tag&&>(__tag),
-                       static_cast<_Args&&>(__args)...)
-        } noexcept;
-    };
-
-template <class _Tag, class... _Args>
-using tag_invoke_result_t =
-    decltype(tag_invoke(__declval<_Tag>(), __declval<_Args>()...));
-
-template <class _Tag, class... _Args>
-struct tag_invoke_result
-{};
-
-template <class _Tag, class... _Args>
-    requires tag_invocable<_Tag, _Args...>
-struct tag_invoke_result<_Tag, _Args...>
-{
-    using type = tag_invoke_result_t<_Tag, _Args...>;
-};
-
-struct tag_invoke_t
-{
-    template <class _Tag, class... _Args>
-        requires tag_invocable<_Tag, _Args...>
-    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 __tag_invoke
-
-using __tag_invoke::tag_invoke_t;
-
-namespace __ti
-{
-inline constexpr tag_invoke_t tag_invoke{};
-} // namespace __ti
-
-using namespace __ti;
-
-template <auto& _Tag>
-using tag_t = __decay_t<decltype(_Tag)>;
-
-using __tag_invoke::__tag_invocable_r;
-using __tag_invoke::nothrow_tag_invocable;
-using __tag_invoke::tag_invocable;
-using __tag_invoke::tag_invoke_result;
-using __tag_invoke::tag_invoke_result_t;
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/inline_scheduler.hpp b/include/sdbusplus/async/stdexec/inline_scheduler.hpp
index f100590..4634e9e 100644
--- a/include/sdbusplus/async/stdexec/inline_scheduler.hpp
+++ b/include/sdbusplus/async/stdexec/inline_scheduler.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
diff --git a/include/sdbusplus/async/stdexec/sequence_senders.hpp b/include/sdbusplus/async/stdexec/sequence_senders.hpp
index b1bfaab..fda8b84 100644
--- a/include/sdbusplus/async/stdexec/sequence_senders.hpp
+++ b/include/sdbusplus/async/stdexec/sequence_senders.hpp
@@ -34,7 +34,7 @@
 struct __mall_contained_in_impl
 {
     template <class... _Needles>
-    using __f = __mand<__mapply<__contains<_Needles>, _Haystack>...>;
+    using __f = __mand<__mapply<__mcontains<_Needles>, _Haystack>...>;
 };
 
 template <class _Needles, class _Haystack>
@@ -42,7 +42,7 @@
     __mapply<__mall_contained_in_impl<_Haystack>, _Needles>;
 
 template <class _Needles, class _Haystack>
-concept __all_contained_in = __mall_contained_in<_Needles, _Haystack>::value;
+concept __all_contained_in = __v<__mall_contained_in<_Needles, _Haystack>>;
 
 // This concept checks if a given sender satisfies the requirements to be
 // returned from `set_next`.
@@ -57,7 +57,7 @@
 // sender and it returns a next-sender. `set_next` is usually called in a
 // context where a sender will be connected to a receiver. Since calling
 // `set_next` usually involves constructing senders it is allowed to throw an
-// exception, which needs to be handled by a calling sequence-operation. The
+// excpetion, which needs to be handled by a calling sequence-operation. The
 // returned object is a sender that can complete with `set_value_t()` or
 // `set_stopped_t()`.
 struct set_next_t
@@ -100,43 +100,37 @@
         STDEXEC_ATTRIBUTE((no_unique_address))
         _Receiver __rcvr_;
 
-        template <same_as<get_env_t> _GetEnv, same_as<__t> _Self>
-        friend auto tag_invoke(_GetEnv, const _Self& __self) noexcept
-            -> env_of_t<_Receiver>
+        auto get_env() const noexcept -> env_of_t<_Receiver>
         {
-            return stdexec::get_env(__self.__rcvr_);
+            return stdexec::get_env(__rcvr_);
         }
 
-        template <same_as<set_value_t> _SetValue, same_as<__t> _Self>
-            requires __callable<set_value_t, _Receiver&&>
-        friend void tag_invoke(_SetValue, _Self&& __self) noexcept
+        void set_value() noexcept
+            requires __callable<set_value_t, _Receiver>
         {
-            return stdexec::set_value(static_cast<_Receiver&&>(__self.__rcvr_));
+            return stdexec::set_value(static_cast<_Receiver&&>(__rcvr_));
         }
 
-        template <same_as<set_stopped_t> _SetStopped, same_as<__t> _Self>
-            requires __callable<set_value_t, _Receiver&&> &&
+        void set_stopped() noexcept
+            requires __callable<set_value_t, _Receiver> &&
                      (unstoppable_token<_Token> ||
-                      __callable<set_stopped_t, _Receiver &&>)
-        friend void tag_invoke(_SetStopped, _Self&& __self) noexcept
+                      __callable<set_stopped_t, _Receiver>)
         {
             if constexpr (unstoppable_token<_Token>)
             {
-                stdexec::set_value(static_cast<_Receiver&&>(__self.__rcvr_));
+                stdexec::set_value(static_cast<_Receiver&&>(__rcvr_));
             }
             else
             {
                 auto __token =
-                    stdexec::get_stop_token(stdexec::get_env(__self.__rcvr_));
+                    stdexec::get_stop_token(stdexec::get_env(__rcvr_));
                 if (__token.stop_requested())
                 {
-                    stdexec::set_stopped(
-                        static_cast<_Receiver&&>(__self.__rcvr_));
+                    stdexec::set_stopped(static_cast<_Receiver&&>(__rcvr_));
                 }
                 else
                 {
-                    stdexec::set_value(
-                        static_cast<_Receiver&&>(__self.__rcvr_));
+                    stdexec::set_value(static_cast<_Receiver&&>(__rcvr_));
                 }
             }
         }
@@ -230,7 +224,7 @@
     }
 
     template <class _Sender, class _Env = empty_env>
-    constexpr auto operator()(_Sender&&, const _Env&) const noexcept
+    constexpr auto operator()(_Sender&&, _Env&& = {}) const noexcept
         -> decltype(__impl<_Sender, _Env>()())
     {
         return {};
@@ -241,27 +235,27 @@
 using __sequence_sndr::get_item_types_t;
 inline constexpr get_item_types_t get_item_types{};
 
-template <class _Sender, class _Env>
+template <class _Sender, class... _Env>
 using item_types_of_t = decltype(get_item_types(stdexec::__declval<_Sender>(),
-                                                stdexec::__declval<_Env>()));
+                                                stdexec::__declval<_Env>()...));
 
-template <class _Sender, class _Env>
-concept sequence_sender =                //
-    stdexec::sender_in<_Sender, _Env> && //
+template <class _Sender, class... _Env>
+concept sequence_sender =                   //
+    stdexec::sender_in<_Sender, _Env...> && //
     enable_sequence_sender<stdexec::__decay_t<_Sender>>;
 
-template <class _Sender, class _Env>
+template <class _Sender, class... _Env>
 concept has_sequence_item_types =
-    requires(_Sender&& __sndr, _Env&& __env) {
+    requires(_Sender&& __sndr, _Env&&... __env) {
         get_item_types(static_cast<_Sender&&>(__sndr),
-                       static_cast<_Env&&>(__env));
+                       static_cast<_Env&&>(__env)...);
     };
 
-template <class _Sender, class _Env>
-concept sequence_sender_in =                  //
-    stdexec::sender_in<_Sender, _Env> &&      //
-    has_sequence_item_types<_Sender, _Env> && //
-    sequence_sender<_Sender, _Env>;
+template <class _Sender, class... _Env>
+concept sequence_sender_in =                     //
+    stdexec::sender_in<_Sender, _Env...> &&      //
+    has_sequence_item_types<_Sender, _Env...> && //
+    sequence_sender<_Sender, _Env...>;
 
 template <class _Receiver>
 struct _WITH_RECEIVER_
@@ -272,7 +266,7 @@
 {};
 
 template <class _Receiver, class _Item>
-auto __try_item(_Item*)
+auto __try_item(_Item*) //
     -> stdexec::__mexception<_MISSING_SET_NEXT_OVERLOAD_FOR_ITEM_<_Item>,
                              _WITH_RECEIVER_<_Receiver>>;
 
@@ -281,7 +275,7 @@
 auto __try_item(_Item*) -> stdexec::__msuccess;
 
 template <class _Receiver, class... _Items>
-auto __try_items(exec::item_types<_Items...>*)
+auto __try_items(exec::item_types<_Items...>*) //
     -> decltype((stdexec::__msuccess(), ...,
                  exec::__try_item<_Receiver>(static_cast<_Items*>(nullptr))));
 
@@ -298,44 +292,39 @@
     stdexec::receiver<_Receiver> && //
     __sequence_receiver_of<_Receiver, _SequenceItems>;
 
-template <class _Items, class _Env>
-using __concat_item_signatures_t = stdexec::__mapply<
-    stdexec::__q<stdexec::__concat_completion_signatures_t>,
-    stdexec::__mapply<stdexec::__transform<stdexec::__mbind_back_q<
-                          stdexec::completion_signatures_of_t, _Env>>,
-                      _Items>>;
-
 template <class _Completions>
-using __gather_error_signals =
-    stdexec::__only_gather_signal<stdexec::set_error_t, _Completions>;
+using __to_sequence_completions_t = //
+    stdexec::__transform_completion_signatures<
+        _Completions,
+        stdexec::__mconst<
+            stdexec::completion_signatures<stdexec::set_value_t()>>::__f,
+        stdexec::__sigs::__default_set_error,
+        stdexec::completion_signatures<stdexec::set_stopped_t()>,
+        stdexec::__concat_completion_signatures>;
 
-template <class _Completions>
-using __gather_stopped_signals =
-    stdexec::__only_gather_signal<stdexec::set_stopped_t, _Completions>;
+template <class _Sender, class... _Env>
+using __item_completion_signatures = //
+    stdexec::transform_completion_signatures<
+        stdexec::__completion_signatures_of_t<_Sender, _Env...>,
+        stdexec::completion_signatures<stdexec::set_value_t()>,
+        stdexec::__mconst<stdexec::completion_signatures<>>::__f>;
 
-template <class _Completions>
-using __to_sequence_completions_t = stdexec::__concat_completion_signatures_t<
-    stdexec::completion_signatures<stdexec::set_value_t()>,
-    __gather_error_signals<_Completions>,
-    __gather_stopped_signals<_Completions>>;
+template <class _Sequence, class... _Env>
+using __sequence_completion_signatures = //
+    stdexec::transform_completion_signatures<
+        stdexec::__completion_signatures_of_t<_Sequence, _Env...>,
+        stdexec::completion_signatures<stdexec::set_value_t()>,
+        stdexec::__mconst<stdexec::completion_signatures<>>::__f>;
 
-template <class _Sender, class _Env>
-using __to_sequence_completion_signatures = stdexec::make_completion_signatures<
-    _Sender, _Env, stdexec::completion_signatures<stdexec::set_value_t()>,
-    stdexec::__mconst<stdexec::completion_signatures<>>::__f>;
-
-template <class _Sequence, class _Env>
-using __sequence_completion_signatures_of_t =
-    stdexec::__concat_completion_signatures_t<
-        stdexec::__try_make_completion_signatures<
-            _Sequence, _Env,
-            stdexec::completion_signatures<stdexec::set_value_t()>,
-            stdexec::__mconst<stdexec::completion_signatures<>>>,
-        stdexec::__mapply<
-            stdexec::__q<stdexec::__concat_completion_signatures_t>,
-            stdexec::__mapply<stdexec::__transform<stdexec::__mbind_back_q<
-                                  __to_sequence_completion_signatures, _Env>>,
-                              item_types_of_t<_Sequence, _Env>>>>;
+template <class _Sequence, class... _Env>
+using __sequence_completion_signatures_of_t = //
+    stdexec::__mapply<
+        stdexec::__mtransform<
+            stdexec::__mbind_back_q<__item_completion_signatures, _Env...>,
+            stdexec::__mbind_back<
+                stdexec::__mtry_q<stdexec::__concat_completion_signatures>,
+                __sequence_completion_signatures<_Sequence, _Env...>>>,
+        item_types_of_t<_Sequence, _Env...>>;
 
 template <class _Receiver, class _Sender>
 concept sequence_receiver_from =                                              //
@@ -363,17 +352,14 @@
            completion_signatures<set_value_t(), set_stopped_t()>>;
 
 template <class _Sender, class _Receiver>
-concept __next_connectable_with_tag_invoke =
+concept __next_connectable =
     receiver<_Receiver> &&                                           //
     sender_in<_Sender, env_of_t<_Receiver>> &&                       //
     !sequence_sender_in<_Sender, env_of_t<_Receiver>> &&             //
     sequence_receiver_of<_Receiver,
                          item_types<stdexec::__decay_t<_Sender>>> && //
-    __receiver_from<__stopped_means_break_t<_Receiver>,
-                    next_sender_of_t<_Receiver, _Sender>> &&         //
-    __connect::__connectable_with_tag_invoke<
-        next_sender_of_t<_Receiver, _Sender>&&,
-        __stopped_means_break_t<_Receiver>>;
+    sender_to<next_sender_of_t<_Receiver, _Sender>,
+              __stopped_means_break_t<_Receiver>>;
 
 template <class _Sender, class _Receiver>
 concept __subscribeable_with_tag_invoke =
@@ -392,19 +378,16 @@
     {
         using _Domain = __late_domain_of_t<_Sender, env_of_t<_Receiver&>>;
         constexpr bool _NothrowTfxSender =
-            __nothrow_callable<get_env_t, _Receiver&> &&
             __nothrow_callable<transform_sender_t, _Domain, _Sender,
                                env_of_t<_Receiver&>>;
         using _TfxSender = __tfx_sndr<_Sender, _Receiver>;
-        if constexpr (__next_connectable_with_tag_invoke<_TfxSender, _Receiver>)
+        if constexpr (__next_connectable<_TfxSender, _Receiver>)
         {
             using _Result =
-                tag_invoke_result_t<connect_t,
-                                    next_sender_of_t<_Receiver, _TfxSender>,
-                                    __stopped_means_break_t<_Receiver>>;
+                connect_result_t<next_sender_of_t<_Receiver, _TfxSender>,
+                                 __stopped_means_break_t<_Receiver>>;
             constexpr bool _Nothrow =
-                nothrow_tag_invocable<connect_t,
-                                      next_sender_of_t<_Receiver, _TfxSender>,
+                __nothrow_connectable<next_sender_of_t<_Receiver, _TfxSender>,
                                       __stopped_means_break_t<_Receiver>>;
             return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr);
         }
@@ -429,8 +412,8 @@
     using __select_impl_t = decltype(__select_impl<_Sender, _Receiver>());
 
     template <sender _Sender, receiver _Receiver>
-        requires __next_connectable_with_tag_invoke<
-                     __tfx_sndr<_Sender, _Receiver>, _Receiver> ||
+        requires __next_connectable<__tfx_sndr<_Sender, _Receiver>,
+                                    _Receiver> ||
                  __subscribeable_with_tag_invoke<__tfx_sndr<_Sender, _Receiver>,
                                                  _Receiver> ||
                  __is_debug_env<env_of_t<_Receiver>>
@@ -441,19 +424,18 @@
         using _TfxSender = __tfx_sndr<_Sender, _Receiver>;
         auto&& __env = get_env(__rcvr);
         auto __domain = __get_late_domain(__sndr, __env);
-        if constexpr (__next_connectable_with_tag_invoke<_TfxSender, _Receiver>)
+        if constexpr (__next_connectable<_TfxSender, _Receiver>)
         {
             static_assert(
-                operation_state<tag_invoke_result_t<
-                    connect_t, next_sender_of_t<_Receiver, _TfxSender>,
-                    __stopped_means_break_t<_Receiver>>>,
+                operation_state<
+                    connect_result_t<next_sender_of_t<_Receiver, _TfxSender>,
+                                     __stopped_means_break_t<_Receiver>>>,
                 "stdexec::connect(sender, receiver) must return a type that "
                 "satisfies the operation_state concept");
             next_sender_of_t<_Receiver, _TfxSender> __next = set_next(
                 __rcvr, transform_sender(
                             __domain, static_cast<_Sender&&>(__sndr), __env));
-            return tag_invoke(
-                connect_t{},
+            return stdexec::connect(
                 static_cast<next_sender_of_t<_Receiver, _TfxSender>&&>(__next),
                 __stopped_means_break_t<_Receiver>{
                     static_cast<_Receiver&&>(__rcvr)});
@@ -496,8 +478,7 @@
         }
     }
 
-    friend constexpr auto tag_invoke(forwarding_query_t, subscribe_t) noexcept
-        -> bool
+    static constexpr auto query(stdexec::forwarding_query_t) noexcept -> bool
     {
         return false;
     }
@@ -517,10 +498,8 @@
 template <class _Sender, class _Receiver>
 concept sequence_sender_to = sequence_receiver_from<_Receiver, _Sender> && //
                              requires(_Sender&& __sndr, _Receiver&& __rcvr) {
-                                 {
-                                     subscribe(static_cast<_Sender&&>(__sndr),
-                                               static_cast<_Receiver&&>(__rcvr))
-                                 };
+                                 subscribe(static_cast<_Sender&&>(__sndr),
+                                           static_cast<_Receiver&&>(__rcvr));
                              };
 
 template <class _Receiver>
diff --git a/include/sdbusplus/async/stdexec/stop_token.hpp b/include/sdbusplus/async/stdexec/stop_token.hpp
index 6c00940..7456ad9 100644
--- a/include/sdbusplus/async/stdexec/stop_token.hpp
+++ b/include/sdbusplus/async/stdexec/stop_token.hpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021-2022 Facebook, Inc. and its affiliates
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -16,8 +16,7 @@
  */
 #pragma once
 
-#include "__detail/__config.hpp"
-#include "concepts.hpp"
+#include "__detail/__stop_token.hpp"
 
 #include <atomic>
 #include <concepts>
@@ -33,19 +32,9 @@
 
 namespace stdexec
 {
-// [stoptoken.inplace], class in_place_stop_token
-class in_place_stop_token;
-
-// [stopsource.inplace], class in_place_stop_source
-class in_place_stop_source;
-
-// [stopcallback.inplace], class template in_place_stop_callback
-template <class _Callback>
-class in_place_stop_callback;
-
 namespace __stok
 {
-struct __in_place_stop_callback_base
+struct __inplace_stop_callback_base
 {
     void __execute() noexcept
     {
@@ -53,10 +42,10 @@
     }
 
   protected:
-    using __execute_fn_t = void(__in_place_stop_callback_base*) noexcept;
+    using __execute_fn_t = void(__inplace_stop_callback_base*) noexcept;
 
-    explicit __in_place_stop_callback_base(   //
-        const in_place_stop_source* __source, //
+    explicit __inplace_stop_callback_base(   //
+        const inplace_stop_source* __source, //
         __execute_fn_t* __execute) noexcept :
         __source_(__source),
         __execute_(__execute)
@@ -64,12 +53,12 @@
 
     void __register_callback_() noexcept;
 
-    friend in_place_stop_source;
+    friend inplace_stop_source;
 
-    const in_place_stop_source* __source_;
+    const inplace_stop_source* __source_;
     __execute_fn_t* __execute_;
-    __in_place_stop_callback_base* __next_ = nullptr;
-    __in_place_stop_callback_base** __prev_ptr_ = nullptr;
+    __inplace_stop_callback_base* __next_ = nullptr;
+    __inplace_stop_callback_base** __prev_ptr_ = nullptr;
     bool* __removed_during_callback_ = nullptr;
     std::atomic<bool> __callback_completed_{false};
 };
@@ -96,9 +85,6 @@
     static constexpr uint32_t __yield_threshold_ = 20;
     uint32_t __count_ = 0;
 };
-
-template <template <class> class>
-struct __check_type_alias_exists;
 } // namespace __stok
 
 // [stoptoken.never], class never_stop_token
@@ -128,17 +114,17 @@
 };
 
 template <class _Callback>
-class in_place_stop_callback;
+class inplace_stop_callback;
 
-// [stopsource.inplace], class in_place_stop_source
-class in_place_stop_source
+// [stopsource.inplace], class inplace_stop_source
+class inplace_stop_source
 {
   public:
-    in_place_stop_source() noexcept = default;
-    ~in_place_stop_source();
-    in_place_stop_source(in_place_stop_source&&) = delete;
+    inplace_stop_source() noexcept = default;
+    ~inplace_stop_source();
+    inplace_stop_source(inplace_stop_source&&) = delete;
 
-    auto get_token() const noexcept -> in_place_stop_token;
+    auto get_token() const noexcept -> inplace_stop_token;
 
     auto request_stop() noexcept -> bool;
 
@@ -149,10 +135,10 @@
     }
 
   private:
-    friend in_place_stop_token;
-    friend __stok::__in_place_stop_callback_base;
+    friend inplace_stop_token;
+    friend __stok::__inplace_stop_callback_base;
     template <class>
-    friend class in_place_stop_callback;
+    friend class inplace_stop_callback;
 
     auto __lock_() const noexcept -> uint8_t;
     void __unlock_(uint8_t) const noexcept;
@@ -160,39 +146,38 @@
     auto __try_lock_unless_stop_requested_(bool) const noexcept -> bool;
 
     auto __try_add_callback_(
-        __stok::__in_place_stop_callback_base*) const noexcept -> bool;
+        __stok::__inplace_stop_callback_base*) const noexcept -> bool;
 
     void __remove_callback_(
-        __stok::__in_place_stop_callback_base*) const noexcept;
+        __stok::__inplace_stop_callback_base*) const noexcept;
 
     static constexpr uint8_t __stop_requested_flag_ = 1;
     static constexpr uint8_t __locked_flag_ = 2;
 
     mutable std::atomic<uint8_t> __state_{0};
-    mutable __stok::__in_place_stop_callback_base* __callbacks_ = nullptr;
+    mutable __stok::__inplace_stop_callback_base* __callbacks_ = nullptr;
     std::thread::id __notifying_thread_;
 };
 
-// [stoptoken.inplace], class in_place_stop_token
-class in_place_stop_token
+// [stoptoken.inplace], class inplace_stop_token
+class inplace_stop_token
 {
   public:
     template <class _Fun>
-    using callback_type = in_place_stop_callback<_Fun>;
+    using callback_type = inplace_stop_callback<_Fun>;
 
-    in_place_stop_token() noexcept : __source_(nullptr) {}
+    inplace_stop_token() noexcept : __source_(nullptr) {}
 
-    in_place_stop_token(const in_place_stop_token& __other) noexcept = default;
+    inplace_stop_token(const inplace_stop_token& __other) noexcept = default;
 
-    in_place_stop_token(in_place_stop_token&& __other) noexcept :
+    inplace_stop_token(inplace_stop_token&& __other) noexcept :
         __source_(std::exchange(__other.__source_, {}))
     {}
 
-    auto operator=(const in_place_stop_token& __other) noexcept
-        -> in_place_stop_token& = default;
+    auto operator=(const inplace_stop_token& __other) noexcept
+        -> inplace_stop_token& = default;
 
-    auto operator=(in_place_stop_token&& __other) noexcept
-        -> in_place_stop_token&
+    auto operator=(inplace_stop_token&& __other) noexcept -> inplace_stop_token&
     {
         __source_ = std::exchange(__other.__source_, nullptr);
         return *this;
@@ -208,51 +193,49 @@
         return __source_ != nullptr;
     }
 
-    void swap(in_place_stop_token& __other) noexcept
+    void swap(inplace_stop_token& __other) noexcept
     {
         std::swap(__source_, __other.__source_);
     }
 
-    auto operator==(const in_place_stop_token&) const noexcept
-        -> bool = default;
+    auto operator==(const inplace_stop_token&) const noexcept -> bool = default;
 
   private:
-    friend in_place_stop_source;
+    friend inplace_stop_source;
     template <class>
-    friend class in_place_stop_callback;
+    friend class inplace_stop_callback;
 
-    explicit in_place_stop_token(const in_place_stop_source* __source) noexcept
-        :
+    explicit inplace_stop_token(const inplace_stop_source* __source) noexcept :
         __source_(__source)
     {}
 
-    const in_place_stop_source* __source_;
+    const inplace_stop_source* __source_;
 };
 
-inline auto in_place_stop_source::get_token() const noexcept
-    -> in_place_stop_token
+inline auto inplace_stop_source::get_token() const noexcept
+    -> inplace_stop_token
 {
-    return in_place_stop_token{this};
+    return inplace_stop_token{this};
 }
 
-// [stopcallback.inplace], class template in_place_stop_callback
+// [stopcallback.inplace], class template inplace_stop_callback
 template <class _Fun>
-class in_place_stop_callback : __stok::__in_place_stop_callback_base
+class inplace_stop_callback : __stok::__inplace_stop_callback_base
 {
   public:
     template <class _Fun2>
         requires constructible_from<_Fun, _Fun2>
-    explicit in_place_stop_callback(in_place_stop_token __token,
-                                    _Fun2&& __fun) //
+    explicit inplace_stop_callback(inplace_stop_token __token,
+                                   _Fun2&& __fun) //
         noexcept(__nothrow_constructible_from<_Fun, _Fun2>) :
-        __stok::__in_place_stop_callback_base(
-            __token.__source_, &in_place_stop_callback::__execute_impl_),
+        __stok::__inplace_stop_callback_base(
+            __token.__source_, &inplace_stop_callback::__execute_impl_),
         __fun_(static_cast<_Fun2&&>(__fun))
     {
         __register_callback_();
     }
 
-    ~in_place_stop_callback()
+    ~inplace_stop_callback()
     {
         if (__source_ != nullptr)
             __source_->__remove_callback_(this);
@@ -260,9 +243,9 @@
 
   private:
     static void
-        __execute_impl_(__stok::__in_place_stop_callback_base* cb) noexcept
+        __execute_impl_(__stok::__inplace_stop_callback_base* cb) noexcept
     {
-        std::move(static_cast<in_place_stop_callback*>(cb)->__fun_)();
+        std::move(static_cast<inplace_stop_callback*>(cb)->__fun_)();
     }
 
     STDEXEC_ATTRIBUTE((no_unique_address))
@@ -271,7 +254,7 @@
 
 namespace __stok
 {
-inline void __in_place_stop_callback_base::__register_callback_() noexcept
+inline void __inplace_stop_callback_base::__register_callback_() noexcept
 {
     if (__source_ != nullptr)
     {
@@ -286,14 +269,14 @@
 }
 } // namespace __stok
 
-inline in_place_stop_source::~in_place_stop_source()
+inline inplace_stop_source::~inplace_stop_source()
 {
     STDEXEC_ASSERT(
         (__state_.load(std::memory_order_relaxed) & __locked_flag_) == 0);
     STDEXEC_ASSERT(__callbacks_ == nullptr);
 }
 
-inline auto in_place_stop_source::request_stop() noexcept -> bool
+inline auto inplace_stop_source::request_stop() noexcept -> bool
 {
     if (!__try_lock_unless_stop_requested_(true))
         return true;
@@ -330,7 +313,7 @@
     return false;
 }
 
-inline auto in_place_stop_source::__lock_() const noexcept -> uint8_t
+inline auto inplace_stop_source::__lock_() const noexcept -> uint8_t
 {
     __stok::__spin_wait __spin;
     auto __old_state = __state_.load(std::memory_order_relaxed);
@@ -348,12 +331,12 @@
     return __old_state;
 }
 
-inline void in_place_stop_source::__unlock_(uint8_t __old_state) const noexcept
+inline void inplace_stop_source::__unlock_(uint8_t __old_state) const noexcept
 {
     (void)__state_.store(__old_state, std::memory_order_release);
 }
 
-inline auto in_place_stop_source::__try_lock_unless_stop_requested_(
+inline auto inplace_stop_source::__try_lock_unless_stop_requested_(
     bool __set_stop_requested) const noexcept -> bool
 {
     __stok::__spin_wait __spin;
@@ -387,8 +370,8 @@
     return true;
 }
 
-inline auto in_place_stop_source::__try_add_callback_(
-    __stok::__in_place_stop_callback_base* __callbk) const noexcept -> bool
+inline auto inplace_stop_source::__try_add_callback_(
+    __stok::__inplace_stop_callback_base* __callbk) const noexcept -> bool
 {
     if (!__try_lock_unless_stop_requested_(false))
     {
@@ -408,8 +391,8 @@
     return true;
 }
 
-inline void in_place_stop_source::__remove_callback_(
-    __stok::__in_place_stop_callback_base* __callbk) const noexcept
+inline void inplace_stop_source::__remove_callback_(
+    __stok::__inplace_stop_callback_base* __callbk) const noexcept
 {
     auto __old_state = __lock_();
 
@@ -452,50 +435,16 @@
     }
 }
 
-template <class _Token>
-concept stoppable_token = copy_constructible<_Token> &&                   //
-                          move_constructible<_Token> &&                   //
-                          std::is_nothrow_copy_constructible_v<_Token> && //
-                          std::is_nothrow_move_constructible_v<_Token> && //
-                          equality_comparable<_Token> &&                  //
-                          requires(const _Token& __token) {
-                              {
-                                  __token.stop_requested()
-                              } noexcept -> __boolean_testable_;
-                              {
-                                  __token.stop_possible()
-                              } noexcept -> __boolean_testable_;
-    // workaround ICE in appleclang 13.1
-#if !defined(__clang__)
-                              typename __stok::__check_type_alias_exists<
-                                  _Token::template callback_type>;
-#endif
-                          };
+using in_place_stop_token
+    [[deprecated("in_place_stop_token has been renamed inplace_stop_token")]] =
+        inplace_stop_token;
 
-template <class _Token, typename _Callback, typename _Initializer = _Callback>
-concept stoppable_token_for =
-    stoppable_token<_Token> && __callable<_Callback> &&                 //
-    requires { typename _Token::template callback_type<_Callback>; } && //
-    constructible_from<_Callback, _Initializer> &&                      //
-    constructible_from<                                                 //
-        typename _Token::template callback_type<_Callback>, _Token,
-        _Initializer> &&                                                //
-    constructible_from<                                                 //
-        typename _Token::template callback_type<_Callback>, _Token&,
-        _Initializer> &&                                                //
-    constructible_from<                                                 //
-        typename _Token::template callback_type<_Callback>, const _Token,
-        _Initializer> &&                                                //
-    constructible_from<typename _Token::template callback_type<_Callback>,
-                       const _Token&, _Initializer>;
+using in_place_stop_source
+    [[deprecated("in_place_stop_token has been renamed inplace_stop_source")]] =
+        inplace_stop_source;
 
-template <class _Token>
-concept unstoppable_token =    //
-    stoppable_token<_Token> && //
-    requires {
-        {
-            _Token::stop_possible()
-        } -> __boolean_testable_;
-    } && //
-    (!_Token::stop_possible());
+template <class _Fun>
+using in_place_stop_callback [[deprecated(
+    "in_place_stop_callback has been renamed inplace_stop_callback")]] =
+    inplace_stop_callback<_Fun>;
 } // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/task.hpp b/include/sdbusplus/async/stdexec/task.hpp
index 60f9e49..2e9cf90 100644
--- a/include/sdbusplus/async/stdexec/task.hpp
+++ b/include/sdbusplus/async/stdexec/task.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 NVIDIA Corporation
+ * 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
@@ -16,6 +16,8 @@
 #pragma once
 
 #include "../stdexec/__detail/__meta.hpp"
+#include "../stdexec/__detail/__optional.hpp"
+#include "../stdexec/__detail/__variant.hpp"
 #include "../stdexec/coroutine.hpp"
 #include "../stdexec/execution.hpp"
 #include "any_sender_of.hpp"
@@ -27,7 +29,6 @@
 #include <cassert>
 #include <exception>
 #include <utility>
-#include <variant>
 
 STDEXEC_PRAGMA_PUSH()
 STDEXEC_PRAGMA_IGNORE_GNU("-Wundefined-inline")
@@ -68,16 +69,17 @@
     };
 
 template <class _ParentPromise>
-void __check_parent_promise_has_scheduler() noexcept
+constexpr bool __check_parent_promise_has_scheduler() noexcept
 {
     static_assert(__indirect_scheduler_provider<_ParentPromise>,
                   "exec::task<T> cannot be co_await-ed in a coroutine that "
                   "does not have an associated scheduler.");
+    return __indirect_scheduler_provider<_ParentPromise>;
 }
 
 struct __forward_stop_request
 {
-    in_place_stop_source& __stop_source_;
+    inplace_stop_source& __stop_source_;
 
     void operator()() noexcept
     {
@@ -97,6 +99,9 @@
     __sticky
 };
 
+struct __parent_promise_t
+{};
+
 template <__scheduler_affinity _SchedulerAffinity =
               __scheduler_affinity::__sticky>
 class __default_task_context_impl
@@ -110,31 +115,39 @@
     STDEXEC_ATTRIBUTE((no_unique_address))
     __if_c<__with_scheduler, __any_scheduler, __ignore> //
         __scheduler_{exec::inline_scheduler{}};
-    in_place_stop_token __stop_token_;
-
-    friend auto tag_invoke(get_scheduler_t,
-                           const __default_task_context_impl& __self) noexcept
-        -> const __any_scheduler&
-        requires(__with_scheduler)
-    {
-        return __self.__scheduler_;
-    }
-
-    friend auto tag_invoke(get_stop_token_t,
-                           const __default_task_context_impl& __self) noexcept
-        -> in_place_stop_token
-    {
-        return __self.__stop_token_;
-    }
+    inplace_stop_token __stop_token_;
 
   public:
-    __default_task_context_impl() = default;
+    template <class _ParentPromise>
+    explicit __default_task_context_impl(__parent_promise_t,
+                                         _ParentPromise& __parent) noexcept
+    {
+        if constexpr (_SchedulerAffinity == __scheduler_affinity::__sticky)
+        {
+            if constexpr (__check_parent_promise_has_scheduler<
+                              _ParentPromise>())
+            {
+                __scheduler_ = get_scheduler(get_env(__parent));
+            }
+        }
+    }
 
     template <scheduler _Scheduler>
     explicit __default_task_context_impl(_Scheduler&& __scheduler) :
         __scheduler_{static_cast<_Scheduler&&>(__scheduler)}
     {}
 
+    auto query(get_scheduler_t) const noexcept -> const __any_scheduler&
+        requires(__with_scheduler)
+    {
+        return __scheduler_;
+    }
+
+    auto query(get_stop_token_t) const noexcept -> inplace_stop_token
+    {
+        return __stop_token_;
+    }
+
     [[nodiscard]] auto stop_requested() const noexcept -> bool
     {
         return __stop_token_.stop_requested();
@@ -151,6 +164,8 @@
     using promise_context_t = __default_task_context_impl;
 
     template <class _ThisPromise, class _ParentPromise = void>
+        requires(!__with_scheduler) ||
+                    __indirect_scheduler_provider<_ParentPromise>
     using awaiter_context_t = __default_awaiter_context<_ParentPromise>;
 };
 
@@ -171,19 +186,13 @@
     explicit __default_awaiter_context(
         __default_task_context_impl<_Affinity>& __self,
         _ParentPromise& __parent) noexcept
-    {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
-    }
+    {}
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // This is the context to be associated with basic_task's awaiter when
 // the parent coroutine's promise type is known, is a __stop_token_provider,
-// and its stop token type is neither in_place_stop_token nor unstoppable.
+// and its stop token type is neither inplace_stop_token nor unstoppable.
 template <__indirect_stop_token_provider _ParentPromise>
 struct __default_awaiter_context<_ParentPromise>
 {
@@ -202,25 +211,20 @@
         __stop_callback_{get_stop_token(get_env(__parent)),
                          __forward_stop_request{__stop_source_}}
     {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
         static_assert(
             std::is_nothrow_constructible_v<__stop_callback_t, __stop_token_t,
                                             __forward_stop_request>);
         __self.__stop_token_ = __stop_source_.get_token();
     }
 
-    in_place_stop_source __stop_source_{};
+    inplace_stop_source __stop_source_{};
     __stop_callback_t __stop_callback_;
 };
 
-// If the parent coroutine's type has a stop token of type in_place_stop_token,
+// If the parent coroutine's type has a stop token of type inplace_stop_token,
 // we don't need to register a stop callback.
 template <__indirect_stop_token_provider _ParentPromise>
-    requires std::same_as<in_place_stop_token,
+    requires std::same_as<inplace_stop_token,
                           stop_token_of_t<env_of_t<_ParentPromise>>>
 struct __default_awaiter_context<_ParentPromise>
 {
@@ -229,11 +233,6 @@
         __default_task_context_impl<_Affinity>& __self,
         _ParentPromise& __parent) noexcept
     {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
         __self.__stop_token_ = get_stop_token(get_env(__parent));
     }
 };
@@ -245,16 +244,9 @@
 struct __default_awaiter_context<_ParentPromise>
 {
     template <__scheduler_affinity _Affinity>
-    explicit __default_awaiter_context(
-        __default_task_context_impl<_Affinity>& __self,
-        _ParentPromise& __parent) noexcept
-    {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
-    }
+    explicit __default_awaiter_context(__default_task_context_impl<_Affinity>&,
+                                       _ParentPromise&) noexcept
+    {}
 };
 
 // Finally, if we don't know the parent coroutine's promise type, assume the
@@ -266,13 +258,7 @@
     explicit __default_awaiter_context(
         __default_task_context_impl<_Affinity>& __self,
         _ParentPromise& __parent) noexcept
-    {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
-    }
+    {}
 
     template <__scheduler_affinity _Affinity,
               __indirect_stop_token_provider _ParentPromise>
@@ -280,20 +266,14 @@
         __default_task_context_impl<_Affinity>& __self,
         _ParentPromise& __parent)
     {
-        if constexpr (_Affinity == __scheduler_affinity::__sticky)
-        {
-            __check_parent_promise_has_scheduler<_ParentPromise>();
-            __self.__scheduler_ = get_scheduler(get_env(__parent));
-        }
         // Register a callback that will request stop on this basic_task's
         // stop_source when stop is requested on the parent coroutine's stop
         // token.
         using __stop_token_t = stop_token_of_t<env_of_t<_ParentPromise>>;
         using __stop_callback_t =
-            typename __stop_token_t::template callback_type<
-                __forward_stop_request>;
+            stop_callback_for_t<__stop_token_t, __forward_stop_request>;
 
-        if constexpr (std::same_as<__stop_token_t, in_place_stop_token>)
+        if constexpr (std::same_as<__stop_token_t, inplace_stop_token>)
         {
             __self.__stop_token_ = get_stop_token(get_env(__parent));
         }
@@ -306,7 +286,7 @@
         }
     }
 
-    in_place_stop_source __stop_source_{};
+    inplace_stop_source __stop_source_{};
     std::any __stop_callback_{};
 };
 
@@ -322,10 +302,10 @@
 {
     void return_value(_Ty value)
     {
-        __data_.template emplace<1>(std::move(value));
+        __data_.template emplace<0>(std::move(value));
     }
 
-    std::variant<std::monostate, _Ty, std::exception_ptr> __data_{};
+    __variant_for<_Ty, std::exception_ptr> __data_{};
 };
 
 template <>
@@ -336,10 +316,10 @@
 
     void return_void()
     {
-        __data_.template emplace<1>(__void{});
+        __data_.template emplace<0>(__void{});
     }
 
-    std::variant<std::monostate, __void, std::exception_ptr> __data_{};
+    __variant_for<__void, std::exception_ptr> __data_{};
 };
 
 enum class disposition : unsigned
@@ -404,8 +384,14 @@
         static void await_resume() noexcept {}
     };
 
+    using __promise_context_t =
+        typename _Context::template promise_context_t<__promise>;
+
     struct __promise : __promise_base<_Ty>, with_awaitable_senders<__promise>
     {
+        using __t = __promise;
+        using __id = __promise;
+
         auto get_return_object() noexcept -> basic_task
         {
             return basic_task(
@@ -424,12 +410,20 @@
 
         [[nodiscard]] auto disposition() const noexcept -> __task::disposition
         {
-            return static_cast<__task::disposition>(this->__data_.index());
+            switch (this->__data_.index())
+            {
+                case 0:
+                    return __task::disposition::succeeded;
+                case 1:
+                    return __task::disposition::failed;
+                default:
+                    return __task::disposition::stopped;
+            }
         }
 
         void unhandled_exception() noexcept
         {
-            this->__data_.template emplace<2>(std::current_exception());
+            this->__data_.template emplace<1>(std::current_exception());
         }
 
         template <sender _Awaitable>
@@ -440,7 +434,7 @@
             // TODO: If we have a complete-where-it-starts query then we can
             // optimize this to avoid the reschedule
             return as_awaitable(transfer(static_cast<_Awaitable&&>(__awaitable),
-                                         get_scheduler(__context_)),
+                                         get_scheduler(*__context_)),
                                 *this);
         }
 
@@ -454,7 +448,7 @@
             {
                 // Create a cleanup action that transitions back onto the
                 // current scheduler:
-                auto __sched = get_scheduler(__context_);
+                auto __sched = get_scheduler(*__context_);
                 auto __cleanup_task = at_coroutine_exit(schedule,
                                                         std::move(__sched));
                 // Insert the cleanup action into the head of the continuation
@@ -465,7 +459,7 @@
                     __coro::coroutine_handle<__promise>::from_promise(*this));
                 (void)__cleanup_task.await_resume();
             }
-            __context_.set_scheduler(__box.__sched_);
+            __context_->set_scheduler(__box.__sched_);
             return as_awaitable(schedule(__box.__sched_), *this);
         }
 
@@ -477,16 +471,12 @@
                 static_cast<_Awaitable&&>(__awaitable));
         }
 
-        using __context_t =
-            typename _Context::template promise_context_t<__promise>;
-
-        friend auto tag_invoke(get_env_t, const __promise& __self) noexcept
-            -> const __context_t&
+        auto get_env() const noexcept -> const __promise_context_t&
         {
-            return __self.__context_;
+            return *__context_;
         }
 
-        __context_t __context_;
+        __optional<__promise_context_t> __context_{};
         bool __rescheduled_{false};
     };
 
@@ -494,8 +484,7 @@
     struct __task_awaitable
     {
         __coro::coroutine_handle<__promise> __coro_;
-        std::optional<awaiter_context_t<__promise, _ParentPromise>>
-            __context_{};
+        __optional<awaiter_context_t<__promise, _ParentPromise>> __context_{};
 
         ~__task_awaitable()
         {
@@ -514,7 +503,9 @@
             -> __coro::coroutine_handle<>
         {
             static_assert(__one_of<_ParentPromise, _ParentPromise2, void>);
-            __context_.emplace(__coro_.promise().__context_,
+            __coro_.promise().__context_.emplace(__parent_promise_t(),
+                                                 __parent.promise());
+            __context_.emplace(*__coro_.promise().__context_,
                                __parent.promise());
             __coro_.promise().set_continuation(__parent);
             if constexpr (requires {
@@ -532,21 +523,22 @@
             __context_.reset();
             scope_guard __on_exit{
                 [this]() noexcept { std::exchange(__coro_, {}).destroy(); }};
-            if (__coro_.promise().__data_.index() == 2)
+            if (__coro_.promise().__data_.index() == 1)
                 std::rethrow_exception(
-                    std::get<2>(std::move(__coro_.promise().__data_)));
+                    std::move(__coro_.promise().__data_.template get<1>()));
             if constexpr (!std::is_void_v<_Ty>)
-                return std::get<1>(std::move(__coro_.promise().__data_));
+                return std::move(__coro_.promise().__data_.template get<0>());
         }
     };
 
+  public:
     // Make this task awaitable within a particular context:
     template <class _ParentPromise>
         requires constructible_from<
-            awaiter_context_t<__promise, _ParentPromise>, __promise&,
+            awaiter_context_t<__promise, _ParentPromise>, __promise_context_t&,
             _ParentPromise&>
-    friend auto tag_invoke(as_awaitable_t, basic_task&& __self,
-                           _ParentPromise&) noexcept
+    STDEXEC_MEMFN_DECL(auto as_awaitable)(this basic_task&& __self,
+                                          _ParentPromise&) noexcept
         -> __task_awaitable<_ParentPromise>
     {
         return __task_awaitable<_ParentPromise>{
@@ -554,18 +546,18 @@
     }
 
     // Make this task generally awaitable:
-    friend auto operator co_await(basic_task&& __self) noexcept
-        -> __task_awaitable<>
+    auto operator co_await() && noexcept -> __task_awaitable<>
         requires __mvalid<awaiter_context_t, __promise>
     {
-        return __task_awaitable<>{std::exchange(__self.__coro_, {})};
+        return __task_awaitable<>{std::exchange(__coro_, {})};
     }
 
     // From the list of types [_Ty], remove any types that are void, and send
     //   the resulting list to __qf<set_value_t>, which uses the list of types
     //   as arguments of a function type. In other words, set_value_t() if _Ty
     //   is void, and set_value_t(_Ty) otherwise.
-    using __set_value_sig_t = __minvoke<__remove<void, __qf<set_value_t>>, _Ty>;
+    using __set_value_sig_t =
+        __minvoke<__mremove<void, __qf<set_value_t>>, _Ty>;
 
     // Specify basic_task's completion signatures
     //   This is only necessary when basic_task is not generally awaitable
@@ -574,8 +566,7 @@
         completion_signatures<__set_value_sig_t,
                               set_error_t(std::exception_ptr), set_stopped_t()>;
 
-    friend auto tag_invoke(get_completion_signatures_t, const basic_task&, auto)
-        -> __task_traits_t
+    auto get_completion_signatures(__ignore = {}) const -> __task_traits_t
     {
         return {};
     }
@@ -606,4 +597,10 @@
 inline constexpr __task::__reschedule_coroutine_on reschedule_coroutine_on{};
 } // namespace exec
 
+namespace stdexec
+{
+template <class _Ty, class _Context>
+inline constexpr bool enable_sender<exec::basic_task<_Ty, _Context>> = true;
+} // namespace stdexec
+
 STDEXEC_PRAGMA_POP()