/*
 * Copyright (c) 2021-2022 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 "__concepts.hpp"
#include "__config.hpp"
#include "__env.hpp"
#include "__execution_fwd.hpp"
#include "__meta.hpp"
#include "__tuple.hpp"
#include "__type_traits.hpp"

#include <cstddef>
#include <type_traits>
#include <utility> // for tuple_size/tuple_element

namespace stdexec
{
/////////////////////////////////////////////////////////////////////////////
// Generic __sender type
namespace __detail
{
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>
    STDEXEC_ATTRIBUTE((always_inline))
    _Data&& operator()(__ignore, _Data&& __data, _Rest&&...) const noexcept
    {
        return (_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>
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>
{
    using __t = __detail::__sexpr_uncurry<_Tp, _Fn>;
};

template <class _Tag>
struct __sexpr_impl;

template <class _Sender>
using __name_of = __detail::__name_of<_Sender>;

namespace __detail
{
template <class _Sexpr, class _Receiver>
struct __op_state;

template <class _Sexpr, class _Receiver>
struct __connect_fn;

template <class _Tag, class _Sexpr, class _Receiver>
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 _Sexpr, class _Receiver>
concept __connectable =
    __callable<__impl_of<_Sexpr>, __copy_cvref_fn<_Sexpr>,
               __connect_fn<_Sexpr, _Receiver>> &&
    __mvalid<__state_type_t, tag_of_t<_Sexpr>, _Sexpr, _Receiver>;

// // Note: This is UB. UBSAN allows it for now.
// template <class _Parent, class _Child>
// _Parent* __parent_from_child(_Child* __child, _Child _Parent::*__mbr_ptr)
// noexcept {
//   alignas(_Parent) char __buf[sizeof(_Parent)];
//   _Parent* __parent = (_Parent*) &__buf;
//   const std::ptrdiff_t __offset = (char*) &(__parent->*__mbr_ptr) - __buf;
//   return (_Parent*) ((char*) __child - __offset);
// }

inline constexpr auto __get_attrs = //
    [](__ignore, const auto&... __child) noexcept -> decltype(auto) {
    if constexpr (sizeof...(__child) == 1)
    {
        return stdexec::get_env(
            __child...); // BUGBUG: should be only the forwarding queries
    }
    else
    {
        return empty_env();
    }
    STDEXEC_UNREACHABLE();
};

inline constexpr auto __get_env = //
    []<class _Receiver>(__ignore, __ignore, const _Receiver& __rcvr) noexcept
    -> env_of_t<const _Receiver&> { return stdexec::get_env(__rcvr); };

inline constexpr auto __get_state = //
    []<class _Sender>(_Sender&& __sndr, __ignore) noexcept -> decltype(auto) {
    return STDEXEC_CALL_EXPLICIT_THIS_MEMFN((_Sender&&)__sndr,
                                            apply)(__get_data());
};

inline constexpr auto __connect = //
    []<class _Sender, class _Receiver>(
        _Sender&& __sndr, _Receiver __rcvr) -> __op_state<_Sender, _Receiver>
    requires __connectable<_Sender, _Receiver>
{
    return __op_state<_Sender, _Receiver>{(_Sender&&)__sndr,
                                          (_Receiver&&)__rcvr};
};

inline constexpr auto __start = //
    []<class _StartTag = start_t, class... _ChildOps>(
        __ignore, __ignore, _ChildOps&... __ops) noexcept
{
    (_StartTag()(__ops), ...);
};

inline constexpr auto __complete = //
    []<class _Index, class _Receiver, class _SetTag, class... _Args>(
        _Index, __ignore, _Receiver& __rcvr, _SetTag,
        _Args&&... __args) noexcept {
    static_assert(__v<_Index> == 0,
                  "I don't know how to complete this operation.");
    _SetTag()(std::move(__rcvr), (_Args&&)__args...);
};

inline constexpr auto __get_completion_signagures = //
    [](__ignore, __ignore) noexcept { return void(); };

template <class _ReceiverId, class _Sexpr, class _Idx>
struct __receiver
{
    struct __t
    {
        using receiver_concept = receiver_t;
        using _Receiver = stdexec::__t<_ReceiverId>;
        using __sexpr = _Sexpr;
        using __index = _Idx;
        using __id = __receiver;
        using __parent_op_t = __op_state<_Sexpr, _Receiver>;
        using __tag_t = tag_of_t<_Sexpr>;

        // A pointer to the parent operation state, which contains the one
        // created with this receiver.
        __parent_op_t* __op_;

        // template <class _ChildSexpr, class _ChildReceiver>
        // static __t __from_op_state(__op_state<_ChildSexpr, _ChildReceiver>*
        // __child) noexcept {
        //   using __parent_op_t = __op_state<_Sexpr, _Receiver>;
        //   std::ptrdiff_t __offset = __parent_op_t::template
        //   __get_child_op_offset<__v<_Idx>>();
        //   __parent_op_t* __parent = (__parent_op_t*) ((char*) __child -
        //   __offset); return __t{__parent};
        // }

        template <__completion_tag _Tag, class... _Args>
        STDEXEC_ATTRIBUTE((always_inline))
        friend void tag_invoke(_Tag, __t&& __self, _Args&&... __args) noexcept
        {
            __self.__op_->__complete(_Idx(), _Tag(), (_Args&&)__args...);
        }

        template <same_as<get_env_t> _Tag, class _SexprTag = __tag_t>
        STDEXEC_ATTRIBUTE((always_inline))
        friend auto tag_invoke(_Tag, const __t& __self) noexcept
            -> __env_type_t<_SexprTag, _Idx, _Sexpr, _Receiver>
        {
            return __self.__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 _Sexpr, class _Receiver>
struct __op_base : __immovable
{
    using __tag_t = typename __decay_t<_Sexpr>::__tag_t;
    using __state_t = __state_type_t<__tag_t, _Sexpr, _Receiver>;

    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS _Receiver __rcvr_;
    STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS __state_t __state_;

    __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr) :
        __rcvr_((_Receiver&&)__rcvr),
        __state_(__sexpr_impl<__tag_t>::get_state((_Sexpr&&)__sndr, __rcvr_))
    {}

    _Receiver& __rcvr() & noexcept
    {
        return __rcvr_;
    }
};

// template <class _Sexpr, class _Receiver>
//   requires __is_instance_of<__id<_Receiver>, __receiver>
//         && __decays_to<_Sexpr, __sexpr_connected_with<_Receiver>>
// struct __op_base<_Sexpr, _Receiver> : __immovable {
//   using __tag_t = typename __decay_t<_Sexpr>::__tag_t;
//   using __state_t = __state_type_t<__tag_t, _Sexpr, _Receiver>;

//   STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS __state_t __state_;

//   __op_base(_Sexpr&& __sndr, _Receiver&& __rcvr)
//     : __state_(__sexpr_impl<__tag_t>::get_state((_Sexpr&&) __sndr, __rcvr)) {
//     STDEXEC_ASSERT(this->__rcvr().__op_ == __rcvr.__op_);
//   }

//   _Receiver __rcvr() const noexcept {
//     return _Receiver::__from_op_state(             //
//       static_cast<__op_state<_Sexpr, _Receiver>*>( //
//         const_cast<__op_base*>(this)));
//   }
// };

STDEXEC_PRAGMA_PUSH()
STDEXEC_PRAGMA_IGNORE_GNU("-Winvalid-offsetof")
STDEXEC_PRAGMA_IGNORE_EDG(offset_in_non_POD_nonstandard)

template <class _Sexpr, class _Receiver>
struct __enable_receiver_from_this
{
    using __op_base_t = __op_base<_Sexpr, _Receiver>;

    decltype(auto) __receiver() noexcept
    {
        using __derived_t = decltype(__op_base_t::__state_);
        __derived_t* __derived = static_cast<__derived_t*>(this);
        constexpr std::size_t __offset = offsetof(__op_base_t, __state_);
        __op_base_t* __base = (__op_base_t*)((char*)__derived - __offset);
        return __base->__rcvr();
    }
};

STDEXEC_PRAGMA_POP()

STDEXEC_PRAGMA_PUSH()
STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")

template <class _Sexpr, class _Receiver>
struct __connect_fn
{
    template <std::size_t _Idx>
    using __receiver_t =
        __t<__receiver<__id<_Receiver>, _Sexpr, __mconstant<_Idx>>>;

    __op_state<_Sexpr, _Receiver>* __op_;

    struct __impl
    {
        __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>>...>
        {
            return __tuple{
                connect((_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...>
    {
        return __impl{__op_}(__indices_for<_Child...>(), _Tag(),
                             (_Data&&)__data, (_Child&&)__child...);
    }
};
STDEXEC_PRAGMA_POP()

template <class _Sexpr, class _Receiver>
struct __op_state : __op_base<_Sexpr, _Receiver>
{
    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 __state_t = typename __op_state::__state_t;
    using __inner_ops_t =
        __result_of<__sexpr_apply, _Sexpr, __connect_fn<_Sexpr, _Receiver>>;

    __inner_ops_t __inner_ops_;

    // 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_) - (char*) __self);
    // }

    __op_state(_Sexpr&& __sexpr, _Receiver __rcvr) :
        __op_state::__op_base{(_Sexpr&&)__sexpr, (_Receiver&&)__rcvr},
        __inner_ops_(__sexpr_apply((_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
    {
        using __tag_t = typename __op_state::__tag_t;
        auto&& __rcvr = __self.__rcvr();
        __tup::__apply(
            [&](auto&... __ops) noexcept {
            __sexpr_impl<__tag_t>::start(__self.__state_, __rcvr, __ops...);
        },
            __self.__inner_ops_);
    }

    template <class _Index, class _Tag2, class... _Args>
    STDEXEC_ATTRIBUTE((always_inline))
    void __complete(_Index, _Tag2, _Args&&... __args) noexcept
    {
        using __tag_t = typename __op_state::__tag_t;
        auto&& __rcvr = this->__rcvr();
        __sexpr_impl<__tag_t>::complete(_Index(), this->__state_, __rcvr,
                                        _Tag2(), (_Args&&)__args...);
    }

    template <class _Index>
    STDEXEC_ATTRIBUTE((always_inline)) //
    auto __get_env(_Index) noexcept
        -> __env_type_t<__tag_t, _Index, _Sexpr, _Receiver>
    {
        const auto& __rcvr = this->__rcvr();
        return __sexpr_impl<__tag_t>::get_env(_Index(), this->__state_, __rcvr);
    }
};

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...>)
            -> __call_result_t<const _Fn&, _Rest...> {
        return __fn((_Rest&&)__rest...);
    };
};
} // namespace __detail

struct __sexpr_defaults
{
    static constexpr auto get_attrs = __detail::__get_attrs;
    static constexpr auto get_env = __detail::__get_env;
    static constexpr auto get_state = __detail::__get_state;
    static constexpr auto connect = __detail::__connect;
    static constexpr auto start = __detail::__start;
    static constexpr auto complete = __detail::__complete;
    static constexpr auto get_completion_signagures =
        __detail::__get_completion_signagures;
};

template <class Tag>
struct __sexpr_impl : __sexpr_defaults
{};

using __detail::__enable_receiver_from_this;

template <class _Tag>
using __get_attrs_fn = __result_of<__detail::__drop_front,
                                   __mtypeof<__sexpr_impl<_Tag>::get_attrs>>;

//////////////////////////////////////////////////////////////////////////////////////////////////
// __sexpr
template <class...>
struct __sexpr
{
    using __id = __sexpr;
    using __t = __sexpr;
};

template <class _ImplFn>
struct __sexpr<_ImplFn>
{
    using sender_concept = sender_t;
    using __t = __sexpr;
    using __id = __sexpr;
    using __desc_t = __call_result_t<_ImplFn, __cp, __detail::__get_desc>;
    using __tag_t = typename __desc_t::__tag;
    using __data_t = typename __desc_t::__data;
    using __children_t = typename __desc_t::__children;
    using __arity_t = __mapply<__msize, __children_t>;

    template <class _Tag>
    using __impl = __sexpr_impl<__meval<__msecond, _Tag, __tag_t>>;

    STDEXEC_ATTRIBUTE((always_inline)) //
    static __tag_t __tag() noexcept
    {
        return {};
    }

    mutable _ImplFn __impl_;

    STDEXEC_ATTRIBUTE((host, device, always_inline))
    explicit __sexpr(_ImplFn __impl) : __impl_((_ImplFn&&)__impl) {}

    template <same_as<get_env_t> _Tag, same_as<__sexpr> _Self>
    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>>>
    {
        return __sexpr_apply(__self,
                             __detail::__drop_front(__impl<_Tag>::get_attrs));
    }

    template <same_as<get_completion_signatures_t> _Tag,
              __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>>
    {
        return {};
    }

    // BUGBUG fix receiver constraint here:
    template <same_as<connect_t> _Tag, __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((_Self&&)__self,
                                                (_Receiver&&)__rcvr))) //
        -> __msecond<
            __if_c<same_as<_Tag, connect_t> && __decays_to<_Self, __sexpr>>,
            __result_of<__impl<_Tag>::connect, _Self, _Receiver>>
    {
        return __impl<_Tag>::connect((_Self&&)__self, (_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>) //
        -> __call_result_t<__detail::__impl_of<_Sender>,
                           __copy_cvref_fn<_Sender>, _ApplyFn>
    {                                                                //
        return ((_Sender&&)__sndr)
            .__impl_(__copy_cvref_fn<_Sender>(), (_ApplyFn&&)__fun); //
    }

    template <std::size_t _Idx, __decays_to_derived_from<__sexpr> _Self>
    STDEXEC_ATTRIBUTE((always_inline))
    friend decltype(auto) get(_Self&& __self) noexcept
        requires(_Idx < (__v<__arity_t> + 2))
    {
        if constexpr (_Idx == 0)
        {
            return __tag_t();
        }
        else
        {
            return __self.__impl_(__copy_cvref_fn<_Self>(),
                                  __nth_pack_element<_Idx>);
        }
        STDEXEC_UNREACHABLE();
    }
};

template <class _ImplFn>
STDEXEC_ATTRIBUTE((host, device))
__sexpr(_ImplFn) -> __sexpr<_ImplFn>;

//////////////////////////////////////////////////////////////////////////////////////////////////
// __make_sexpr
namespace __detail
{
template <class _Tag>
struct __make_sexpr_t
{
    template <class _Data = __, class... _Child>
    constexpr auto operator()(_Data __data = {}, _Child... __child) const;
};

#if STDEXEC_NVHPC() || (STDEXEC_GCC() && __GNUC__ < 13)
// The NVIDIA HPC compiler and gcc prior to v13 struggle with capture
// initializers for a parameter pack. As a workaround, we use a wrapper that
// performs moves when non-const lvalues are copied. That constructor is
// only used when capturing the variables, never when the resulting lambda
// is copied or moved.

// Move-by-copy
template <class _Ty>
struct __mbc
{
    template <class _Cvref>
    using __f = __minvoke<_Cvref, _Ty>;

    _Ty __value;

    STDEXEC_ATTRIBUTE((always_inline))
    explicit __mbc(_Ty& __v) noexcept(
        std::is_nothrow_move_constructible_v<_Ty>) :
        __value((_Ty&&)__v)
    {}

    // This is a template so as to not be considered a copy/move constructor.
    // Therefore, it doesn't suppress the generation of the default copy/move
    // constructors.
    STDEXEC_ATTRIBUTE((always_inline))
    __mbc(same_as<__mbc> auto& __that) noexcept(
        std::is_nothrow_move_constructible_v<_Ty>) :
        __value(static_cast<_Ty&&>(__that.__value))
    {}
};

// Rather strange definition of the lambda return type below is to reap the
// benefits of SFINAE without nvc++ encoding the whole return type into the
// symbol name.
template <class _Ty>
extern _Ty (*__f)();

// Anonymous namespace here is to avoid symbol name collisions with the
// lambda functions returned by __make_tuple.
namespace
{
constexpr auto __make_tuple = //
    []<class _Tag, class... _Captures>(_Tag, _Captures&&... __captures) {
    return
        [=]<class _Cvref, class _Fun>(_Cvref __cvref, _Fun&& __fun) mutable  //
        noexcept(
            __nothrow_callable<_Fun, _Tag, __minvoke<_Captures, _Cvref>...>) //
        -> decltype(__f<__call_result_t<_Fun, _Tag,
                                        __minvoke<_Captures, _Cvref>...>>())
            requires __callable<_Fun, _Tag, __minvoke<_Captures, _Cvref>...>
    {
        return ((_Fun&&)__fun)(
            _Tag(),
            const_cast<__minvoke<_Captures, _Cvref>&&>(__captures.__value)...);
    };
};
} // anonymous namespace

template <class _Tag>
template <class _Data, class... _Child>
constexpr auto __make_sexpr_t<_Tag>::operator()(_Data __data,
                                                _Child... __child) const
{
    return __sexpr{__make_tuple(_Tag(), __detail::__mbc(__data),
                                __detail::__mbc(__child)...)};
}
#else
// Anonymous namespace here is to avoid symbol name collisions with the
// lambda functions returned by __make_tuple.
namespace
{
constexpr auto __make_tuple = //
    []<class _Tag, class... _Captures>(_Tag, _Captures&&... __captures) {
    return
        [... __captures = (_Captures&&)__captures]<class _Cvref, class _Fun>(
            _Cvref, _Fun&& __fun) mutable                                    //
        noexcept(
            __nothrow_callable<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>) //
        -> __call_result_t<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>
            requires __callable<_Fun, _Tag, __minvoke<_Cvref, _Captures>...>
    {
        return ((_Fun&&)__fun)(
            _Tag(), const_cast<__minvoke<_Cvref, _Captures>&&>(__captures)...);
    };
};
} // anonymous namespace

template <class _Tag>
template <class _Data, class... _Child>
constexpr auto __make_sexpr_t<_Tag>::operator()(_Data __data,
                                                _Child... __child) const
{
    return __sexpr{__make_tuple(_Tag(), (_Data&&)__data, (_Child&&)__child...)};
};
#endif

template <class _Tag>
inline constexpr __make_sexpr_t<_Tag> __make_sexpr{};
} // namespace __detail

using __detail::__make_sexpr;

template <class _Tag, class _Data, class... _Child>
using __sexpr_t = __result_of<__make_sexpr<_Tag>, _Data, _Child...>;

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(
            ((_Sender&&)__sndr), apply)((_ApplyFn&&)__fun)))  //
        -> decltype(STDEXEC_CALL_EXPLICIT_THIS_MEMFN(((_Sender&&)__sndr),
                                                     apply)((_ApplyFn&&)__fun))
    {
        return STDEXEC_CALL_EXPLICIT_THIS_MEMFN(((_Sender&&)__sndr),
                                                apply)((_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
{
struct __basic_sender_name
{
    template <class _Sender>
    using __f = //
        __call_result_t<__sexpr_apply_result_t<_Sender, __basic_sender_name>>;

    template <class _Tag, class _Data, class... _Child>
    auto operator()(_Tag, _Data&&, _Child&&...) const //
        -> __sexpr<_Tag, _Data, __name_of<_Child>...> (*)();
};

struct __id_name
{
    template <class _Sender>
    using __f = __name_of<__id<_Sender>>;
};

template <class _Sender>
extern __mcompose<__cplr, __name_of_fn<_Sender>> __name_of_v<_Sender&>;

template <class _Sender>
extern __mcompose<__cprr, __name_of_fn<_Sender>> __name_of_v<_Sender&&>;

template <class _Sender>
extern __mcompose<__cpclr, __name_of_fn<_Sender>> __name_of_v<const _Sender&>;

template <class _Impl>
extern __basic_sender_name __name_of_v<__sexpr<_Impl>>;

template <__has_id _Sender>
    requires(!same_as<__id<_Sender>, _Sender>)
extern __id_name __name_of_v<_Sender>;
} // namespace __detail
} // namespace stdexec

namespace std
{
template <class _Impl>
struct tuple_size<stdexec::__sexpr<_Impl>> :
    integral_constant<
        size_t, stdexec::__v<typename stdexec::__sexpr<_Impl>::__arity_t> + 2>
{};

template <size_t _Idx, class _Impl>
struct tuple_element<_Idx, stdexec::__sexpr<_Impl>>
{
    using type = stdexec::__remove_rvalue_reference_t<stdexec::__call_result_t<
        _Impl, stdexec::__cp, stdexec::__nth_pack_element_t<_Idx>>>;
};
} // namespace std
