/*
 * Copyright (c) 2026 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 "__memory.hpp"
#include "__type_traits.hpp"
#include "__typeinfo.hpp"
#include "__utility.hpp"

#include <cstddef>
#include <cstdint>
#include <cstring>

#include <bit>
#include <exception>
#include <memory>
#include <span>
#include <type_traits>
#include <utility>

#include "__prologue.hpp"

STDEXEC_PRAGMA_IGNORE_GNU("-Wredundant-consteval-if")
STDEXEC_PRAGMA_IGNORE_GNU("-Warray-bounds")

// NOLINTBEGIN(moderize-use-override)

namespace STDEXEC::__any
{

  //////////////////////////////////////////////////////////////////////////////////////////
  //! any: a library for ad hoc polymorphism with value semantics
  //!
  //! @par Terminology:
  //!
  //! - "root":
  //!
  //!   A type satisfying the @c root concept that is used as the nucleus of a "model".
  //!   There are 5 root types:
  //!
  //!   - @c __iroot:                 the abstract root
  //!   - @c __value_root:            holds a concrete value
  //!   - @c __reference_root:        holds a concrete reference
  //!   - @c __value_proxy_root:      holds a type-erased value model
  //!   - @c __reference_proxy_root:  holds a type-erased reference model
  //!
  //!   Aside from @c __iroot, all root types inherit from @c __iabstract<Interface>, where
  //!   @c Interface is the interface that the root type implements.
  //!
  //!   The @c root concept is defined as:
  //!
  //!   @code
  //!   template <class Root>
  //!   concept root = requires (Root& root)
  //!   {
  //!     __any::__value(root);
  //!     { __any::reset(root); } -> std::same_as<void>;
  //!     { __any::type(root) } -> std::same_as<const __type_index &>;
  //!     { __any::data(root) } -> std::same_as<void *>;
  //!     { __any::empty(root) } -> std::same_as<bool>;
  //!   };
  //!   @endcode
  //!
  //! - "model":
  //!
  //!   A polymorphic wrapper around a root that is constructed by recursively applying a
  //!   given interface and its base interfaces to the root type. For example, given an
  //!   interface @c Derived that __extends @c Base, the value proxy model is a type derived
  //!   from @c Derived<Base<__value_proxy_root<Derived>>>. Model types implement their given
  //!   interfaces in terms of the root type. There are 5 model types:
  //!
  //!   - @c __iabstract:             akin to an abstract base class for the
  //!                                 interface
  //!   - @c __value_model:           implements the interface for a concrete value
  //!   - @c __reference_model:       implements the interface for a concrete
  //!                                 reference
  //!   - @c __value_proxy_model:     implements the interface over a type-erased
  //!                                 value model
  //!   - @c __reference_proxy_model: implements the interface over a type-erased
  //!                                 reference model
  //!
  //! - "proxy":
  //!
  //!   A level of indirection that stores either a type-erased model in a small buffer or a
  //!   pointer to an object stored elsewhere. The @c __value_proxy_root and @c
  //!   __reference_proxy_root types model the @c root concept and contain an array of bytes
  //!   in which they stores either a polymorphic model in-situ or a (tagged) pointer to a
  //!   heap-allocated model. The @c __value_proxy_model and @c __reference_proxy_model types
  //!   implement the given interface in terms of the root type.
  //!
  //! @par Notes:
  //!
  //! - @c Interface<Base> inherits directly from @c any::interface<Interface,Base>, which
  //!   inherits directly from @c Base.
  //!
  //! - Given an interface template @c Derived that __extends @c Base, the type
  //!   @c __iabstract<Derived> is derived from @c __iabstract<Base>.
  //!
  //! - In the case of multiple interface extension, the inheritance is forced to be linear.
  //!   As a result, for an interface @c C that __extends @c A and @c B (in that order),
  //!   @c __iabstract<C> will have a linear inheritance hierarchy; it will be an alias for
  //!   @c C<B<A<__iroot>>>. The result is that @c __iabstract<C> inherits from @c __iabstract<A>
  //!   but not from @c __iabstract<B>.
  //!
  //! - The "`__proxy_root`" types both implement an @c emplace function that accepts a
  //!   concrete value or reference, wraps it in the appropriate "`__model`" type, and stores
  //!   it either in-situ or on the heap depending on its size and whether it is nothrow
  //!   moveable.
  //!
  //! - The @c __root types (excluding @c __iroot) all inherit from @c __iabstract<Interface>.
  //!   The @c __model types implement the interface in terms of the root type.
  //!
  //! - @c any<Derived> inherits from @c __value_proxy_model<Derived>, which in turn inherits
  //!   from @c Derived<Base<__value_proxy_root<Derived>>>, which in turn inherits from
  //!   @c Derived<Base<__iroot>> (aka @c __iabstract<Derived> ).
  //!
  //! - @c __any_ptr<Derived> is implemented in terms of a mutable private
  //!   @c __reference_proxy_model<Derived> data member, which in turn inherits from
  //!   @c Derived<Base<__reference_proxy_root<Derived>>>.
  //!
  //! - For every @c any<Interface> instantiation, there are 5 instantiations of
  //!   @c Interface:
  //!
  //!   1. @c Interface<...Bases...<__iroot>>>...>
  //!   2. @c Interface<...Bases...<__value_root<Value,Interface>>...>
  //!   3. @c Interface<...Bases...<__reference_root<Value,Interface>>...>
  //!   4. @c Interface<...Bases...<__value_proxy_root<Interface>>...>
  //!   5. @c Interface<...Bases...<__reference_proxy_root<Interface>>...>

  inline constexpr size_t      __default_buffer_size = 3 * sizeof(void *);
  inline constexpr char const *__pure_virt_msg       = "internal error: pure virtual %s() called\n";

  //////////////////////////////////////////////////////////////////////////////////////////
  // forward declarations

  // any types
  template <template <class> class _Interface>
  struct __any;

  template <template <class> class _Interface>
  struct __any_ptr_base;

  template <template <class> class _Interface>
  struct __any_ptr;

  template <template <class> class _Interface>
  struct __any_cptr;

  template <template <class> class... _BaseInterfaces>
  struct __extends;

  // semiregular interfaces
  template <class _Base>
  struct __imovable;

  template <class _Base>
  struct __icopyable;

  template <class _Base>
  struct __iequality_comparable;

  template <class _Base>
  struct __isemiregular;

  struct __iroot;

  template <template <class> class _Interface>
  using __bases_of = _Interface<__iroot>::__bases_type;

  template <template <class> class _Interface,
            class _Base,
            class _BaseInterfaces   = __extends<>,
            size_t _BufferSize      = __default_buffer_size,
            size_t _BufferAlignment = alignof(void *)>
  struct __interface_base;

  //////////////////////////////////////////////////////////////////////////////////////////
  // __interface_cast
  template <template <class> class _Interface, class _Base>
  STDEXEC_ATTRIBUTE(nodiscard, always_inline)
  constexpr _Interface<_Base> &__interface_cast(_Interface<_Base> &__arg) noexcept
  {
    return __arg;
  }

  template <template <class> class _Interface, class _Base>
  STDEXEC_ATTRIBUTE(nodiscard, always_inline)
  constexpr _Interface<_Base> const &__interface_cast(_Interface<_Base> const &__arg) noexcept
  {
    return __arg;  // NOLINT(bugprone-return-const-ref-from-parameter)
  }

  //////////////////////////////////////////////////////////////////////////////////////////
  // accessors
  struct __access
  {
    struct __value_t
    {
      template <class _Ty>
      STDEXEC_ATTRIBUTE(nodiscard, always_inline)
      constexpr auto &&operator()(_Ty &&__arg) const noexcept
      {
        return __arg.__value_(static_cast<_Ty &&>(__arg));
      }
    };

    struct __empty_t
    {
      template <class _Ty>
      STDEXEC_ATTRIBUTE(nodiscard, always_inline)
      constexpr bool operator()(_Ty const &__arg) const noexcept
      {
        return __arg.__empty_();
      }
    };

    struct __reset_t
    {
      template <class _Ty>
      STDEXEC_ATTRIBUTE(always_inline)
      constexpr void operator()(_Ty &__arg) const noexcept
      {
        __arg.__reset_();
      }
    };

    struct __type_t
    {
      template <class _Ty>
      STDEXEC_ATTRIBUTE(nodiscard, always_inline)
      constexpr __type_index const &operator()(_Ty const &__arg) const noexcept
      {
        return __arg.__type_();
      }
    };

    struct __data_t
    {
      template <class _Ty>
      STDEXEC_ATTRIBUTE(nodiscard, always_inline)
      constexpr auto *operator()(_Ty &__arg) const noexcept
      {
        return __arg.__data_();
      }
    };

    struct __caddressof_t
    {
      template <template <class> class _Interface, class _Base>
      [[nodiscard]]
      constexpr auto operator()(_Interface<_Base> const &__arg) const noexcept
      {
        return __any_cptr<_Interface>(std::addressof(__arg));
      }
    };

    struct __addressof_t : __caddressof_t
    {
      using __caddressof_t::operator();

      template <template <class> class _Interface, class _Base>
      [[nodiscard]]
      constexpr auto operator()(_Interface<_Base> &__arg) const noexcept
      {
        return __any_ptr<_Interface>(std::addressof(__arg));
      }
    };
  };

  [[maybe_unused]]
  inline constexpr auto __value = __access::__value_t{};
  [[maybe_unused]]
  inline constexpr auto __empty = __access::__empty_t{};
  [[maybe_unused]]
  inline constexpr auto __reset = __access::__reset_t{};
  [[maybe_unused]]
  inline constexpr auto __type = __access::__type_t{};
  [[maybe_unused]]
  inline constexpr auto __data = __access::__data_t{};
  [[maybe_unused]]
  inline constexpr auto __addressof = __access::__addressof_t{};
  [[maybe_unused]]
  inline constexpr auto __caddressof = __access::__caddressof_t{};

  // __value_of_t
  template <class _Ty>
  using __value_of_t = std::decay_t<decltype(__value(__declval<_Ty &>()))>;

  //////////////////////////////////////////////////////////////////////////////////////////
  // __extension_of
  template <class _Interface, template <class> class _BaseInterface>
  concept __extension_of = requires(_Interface const &__arg) {
    STDEXEC::__any::__interface_cast<_BaseInterface>(__arg);
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  enum class __box_kind
  {
    __abstract,
    __object,
    __proxy
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  enum class __root_kind
  {
    __value,
    __reference
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __is_small: Model is Interface<_Ty> for some concrete _Ty
  template <class _Model>
  [[nodiscard]]
  constexpr bool __is_small(size_t __buffer_size) noexcept
  {
    if constexpr (_Model::__root_kind == __root_kind::__reference)
    {
      STDEXEC_ASSERT(sizeof(_Model) <= __buffer_size);
      return true;
    }
    else
    {
      // If _Model requires movability, then it must be nothrow moveable to be small.
      STDEXEC_CONSTEXPR_LOCAL bool __nothrow_movable = !__extension_of<_Model, __imovable>
                                                    || __nothrow_move_constructible<_Model>;
      return sizeof(_Model) <= __buffer_size && __nothrow_movable;
    }
  }

  //////////////////////////////////////////////////////////////////////////////////////////
  // __tagged_ptr
  struct __tagged_ptr
  {
    STDEXEC_ATTRIBUTE(always_inline)
    /*implicit*/ constexpr __tagged_ptr() noexcept
      : __data_(std::uintptr_t(1))
    {}

    STDEXEC_ATTRIBUTE(always_inline)
    /*implicit*/ __tagged_ptr(void *__ptr, bool __tag = true) noexcept
      : __data_(reinterpret_cast<std::uintptr_t>(__ptr) | std::uintptr_t(__tag))
    {}

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    void *__get() const noexcept
    {
      return reinterpret_cast<void *>(__data_ & ~std::uintptr_t(1));
    }

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr bool __is_tagged() const noexcept
    {
      return bool(__data_ & std::uintptr_t(1));
    }

    [[nodiscard]]
    constexpr bool operator==(std::nullptr_t) const noexcept
    {
      return __data_ <= std::uintptr_t(1);
    }

   private:
    std::uintptr_t __data_;
  };

  // template <class _Root>
  // concept root = requires (_Root& root)
  // {
  //   _Root::__value_(root);
  //   root.__reset_();
  //   { root.__type_() } -> std::same_as<const __type_index &>;
  //   { root.__data_() } -> std::same_as<void *>;
  //   { root.__empty_() } -> std::same_as<bool>;
  // };

  //! @c __iabstract must be an alias in order for @c __iabstract<_Derived> to be
  //! derived from
  //! @c __iabstract<_Base>. @c __iabstract<_Derived> is an alias for @c
  //! Derived<Base<__iroot>>.
  template <template <class> class _Interface, class _BaseInterfaces = __bases_of<_Interface>>
  using __iabstract = _Interface<__mcall1<_BaseInterfaces, __iroot>>;

  //////////////////////////////////////////////////////////////////////////////////////////
  // __iroot
  struct __iroot
  {
    static constexpr STDEXEC::__any::__box_kind __box_kind = STDEXEC::__any::__box_kind::__abstract;
    static constexpr size_t __buffer_size                  = sizeof(__tagged_ptr);  // minimum size
    static constexpr size_t __buffer_alignment = alignof(__tagged_ptr);  // minimum alignment
    using __bases_type                         = __extends<>;

    // needed by MSVC for EBO to work for some reason:
    constexpr virtual ~__iroot() = default;

    constexpr virtual void __delete_() noexcept
    {
      this->~__iroot();
    }

   private:
    template <template <class> class, class, class, size_t, size_t>
    friend struct __interface_base;
    friend struct __access;

    template <class _Self>
    static constexpr auto __value_(_Self &&) noexcept -> _Self &&
    {
      return STDEXEC::__die<_Self &&>(__pure_virt_msg, "__value");
    }

    [[nodiscard]]
    constexpr virtual bool __empty_() const noexcept
    {
      return STDEXEC::__die<bool>(__pure_virt_msg, "empty");
    }

    constexpr virtual void __reset_() noexcept
    {
      STDEXEC::__die(__pure_virt_msg, "reset");
    }

    [[nodiscard]]
    constexpr virtual __type_index const &__type_() const noexcept
    {
      return STDEXEC::__die<__type_index const &>(__pure_virt_msg, "type");
    }

    [[nodiscard]]
    constexpr virtual void *__data_() const noexcept
    {
      return STDEXEC::__die<void *>(__pure_virt_msg, "data");
    }

    void __slice_to_() noexcept            = delete;  // NOLINT(modernize-use-equals-delete)
    void __indirect_bind_() const noexcept = delete;  // NOLINT(modernize-use-equals-delete)
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __box
  template <class _Value>
  struct __box
  {
    constexpr explicit __box(_Value __val) noexcept
      : __val_(std::move(__val))
    {}

    template <class... _Args>
    constexpr explicit __box(_Args &&...__args) noexcept
      : __val_(static_cast<_Args &&>(__args)...)
    {}

#if !STDEXEC_GCC()
    template <class _Fn, class... _Args>
    constexpr explicit __box(__in_place_from_t, _Fn &&__fn, _Args &&...__args)
      noexcept(__nothrow_callable<_Fn, _Args...>)
      : __val_(static_cast<_Fn &&>(__fn)(static_cast<_Args &&>(__args)...))
    {
      static_assert(__same_as<__call_result_t<_Fn, _Args...>, _Value>);
    }
#else
    template <class _Fn, class... _Args>
    constexpr explicit __box(__in_place_from_t, _Fn &&__fn, _Args &&...__args)
      noexcept(__nothrow_callable<_Fn, _Args...>)
    {
      // for unknown reasons, GCC (sometimes) doesn't like initializing __val_ with the
      // result of this function call in the member initialization clause when _Value
      // is immovable even though the conditions should be right to trigger C++17's
      // mandatory copy elision, but this in-place new into an uninitialized anonymous
      // union member works just fine
      static_assert(__same_as<__call_result_t<_Fn, _Args...>, _Value>);
      new ((void *) std::addressof(__val_))
        _Value(static_cast<_Fn &&>(__fn)(static_cast<_Args &&>(__args)...));
    }

    constexpr __box(__box &&__other) noexcept(__nothrow_move_constructible<_Value>)
      requires __std::move_constructible<_Value>
      : __val_(static_cast<_Value &&>(__other).__val_)
    {}

    constexpr __box(__box const &__other) noexcept(__nothrow_copy_constructible<_Value>)
      requires __std::copy_constructible<_Value>
      : __val_(__other.__val_)
    {}

    constexpr ~__box()
    {
      __val_.~_Value();
    }

    constexpr __box &operator=(__box &&__rhs) noexcept(__nothrow_move_assignable<_Value>)
      requires __move_assignable<_Value>
    {
      __val_ = static_cast<__box &&>(__rhs).__val_;
      return *this;
    }

    constexpr __box &operator=(__box const &__rhs) noexcept(__nothrow_copy_assignable<_Value>)
      requires __copy_assignable<_Value>
    {
      __val_ = __rhs.__val_;
      return *this;
    }
#endif

    template <class _Self>
    [[nodiscard]]
    static constexpr auto __value_(_Self &&__self) noexcept -> auto &&
    {
      return static_cast<_Self &&>(__self).__val_;
    }

   private:
#if !STDEXEC_GCC()
    STDEXEC_ATTRIBUTE(no_unique_address)
    _Value __val_;
#else
    union
    {
      STDEXEC_ATTRIBUTE(no_unique_address)
      _Value __val_;
    };
#endif
  };

  template <class _Interface, __box_kind _BoxKind>
  concept __has_box_kind = std::remove_reference_t<_Interface>::__box_kind == _BoxKind;

  // Without the check against __has_box_kind, this concept would always be
  // satisfied when building an object model or a proxy model because of the
  // abstract implementation of Interface in the __iabstract layer.
  //
  // any<Derived>
  //   : __value_proxy_model<Derived, V>
  //       : Derived<Base<__value_proxy_root<Derived, V>>>    // __box_kind == proxy
  //         ^^^^^^^        : Derived<Base<__iroot>>          // __box_kind == abstract
  //                          ^^^^^^^

  template <class _Derived, template <class> class _Interface>
  concept __already_implements = requires(_Derived const &__arg) {
    { STDEXEC::__any::__interface_cast<_Interface>(__arg) } -> __has_box_kind<_Derived::__box_kind>;
  };

  // If we are slicing into a buffer that is smaller than our own, then slicing
  // may throw.
  template <class _Interface, class _Base, size_t _BufferSize>
  concept __nothrow_slice = (_Base::__box_kind != __box_kind::__abstract)
                         && (_Base::__root_kind == __root_kind::__value)
                         && (_Interface::__buffer_size >= _BufferSize);

  //////////////////////////////////////////////////////////////////////////////////////////
  // __extends
  template <>
  struct __extends<>
  {
    template <class _Base>
    using __f = _Base;
  };

  template <template <class> class _BaseInterface, template <class> class... _BaseInterfaces>
  struct __extends<_BaseInterface, _BaseInterfaces...>
  {
    template <class _Base, class _BasesOfBase = __mcall1<__bases_of<_BaseInterface>, _Base>>
    using __f = __mcall1<__extends<_BaseInterfaces...>,
                         // If Base already implements BaseInterface, do not re-apply it.
                         __if_c<__already_implements<_Base, _BaseInterface>,
                                _BasesOfBase,
                                _BaseInterface<_BasesOfBase>>>;
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __emplace_into
  template <class _Model, class _Allocator, class... _Args>
  constexpr _Model &__emplace_into([[maybe_unused]] _Allocator const    &__alloc,
                                   [[maybe_unused]] __iroot            *&__root_ptr,
                                   [[maybe_unused]] std::span<std::byte> __buff,
                                   _Args &&...__args)
  {
    static_assert(__decays_to<_Model, _Model>);
    STDEXEC_IF_CONSTEVAL
    {
      __root_ptr = ::new _Model(static_cast<_Args &&>(__args)...);
      return *static_cast<_Model *>(__root_ptr);
    }
    else
    {
      if (STDEXEC::__any::__is_small<_Model>(__buff.size()))
      {
        return *std::construct_at(reinterpret_cast<_Model *>(__buff.data()),
                                  static_cast<_Args &&>(__args)...);
      }
      else
      {
        auto __alloc2         = STDEXEC::__rebind_allocator<_Model>(__alloc);
        using __traits_t      = std::allocator_traits<decltype(__alloc2)>;
        auto *const   __model = __traits_t::allocate(__alloc2, 1);
        __scope_guard __guard{[&]() noexcept { __traits_t::deallocate(__alloc2, __model, 1); }};
        __traits_t::construct(__alloc2, __model, static_cast<_Args &&>(__args)...);
        __guard.__dismiss();
        *__std::start_lifetime_as<__tagged_ptr>(__buff.data()) = __tagged_ptr(__model);
        return *__model;
      }
    }
  }

  template <int = 0, class _CvRefValue, class _Allocator, class _Value = std::decay_t<_CvRefValue>>
  STDEXEC_ATTRIBUTE(always_inline)
  constexpr _Value &__emplace_into(_Allocator const    &__alloc,
                                   __iroot            *&__root_ptr,
                                   std::span<std::byte> __buff,
                                   _CvRefValue        &&__val)
  {
    return STDEXEC::__any::__emplace_into<_Value>(__alloc,
                                                  __root_ptr,
                                                  __buff,
                                                  static_cast<_CvRefValue &&>(__val));
  }

  // reference
  template <template <class> class _Interface,
            class _Value,
            class _Extension = __iabstract<_Interface>>
  struct __reference_root;

  template <template <class> class _Interface,
            class _Value,
            class _Extension = __iabstract<_Interface>>
  struct __reference_model
    : _Interface<__mcall1<__bases_of<_Interface>, __reference_root<_Interface, _Value, _Extension>>>
  {
    using __base_t = _Interface<
      __mcall1<__bases_of<_Interface>, __reference_root<_Interface, _Value, _Extension>>>;
    using __base_t::__base_t;
  };

  // reference proxy
  template <template <class> class _Interface>
  struct __reference_proxy_root;

  template <template <class> class _Interface>
  struct __reference final  // __reference_proxy_model
    : _Interface<__mcall1<__bases_of<_Interface>, __reference_proxy_root<_Interface>>>
  {};

  template <template <class> class _Interface>
  using __reference_proxy_model = __reference<_Interface>;

  // __value
  template <template <class> class _Interface, class _Value, class _Allocator>
  struct __value_root_with_allocator;

  template <template <class> class _Interface, class _Value, class _Allocator>
  struct __value_model final
    : _Interface<__mcall1<__bases_of<_Interface>,
                          __value_root_with_allocator<_Interface, _Value, _Allocator>>>
  {
    using __base_t =
      _Interface<__mcall1<__bases_of<_Interface>,
                          __value_root_with_allocator<_Interface, _Value, _Allocator>>>;
    using __base_t::__base_t;

    constexpr void __delete_() noexcept final
    {
      auto __alloc     = STDEXEC::__rebind_allocator<__value_model>(this->__get_allocator());
      using __traits_t = std::allocator_traits<decltype(__alloc)>;
      __traits_t::destroy(__alloc, this);
      __traits_t::deallocate(__alloc, this, 1);
    }

    // This is a virtual override if _Interface extends __imovable
    //! @pre __is_small<__value_model>(__buff.size())
    constexpr void __move_to(__iroot *&__ptr, std::span<std::byte> __buff) noexcept
    {
      static_assert(__extension_of<__iabstract<_Interface>, __imovable>);
      STDEXEC_ASSERT(STDEXEC::__any::__is_small<__value_model>(__buff.size()));
      STDEXEC::__any::__emplace_into<__value_model>(this->__get_allocator(),
                                                    __ptr,
                                                    __buff,
                                                    std::allocator_arg,
                                                    this->__get_allocator(),
                                                    __value(std::move(*this)));
      __reset(*this);
    }

    // This is a virtual override if _Interface extends __icopyable
    constexpr void __copy_to(__iroot *&__ptr, std::span<std::byte> __buff) const
    {
      static_assert(__extension_of<__iabstract<_Interface>, __icopyable>);
      STDEXEC_ASSERT(!__empty(*this));
      STDEXEC::__any::__emplace_into<__value_model>(this->__get_allocator(),
                                                    __ptr,
                                                    __buff,
                                                    std::allocator_arg,
                                                    this->__get_allocator(),
                                                    __value(*this));
    }
  };

  // value proxy
  template <template <class> class _Interface>
  struct __value_proxy_root;

  template <template <class> class _Interface>
  struct __value_proxy_model
    : _Interface<__mcall1<__bases_of<_Interface>, __value_proxy_root<_Interface>>>
  {};

  template <class _Interface, __root_kind _RootKind>
  concept __has_root_kind = _Interface::__root_kind == _RootKind;

  //////////////////////////////////////////////////////////////////////////////////////////
  //! __interface_base
  template <template <class> class _Interface,
            class _Base,
            class _BaseInterfaces,
            size_t _BufferSize,
            size_t _BufferAlignment>
  struct __interface_base : _Base
  {
    static_assert(std::popcount(_BufferAlignment) == 1, "BufferAlignment must be a power of two");
    using __bases_type          = _BaseInterfaces;
    using __this_interface_type = __iabstract<_Interface, _BaseInterfaces>;
    using _Base::__indirect_bind_;
    using _Base::__slice_to_;
    using _Base::_Base;

    // The actual buffer size is the user-specified buffer size plus the size of a pointer,
    // because space is needed for the virtual table pointer.
    static constexpr size_t __buffer_size = _BufferSize + sizeof(void *) > _Base::__buffer_size
                                            ? _BufferSize + sizeof(void *)
                                            : _Base::__buffer_size;

    static constexpr size_t __buffer_alignment = _BufferAlignment > _Base::__buffer_alignment
                                                 ? _BufferAlignment
                                                 : _Base::__buffer_alignment;

    static constexpr bool __can_slice = __extension_of<_Base, __imovable>
                                     && (__has_root_kind<_Base, __root_kind::__value>
                                         || __extension_of<_Base, __icopyable>);

    static constexpr bool __nothrow_slice =
      STDEXEC::__any::__nothrow_slice<__this_interface_type, _Base, __buffer_size>;

    //! @pre !empty(*this)
    constexpr virtual void __slice_to_(__value_proxy_root<_Interface> &__result)  //
      noexcept(__nothrow_slice)
    {
      STDEXEC_ASSERT(__can_slice);
      STDEXEC_ASSERT(!__empty(*this));

      if constexpr (_Base::__box_kind == __box_kind::__abstract || !__can_slice)
      {
        STDEXEC_ASSERT(!"should never be here: __slice_to_ called on a type that cannot be sliced");
        __std::unreachable();
      }
      else if constexpr (__same_as<typename _Base::__interface_type, __this_interface_type>)
      {
        STDEXEC_ASSERT(!"we should be calling __move_to or __copy_to, not __slice_to_");
        __std::unreachable();
      }
      else if constexpr (_Base::__box_kind == __box_kind::__proxy)
      {
        __value(*this).__slice_to_(__result);
        __reset(*this);
      }
      else
      {
        // Move from type-erased values, but not from type-erased references.
        STDEXEC_CONSTEXPR_LOCAL bool __is_value = _Base::__root_kind == __root_kind::__value;
        __result.emplace(__value(STDEXEC::__maybe_move<__is_value>(*this)));  // could throw
      }
    }

    //! @pre !empty(*this)
    constexpr virtual void __indirect_bind_(__reference_proxy_root<_Interface> &__result) noexcept
    {
      STDEXEC_ASSERT(!__empty(*this));
      if constexpr (_Base::__box_kind == __box_kind::__proxy)
        __value(*this).__indirect_bind_(__result);
      else if constexpr (_Base::__box_kind == __box_kind::__object)
        __result.__object_bind_(*this);
    }

    //! @pre !empty(*this)
    constexpr virtual void
    __indirect_bind_(__reference_proxy_root<_Interface> &__result) const noexcept
    {
      STDEXEC_ASSERT(!__empty(*this));
      if constexpr (_Base::__box_kind == __box_kind::__proxy)
        __value(*this).__indirect_bind_(__result);
      else if constexpr (_Base::__box_kind == __box_kind::__object)
        __result.__object_bind_(*this);
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __box_root_kind
  template <__box_kind _BoxKind, __root_kind _RootKind>
  struct __box_root_kind
  {
    static constexpr STDEXEC::__any::__box_kind  __box_kind  = _BoxKind;
    static constexpr STDEXEC::__any::__root_kind __root_kind = _RootKind;
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __value_root
  template <template <class> class _Interface, class _Value>
  struct STDEXEC_ATTRIBUTE(empty_bases) __value_root
    : __iabstract<_Interface>
    , __box_root_kind<__box_kind::__object, __root_kind::__value>
    , __box<_Value>
  {
    using __value_type     = _Value;
    using __interface_type = __iabstract<_Interface>;
    using __value_root::__box_root_kind::__box_kind;
    using __box<_Value>::__box;
    using __box<_Value>::__value_;

    [[nodiscard]]
    constexpr bool __empty_() const noexcept final
    {
      return false;
    }

    constexpr void __reset_() noexcept final
    {
      // no-op
    }

    [[nodiscard]]
    constexpr __type_index const &__type_() const noexcept final
    {
      return __mtypeid<_Value>;
    }

    [[nodiscard]]
    constexpr void *__data_() const noexcept final
    {
      return const_cast<void *>(static_cast<void const *>(std::addressof(__value(*this))));
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __value_root_with_allocator
  template <template <class> class _Interface, class _Value, class _Allocator>
  struct STDEXEC_ATTRIBUTE(empty_bases) __value_root_with_allocator
    : __value_root<_Interface, _Value>
    , private _Allocator
  {
    constexpr explicit __value_root_with_allocator(_Value            __val,
                                                   _Allocator const &__alloc = _Allocator())
      : __value_root<_Interface, _Value>(std::move(__val))
      , _Allocator(__alloc)
    {}

    template <class... _Args>
    constexpr explicit __value_root_with_allocator(std::allocator_arg_t,
                                                   _Allocator const &__alloc,
                                                   _Args &&...__args)
      : __value_root<_Interface, _Value>(static_cast<_Args &&>(__args)...)
      , _Allocator(__alloc)
    {}

    [[nodiscard]]
    constexpr auto __get_allocator() const noexcept -> _Allocator const &
    {
      return *this;
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __value_proxy_root
  template <template <class> class _Interface>
  struct STDEXEC_ATTRIBUTE(empty_bases) __value_proxy_root
    : __iabstract<_Interface>
    , __box_root_kind<__box_kind::__proxy, __root_kind::__value>
  {
    using __interface_type = __iabstract<_Interface>;
    using __iabstract<_Interface>::__buffer_size;
    using __iabstract<_Interface>::__buffer_alignment;
    using __value_proxy_root::__box_root_kind::__box_kind;

    static constexpr bool __movable  = __extension_of<__iabstract<_Interface>, __imovable>;
    static constexpr bool __copyable = __extension_of<__iabstract<_Interface>, __icopyable>;

    STDEXEC_ATTRIBUTE(always_inline)
    constexpr __value_proxy_root() noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        __root_ptr_ = nullptr;
      }
      else
      {
        *__std::start_lifetime_as<__tagged_ptr>(__buff_) = __tagged_ptr();
      }
    }

    constexpr __value_proxy_root(__value_proxy_root &&__other) noexcept
      requires __movable
      : __value_proxy_root()
    {
      swap(__other);
    }

    constexpr __value_proxy_root(__value_proxy_root const &__other)
      requires __copyable
      : __value_proxy_root()
    {
      if (!__empty(__other))
        __value(__other).__copy_to(__root_ptr_, __buff_);
    }

    constexpr ~__value_proxy_root()
    {
      __reset_();
    }

    constexpr __value_proxy_root &operator=(__value_proxy_root &&__other) noexcept
      requires __movable
    {
      if (this != std::addressof(__other))
      {
        __reset_();
        swap(__other);
      }
      return *this;
    }

    constexpr __value_proxy_root &operator=(__value_proxy_root const &__other)
      requires __copyable
    {
      if (this != std::addressof(__other))
        __value_proxy_root(__other).swap(*this);
      return *this;
    }

    constexpr void swap(__value_proxy_root &__other) noexcept
      requires __movable
    {
      STDEXEC_IF_CONSTEVAL
      {
        std::swap(__root_ptr_, __other.__root_ptr_);
      }
      else
      {
        if (this == std::addressof(__other))
          return;

        auto &__this_ptr = *__std::start_lifetime_as<__tagged_ptr>(__buff_);
        auto &__that_ptr = *__std::start_lifetime_as<__tagged_ptr>(__other.__buff_);

        // This also covers the case where both __this_ptr and __that_ptr are null.
        if (__this_ptr.__is_tagged() && __that_ptr.__is_tagged())
          return std::swap(__this_ptr, __that_ptr);

        if (__this_ptr == nullptr)
          return __other.__move_to_empty(*this);

        if (__that_ptr == nullptr)
          return (*this).__move_to_empty(__other);

        auto __temp = std::move(*this);
        __other.__move_to_empty(*this);
        __temp.__move_to_empty(__other);
      }
    }

    template <class _Value, class... _Args>
    constexpr _Value &emplace(_Args &&...__args)
    {
      __reset_();
      return __emplace_<_Value>(static_cast<_Args &&>(__args)...);
    }

    template <int = 0, class _CvRefValue, class _Value = std::decay_t<_CvRefValue>>
    constexpr _Value &emplace(_CvRefValue &&__val)
    {
      __reset_();
      return __emplace_<_Value>(static_cast<_CvRefValue &&>(__val));
    }

    [[nodiscard]]
    constexpr bool __in_situ_() const noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        return false;
      }
      else
      {
        return !(*__std::start_lifetime_as<__tagged_ptr>(__buff_)).__is_tagged();
      }
    }

   private:
    template <template <class> class>
    friend struct __any;
    friend struct __access;

    template <class _Value, class _Allocator, class... _Args>
    constexpr _Value &__emplace_(std::allocator_arg_t, _Allocator const &__alloc, _Args &&...__args)
    {
      static_assert(__decays_to<_Value, _Value>, "Value must be an object type.");
      static_assert(__simple_allocator<_Allocator>);
      using __model_type = __value_model<_Interface, _Value, _Allocator>;
      auto &__model      =  //
        STDEXEC::__any::__emplace_into<__model_type>(__alloc,
                                                     __root_ptr_,
                                                     __buff_,
                                                     std::allocator_arg,
                                                     __alloc,
                                                     static_cast<_Args &&>(__args)...);
      return __value(__model);
    }

    template <class _Value, class... _Args>
    constexpr _Value &__emplace_(_Args &&...__args)
    {
      std::allocator<_Value> const __alloc{};
      return __emplace_<_Value>(std::allocator_arg, __alloc, static_cast<_Args &&>(__args)...);
    }

    template <class _Allocator, class _Fn, class... _Args>
    constexpr auto
    __emplace_from_(std::allocator_arg_t, _Allocator const &__alloc, _Fn &&__fn, _Args &&...__args)
      -> __call_result_t<_Fn, _Args...> &
    {
      static_assert(__simple_allocator<_Allocator>);
      using __value_type = __call_result_t<_Fn, _Args...>;
      using __model_type = __value_model<_Interface, __value_type, _Allocator>;
      auto &__model      =  //
        STDEXEC::__any::__emplace_into<__model_type>(__alloc,
                                                     __root_ptr_,
                                                     __buff_,
                                                     std::allocator_arg,
                                                     __alloc,
                                                     __in_place_from,
                                                     static_cast<_Fn &&>(__fn),
                                                     static_cast<_Args &&>(__args)...);
      return __value(__model);
    }

    template <class _Fn, class... _Args>
    constexpr auto
    __emplace_from_(_Fn &&__fn, _Args &&...__args) -> __call_result_t<_Fn, _Args...> &
    {
      using __value_type = __call_result_t<_Fn, _Args...>;
      std::allocator<__value_type> const __alloc{};
      return __emplace_from_(std::allocator_arg,
                             __alloc,
                             static_cast<_Fn &&>(__fn),
                             static_cast<_Args &&>(__args)...);
    }

    template <class _Self>
    [[nodiscard]]
    static constexpr auto __value_(_Self &&__self) noexcept -> auto &&
    {
      using __root_ptr_t      = std::add_pointer_t<__copy_cvref_t<_Self, __iroot>>;
      using __interface_ref_t = __copy_cvref_t<_Self &&, __iabstract<_Interface>>;
      using __interface_ptr_t = std::add_pointer_t<__interface_ref_t>;
      STDEXEC_IF_CONSTEVAL
      {
        return static_cast<__interface_ref_t>(
          *STDEXEC::__polymorphic_downcast<__interface_ptr_t>(__self.__root_ptr_));
      }
      else
      {
        auto const __ptr = *__std::start_lifetime_as<__tagged_ptr>(__self.__buff_);
        STDEXEC_ASSERT(__ptr != nullptr);
        auto *__root_ptr = static_cast<__root_ptr_t>(__ptr.__is_tagged() ? __ptr.__get()
                                                                         : __self.__buff_);
        return static_cast<__interface_ref_t>(
          *STDEXEC::__polymorphic_downcast<__interface_ptr_t>(__root_ptr));
      }
    }

    [[nodiscard]]
    constexpr bool __empty_() const noexcept final
    {
      STDEXEC_IF_CONSTEVAL
      {
        return __root_ptr_ == nullptr;
      }
      else
      {
        return *__std::start_lifetime_as<__tagged_ptr>(__buff_) == nullptr;
      }
    }

    constexpr void __move_to_empty(__value_proxy_root &__other) noexcept
      requires __movable
    {
      STDEXEC_IF_CONSTEVAL
      {
        __other.__root_ptr_ = std::exchange(__root_ptr_, nullptr);
      }
      else
      {
        STDEXEC_ASSERT(!__empty(*this));
        STDEXEC_ASSERT(__empty(__other));
        auto &__this_ptr = *__std::start_lifetime_as<__tagged_ptr>(__buff_);
        auto &__that_ptr = *__std::start_lifetime_as<__tagged_ptr>(__other.__buff_);
        if (__this_ptr.__is_tagged())
        {
          __that_ptr = std::exchange(__this_ptr, nullptr);
        }
        else
        {
          __value(*this).__move_to(__other.__root_ptr_, __other.__buff_);
          __reset(*this);
        }
      }
    }

    STDEXEC_ATTRIBUTE(always_inline)
    constexpr void __reset_() noexcept final
    {
      STDEXEC_IF_CONSTEVAL
      {
        delete std::exchange(__root_ptr_, nullptr);
      }
      else
      {
        auto &__ptr = *__std::start_lifetime_as<__tagged_ptr>(__buff_);
        if (__ptr == nullptr)
          return;
        else if (!__ptr.__is_tagged())
          std::destroy_at(std::addressof(__value(*this)));
        else
          __value(*this).__delete_();

        __ptr = __tagged_ptr();
      }
    }

    [[nodiscard]]
    constexpr __type_index const &__type_() const noexcept final
    {
      return __empty_() ? __mtypeid<void> : __type(__value(*this));
    }

    [[nodiscard]]
    constexpr void *__data_() const noexcept final
    {
      return __empty_() ? nullptr : __data(__value(*this));
    }

    union
    {
      __iroot *__root_ptr_ = nullptr;                                //!< Used in consteval context
      alignas(__buffer_alignment) std::byte __buff_[__buffer_size];  //!< Used in runtime context
    };
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __reference_union
  template <class _Value>
  struct __reference_union
  {
    union
    {
      _Value  *__value_ptr_ = nullptr;
      __iroot *__root_ptr_;  // points to a __value_root<_Extension, _Value>
    };
    bool __which_ = false;  // true if root, false if value
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __reference_root
  template <template <class> class _Interface, class _Value>
  struct STDEXEC_ATTRIBUTE(empty_bases) __reference_root<_Interface, _Value>
    : __iabstract<_Interface>
    , __box_root_kind<__box_kind::__object, __root_kind::__reference>
  {
    using __value_type     = _Value;
    using __interface_type = __iabstract<_Interface>;
    using __reference_root::__box_root_kind::__box_kind;

    __reference_root(__reference_root &&)            = delete;
    __reference_root &operator=(__reference_root &&) = delete;

    constexpr explicit __reference_root(_Value *__value_ptr, __iroot *__root_ptr) noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        if (__value_ptr != nullptr)
          __union_ = ::new __reference_union<_Value>{.__value_ptr_ = __value_ptr,
                                                     .__which_     = false};
        else
          __union_ = ::new __reference_union<_Value>{.__root_ptr_ = __root_ptr, .__which_ = true};
      }
      else
      {
        if (__value_ptr != nullptr)
          __void_ptr_ = __tagged_ptr(__value_ptr, false);
        else
          __void_ptr_ = __tagged_ptr(__root_ptr, true);
      }
    }

    constexpr ~__reference_root()
    {
      STDEXEC_IF_CONSTEVAL
      {
        delete __union_;
      }
    }

    // Returns true if the reference is indirect (i.e., via a root)
    [[nodiscard]]
    constexpr bool __is_indirect_() const noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        return __union_->__which_;
      }
      else
      {
        return __void_ptr_.__is_tagged();
      }
    }

    [[nodiscard]]
    constexpr _Value *__get_value_ptr_() const noexcept
    {
      if (__is_indirect_())
        return nullptr;

      STDEXEC_IF_CONSTEVAL
      {
        return __union_->__value_ptr_;
      }
      else
      {
        return static_cast<_Value *>(__void_ptr_.__get());
      }
    }

    [[nodiscard]]
    constexpr __iroot *__get_root_ptr_() const noexcept
    {
      if (!__is_indirect_())
        return nullptr;

      STDEXEC_IF_CONSTEVAL
      {
        return __union_->__root_ptr_;
      }
      else
      {
        return static_cast<__iroot *>(__void_ptr_.__get());
      }
    }

    template <class _Self>
    [[nodiscard]]
    static constexpr auto __value_(_Self &&__self) noexcept -> auto &&
    {
      using __from_ref_t
        [[maybe_unused]] = __if_c<std::is_lvalue_reference_v<_Self>, _Value &, _Value &&>;
      using __to_ref_t   = __copy_cvref_t<_Self &&, __value_type>;

      STDEXEC_IF_NOT_CONSTEVAL
      {
        // We permit getting an rvalue reference when _Self&& is also an rvalue reference.
        STDEXEC_ASSERT((__std::convertible_to<__from_ref_t, __to_ref_t>)
                       && "attempt to get a mutable reference from a const reference");
      }

      if (__self.__is_indirect_())
        return static_cast<__to_ref_t>(const_cast<__to_ref_t &>(__self.__dereference_()));
      else
        return static_cast<__to_ref_t>(const_cast<__to_ref_t &>(*__self.__get_value_ptr_()));
    }

    [[nodiscard]]
    constexpr bool __empty_() const noexcept final
    {
      return false;
    }

    constexpr void __reset_() noexcept final
    {
      // no-op
    }

    [[nodiscard]]
    constexpr __type_index const &__type_() const noexcept final
    {
      return __mtypeid<__value_type>;
    }

    [[nodiscard]]
    constexpr void *__data_() const noexcept final
    {
      return const_cast<void *>(static_cast<void const *>(std::addressof(__value(*this))));
    }

   private:
    static_assert(!__extension_of<_Value, _Interface>,
                  "_Value must be a concrete type, not an _Interface type.");

    [[nodiscard]]
    constexpr virtual _Value &__dereference_() const noexcept
    {
      auto *__root_ptr     = __get_root_ptr_();
      using __value_root_t = __value_root<_Interface, __value_type>;
      return __value(*STDEXEC::__polymorphic_downcast<__value_root_t *>(__root_ptr));
    }

    union
    {
      __reference_union<_Value> *__union_;
      __tagged_ptr               __void_ptr_;
    };
  };

  template <template <class> class _Interface, class _Value, template <class> class _Extension>
  struct __reference_root<_Interface, _Value, __iabstract<_Extension>>
    : __reference_root<_Interface, _Value>
  {
    using __value_type = _Value;
    using __reference_root<_Interface, _Value>::__reference_root;

    [[nodiscard]]
    constexpr _Value &__dereference_() const noexcept final
    {
      auto *__root_ptr     = (*this).__get_root_ptr_();
      using __value_root_t = __value_root<_Extension, __value_type>;
      return __value(*STDEXEC::__polymorphic_downcast<__value_root_t *>(__root_ptr));
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __reference_proxy_root
  template <template <class> class _Interface>
  struct STDEXEC_ATTRIBUTE(empty_bases) __reference_proxy_root
    : __iabstract<_Interface>
    , __box_root_kind<__box_kind::__proxy, __root_kind::__reference>
  {
    using __interface_type = __iabstract<_Interface>;
    using __reference_proxy_root::__box_root_kind::__box_kind;

    constexpr __reference_proxy_root() noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        __root_ptr_ = nullptr;
      }
      else
      {
        *__std::start_lifetime_as<__tagged_ptr>(__buff_) = __tagged_ptr();
      }
    }

    // __reference_proxy_root is not movable or copyable to preserve const-correctness of
    // __any_cptr. Dereferencing an __any_cptr returns an lvalue reference to a const
    // __reference_proxy_model. If __reference_proxy_model were copyable or movable, then
    // it would be possible to cast away const-ness simply by copying or moving the
    // __reference_proxy_model into a non-const object. That would be bad.
    __reference_proxy_root(__reference_proxy_root &&)            = delete;
    __reference_proxy_root &operator=(__reference_proxy_root &&) = delete;

    constexpr void __copy_from(__reference_proxy_root const &__other) noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        __value(__other).__indirect_bind_(*this);
      }
      else
      {
        std::memcpy(__buff_, __other.__buff_, sizeof(__buff_));
      }
    }

    constexpr ~__reference_proxy_root()
    {
      __reset_();
    }

    constexpr void swap(__reference_proxy_root &__other) noexcept
    {
      if (this == std::addressof(__other))
        return;

      STDEXEC_IF_CONSTEVAL
      {
        std::swap(__root_ptr_, __other.__root_ptr_);
      }
      else
      {
        std::swap(__buff_, __other.__buff_);
      }
    }

    template <__extension_of<_Interface> _CvModel>
    constexpr void __model_bind_(_CvModel &__model) noexcept
    {
      static_assert(__extension_of<_CvModel, _Interface>, "CvModel must implement Interface");
      STDEXEC_IF_CONSTEVAL
      {
        __model.__indirect_bind_(*this);
      }
      else
      {
        if constexpr (std::derived_from<_CvModel, __iabstract<_Interface>>)
        {
          //! Optimize for when Base derives from __iabstract<_Interface>. _Store the
          //! address of __value(__other) directly in __result as a tagged ptr instead of
          //! introducing an indirection.
          //! @post __is_tagged() == true
          auto &__ptr = *__std::start_lifetime_as<__tagged_ptr>(__buff_);
          __ptr = static_cast<__interface_type *>(std::addressof(STDEXEC::__unconst(__model)));
        }
        else
        {
          //! @post __is_tagged() == false
          __model.__indirect_bind_(*this);
        }
      }
    }

    template <class _CvModel>
    constexpr void __object_bind_(_CvModel &__model) noexcept
    {
      static_assert(__extension_of<_CvModel, _Interface>);
      using __extension_type = _CvModel::__interface_type;
      using __value_type     = _CvModel::__value_type;
      using __model_type     = __reference_model<_Interface, __value_type, __extension_type>;
      if constexpr (_CvModel::__root_kind == __root_kind::__reference)
      {
        STDEXEC::__any::__emplace_into<__model_type>(std::allocator<std::byte>{},  // not used
                                                     __root_ptr_,
                                                     __buff_,
                                                     __model.__get_value_ptr_(),
                                                     __model.__get_root_ptr_());
      }
      else
      {
        __iroot *__root_ptr = std::addressof(STDEXEC::__unconst(__model));
        STDEXEC::__any::__emplace_into<__model_type>(std::allocator<std::byte>{},  // not used
                                                     __root_ptr_,
                                                     __buff_,
                                                     static_cast<__value_type *>(nullptr),
                                                     STDEXEC_DECAY_COPY(__root_ptr));
      }
    }

    template <class _CvValue>
    constexpr void __value_bind_(_CvValue &__val) noexcept
    {
      static_assert(!__extension_of<_CvValue, _Interface>);
      using __model_type = __reference_model<_Interface, _CvValue>;
      STDEXEC::__any::__emplace_into<__model_type>(std::allocator<std::byte>{},  // not used
                                                   __root_ptr_,
                                                   __buff_,
                                                   std::addressof(__val),
                                                   static_cast<__iroot *>(nullptr));
    }

    template <class _Self>
    [[nodiscard]]
    static constexpr auto __value_(_Self &&__self) noexcept -> auto &&
    {
      using __root_ptr_t      = std::add_pointer_t<__copy_cvref_t<_Self, __iroot>>;
      using __interface_ref_t = __copy_cvref_t<_Self &&, __iabstract<_Interface>>;
      using __interface_ptr_t = std::add_pointer_t<__interface_ref_t>;
      STDEXEC_IF_CONSTEVAL
      {
        return static_cast<__interface_ref_t>(
          *STDEXEC::__polymorphic_downcast<__interface_ptr_t>(__self.__root_ptr_));
      }
      else
      {
        STDEXEC_ASSERT(!__empty(__self));
        auto const  __ptr      = *__std::start_lifetime_as<__tagged_ptr>(__self.__buff_);
        auto *const __root_ptr = static_cast<__root_ptr_t>(__ptr.__is_tagged() ? __ptr.__get()
                                                                               : __self.__buff_);
        return static_cast<__interface_ref_t>(
          *STDEXEC::__polymorphic_downcast<__interface_ptr_t>(__root_ptr));
      }
    }

    [[nodiscard]]
    constexpr bool __empty_() const noexcept final
    {
      STDEXEC_IF_CONSTEVAL
      {
        return __root_ptr_ == nullptr;
      }
      else
      {
        return *__std::start_lifetime_as<__tagged_ptr>(__buff_) == nullptr;
      }
    }

    constexpr void __reset_() noexcept final
    {
      STDEXEC_IF_CONSTEVAL
      {
        delete std::exchange(__root_ptr_, nullptr);
      }
      else
      {
        *__std::start_lifetime_as<__tagged_ptr>(__buff_) = __tagged_ptr();
      }
    }

    [[nodiscard]]
    constexpr __type_index const &__type_() const noexcept final
    {
      return __empty_() ? __mtypeid<void> : __type(__value(*this));
    }

    [[nodiscard]]
    constexpr void *__data_() const noexcept final
    {
      return __empty_() ? nullptr : __data(__value(*this));
    }

    [[nodiscard]]
    constexpr bool __is_indirect_() const noexcept
    {
      STDEXEC_IF_CONSTEVAL
      {
        return true;
      }
      else
      {
        return !(*__std::start_lifetime_as<__tagged_ptr>(__buff_)).__is_tagged();
      }
    }

   private:
    union
    {
      __iroot *__root_ptr_ = nullptr;  //!< Used in consteval context
      // storage for one vtable __ptr and one pointer for the referant
      mutable std::byte __buff_[2 * sizeof(void *)];  //!< Used in runtime context
    };
  };  // struct __reference_proxy_root

  //////////////////////////////////////////////////////////////////////////////////////////
  // __bad_any_cast
  struct __bad_any_cast : std::exception
  {
    [[nodiscard]]
#if __cpp_lib_constexpr_exceptions >= 202502L  // constexpr support for std::exception
    constexpr
#endif
      char const *what() const noexcept override
    {
      return "__bad_any_cast";
    }
  };

#if defined(__cpp_exceptions) && __cpp_exceptions >= 199711L
  [[noreturn]]
  inline void __throw_bad_any_cast()
  {
    throw __bad_any_cast();
  }
#else
  [[noreturn]]
  inline constexpr void __throw_bad_any_cast() noexcept
  {
    STDEXEC::__die("__bad_any_cast\n");
  }
#endif

  //////////////////////////////////////////////////////////////////////////////////////////
  //! __any_static_cast
  template <class _Value>
  struct __any_static_cast_impl_t
  {
    template <template <class> class _Interface, class _Base>
    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto *operator()(_Interface<_Base> *__proxy_ptr) const noexcept
    {
      return __cast_<_Interface>(__proxy_ptr);
    }

    template <template <class> class _Interface, class _Base>
    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto *operator()(_Interface<_Base> const *__proxy_ptr) const noexcept
    {
      return __cast_<_Interface>(__proxy_ptr);
    }

   private:
    static_assert(__decays_to<_Value, _Value>, "Value must be a decayed type.");

    template <class _CvModel>
    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    static constexpr auto *__value_ptr_(_CvModel *__model_ptr) noexcept
    {
      return __model_ptr != nullptr ? std::addressof(__value(*__model_ptr)) : nullptr;
    }

    template <class _CvProxy>
    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    static constexpr bool __is_reference_(_CvProxy *__proxy_ptr) noexcept
    {
      if constexpr (_CvProxy::__root_kind == __root_kind::__reference)
        return (*__proxy_ptr).__is_indirect_();
      else
        return false;
    }

    template <template <class> class _Interface, class _CvProxy>
    [[nodiscard]]
    static constexpr auto *__cast_(_CvProxy *__proxy_ptr) noexcept
    {
      static_assert(_CvProxy::__box_kind == __box_kind::__proxy, "CvProxy must be a proxy type.");
      static_assert(!__extension_of<_Value, _Interface>,
                    "Cannot dynamic cast to an _Interface type.");
      using __value_model     = __copy_cvref_t<_CvProxy, __value_root<_Interface, _Value>>;
      using __reference_model = __copy_cvref_t<_CvProxy, __reference_root<_Interface, _Value>>;

      // get the address of the model from the proxy:
      auto *__model_ptr = std::addressof(__value(*__proxy_ptr));

      // If CvProxy is a reference proxy that stores the model indirectly, then __model_ptr
      // points to a reference model. Otherwise, it points to a value model.
      return __is_reference_(__proxy_ptr)
             ? __value_ptr_(STDEXEC::__polymorphic_downcast<__reference_model *>(__model_ptr))
             : __value_ptr_(STDEXEC::__polymorphic_downcast<__value_model *>(__model_ptr));
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  //! __any_static_cast
  template <class _Value>
  struct __any_dynamic_cast_t
  {
    template <class _CvProxy>
    [[nodiscard]]
    constexpr auto *operator()(_CvProxy *__proxy_ptr) const noexcept
    {
      return __type(*__proxy_ptr) == __mtypeid<_Value>
             ? __any_static_cast_impl_t<_Value>{}(__proxy_ptr)
             : nullptr;
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __basic_cast_t
  template <class _Value, template <class> class _Cast>
  struct __basic_cast_t
  {
    template <template <class> class _Interface, class _Base>
    [[nodiscard]]
    constexpr auto *operator()(_Interface<_Base> *__ptr) const noexcept
    {
      if constexpr (__extension_of<_Value, _Interface>)
        return __ptr;
      else if (__ptr == nullptr || __empty(*__ptr))
        return static_cast<_Value *>(nullptr);
      else
        return __cast(__ptr);
    }

    template <template <class> class _Interface, class _Base>
    [[nodiscard]]
    constexpr auto *operator()(_Interface<_Base> const *__ptr) const noexcept
    {
      if constexpr (__extension_of<_Value, _Interface>)
        return __ptr;
      else if (__ptr == nullptr || __empty(*__ptr))
        return static_cast<_Value const *>(nullptr);
      else
        return __cast(__ptr);
    }

    template <template <class> class _Interface, class _Base>
    [[nodiscard]]
    constexpr auto &&operator()(_Interface<_Base> &&__object) const
    {
      auto *__ptr = (*this)(std::addressof(__object));
      if (__ptr == nullptr)
        __throw_bad_any_cast();
      if constexpr (_Base::__root_kind == __root_kind::__reference)
        return *__ptr;
      else
        return std::move(*__ptr);
    }

    template <template <class> class _Interface, class _Base>
    [[nodiscard]]
    constexpr auto &operator()(_Interface<_Base> &__object) const
    {
      auto *__ptr = (*this)(std::addressof(__object));
      if (__ptr == nullptr)
        __throw_bad_any_cast();
      return *__ptr;
    }

    template <template <class> class _Interface, class _Base>
    [[nodiscard]]
    constexpr auto &operator()(_Interface<_Base> const &__object) const
    {
      auto *__ptr = (*this)(std::addressof(__object));
      if (__ptr == nullptr)
        __throw_bad_any_cast();
      return *__ptr;
    }

    template <template <class> class _Interface>
    [[nodiscard]]
    constexpr auto *operator()(__any_ptr<_Interface> const &__ptr) const
    {
      return (*this)(__ptr.operator->());
    }

    template <template <class> class _Interface>
    [[nodiscard]]
    constexpr auto *operator()(__any_cptr<_Interface> const &__ptr) const
    {
      return (*this)(__ptr.operator->());
    }

   private:
    static_assert(__decays_to<_Value, _Value>);
    // The cast is either checked (dynamic) or unchecked (static)
    static constexpr _Cast<_Value> __cast{};
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __any_cast
  template <class _Value>
  struct __any_cast_t : __basic_cast_t<_Value, __any_dynamic_cast_t>
  {};

  template <class _Value>
  constexpr __any_cast_t<_Value> __any_cast{};

  //////////////////////////////////////////////////////////////////////////////////////////
  // __any_static_cast
  template <class _Value>
  struct __any_static_cast_t : __basic_cast_t<_Value, __any_static_cast_impl_t>
  {};

  template <class _Value>
  constexpr __any_static_cast_t<_Value> __any_static_cast{};

  //////////////////////////////////////////////////////////////////////////////////////////
  // __imovable
  template <class _Base>
  struct __imovable : __interface_base<__imovable, _Base>
  {
    using __imovable::__interface_base::__interface_base;

    constexpr virtual void __move_to(__iroot *&, std::span<std::byte>) noexcept
    {
      STDEXEC::__die(__pure_virt_msg, "__move_to");
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __icopyable
  template <class _Base>
  struct __icopyable : __interface_base<__icopyable, _Base, __extends<__imovable>>
  {
    using __icopyable::__interface_base::__interface_base;

    constexpr virtual void __copy_to(__iroot *&, std::span<std::byte>) const
    {
      STDEXEC::__die(__pure_virt_msg, "__copy_to");
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // utils
  template <class _Value, template <class> class _Interface>
  concept __model_of = __decays_to<_Value, _Value> && !std::derived_from<_Value, __iroot>;

  //////////////////////////////////////////////////////////////////////////////////////////
  // any
  template <template <class> class _Interface>
  struct __any : __value_proxy_model<_Interface>
  {
   private:
    template <class _Other>
    static constexpr bool __as_large_as =
      (__iabstract<_Interface>::__buffer_size >= _Interface<_Other>::__buffer_size)
      && (_Interface<_Other>::__buffer_alignment % __iabstract<_Interface>::__buffer_alignment == 0)
      && (_Other::__root_kind == __root_kind::__value);

   public:
    __any() = default;

    // Construct from an object that implements the interface (and is not an any<>
    // itself)
    template <__model_of<_Interface> _Value, class _Allocator = std::allocator<_Value>>
    constexpr __any(_Value __val, _Allocator const &__alloc = _Allocator())
      : __any()
    {
      static_assert(__simple_allocator<_Allocator>);
      (*this).template __emplace_<_Value>(std::allocator_arg, __alloc, std::move(__val));
    }

    template <class _Value, class... _Args>
    constexpr explicit __any(std::in_place_type_t<_Value>, _Args &&...__args)
      : __any()
    {
      (*this).template __emplace_<_Value>(static_cast<_Args &&>(__args)...);
    }

    template <class _Fn, class... _Args>
    constexpr explicit __any(__in_place_from_t, _Fn &&__fn, _Args &&...__args)
      : __any()
    {
      (*this).__emplace_from_(static_cast<_Fn &&>(__fn), static_cast<_Args &&>(__args)...);
    }

    // Implicit derived-to-base conversion constructor
    template <class _Other>
      requires __extension_of<_Interface<_Other>, __imovable>
            && (_Other::__root_kind == __root_kind::__value)
    constexpr __any(_Interface<_Other> __other) noexcept(__as_large_as<_Other>)
    {
      (*this).__assign_from(std::move(__other));
    }

    template <class _Other>
      requires __extension_of<_Interface<_Other>, __icopyable>
            && (_Other::__root_kind == __root_kind::__reference)
    constexpr __any(_Interface<_Other> const &__other)
    {
      _Interface<_Other> __tmp;
      __tmp.__copy_from(__other);
      (*this).__assign_from(std::move(__tmp));
    }

    template <__model_of<_Interface> _Value>
    constexpr __any &operator=(_Value __val)
    {
      __reset(*this);
      (*this).template __emplace_<_Value>(std::move(__val));
      return *this;
    }

    // Implicit derived-to-base conversion constructor
    template <class _Other>
      requires __extension_of<_Interface<_Other>, __imovable>
            && (_Other::__root_kind == __root_kind::__value)
    constexpr __any &operator=(_Interface<_Other> __other) noexcept(__as_large_as<_Other>)
    {
      __reset(*this);
      (*this).__assign_from(std::move(__other));
      return *this;
    }

    template <class _Other>
      requires __extension_of<_Interface<_Other>, __icopyable>
            && (_Other::__root_kind == __root_kind::__reference)
    constexpr __any &operator=(_Interface<_Other> const &__other)
    {
      // Guard against self-assignment when __other is a reference to *this
      if (__data(__other) == __data(*this))
        return *this;

      _Interface<_Other> __tmp;
      __tmp.__copy_from(__other);

      __reset(*this);
      (*this).__assign_from(std::move(__tmp));
      return *this;
    }

    friend constexpr void swap(__any &__lhs, __any &__rhs) noexcept
      requires __any::__movable
    {
      __lhs.swap(__rhs);
    }

   private:
    // Assigning from a type that __extends _Interface. Its buffer may be larger than
    // ours, or it may be a reference type, so we can be only conditionally
    // noexcept.
    template <class _Other>
      requires __extension_of<_Interface<_Other>, __imovable>
    constexpr void __assign_from(_Interface<_Other> &&__other) noexcept(__as_large_as<_Other>)
    {
      using __root_t = __value_proxy_root<_Interface>;
      STDEXEC_CONSTEXPR_LOCAL
      bool __is_value = _Other::__root_kind == __root_kind::__value;
      STDEXEC_CONSTEXPR_LOCAL
      bool __ptr_convertible = std::derived_from<_Other, __iabstract<_Interface>>;

      if (__empty(__other))
        return;

      if constexpr (!__is_value || !__ptr_convertible)  // compile-time condition
      {                                                 // NOLINT(bugprone-branch-clone)
        return __other.__slice_to_(*this);
      }
      else if (__other.__in_situ_())  // runtime condition
      {
        using __other_interface_t = _Other::__interface_type;
        if constexpr (__same_as<__other_interface_t, __iabstract<_Interface>>)
          static_cast<__root_t &>(*this) = static_cast<__root_t &&>(__other);
        else
          return __other.__slice_to_(*this);
      }
      else STDEXEC_IF_CONSTEVAL
      {
        (*this).__root_ptr_ = std::exchange(__other.__root_ptr_, nullptr);
      }
      else
      {
        auto &__this_ptr = *__std::start_lifetime_as<__tagged_ptr>((*this).__buff_);
        auto &__that_ptr = *__std::start_lifetime_as<__tagged_ptr>(__other.__buff_);
        __this_ptr       = std::exchange(__that_ptr, nullptr);
      }
    }

    static_assert(sizeof(__iabstract<_Interface>) == sizeof(void *));  // sanity check
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __any_ptr_base
  template <template <class> class _Interface>
  struct __any_ptr_base
  {
    __any_ptr_base() = default;

    constexpr __any_ptr_base(std::nullptr_t) noexcept
      : __reference_()
    {}

    constexpr __any_ptr_base(__any_ptr_base const &__other) noexcept
      : __reference_()
    {
      __reference_.__copy_from(__other.__reference_);
    }

    template <template <class> class _OtherInterface>
      requires __extension_of<__iabstract<_OtherInterface>, _Interface>
    constexpr __any_ptr_base(__any_ptr_base<_OtherInterface> const &__other) noexcept
      : __reference_()
    {
      (*this).__proxy_assign(std::addressof(__other.__reference_));
    }

    constexpr __any_ptr_base &operator=(__any_ptr_base const &__other) noexcept
    {
      __reset(__reference_);
      __reference_.__copy_from(__other.__reference_);
      return *this;
    }

    constexpr __any_ptr_base &operator=(std::nullptr_t) noexcept
    {
      __reset(__reference_);
      return *this;
    }

    template <template <class> class _OtherInterface>
      requires __extension_of<__iabstract<_OtherInterface>, _Interface>
    constexpr __any_ptr_base &operator=(__any_ptr_base<_OtherInterface> const &__other) noexcept
    {
      __reset(__reference_);
      (*this).__proxy_assign(std::addressof(__other.__reference_));
      return *this;
    }

    friend constexpr void swap(__any_ptr_base &__lhs, __any_ptr_base &__rhs) noexcept
    {
      __lhs.__reference_.swap(__rhs.__reference_);
    }

    [[nodiscard]]
    constexpr bool operator==(__any_ptr_base const &__other) const noexcept
    {
      return __data(__reference_) == __data(__other.__reference_);
    }

   private:
    using __model_type = __reference_proxy_model<_Interface>;
    static_assert(sizeof(__iabstract<_Interface>) == sizeof(void *));  // sanity check

    template <template <class> class>
    friend struct __any_ptr_base;
    friend struct __any_ptr<_Interface>;
    friend struct __any_cptr<_Interface>;

    //! @param __other A pointer to a value proxy model implementing _Interface.
    template <__extension_of<_Interface> _CvValueProxy>
    constexpr void __proxy_assign(_CvValueProxy *__proxy_ptr) noexcept
    {
      static_assert(_CvValueProxy::__box_kind == __box_kind::__proxy);
      constexpr bool __is_const_ = std::is_const_v<_CvValueProxy>;

      if (__proxy_ptr == nullptr || __empty(*__proxy_ptr))
        return;
      // _Optimize for when _CvValueProxy derives from __iabstract<_Interface>. _Store the address
      // of __value(__other) directly in __result as a tagged ptr instead of introducing an
      // indirection.
      else if constexpr (std::derived_from<_CvValueProxy, __iabstract<_Interface>>)
        __reference_.__model_bind_(STDEXEC::__as_const_if<__is_const_>(__value(*__proxy_ptr)));
      else
        __value(*__proxy_ptr).__indirect_bind_(__reference_);
    }

    //! @param __other A pointer to a reference proxy model implementing _Interface.
    template <__extension_of<_Interface> _CvReferenceProxy>
      requires(_CvReferenceProxy::__root_kind == __root_kind::__reference)
    constexpr void __proxy_assign(_CvReferenceProxy *__proxy_ptr) noexcept
    {
      static_assert(_CvReferenceProxy::__box_kind == __box_kind::__proxy);
      constexpr bool __is_const_ = std::is_const_v<_CvReferenceProxy>;

      if (__proxy_ptr == nullptr || __empty(*__proxy_ptr))
        return;
      // in the case where _CvReferenceProxy is a base class of __model_type, we can simply
      // downcast and copy the model directly.
      else if constexpr (std::derived_from<__model_type, _CvReferenceProxy>)
        __reference_.__copy_from(
          *STDEXEC::__polymorphic_downcast<__model_type const *>(__proxy_ptr));
      // _Otherwise, we are assigning from a derived reference to a base reference, and the
      // __other reference is indirect (i.e., it holds a __reference_model in its buffer). We
      // need to copy the referant model.
      else if ((*__proxy_ptr).__is_indirect_())
        __value(*__proxy_ptr).__indirect_bind_(__reference_);
      else
        __reference_.__model_bind_(STDEXEC::__as_const_if<__is_const_>(__value(*__proxy_ptr)));
    }

    template <class _CvValue>
    constexpr void __value_assign(_CvValue *__value_ptr) noexcept
    {
      if (__value_ptr != nullptr)
        __reference_.__value_bind_(*__value_ptr);
    }

    // the proxy model is mutable so that a const __any_ptr can return non-const
    // references from operator-> and operator*.
    mutable __model_type __reference_;
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __any_ptr
  template <template <class> class _Interface>
  struct __any_ptr : __any_ptr_base<_Interface>
  {
    using __reference = __any_ptr_base<_Interface>::__model_type;
    using __pointer   = __reference *;

    using __any_ptr_base<_Interface>::__any_ptr_base;
    using __any_ptr_base<_Interface>::operator=;

    // Disable const-to-mutable conversions:
    template <template <class> class _Other>
    __any_ptr(__any_cptr<_Other> const &) = delete;
    template <template <class> class _Other>
    __any_ptr &operator=(__any_cptr<_Other> const &) = delete;

    template <__model_of<_Interface> _Value>
    constexpr __any_ptr(_Value *__value_ptr) noexcept
      : __any_ptr_base<_Interface>()
    {
      (*this).__value_assign(__value_ptr);
    }

    template <__extension_of<_Interface> _Proxy>
    constexpr __any_ptr(_Proxy *__proxy_ptr) noexcept
      : __any_ptr_base<_Interface>()
    {
      (*this).__proxy_assign(__proxy_ptr);
    }

    template <__extension_of<_Interface> _Proxy>
    __any_ptr(_Proxy const *) = delete;

    template <__model_of<_Interface> _Value>
    constexpr __any_ptr &operator=(_Value *__value_ptr) noexcept
    {
      __reset((*this).__reference_);
      (*this).__value_assign(__value_ptr);
      return *this;
    }

    template <__extension_of<_Interface> _Proxy>
    constexpr __any_ptr &operator=(_Proxy *__proxy_ptr) noexcept
    {
      __reset((*this).__reference_);
      (*this).__proxy_assign(__proxy_ptr);
      return *this;
    }

    template <__extension_of<_Interface> _Proxy>
    __any_ptr &operator=(_Proxy const *__proxy_ptr) = delete;

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto *operator->() const noexcept
    {
      return std::addressof((*this).__reference_);
    }

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto &operator*() const noexcept
    {
      return (*this).__reference_;
    }
  };

  template <template <class> class _Interface, class _Base>
  STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE __any_ptr(_Interface<_Base> *) -> __any_ptr<_Interface>;

  //////////////////////////////////////////////////////////////////////////////////////////
  // __any_cptr
  template <template <class> class _Interface>
  struct __any_cptr : __any_ptr_base<_Interface>
  {
    using __reference = __any_ptr_base<_Interface>::__model_type const;
    using __pointer   = __reference *;

    using __any_ptr_base<_Interface>::__any_ptr_base;
    using __any_ptr_base<_Interface>::operator=;

    template <__model_of<_Interface> _Value>
    constexpr __any_cptr(_Value const *__value_ptr) noexcept
      : __any_ptr_base<_Interface>()
    {
      (*this).__value_assign(__value_ptr);
    }

    template <__extension_of<_Interface> _Proxy>
    constexpr __any_cptr(_Proxy const *__proxy_ptr) noexcept
      : __any_ptr_base<_Interface>()
    {
      (*this).__proxy_assign(__proxy_ptr);
    }

    template <__model_of<_Interface> _Value>
    constexpr __any_cptr &operator=(_Value const *__value_ptr) noexcept
    {
      __reset((*this).__reference_);
      (*this).__value_assign(__value_ptr);
      return *this;
    }

    template <__extension_of<_Interface> _Proxy>
    constexpr __any_cptr &operator=(_Proxy const *__proxy_ptr) noexcept
    {
      __reset((*this).__reference_);
      (*this).__proxy_assign(__proxy_ptr);
      return *this;
    }

    friend constexpr void swap(__any_cptr &__lhs, __any_cptr &__rhs) noexcept
    {
      __lhs.__reference_.swap(__rhs.__reference_);
    }

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto const *operator->() const noexcept
    {
      return std::addressof((*this).__reference_);
    }

    STDEXEC_ATTRIBUTE(nodiscard, always_inline)
    constexpr auto const &operator*() const noexcept
    {
      return (*this).__reference_;
    }
  };

  template <template <class> class _Interface, class _Base>
  STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE
  __any_cptr(_Interface<_Base> const *) -> __any_cptr<_Interface>;

  //////////////////////////////////////////////////////////////////////////////////////////
  // __iequality_comparable
  template <class _Base>
  struct __iequality_comparable : __interface_base<__iequality_comparable, _Base>
  {
    using __iequality_comparable::__interface_base::__interface_base;

    template <class _Other>
    [[nodiscard]]
    constexpr bool operator==(__iequality_comparable<_Other> const &__other) const
    {
      return __equal_to(STDEXEC::__any::__caddressof(__other));
    }

   private:
    [[nodiscard]]
    // NOLINTNEXTLINE(modernize-use-override)
    constexpr virtual bool __equal_to(__any_cptr<__iequality_comparable> __other) const
    {
      auto const &type = STDEXEC::__any::__type(*this);

      if (type != STDEXEC::__any::__type(*__other))
        return false;

      if (type == __mtypeid<void>)
        return true;

      using __value_type = __value_of_t<__iequality_comparable>;
      return __value(*this) == STDEXEC::__any::__any_static_cast<__value_type>(*__other);
    }
  };

  //////////////////////////////////////////////////////////////////////////////////////////
  // __isemiregular
  template <class _Base>
  struct __isemiregular
    : __interface_base<__isemiregular, _Base, __extends<__icopyable, __iequality_comparable>>
  {
    using __isemiregular::__interface_base::__interface_base;
  };

}  // namespace STDEXEC::__any

// NOLINTEND(moderize-use-override)

#include "__epilogue.hpp"
