// <mdspan> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file mdspan
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_MDSPAN
#define _GLIBCXX_MDSPAN 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <span>
#include <array>
#include <type_traits>
#include <utility>

#define __glibcxx_want_mdspan
#define __glibcxx_want_aligned_accessor
#define __glibcxx_want_submdspan
#include <bits/version.h>

#if __glibcxx_aligned_accessor
#include <bits/align.h>
#endif

#if __glibcxx_submdspan
#include <tuple>
#endif

#if __cplusplus > 202302L
#include <bits/stdexcept_throw.h>
#endif

#ifdef __glibcxx_mdspan

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  namespace __mdspan
  {
    consteval bool
    __all_static(std::span<const size_t> __extents)
    {
      for(auto __ext : __extents)
	if (__ext == dynamic_extent)
	  return false;
      return true;
    }

    consteval bool
    __all_dynamic(std::span<const size_t> __extents)
    {
      for(auto __ext : __extents)
	if (__ext != dynamic_extent)
	  return false;
      return true;
    }

    template<typename _IndexType, typename _OIndexTypeRef>
      constexpr _IndexType
      __index_type_cast(_OIndexTypeRef&& __other)
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4020. extents::index-cast weirdness
	using _OIndexType = std::remove_cvref_t<_OIndexTypeRef>;
	if constexpr (std::is_integral_v<_OIndexType>)
	  {
	    constexpr _IndexType __index_type_max
	      = __gnu_cxx::__int_traits<_IndexType>::__max;
	    constexpr _OIndexType __oindex_type_max
	      = __gnu_cxx::__int_traits<_OIndexType>::__max;

	    if constexpr (__index_type_max < __oindex_type_max)
	      __glibcxx_assert(cmp_less_equal(__other, __index_type_max));

	    if constexpr (std::is_signed_v<_OIndexType>)
	      __glibcxx_assert(__other >= 0);
	    return static_cast<_IndexType>(__other);
	  }
	else
	  {
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 4314. Missing move in mdspan layout mapping::operator()
	    auto __ret = static_cast<_IndexType>(std::forward<_OIndexTypeRef>(__other));
	    if constexpr (std::is_signed_v<_IndexType>)
	      __glibcxx_assert(__ret >= 0);
	    return __ret;
	  }
      }

    template<array _Extents>
      class _StaticExtents
      {
      public:
	static constexpr size_t _S_rank = _Extents.size();

	// For __r in [0, _S_rank], _S_dynamic_index(__r) is the number
	// of dynamic extents up to (and not including) __r.
	//
	// If __r is the index of a dynamic extent, then
	// _S_dynamic_index[__r] is the index of that extent in
	// _M_dyn_exts.
	static constexpr size_t
	_S_dynamic_index(size_t __r) noexcept
	{ return _S_dynamic_index_data[__r]; }

	static constexpr auto _S_dynamic_index_data = [] consteval
	{
	  array<size_t, _S_rank+1> __ret;
	  size_t __dyn = 0;
	  for (size_t __i = 0; __i < _S_rank; ++__i)
	    {
	      __ret[__i] = __dyn;
	      __dyn += (_Extents[__i] == dynamic_extent);
	    }
	  __ret[_S_rank] = __dyn;
	  return __ret;
	}();

	static constexpr size_t _S_rank_dynamic = _S_dynamic_index(_S_rank);

	// For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv(__r) is the
	// index of the __r-th dynamic extent in _Extents.
	static constexpr size_t
	_S_dynamic_index_inv(size_t __r) noexcept
	{ return _S_dynamic_index_inv_data[__r]; }

	static constexpr auto _S_dynamic_index_inv_data = [] consteval
	{
	  array<size_t, _S_rank_dynamic> __ret;
	  for (size_t __i = 0, __r = 0; __i < _S_rank; ++__i)
	    if (_Extents[__i] == dynamic_extent)
	      __ret[__r++] = __i;
	  return __ret;
	}();

	static constexpr size_t
	_S_static_extent(size_t __r) noexcept
	{ return _Extents[__r]; }
      };

    template<array _Extents>
      requires (__all_dynamic<_Extents>())
      class _StaticExtents<_Extents>
      {
      public:
	static constexpr size_t _S_rank = _Extents.size();

	static constexpr size_t
	_S_dynamic_index(size_t __r) noexcept
	{ return __r; }

	static constexpr size_t _S_rank_dynamic = _S_rank;

	static constexpr size_t
	_S_dynamic_index_inv(size_t __k) noexcept
	{ return __k; }

	static constexpr size_t
	_S_static_extent(size_t) noexcept
	{ return dynamic_extent; }
      };

    template<typename _IndexType, array _Extents>
      class _ExtentsStorage : public _StaticExtents<_Extents>
      {
      private:
	using _Base = _StaticExtents<_Extents>;

      public:
	using _Base::_S_rank;
	using _Base::_S_rank_dynamic;
	using _Base::_S_dynamic_index;
	using _Base::_S_dynamic_index_inv;
	using _Base::_S_static_extent;

	static constexpr bool
	_S_is_dynamic(size_t __r) noexcept
	{
	  if constexpr (__all_static(_Extents))
	    return false;
	  else if constexpr (__all_dynamic(_Extents))
	    return true;
	  else
	    return _Extents[__r] == dynamic_extent;
	}

	template<typename _OIndexType>
	  static constexpr _IndexType
	  _S_int_cast(const _OIndexType& __other) noexcept
	  { return _IndexType(__other); }

	constexpr _IndexType
	_M_extent(size_t __r) const noexcept
	{
	  if (_S_is_dynamic(__r))
	    return _M_dyn_exts[_S_dynamic_index(__r)];
	  else
	    return _S_static_extent(__r);
	}

	template<size_t _OtherRank, typename _GetOtherExtent>
	  static constexpr bool
	  _S_is_compatible_extents(_GetOtherExtent __get_extent) noexcept
	  {
	    if constexpr (_OtherRank == _S_rank)
	      for (size_t __i = 0; __i < _S_rank; ++__i)
		if (!_S_is_dynamic(__i)
		    && !cmp_equal(_Extents[__i], _S_int_cast(__get_extent(__i))))
		  return false;
	    return true;
	  }

	template<size_t _OtherRank, typename _GetOtherExtent>
	  constexpr void
	  _M_init_dynamic_extents(_GetOtherExtent __get_extent) noexcept
	  {
	    __glibcxx_assert(_S_is_compatible_extents<_OtherRank>(__get_extent));
	    for (size_t __i = 0; __i < _S_rank_dynamic; ++__i)
	      {
		size_t __di = __i;
		if constexpr (_OtherRank != _S_rank_dynamic)
		  __di = _S_dynamic_index_inv(__i);
		_M_dyn_exts[__i] = _S_int_cast(__get_extent(__di));
	      }
	  }

	constexpr
	_ExtentsStorage() noexcept = default;

	template<typename _OIndexType, array _OExtents>
	  constexpr
	  _ExtentsStorage(const _ExtentsStorage<_OIndexType, _OExtents>&
			  __other) noexcept
	  {
	    _M_init_dynamic_extents<_S_rank>([&__other](size_t __i)
	      { return __other._M_extent(__i); });
	  }

	template<typename _OIndexType, size_t _Nm>
	  constexpr
	  _ExtentsStorage(span<const _OIndexType, _Nm> __exts) noexcept
	  {
	    _M_init_dynamic_extents<_Nm>(
	      [&__exts](size_t __i) -> const _OIndexType&
	      { return __exts[__i]; });
	  }

	static constexpr const array<size_t, _S_rank>&
	_S_static_extents() noexcept
	{ return _Extents; }

	constexpr span<const _IndexType>
	_M_dynamic_extents(size_t __begin, size_t __end) const noexcept
	requires (_Extents.size() > 0)
	{
	  return {_M_dyn_exts + _S_dynamic_index(__begin),
		  _S_dynamic_index(__end) - _S_dynamic_index(__begin)};
	}

      private:
	using _Storage = __array_traits<_IndexType, _S_rank_dynamic>::_Type;
	[[no_unique_address]] _Storage _M_dyn_exts{};
      };

    template<typename _OIndexType, typename _SIndexType>
      concept __valid_index_type =
	is_convertible_v<_OIndexType, _SIndexType> &&
	is_nothrow_constructible_v<_SIndexType, _OIndexType>;

    template<size_t _Extent, typename _IndexType>
      concept
      __valid_static_extent = _Extent == dynamic_extent
	|| _Extent <= __gnu_cxx::__int_traits<_IndexType>::__max;

    template<typename _Extents>
      constexpr const array<size_t, _Extents::rank()>&
      __static_extents() noexcept
      { return _Extents::_Storage::_S_static_extents(); }

    template<typename _Extents>
      constexpr span<const size_t>
      __static_extents(size_t __begin, size_t __end) noexcept
      {
	const auto& __sta_exts = __static_extents<_Extents>();
	return span<const size_t>(__sta_exts.data() + __begin, __end - __begin);
      }

    // Pre-compute: \prod_{i = 0}^r _Extents[i], for r = 0,..., n (exclusive)
    template<array _Extents>
      constexpr auto __fwd_partial_prods = [] consteval
	{
	  constexpr size_t __rank = _Extents.size();
	  std::array<size_t, __rank> __ret;
	  size_t __prod = 1;
	  for (size_t __r = 0; __r < __rank; ++__r)
	    {
	      __ret[__r] = __prod;
	      if (size_t __ext = _Extents[__r]; __ext != dynamic_extent)
		__prod *= __ext;
	    }
	  return __ret;
	}();

    // Pre-compute: \prod_{i = r+1}^{n-1} _Extents[i]
    template<array _Extents>
      constexpr auto __rev_partial_prods = [] consteval
	{
	  constexpr size_t __rank = _Extents.size();
	  std::array<size_t, __rank> __ret;
	  size_t __prod = 1;
	  for (size_t __r = __rank; __r > 0; --__r)
	    {
	      __ret[__r - 1] = __prod;
	      if (size_t __ext = _Extents[__r - 1]; __ext != dynamic_extent)
		__prod *= __ext;
	    }
	  return __ret;
	}();

    template<typename _Extents>
      constexpr span<const typename _Extents::index_type>
      __dynamic_extents(const _Extents& __exts, size_t __begin = 0,
			size_t __end = _Extents::rank()) noexcept
      { return __exts._M_exts._M_dynamic_extents(__begin, __end); }
  }

#if __glibcxx_submdspan
  struct full_extent_t
  {
    explicit full_extent_t() = default;
  };

  inline constexpr full_extent_t full_extent{};

  template<typename _OffsetType, typename _ExtentType, typename _StrideType>
    struct extent_slice
    {
      static_assert(__is_signed_or_unsigned_integer<_OffsetType>::value
	|| __detail::__integral_constant_like<_OffsetType>);
      static_assert(__is_signed_or_unsigned_integer<_ExtentType>::value
	|| __detail::__integral_constant_like<_ExtentType>);
      static_assert(__is_signed_or_unsigned_integer<_StrideType>::value
	|| __detail::__integral_constant_like<_StrideType>);

      using offset_type = _OffsetType;
      using extent_type = _ExtentType;
      using stride_type = _StrideType;

      [[no_unique_address]] offset_type offset{};
      [[no_unique_address]] extent_type extent{};
      [[no_unique_address]] stride_type stride{};
    };

  template<typename _FirstType, typename _LastType, typename _StrideType = constant_wrapper<1zu>>
    struct range_slice
    {
      static_assert(__is_signed_or_unsigned_integer<_FirstType>::value
	|| __detail::__integral_constant_like<_FirstType>);
      static_assert(__is_signed_or_unsigned_integer<_LastType>::value
	|| __detail::__integral_constant_like<_LastType>);
      static_assert(__is_signed_or_unsigned_integer<_StrideType>::value
	|| __detail::__integral_constant_like<_StrideType>);

      [[no_unique_address]] _FirstType first{};
      [[no_unique_address]] _LastType last{};
      [[no_unique_address]] _StrideType stride{};
    };

  template<typename _Mapping>
    struct submdspan_mapping_result
    {
      [[no_unique_address]] _Mapping mapping = _Mapping();
      size_t offset{};
    };

  template<typename _Tp>
    constexpr bool __is_submdspan_mapping_result = false;

  template<typename _Mapping>
    constexpr bool __is_submdspan_mapping_result<submdspan_mapping_result<_Mapping>> = true;

  template<typename _Mapping>
    concept __submdspan_mapping_result = __is_submdspan_mapping_result<_Mapping>;

#endif // __glibcxx_submdspan

  template<typename _IndexType, size_t... _Extents>
    class extents
    {
      static_assert(__is_signed_or_unsigned_integer<_IndexType>::value,
		    "IndexType must be a signed or unsigned integer type");
      static_assert(
	  (__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
	  "Extents must either be dynamic or representable as IndexType");

      using _Storage = __mdspan::_ExtentsStorage<
	_IndexType, array<size_t, sizeof...(_Extents)>{_Extents...}>;
      [[no_unique_address]] _Storage _M_exts;

    public:
      using index_type = _IndexType;
      using size_type = make_unsigned_t<index_type>;
      using rank_type = size_t;

      static constexpr rank_type
      rank() noexcept { return _Storage::_S_rank; }

      static constexpr rank_type
      rank_dynamic() noexcept { return _Storage::_S_rank_dynamic; }

      static constexpr size_t
      static_extent(rank_type __r) noexcept
      {
	__glibcxx_assert(__r < rank());
	if constexpr (rank() == 0)
	  __builtin_trap();
	else
	  return _Storage::_S_static_extent(__r);
      }

      constexpr index_type
      extent(rank_type __r) const noexcept
      {
	__glibcxx_assert(__r < rank());
	if constexpr (rank() == 0)
	  __builtin_trap();
	else
	  return _M_exts._M_extent(__r);
      }

      constexpr
      extents() noexcept = default;

    private:
      static consteval bool
      _S_is_less_dynamic(size_t __ext, size_t __oext)
      { return (__ext != dynamic_extent) && (__oext == dynamic_extent); }

      template<typename _OIndexType, size_t... _OExtents>
	static consteval bool
	_S_ctor_explicit()
	{
	  return (_S_is_less_dynamic(_Extents, _OExtents) || ...)
	    || (__gnu_cxx::__int_traits<index_type>::__max
		< __gnu_cxx::__int_traits<_OIndexType>::__max);
	}

      template<size_t... _OExtents>
	static consteval bool
	_S_is_compatible_extents()
	{
	  if constexpr (sizeof...(_OExtents) != rank())
	    return false;
	  else
	    return ((_OExtents == dynamic_extent || _Extents == dynamic_extent
		     || _OExtents == _Extents) && ...);
	}

    public:
      template<typename _OIndexType, size_t... _OExtents>
	requires (_S_is_compatible_extents<_OExtents...>())
	constexpr explicit(_S_ctor_explicit<_OIndexType, _OExtents...>())
	extents(const extents<_OIndexType, _OExtents...>& __other) noexcept
	: _M_exts(__other._M_exts)
	{ }

      template<__mdspan::__valid_index_type<index_type>... _OIndexTypes>
	requires (sizeof...(_OIndexTypes) == rank()
		  || sizeof...(_OIndexTypes) == rank_dynamic())
	constexpr explicit extents(_OIndexTypes... __exts) noexcept
	: _M_exts(span<const _IndexType, sizeof...(_OIndexTypes)>(
	    initializer_list{static_cast<_IndexType>(std::move(__exts))...}))
	{ }

      template<typename _OIndexType, size_t _Nm>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	  && (_Nm == rank() || _Nm == rank_dynamic())
	constexpr explicit(_Nm != rank_dynamic())
	extents(span<_OIndexType, _Nm> __exts) noexcept
	: _M_exts(span<const _OIndexType, _Nm>(__exts))
	{ }

      template<typename _OIndexType, size_t _Nm>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	  && (_Nm == rank() || _Nm == rank_dynamic())
	constexpr explicit(_Nm != rank_dynamic())
	extents(const array<_OIndexType, _Nm>& __exts) noexcept
	: _M_exts(span<const _OIndexType, _Nm>(__exts))
	{ }

      template<typename _OIndexType, size_t... _OExtents>
	friend constexpr bool
	operator==(const extents& __self,
		   const extents<_OIndexType, _OExtents...>& __other) noexcept
	{
	  if constexpr (!_S_is_compatible_extents<_OExtents...>())
	    return false;
	  else
	    {
	      auto __impl = [&__self, &__other]<size_t... _Counts>(
		  index_sequence<_Counts...>)
		{ return (cmp_equal(__self.extent(_Counts),
				    __other.extent(_Counts)) && ...); };
	      return __impl(make_index_sequence<__self.rank()>());
	    }
	}

    private:
      friend constexpr const array<size_t, rank()>&
      __mdspan::__static_extents<extents>() noexcept;

      friend constexpr span<const index_type>
      __mdspan::__dynamic_extents<extents>(const extents&, size_t, size_t)
      noexcept;

      template<typename _OIndexType, size_t... _OExtents>
	friend class extents;
    };

  namespace __mdspan
  {
    template<typename _Tp, size_t _Nm>
      constexpr bool
      __contains_zero(span<_Tp, _Nm> __exts) noexcept
      {
	for (size_t __i = 0; __i < __exts.size(); ++__i)
	  if (__exts[__i] == 0)
	    return true;
	return false;
      }

    template<typename _Tp, size_t _Nm>
      consteval bool
      __contains_zero(const array<_Tp, _Nm>& __exts) noexcept
      { return __contains_zero(span<const _Tp>(__exts)); }

    template<typename _Extents>
      constexpr bool
      __empty(const _Extents& __exts) noexcept
      {
	if constexpr (__contains_zero(__static_extents<_Extents>()))
	  return true;
	else if constexpr (_Extents::rank_dynamic() > 0)
	  return __contains_zero(__dynamic_extents(__exts));
	else
	  return false;
      }

    template<typename _Extents>
      constexpr typename _Extents::index_type
      __extents_prod(const _Extents& __exts, size_t __sta_prod, size_t __begin,
		     size_t __end) noexcept
      {
	if (__sta_prod == 0)
	  return 0;

	size_t __ret = __sta_prod;
	if constexpr (_Extents::rank_dynamic() > 0)
	  for (auto __factor : __dynamic_extents(__exts, __begin, __end))
	    __ret *= size_t(__factor);
	return static_cast<typename _Extents::index_type>(__ret);
      }

    // Preconditions: _r < _Extents::rank()
    template<typename _Extents>
      constexpr typename _Extents::index_type
      __fwd_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept
      {
	size_t __sta_prod = [__begin, __end] {
	  span<const size_t> __sta_exts
	    = __static_extents<_Extents>(__begin, __end);
	  size_t __ret = 1;
	  for(auto __ext : __sta_exts)
	    if (__ext != dynamic_extent)
	      __ret *= __ext;
	  return __ret;
	}();
	return __extents_prod(__exts, __sta_prod, __begin, __end);
      }

    template<typename _Extents>
      constexpr typename _Extents::index_type
      __fwd_prod(const _Extents& __exts, size_t __r) noexcept
      {
	constexpr size_t __rank = _Extents::rank();
	constexpr auto& __sta_exts = __static_extents<_Extents>();
	if constexpr (__rank == 1)
	  return 1;
	else if constexpr (__rank == 2)
	  return __r == 0 ? 1 : __exts.extent(0);
	else if constexpr (__all_dynamic(std::span(__sta_exts).first(__rank-1)))
	  return __extents_prod(__exts, 1, 0, __r);
	else
	  {
	    size_t __sta_prod = __fwd_partial_prods<__sta_exts>[__r];
	    return __extents_prod(__exts, __sta_prod, 0, __r);
	  }
      }

    template<typename _IndexType, size_t _Nm>
      consteval _IndexType
      __fwd_prod(span<const _IndexType, _Nm> __values)
      {
	_IndexType __ret = 1;
	for(auto __value : __values)
	  __ret *= __value;
	return __ret;
      }

    // Preconditions: _r < _Extents::rank()
    template<typename _Extents>
      constexpr typename _Extents::index_type
      __rev_prod(const _Extents& __exts, size_t __r) noexcept
      {
	constexpr size_t __rank = _Extents::rank();
	constexpr auto& __sta_exts = __static_extents<_Extents>();
	if constexpr (__rank == 1)
	  return 1;
	else if constexpr (__rank == 2)
	  return __r == 0 ? __exts.extent(1) : 1;
	else if constexpr (__all_dynamic(std::span(__sta_exts).last(__rank-1)))
	  return __extents_prod(__exts, 1, __r + 1, __rank);
	else
	  {
	    size_t __sta_prod = __rev_partial_prods<__sta_exts>[__r];
	    return __extents_prod(__exts, __sta_prod, __r + 1, __rank);
	  }
      }

    template<typename _Extents>
      constexpr typename _Extents::index_type
      __size(const _Extents& __exts) noexcept
      {
	constexpr size_t __sta_prod = [] {
	  span<const size_t> __sta_exts = __static_extents<_Extents>();
	  size_t __ret = 1;
	  for(auto __ext : __sta_exts)
	    if (__ext != dynamic_extent)
	      __ret *= __ext;
	  return __ret;
	}();
	return __extents_prod(__exts, __sta_prod, 0, _Extents::rank());
      }

    template<typename _IndexType, size_t... _Counts>
      auto __build_dextents_type(integer_sequence<size_t, _Counts...>)
	-> extents<_IndexType, ((void) _Counts, dynamic_extent)...>;
  }

  template<typename _IndexType, size_t _Rank>
    using dextents = decltype(__mdspan::__build_dextents_type<_IndexType>(
	make_index_sequence<_Rank>()));

#if __glibcxx_mdspan >= 202406L
  template<size_t _Rank, typename _IndexType = size_t>
    using dims = dextents<_IndexType, _Rank>;
#endif

  template<typename... _Integrals>
    requires (is_convertible_v<_Integrals, size_t> && ...)
    explicit extents(_Integrals...) ->
      extents<size_t, __detail::__maybe_static_ext<_Integrals>...>;

  struct layout_left
  {
    template<typename _Extents>
      class mapping;
  };

  struct layout_right
  {
    template<typename _Extents>
      class mapping;
  };

  struct layout_stride
  {
    template<typename _Extents>
      class mapping;
  };

#ifdef __glibcxx_padded_layouts
  template<size_t _PaddingValue>
    struct layout_left_padded
    {
      template<typename _Extents>
	class mapping;
    };

  template<size_t _PaddingValue>
    struct layout_right_padded
    {
      template<typename _Extents>
	class mapping;
    };
#endif

  namespace __mdspan
  {
    template<typename _Tp>
      constexpr bool __is_extents = false;

    template<typename _IndexType, size_t... _Extents>
      constexpr bool __is_extents<extents<_IndexType, _Extents...>> = true;

    template<typename _Extents, typename... _Indices>
      constexpr typename _Extents::index_type
      __linear_index_left(const _Extents& __exts, _Indices... __indices)
      noexcept
      {
	using _IndexType = typename _Extents::index_type;
	_IndexType __res = 0;
	if constexpr (sizeof...(__indices) > 0)
	  {
	    _IndexType __mult = 1;
	    auto __update = [&, __pos = 0u](_IndexType __idx) mutable
	      {
		_GLIBCXX_DEBUG_ASSERT(cmp_less(__idx, __exts.extent(__pos)));
		__res += __idx * __mult;
		__mult *= __exts.extent(__pos);
		++__pos;
	      };
	    (__update(__indices), ...);
	  }
	return __res;
      }

    template<typename _IndexType>
      consteval _IndexType
      __static_quotient(std::span<const size_t> __sta_exts,
	_IndexType __nom = __gnu_cxx::__int_traits<_IndexType>::__max)
      {
	for (auto __factor : __sta_exts)
	  {
	    if (__factor != dynamic_extent)
	      __nom /= _IndexType(__factor);
	    if (__nom == 0)
	      break;
	  }
	return __nom;
      }

    template<typename _Extents,
	     typename _IndexType = typename _Extents::index_type>
      requires __is_extents<_Extents>
      consteval _IndexType
      __static_quotient(_IndexType __nom
			  = __gnu_cxx::__int_traits<_IndexType>::__max)
      {
	std::span<const size_t> __sta_exts = __static_extents<_Extents>();
	return __static_quotient<_IndexType>(__sta_exts, __nom);
      }

    template<typename _Extents>
      constexpr bool
      __is_representable_extents(const _Extents& __exts) noexcept
      {
	using _IndexType = _Extents::index_type;

	if constexpr (__contains_zero(__static_extents<_Extents>()))
	  return true;
	else
	  {
	    constexpr auto __sta_quo = __static_quotient<_Extents>();
	    if constexpr (_Extents::rank_dynamic() == 0)
	      return __sta_quo != 0;
	    else
	      {
		auto __dyn_exts = __dynamic_extents(__exts);
		if (__contains_zero(__dyn_exts))
		  return true;

		if constexpr (__sta_quo == 0)
		  return false;
		else
		  {
		    auto __dyn_quo = _IndexType(__sta_quo);
		    for (auto __factor : __dyn_exts)
		      {
			__dyn_quo /= __factor;
			if (__dyn_quo == 0)
			  return false;
		      }
		    return true;
		  }
	      }
	  }
      }

    template<typename _Extents, typename _IndexType>
      concept __representable_size = _Extents::rank_dynamic() != 0
	|| __contains_zero(__static_extents<_Extents>())
	|| (__static_quotient<_Extents, _IndexType>() != 0);

    template<typename _Layout, typename _Mapping>
      concept __mapping_of =
	is_same_v<typename _Layout::template mapping<
		    typename _Mapping::extents_type>,
		  _Mapping>;

    template<template<size_t> typename _Layout, typename _Mapping>
      concept __padded_mapping_of = __mapping_of<
	_Layout<_Mapping::padding_value>, _Mapping>;

#ifdef __glibcxx_padded_layouts
    template<typename _Mapping>
      constexpr bool __is_left_padded_mapping = __padded_mapping_of<
	layout_left_padded, _Mapping>;

    template<typename _Mapping>
      constexpr bool __is_right_padded_mapping = __padded_mapping_of<
	layout_right_padded, _Mapping>;

    template<typename _Mapping>
      constexpr bool __is_padded_mapping = __is_left_padded_mapping<_Mapping>
	|| __is_right_padded_mapping<_Mapping>;
#endif

    template<typename _PaddedMapping>
      consteval size_t
      __get_static_stride()
      { return _PaddedMapping::_PaddedStorage::_S_static_stride; }

    template<typename _Mapping>
      concept __standardized_mapping = __mapping_of<layout_left, _Mapping>
				       || __mapping_of<layout_right, _Mapping>
				       || __mapping_of<layout_stride, _Mapping>
#ifdef __glibcxx_padded_layouts
				       || __is_left_padded_mapping<_Mapping>
				       || __is_right_padded_mapping<_Mapping>
#endif
				       ;

    // A tag type to create internal ctors.
    class __internal_ctor
    { };

    template<typename _Mapping>
      constexpr typename _Mapping::index_type
      __offset(const _Mapping& __m) noexcept
      {
	using _IndexType = typename _Mapping::index_type;
	constexpr auto __rank = _Mapping::extents_type::rank();

	if constexpr (__standardized_mapping<_Mapping>)
	  return 0;
	else if (__empty(__m.extents()))
	  return 0;
	else
	  {
	    auto __impl = [&__m]<size_t... _Counts>(index_sequence<_Counts...>)
	      { return __m(((void) _Counts, _IndexType(0))...); };
	    return __impl(make_index_sequence<__rank>());
	  }
      }

#ifdef __glibcxx_submdspan
    template<typename _Tp>
      constexpr bool __is_extent_slice = false;

    template<typename _OffsetType, typename _ExtentType, typename _StrideType>
      constexpr bool __is_extent_slice<extent_slice<_OffsetType,
	  _ExtentType, _StrideType>> = true;

    template<typename _Tp>
      constexpr bool __is_range_slice = false;

    template<typename _FirstType, typename _LastType, typename _StrideType>
      constexpr bool __is_range_slice<range_slice<_FirstType,
	  _LastType, _StrideType>> = true;

    template<typename _IndexType, typename _OIndexType>
      consteval bool
      __is_representable_integer(_OIndexType __value)
      {
	constexpr auto __min = __gnu_cxx::__int_traits<_IndexType>::__min;
	constexpr auto __max = __gnu_cxx::__int_traits<_IndexType>::__max;
	return std::cmp_less_equal(__min, __value)
	    && std::cmp_less_equal(__value, __max);
      }

    template<size_t _Index, typename _Extents>
      constexpr auto
      __extract_extent(const _Extents& __exts)
      {
	using _IndexType = typename _Extents::index_type;
	return extents<_IndexType, _Extents::static_extent(_Index)>{
	  __exts.extent(_Index)};
      }

    template<typename _Slice, typename _IndexType>
      concept __acceptable_slice_type = same_as<_Slice, full_extent_t>
	  || same_as<_Slice, _IndexType> || __is_constant_wrapper_v<_Slice>
	  || __is_extent_slice<_Slice>;

    template<typename _IndexType, typename... _Slices>
      consteval auto
      __subrank()
      {
	return (static_cast<size_t>(!convertible_to<_Slices, _IndexType>)
		+ ... + 0);
      }

    template<typename _IndexType, typename... _Slices>
      consteval auto
      __inv_map_rank()
      {
	constexpr auto __rank = sizeof...(_Slices);
	constexpr auto __sub_rank = __subrank<_IndexType, _Slices...>();
	auto __map = std::array<size_t, __sub_rank>{};
	auto __is_int_like = std::array<bool, __rank>{
	  convertible_to<_Slices, _IndexType>...};

	size_t __i = 0;
	for (size_t __k = 0; __k < __rank; ++__k)
	  if (!__is_int_like[__k])
	    __map[__i++] = __k;
	return __map;
      }

    template<typename _Slice>
      constexpr auto
      __slice_begin(_Slice __slice)
      {
	if constexpr (same_as<_Slice, full_extent_t>)
	  return 0;
	else if constexpr (__is_extent_slice<_Slice>)
	  return __slice.offset;
	else
	  return __slice; // collapsing slice
      }

    template<typename _Mapping, typename... _Slices>
      constexpr size_t
      __suboffset(const _Mapping& __mapping, const _Slices&... __slices)
      {
	using _IndexType = typename _Mapping::index_type;
	auto __any_past_the_end = [&]<size_t... _Is>(index_sequence<_Is...>)
	{
	  auto __is_past_the_end = [](const auto& __slice, const auto& __ext)
	  {
	    using _Slice = remove_cvref_t<decltype(__slice)>;
	    if constexpr (is_convertible_v<_Slice, _IndexType>)
	      return false;
	    else if constexpr (same_as<_Slice, full_extent_t>
		&& __ext.static_extent(0) != 0
		&& __ext.static_extent(0) != dynamic_extent)
	      return false;
	    else
	      return __mdspan::__slice_begin(__slice) == __ext.extent(0);
	  };

	  const auto& __exts = __mapping.extents();
	  return ((__is_past_the_end(__slices...[_Is],
				     __mdspan::__extract_extent<_Is>(__exts))) || ...);
	};

	if constexpr ((same_as<_Slices, full_extent_t> && ...))
	  return __mdspan::__offset(__mapping);

	if (__any_past_the_end(std::make_index_sequence<sizeof...(__slices)>()))
	  return __mapping.required_span_size();
	return __mapping(__mdspan::__slice_begin(__slices)...);
      }

    template<typename _IndexType, size_t _Extent, typename _Slice>
      consteval size_t
      __static_slice_extent()
      {
	if constexpr (same_as<_Slice, full_extent_t>)
	  return _Extent;
	else if constexpr (same_as<_Slice, constant_wrapper<_IndexType(0)>>)
	  return 0;
	else if constexpr (__is_constant_wrapper_v<typename _Slice::extent_type>)
	  return _Slice::extent_type::value;
	else
	  return dynamic_extent;
      }

    template<size_t _K, typename _Extents, typename _Slice>
      constexpr typename _Extents::index_type
      __dynamic_slice_extent(const _Extents& __exts, _Slice __slice)
      {
	if constexpr (__is_extent_slice<_Slice>)
	  return __slice.extent;
	else
	  return __exts.extent(_K);
      }

    template<typename _IndexType, size_t... _Extents, typename... _Slices>
      requires (sizeof...(_Slices) == sizeof...(_Extents))
      constexpr auto
      __subextents(const extents<_IndexType, _Extents...>& __exts,
		   _Slices... __slices)
      {
	constexpr auto __inv_map = __mdspan::__inv_map_rank<_IndexType, _Slices...>();
	auto __impl = [&]<size_t... _Indices>(std::index_sequence<_Indices...>)
	{
	  using _SubExts = extents<_IndexType,
	      __mdspan::__static_slice_extent<_IndexType,
		 _Extents...[__inv_map[_Indices]],
		 _Slices...[__inv_map[_Indices]]>()...>;
	  if constexpr (_SubExts::rank_dynamic() == 0)
	    return _SubExts{};
	  else
	    {
	      using _StaticSubExtents = __mdspan::_StaticExtents<
		__mdspan::__static_extents<_SubExts>()>;
	      auto __create = [&]<size_t... _Is>(std::index_sequence<_Is...>)
	      {
		constexpr auto __slice_idx = [__inv_map](size_t __i) consteval
		{
		  return __inv_map[_StaticSubExtents::_S_dynamic_index_inv(__i)];
		};

		return _SubExts{__mdspan::__dynamic_slice_extent<__slice_idx(_Is)>(
		     __exts, __slices...[__slice_idx(_Is)])...};
	      };
	      constexpr auto __dyn_subrank = _SubExts::rank_dynamic();
	      return __create(std::make_index_sequence<__dyn_subrank>());
	    }
	};

	return __impl(std::make_index_sequence<__inv_map.size()>());
      }

    enum class _LayoutSide
    {
      __left,
      __right,
      __unknown
    };

    template<typename _Mapping>
      consteval _LayoutSide
      __mapping_side()
      {
	if constexpr (__is_left_padded_mapping<_Mapping>
	    || __mapping_of<layout_left, _Mapping>)
	  return _LayoutSide::__left;
	if constexpr (__is_right_padded_mapping<_Mapping>
	    || __mapping_of<layout_right, _Mapping>)
	  return _LayoutSide::__right;
	else
	  return _LayoutSide::__unknown;
      }

    template<_LayoutSide _Side, size_t _Rank>
      struct _StridesTrait
      {
	static constexpr const _LayoutSide _S_side = _Side;

	static constexpr size_t
	_S_idx(size_t __k) noexcept
	{
	  if constexpr (_Side == _LayoutSide::__left)
	    return __k;
	  else
	    return _Rank - 1 - __k;
	}

	// Unifies the formulas for computing strides for padded and unpadded
	// layouts.
	template<typename _Mapping>
	  static constexpr typename _Mapping::index_type
	  _S_padded_extent(const _Mapping& __mapping, size_t __k)
	  {
	    if (__k == 0)
	      return __mapping.stride(_S_idx(1));
	    else
	      return __mapping.extents().extent(_S_idx(__k));
	  }

	template<typename _IndexType, typename... _Slices>
	  static consteval auto
	  _S_inv_map()
	  {
	    static_assert(_Side != _LayoutSide::__unknown);
	    auto __impl = [&]<size_t... _Is>(std::index_sequence<_Is...>)
	    {
	      return __mdspan::__inv_map_rank<_IndexType, _Slices...[_S_idx(_Is)]...>();
	    };
	    return __impl(std::make_index_sequence<_Rank>());
	  }
      };

    template<typename _SubExts, typename _Mapping, typename... _Slices>
      constexpr auto
      __substrides_generic(const _Mapping& __mapping, const _Slices&... __slices)
      {
	using _IndexType = typename _Mapping::index_type;
	if constexpr (_SubExts::rank() == 0)
	  return array<_IndexType, _SubExts::rank()>{};
	else
	  {
	    auto __stride = [&__mapping](size_t __k, auto __slice) -> _IndexType
	    {
	      if constexpr (__is_extent_slice<decltype(__slice)>)
		if (__slice.extent > 1)
		  return __mapping.stride(__k) * __slice.stride;
	      return __mapping.stride(__k);
	    };

	    auto __impl = [&]<size_t... _Is>(std::index_sequence<_Is...>)
	    {
	      constexpr auto __inv_map
		= __mdspan::__inv_map_rank<_IndexType, _Slices...>();
	      return array<_IndexType, _SubExts::rank()>{
		__stride(__inv_map[_Is], __slices...[__inv_map[_Is]])...};
	    };
	    return __impl(std::make_index_sequence<_SubExts::rank()>());
	  }
      };

    template<typename _SubExts, typename _Mapping, typename... _Slices>
      constexpr auto
      __substrides_standardized(const _Mapping& __mapping,
			       const _Slices&... __slices)
      {
	using _IndexType = typename _Mapping::index_type;
	using _Trait = _StridesTrait<__mapping_side<_Mapping>(),
				     _Mapping::extents_type::rank()>;
	using _SubTrait = _StridesTrait<__mapping_side<_Mapping>(), _SubExts::rank()>;

	constexpr size_t __sub_rank = _SubExts::rank();

	std::array<_IndexType, __sub_rank> __ret;
	if constexpr (__sub_rank > 0)
	  {
	    constexpr auto __inv_map
	      = _Trait::template _S_inv_map<_IndexType, _Slices...>();
	    auto __loop = [&]<size_t... _Ks>(std::index_sequence<_Ks...>)
	    {
	      size_t __i0 = 0;
	      size_t __stride = 1;
	      auto __body = [&](size_t __k, auto __slice)
	      {
		for (size_t __i = __i0; __i < __inv_map[__k]; ++__i)
		  __stride *= _Trait::_S_padded_extent(__mapping, __i);

		size_t __krev = _SubTrait::_S_idx(__k);
		if constexpr (__is_extent_slice<decltype(__slice)>)
		  {
		    if (__slice.extent > 1)
		      __ret[__krev] = __stride * __slice.stride;
		    else
		      __ret[__krev] = __stride;
		  }
		else
		  __ret[__krev] = __stride;

		__i0 = __inv_map[__k];
	      };

	      ((__body(_Ks, __slices...[_Trait::_S_idx(__inv_map[_Ks])])),...);
	    };
	    __loop(std::make_index_sequence<__sub_rank>());
	  }
	return __ret;
      }


    template<typename _SubExts, typename _Mapping, typename... _Slices>
      constexpr auto
      __substrides(const _Mapping& __mapping, const _Slices&... __slices)
      {
	if constexpr (__mdspan::__mapping_side<_Mapping>() == _LayoutSide::__unknown)
	  return __mdspan::__substrides_generic<_SubExts>(__mapping, __slices...);
	else
	  return __mdspan::__substrides_standardized<_SubExts>(__mapping, __slices...);
      }

    template<typename _Slice>
      concept __is_unit_stride_slice = (__mdspan::__is_extent_slice<_Slice>
	  && __is_constant_wrapper_v<typename _Slice::stride_type>
	  && _Slice::stride_type::value == 1)
	|| std::same_as<_Slice, full_extent_t>;

    // These are (forced) exclusive categories:
    //  - full & collapsing: obvious,
    //  - unit_extent_slice: extent_slice{a, b, cw<1>}, but not `full`,
    //  - extent_slice: extent_slice{a, b, c} with c != cw<1>.
    enum class _SliceKind
    {
      __extent_slice,
      __unit_stride_slice,
      __full,
      __collapsing
    };

    template<typename _Slice>
      consteval _SliceKind
      __make_slice_kind()
      {
	if constexpr (std::same_as<_Slice, full_extent_t>)
	  return _SliceKind::__full;
	else if constexpr (__mdspan::__is_extent_slice<_Slice>)
	  {
	    if constexpr (__mdspan::__is_unit_stride_slice<_Slice>)
	      return _SliceKind::__unit_stride_slice;
	    else
	      return _SliceKind::__extent_slice;
	  }
	else
	  return _SliceKind::__collapsing;
      }

    template<typename... _Slices>
      consteval array<_SliceKind, sizeof...(_Slices)>
      __make_slice_kind_array()
      {
	return array<_SliceKind, sizeof...(_Slices)>{
	  __mdspan::__make_slice_kind<_Slices>()...};
      }

    //                   __block_size - 1
    // [full, ..., full, unit_slice    , *]
    consteval bool
    __is_block(span<const _SliceKind> __slice_kinds, size_t __block_size)
    {
      if (__block_size == 0)
	return false;

      if (__block_size > __slice_kinds.size())
	return false;

      for (size_t __i = 0; __i < __block_size - 1; ++__i)
	if (__slice_kinds[__i] != _SliceKind::__full)
	  return false;

      auto __last = __slice_kinds[__block_size - 1];
      return __last == _SliceKind::__full
	  || __last == _SliceKind::__unit_stride_slice;
    }

    //                         __u              __u + __sub_rank-2
    // [unit_slice, i, ..., k, full, ..., full, unit_slice, *]
    static consteval size_t
    __padded_block_begin_generic(span<const _SliceKind> __slice_kinds,
				 size_t __sub_rank)
    {
      if (__slice_kinds[0] != _SliceKind::__full
	  && __slice_kinds[0] != _SliceKind::__unit_stride_slice)
	return dynamic_extent;
      else if (__slice_kinds.size() == 1)
	return dynamic_extent;
      else
	{
	  size_t __u = 1;
	  while(__u < __slice_kinds.size()
		&& __slice_kinds[__u] == _SliceKind::__collapsing)
	    ++__u;

	  if (__mdspan::__is_block(__slice_kinds.subspan(__u), __sub_rank -1))
	    return __u;
	  return dynamic_extent;
	}
    }

    template<_LayoutSide _Side, size_t _Nm>
      static consteval size_t
      __padded_block_begin(span<const _SliceKind, _Nm> __slice_kinds, size_t __sub_rank)
      {
	if constexpr (_Side == _LayoutSide::__left)
	  return __mdspan::__padded_block_begin_generic(__slice_kinds, __sub_rank);
	else
	  {
	    std::array<_SliceKind, _Nm> __rev_slices;
	    for(size_t __i = 0; __i < _Nm; ++__i)
	      __rev_slices[__i] = __slice_kinds[_Nm - 1 - __i];
	    auto __rev_slice_kinds = span<const _SliceKind>(__rev_slices);

	    auto __u = __mdspan::__padded_block_begin_generic(__rev_slice_kinds,
							      __sub_rank);
	    return __u == dynamic_extent ? dynamic_extent : _Nm - 1 - __u;
	  }
      }

    template<_LayoutSide _Side, bool _Padded>
      struct _SubMdspanMapping;

    template<>
      struct _SubMdspanMapping<_LayoutSide::__left, false>
      {
	using _Layout = layout_left;
	template<size_t _Pad> using _PaddedLayout = layout_left_padded<_Pad>;

	template<typename _Mapping, size_t _Us>
	  static consteval size_t
	  _S_pad()
	  {
	    using _Extents = typename _Mapping::extents_type;
	    constexpr auto __sta_exts = __mdspan::__static_extents<_Extents>(0, _Us);
	    if constexpr (!__mdspan::__all_static(__sta_exts))
	      return dynamic_extent;
	    else
	      return __mdspan::__fwd_prod(__sta_exts);
	  }

	template<size_t _Nm>
	  static consteval bool
	  _S_is_unpadded_submdspan(span<const _SliceKind, _Nm> __slice_kinds, size_t __sub_rank)
	  { return __mdspan::__is_block(__slice_kinds, __sub_rank); }
      };

    template<>
      struct _SubMdspanMapping<_LayoutSide::__left, true>
      {
	using _Layout = layout_left;
	template<size_t _Pad> using _PaddedLayout = layout_left_padded<_Pad>;

	template<typename _Mapping, size_t _Us>
	  static consteval size_t
	  _S_pad()
	  {
	    using _Extents = typename _Mapping::extents_type;
	    constexpr auto __sta_exts
	      = __mdspan::__static_extents<_Extents>(1, _Us);
	    constexpr auto __sta_padstride
	      = __mdspan::__get_static_stride<_Mapping>();
	    if constexpr (__sta_padstride == dynamic_extent
			  || !__mdspan::__all_static(__sta_exts))
	      return dynamic_extent;
	    else
	      return __sta_padstride * __mdspan::__fwd_prod(__sta_exts);
	  }

	template<size_t _Nm>
	  static consteval bool
	  _S_is_unpadded_submdspan(span<const _SliceKind, _Nm> __slice_kinds,
				   size_t __sub_rank)
	  {
	    if (__sub_rank == 1)
	      return __slice_kinds[0] == _SliceKind::__unit_stride_slice
		|| __slice_kinds[0] == _SliceKind::__full;
	    else
	      return false;
	  }
      };

    template<>
      struct _SubMdspanMapping<_LayoutSide::__right, false>
      {
	using _Layout = layout_right;
	template<size_t _Pad> using _PaddedLayout = layout_right_padded<_Pad>;

	template<typename _Mapping, size_t _Us>
	  static consteval size_t
	  _S_pad()
	  {
	    using _Extents = typename _Mapping::extents_type;
	    constexpr auto __rank = _Extents::rank();
	    constexpr auto __sta_exts
	      = __mdspan::__static_extents<_Extents>(_Us + 1, __rank);
	    if constexpr (!__mdspan::__all_static(__sta_exts))
	      return dynamic_extent;
	    else
	      return __fwd_prod(__sta_exts);
	  }

	template<size_t _Nm>
	  static consteval bool
	  _S_is_unpadded_submdspan(span<const _SliceKind, _Nm> __slice_kinds,
				   size_t __sub_rank)
	  {
	    auto __rev_slice_kinds = array<_SliceKind, _Nm>{};
	    for(size_t __i = 0; __i < _Nm; ++__i)
	      __rev_slice_kinds[__i] = __slice_kinds[_Nm - 1 - __i];
	    return __mdspan::__is_block(span(__rev_slice_kinds), __sub_rank);
	  }
      };

    template<>
      struct _SubMdspanMapping<_LayoutSide::__right, true>
      {
	using _Layout = layout_right;
	template<size_t _Pad> using _PaddedLayout = layout_right_padded<_Pad>;

	template<typename _Mapping, size_t _Us>
	  static consteval size_t
	  _S_pad()
	  {
	    using _Extents = typename _Mapping::extents_type;
	    constexpr auto __rank = _Extents::rank();
	    constexpr auto __sta_exts
	      = __mdspan::__static_extents<_Extents>(_Us + 1, __rank - 1);
	    constexpr auto __sta_padstride
	      = __mdspan::__get_static_stride<_Mapping>();
	    if constexpr (__sta_padstride == dynamic_extent
			  || !__mdspan::__all_static(__sta_exts))
	      return dynamic_extent;
	    else
	      return __sta_padstride * __mdspan::__fwd_prod(__sta_exts);
	  }

	template<size_t _Nm>
	  static consteval bool
	  _S_is_unpadded_submdspan(span<const _SliceKind, _Nm> __slice_kinds,
				   size_t __sub_rank)
	  {
	    if (__sub_rank == 1)
	      return __slice_kinds[_Nm - 1] == _SliceKind::__unit_stride_slice
		|| __slice_kinds[_Nm - 1] == _SliceKind::__full;
	    else
	      return false;
	  }
      };


    template<typename _Mapping>
      constexpr auto
      __submdspan_mapping_impl(const _Mapping& __mapping)
      { return submdspan_mapping_result{__mapping, 0}; }

    template<typename _Mapping, typename... _Slices>
      requires (sizeof...(_Slices) > 0)
      constexpr auto
      __submdspan_mapping_impl(const _Mapping& __mapping, _Slices... __slices)
      {
	using _IndexType = typename _Mapping::index_type;
	static_assert((__acceptable_slice_type<_Slices, _IndexType> && ...));

	constexpr auto __side = __mdspan::__mapping_side<_Mapping>();
	constexpr auto __rank = sizeof...(_Slices);
	using _Trait = _SubMdspanMapping<__side, __is_padded_mapping<_Mapping>>;
	using _SliceView = span<const _SliceKind, __rank>;

	constexpr auto __slice_kinds = __mdspan::__make_slice_kind_array<_Slices...>();
	auto __offset = __mdspan::__suboffset(__mapping, __slices...);
	auto __sub_exts = __mdspan::__subextents(__mapping.extents(), __slices...);
	using _SubExts = decltype(__sub_exts);
	constexpr auto __sub_rank = _SubExts::rank();
	if constexpr (__sub_rank == 0)
	  return submdspan_mapping_result{
	    typename _Trait::_Layout::mapping(__sub_exts), __offset};
	else if constexpr (_Trait::_S_is_unpadded_submdspan(
	      _SliceView(__slice_kinds), __sub_rank))
	  return submdspan_mapping_result{
	    typename _Trait::_Layout::mapping(__sub_exts), __offset};
	else if constexpr (
	    constexpr auto __u = __padded_block_begin<__side>(
		_SliceView(__slice_kinds), __sub_rank);
	    __u != dynamic_extent)
	  {
	    constexpr auto __pad = _Trait::template _S_pad<_Mapping, __u>();
	    using _Layout = typename _Trait::template _PaddedLayout<__pad>;
	    return submdspan_mapping_result{
	      typename _Layout::mapping(__sub_exts, __mapping.stride(__u)),
	      __offset};
	  }
	else
	  {
	    auto __sub_strides
	      = __mdspan::__substrides<_SubExts>(__mapping, __slices...);
	    return submdspan_mapping_result{
	      layout_stride::mapping(__sub_exts, __sub_strides),  __offset};
	  }
      }
#endif // __glibcxx_submdspan
  }

  template<typename _Extents>
    class layout_left::mapping
    {
    public:
      using extents_type = _Extents;
      using index_type = typename extents_type::index_type;
      using size_type = typename extents_type::size_type;
      using rank_type = typename extents_type::rank_type;
      using layout_type = layout_left;

      static_assert(__mdspan::__representable_size<extents_type, index_type>,
	"The size of extents_type must be representable as index_type");

      constexpr
      mapping() noexcept = default;

      constexpr
      mapping(const mapping&) noexcept = default;

      constexpr
      mapping(const extents_type& __extents) noexcept
      : _M_extents(__extents)
      { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); }

      template<typename _OExtents>
	requires is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	mapping(const mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ }

      template<typename _OExtents>
	requires (extents_type::rank() <= 1)
		  && is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	mapping(const layout_right::mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ }

      // noexcept for consistency with other layouts.
      template<typename _OExtents>
	requires is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!(extents_type::rank() == 0
			     && is_convertible_v<_OExtents, extents_type>))
	mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ __glibcxx_assert(*this == __other); }

#if __glibcxx_padded_layouts
      template<typename _LeftpadMapping>
	requires __mdspan::__is_left_padded_mapping<_LeftpadMapping>
		 && is_constructible_v<extents_type,
				       typename _LeftpadMapping::extents_type>
	constexpr
	explicit(!is_convertible_v<typename _LeftpadMapping::extents_type,
				   extents_type>)
	mapping(const _LeftpadMapping& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{
	  constexpr size_t __ostride_sta
	    = __mdspan::__get_static_stride<_LeftpadMapping>();

	  if constexpr (extents_type::rank() > 1)
	    {
	      if constexpr (extents_type::static_extent(0) != dynamic_extent
			    && __ostride_sta != dynamic_extent)
		static_assert(extents_type::static_extent(0) == __ostride_sta);
	      else
		__glibcxx_assert(__other.stride(1)
		    == __other.extents().extent(0));
	    }
	}
#endif // __glibcxx_padded_layouts

      constexpr mapping&
      operator=(const mapping&) noexcept = default;

      constexpr const extents_type&
      extents() const noexcept { return _M_extents; }

      constexpr index_type
      required_span_size() const noexcept
      { return __mdspan::__size(_M_extents); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4314. Missing move in mdspan layout mapping::operator()
      template<__mdspan::__valid_index_type<index_type>... _Indices>
	requires (sizeof...(_Indices) == extents_type::rank())
	constexpr index_type
	operator()(_Indices... __indices) const noexcept
	{
	  return __mdspan::__linear_index_left(_M_extents,
	    static_cast<index_type>(std::move(__indices))...);
	}

      static constexpr bool
      is_always_unique() noexcept { return true; }

      static constexpr bool
      is_always_exhaustive() noexcept { return true; }

      static constexpr bool
      is_always_strided() noexcept { return true; }

      static constexpr bool
      is_unique() noexcept { return true; }

      static constexpr bool
      is_exhaustive() noexcept { return true; }

      static constexpr bool
      is_strided() noexcept { return true; }

      constexpr index_type
      stride(rank_type __i) const noexcept
      requires (extents_type::rank() > 0)
      {
	__glibcxx_assert(__i < extents_type::rank());
	return __mdspan::__fwd_prod(_M_extents, __i);
      }

      template<typename _OExtents>
	requires (extents_type::rank() == _OExtents::rank())
	friend constexpr bool
	operator==(const mapping& __self, const mapping<_OExtents>& __other)
	noexcept
	{ return __self.extents() == __other.extents(); }

    private:
      template<typename _OExtents>
	constexpr explicit
	mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept
	: _M_extents(__oexts)
	{
	  static_assert(__mdspan::__representable_size<_OExtents, index_type>,
	    "The size of OtherExtents must be representable as index_type");
	  __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents));
	}

#if __glibcxx_submdspan
      template<typename... _Slices>
	requires (extents_type::rank() == sizeof...(_Slices))
	friend constexpr auto
	submdspan_mapping(const mapping& __mapping, _Slices... __slices)
	{ return __mdspan::__submdspan_mapping_impl(__mapping, __slices...); }
#endif // __glibcxx_submdspan

	[[no_unique_address]] extents_type _M_extents{};
    };

  namespace __mdspan
  {
    template<typename _Extents, typename... _Indices>
      constexpr typename _Extents::index_type
      __linear_index_right(const _Extents& __exts, _Indices... __indices)
      noexcept
      {
	using _IndexType = typename _Extents::index_type;
	array<_IndexType, sizeof...(__indices)> __ind_arr{__indices...};
	_IndexType __res = 0;
	if constexpr (sizeof...(__indices) > 0)
	  {
	    _IndexType __mult = 1;
	    auto __update = [&, __pos = __exts.rank()](_IndexType) mutable
	      {
		--__pos;
		_GLIBCXX_DEBUG_ASSERT(cmp_less(__ind_arr[__pos],
					       __exts.extent(__pos)));
		__res += __ind_arr[__pos] * __mult;
		__mult *= __exts.extent(__pos);
	      };
	    (__update(__indices), ...);
	  }
	return __res;
      }
  }

  template<typename _Extents>
    class layout_right::mapping
    {
    public:
      using extents_type = _Extents;
      using index_type = typename extents_type::index_type;
      using size_type = typename extents_type::size_type;
      using rank_type = typename extents_type::rank_type;
      using layout_type = layout_right;

      static_assert(__mdspan::__representable_size<extents_type, index_type>,
	"The size of extents_type must be representable as index_type");

      constexpr
      mapping() noexcept = default;

      constexpr
      mapping(const mapping&) noexcept = default;

      constexpr
      mapping(const extents_type& __extents) noexcept
      : _M_extents(__extents)
      { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); }

      template<typename _OExtents>
	requires is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	mapping(const mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ }

      template<typename _OExtents>
	requires (extents_type::rank() <= 1)
	    && is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	mapping(const layout_left::mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ }

      template<typename _OExtents>
	requires is_constructible_v<extents_type, _OExtents>
	constexpr explicit(!(extents_type::rank() == 0
			     && is_convertible_v<_OExtents, extents_type>))
	mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{ __glibcxx_assert(*this == __other); }

#if __glibcxx_padded_layouts
      template<typename _RightPaddedMapping>
	requires __mdspan::__is_right_padded_mapping<_RightPaddedMapping>
		 && is_constructible_v<extents_type,
		      typename _RightPaddedMapping::extents_type>
	constexpr
	explicit(!is_convertible_v<typename _RightPaddedMapping::extents_type,
				   extents_type>)
	mapping(const _RightPaddedMapping& __other) noexcept
	: mapping(__other.extents(), __mdspan::__internal_ctor{})
	{
	  constexpr size_t __rank = extents_type::rank();
	  constexpr size_t __ostride_sta
	    = __mdspan::__get_static_stride<_RightPaddedMapping>();

	  if constexpr (__rank > 1)
	    {
	      if constexpr (extents_type::static_extent(__rank - 1) != dynamic_extent
		  && __ostride_sta != dynamic_extent)
		static_assert(extents_type::static_extent(__rank - 1)
		    == __ostride_sta);
	      else
		__glibcxx_assert(__other.stride(__rank - 2)
		    == __other.extents().extent(__rank - 1));
	    }
	}
#endif

      constexpr mapping&
      operator=(const mapping&) noexcept = default;

      constexpr const extents_type&
      extents() const noexcept { return _M_extents; }

      constexpr index_type
      required_span_size() const noexcept
      { return __mdspan::__size(_M_extents); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4314. Missing move in mdspan layout mapping::operator()
      template<__mdspan::__valid_index_type<index_type>... _Indices>
	requires (sizeof...(_Indices) == extents_type::rank())
	constexpr index_type
	operator()(_Indices... __indices) const noexcept
	{
	  return __mdspan::__linear_index_right(
	    _M_extents, static_cast<index_type>(std::move(__indices))...);
	}

      static constexpr bool
      is_always_unique() noexcept
      { return true; }

      static constexpr bool
      is_always_exhaustive() noexcept
      { return true; }

      static constexpr bool
      is_always_strided() noexcept
      { return true; }

      static constexpr bool
      is_unique() noexcept
      { return true; }

      static constexpr bool
      is_exhaustive() noexcept
      { return true; }

      static constexpr bool
      is_strided() noexcept
      { return true; }

      constexpr index_type
      stride(rank_type __i) const noexcept
      requires (extents_type::rank() > 0)
      {
	__glibcxx_assert(__i < extents_type::rank());
	return __mdspan::__rev_prod(_M_extents, __i);
      }

      template<typename _OExtents>
	requires (extents_type::rank() == _OExtents::rank())
	friend constexpr bool
	operator==(const mapping& __self, const mapping<_OExtents>& __other)
	noexcept
	{ return __self.extents() == __other.extents(); }

    private:
      template<typename _OExtents>
	constexpr explicit
	mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept
	: _M_extents(__oexts)
	{
	  static_assert(__mdspan::__representable_size<_OExtents, index_type>,
	    "The size of OtherExtents must be representable as index_type");
	  __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents));
	}

#if __glibcxx_submdspan
      template<typename... _Slices>
	requires (extents_type::rank() == sizeof...(_Slices))
	friend constexpr auto
	submdspan_mapping(const mapping& __mapping, _Slices... __slices)
	{ return __mdspan::__submdspan_mapping_impl(__mapping, __slices...); }
#endif // __glibcxx_submdspan

	[[no_unique_address]] extents_type _M_extents{};
    };

  namespace __mdspan
  {
    template<typename _Mp>
      concept __mapping_alike = requires
      {
	requires __is_extents<typename _Mp::extents_type>;
	{ _Mp::is_always_strided() } -> same_as<bool>;
	{ _Mp::is_always_exhaustive() } -> same_as<bool>;
	{ _Mp::is_always_unique() } -> same_as<bool>;
	bool_constant<_Mp::is_always_strided()>::value;
	bool_constant<_Mp::is_always_exhaustive()>::value;
	bool_constant<_Mp::is_always_unique()>::value;
      };

    template<typename _Mapping, typename... _Indices>
      constexpr typename _Mapping::index_type
      __linear_index_strides(const _Mapping& __m, _Indices... __indices)
      noexcept
      {
	using _IndexType = typename _Mapping::index_type;
	_IndexType __res = 0;
	if constexpr (sizeof...(__indices) > 0)
	  {
	    auto __update = [&, __pos = 0u](_IndexType __idx) mutable
	      {
		_GLIBCXX_DEBUG_ASSERT(cmp_less(__idx,
					       __m.extents().extent(__pos)));
		__res += __idx * __m.stride(__pos++);
	      };
	    (__update(__indices), ...);
	  }
	return __res;
      }
  }

  template<typename _Extents>
    class layout_stride::mapping
    {
    public:
      using extents_type = _Extents;
      using index_type = typename extents_type::index_type;
      using size_type = typename extents_type::size_type;
      using rank_type = typename extents_type::rank_type;
      using layout_type = layout_stride;

      static_assert(__mdspan::__representable_size<extents_type, index_type>,
	"The size of extents_type must be representable as index_type");

      constexpr
      mapping() noexcept
      {
	// The precondition is either statically asserted, or automatically
	// satisfied because dynamic extents are zero-initialized.
	size_t __stride = 1;
	for (size_t __i = extents_type::rank(); __i > 0; --__i)
	  {
	    _M_strides[__i - 1] = index_type(__stride);
	    __stride *= size_t(_M_extents.extent(__i - 1));
	  }
      }

      constexpr
      mapping(const mapping&) noexcept = default;

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr
	mapping(const extents_type& __exts,
		span<_OIndexType, extents_type::rank()> __strides) noexcept
	: _M_extents(__exts)
	{
	  for (size_t __i = 0; __i < extents_type::rank(); ++__i)
	    _M_strides[__i] = index_type(as_const(__strides[__i]));
	}

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr
	mapping(const extents_type& __exts,
		const array<_OIndexType, extents_type::rank()>& __strides)
	noexcept
	: mapping(__exts,
		  span<const _OIndexType, extents_type::rank()>(__strides))
	{ }

      template<__mdspan::__mapping_alike _StridedMapping>
	requires (is_constructible_v<extents_type,
				     typename _StridedMapping::extents_type>
		  && _StridedMapping::is_always_unique()
		  && _StridedMapping::is_always_strided())
	constexpr explicit(!(
	  is_convertible_v<typename _StridedMapping::extents_type, extents_type>
	  && __mdspan::__standardized_mapping<_StridedMapping>))
	mapping(const _StridedMapping& __other) noexcept
	: _M_extents(__other.extents())
	{
	  using _OIndexType = _StridedMapping::index_type;
	  using _OExtents = _StridedMapping::extents_type;

	  __glibcxx_assert(__mdspan::__offset(__other) == 0);
	  static_assert(__mdspan::__representable_size<_OExtents, index_type>,
	    "The size of StridedMapping::extents_type must be representable as"
	    " index_type");
	  if constexpr (cmp_greater(__gnu_cxx::__int_traits<_OIndexType>::__max,
				    __gnu_cxx::__int_traits<index_type>::__max))
	    __glibcxx_assert(!cmp_less(
		__gnu_cxx::__int_traits<index_type>::__max,
		__other.required_span_size())
	      && "other.required_span_size() must be representable"
		 " as index_type");
	  if constexpr (extents_type::rank() > 0)
	    for (size_t __i = 0; __i < extents_type::rank(); ++__i)
	      _M_strides[__i] = index_type(__other.stride(__i));
	}

      constexpr mapping&
      operator=(const mapping&) noexcept = default;

      constexpr const extents_type&
      extents() const noexcept { return _M_extents; }

      constexpr array<index_type, extents_type::rank()>
      strides() const noexcept
      {
	array<index_type, extents_type::rank()> __ret;
	for (size_t __i = 0; __i < extents_type::rank(); ++__i)
	  __ret[__i] = _M_strides[__i];
	return __ret;
      }

      constexpr index_type
      required_span_size() const noexcept
      {
	if (__mdspan::__empty(_M_extents))
	  return 0;

	index_type __ret = 1;
	for (size_t __i = 0; __i < extents_type::rank(); ++__i)
	  __ret += (_M_extents.extent(__i) - 1) * _M_strides[__i];
	return __ret;
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4314. Missing move in mdspan layout mapping::operator()
      template<__mdspan::__valid_index_type<index_type>... _Indices>
	requires (sizeof...(_Indices) == extents_type::rank())
	constexpr index_type
	operator()(_Indices... __indices) const noexcept
	{
	  return __mdspan::__linear_index_strides(*this,
	    static_cast<index_type>(std::move(__indices))...);
	}

      static constexpr bool
      is_always_unique() noexcept { return true; }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4266. layout_stride::mapping should treat empty mappings as exhaustive
      static constexpr bool
      is_always_exhaustive() noexcept
      {
	return (_Extents::rank() == 0) || __mdspan::__contains_zero(
	    __mdspan::__static_extents<extents_type>());
      }

      static constexpr bool
      is_always_strided() noexcept { return true; }

      static constexpr bool
      is_unique() noexcept { return true; }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4266. layout_stride::mapping should treat empty mappings as exhaustive
      constexpr bool
      is_exhaustive() const noexcept
      {
	if constexpr (!is_always_exhaustive())
	  {
	    auto __size = __mdspan::__size(_M_extents);
	    if(__size > 0)
	      return __size == required_span_size();
	  }
	return true;
      }

      static constexpr bool
      is_strided() noexcept { return true; }

      constexpr index_type
      stride(rank_type __r) const noexcept { return _M_strides[__r]; }

      template<__mdspan::__mapping_alike _OMapping>
	requires ((extents_type::rank() == _OMapping::extents_type::rank())
		  && _OMapping::is_always_strided())
	friend constexpr bool
	operator==(const mapping& __self, const _OMapping& __other) noexcept
	{
	  if (__self.extents() != __other.extents())
	    return false;
	  if constexpr (extents_type::rank() > 0)
	    for (size_t __i = 0; __i < extents_type::rank(); ++__i)
	      if (!cmp_equal(__self.stride(__i), __other.stride(__i)))
		return false;
	  return __mdspan::__offset(__other) == 0;
	}

    private:
#if __glibcxx_submdspan
      template<typename... _Slices>
	requires (extents_type::rank() == sizeof...(_Slices))
	friend constexpr auto
	submdspan_mapping(const mapping& __mapping, _Slices... __slices)
	{
	  if constexpr (sizeof...(_Slices) == 0)
	    return submdspan_mapping_result{__mapping, 0};
	  else
	    {
	      auto __offset = __mdspan::__suboffset(__mapping, __slices...);
	      auto __sub_exts = __mdspan::__subextents(__mapping.extents(), __slices...);
	      auto __sub_strides
		= __mdspan::__substrides<decltype(__sub_exts)>(__mapping, __slices...);
	      return submdspan_mapping_result{
		layout_stride::mapping(__sub_exts, __sub_strides), __offset};
	    }
	}
#endif

      using _Strides = typename __array_traits<index_type,
					       extents_type::rank()>::_Type;
      [[no_unique_address]] extents_type _M_extents;
      [[no_unique_address]] _Strides _M_strides;
    };

#ifdef __glibcxx_padded_layouts
  namespace __mdspan
  {
    constexpr size_t
    __least_multiple(size_t __x, size_t __y)
    {
      if (__x <= 1)
	return __y;
      return (__y / __x + (__y % __x != 0)) * __x ;
    }

    template<typename _IndexType>
    constexpr bool
    __is_representable_least_multiple(size_t __x, size_t __y)
    {
      constexpr auto __y_max = __gnu_cxx::__int_traits<_IndexType>::__max;
      if(std::cmp_greater(__y, __y_max))
	return false;

      if(__x <= 1)
	return true;

      auto __max_delta = __y_max - static_cast<_IndexType>(__y);
      auto __y_mod_x = __y % __x;
      auto __delta = (__y_mod_x == 0) ? size_t(0) : (__x - __y_mod_x);
      return std::cmp_less_equal(__delta, __max_delta);
    }

    template<typename _Extents, size_t _PaddingValue, typename _LayoutTraits,
	     size_t _Rank = _Extents::rank()>
      concept __valid_static_stride = (_Extents::rank() <= 1)
	|| (_PaddingValue == dynamic_extent)
	|| (_Extents::static_extent(_LayoutTraits::_S_ext_idx) == dynamic_extent)
	|| (__is_representable_least_multiple<size_t>(
	    _PaddingValue, _Extents::static_extent(_LayoutTraits::_S_ext_idx)));

    template<size_t _PaddedStride, typename _Extents,
	     typename _LayoutTraits>
      consteval bool
      __is_representable_padded_size()
      {
	using _IndexType = typename _Extents::index_type;
	auto __sta_exts = __static_extents<_Extents>(
	  _LayoutTraits::_S_unpad_begin, _LayoutTraits::_S_unpad_end);
	size_t __max = __gnu_cxx::__int_traits<_IndexType>::__max;
	return __static_quotient(__sta_exts, __max / _PaddedStride) != 0;
      }

    template<typename _Extents, size_t _PaddedStride, typename _LayoutTraits,
	     size_t _Rank = _Extents::rank()>
      concept __valid_padded_size = (_Rank <= 1)
	|| (_PaddedStride == dynamic_extent)
	|| (!__all_static(__static_extents<_Extents>()))
	|| (__contains_zero(__static_extents<_Extents>()))
	|| (__is_representable_padded_size<_PaddedStride, _Extents,
					   _LayoutTraits>());

    template<typename _Extents, typename _Stride, typename... _Indices>
      constexpr typename _Extents::index_type
      __linear_index_leftpad(const _Extents& __exts, _Stride __stride,
			     _Indices... __indices)
      {
	// i0 + stride*(i1 + extents.extent(1)*...)
	using _IndexType = typename _Extents::index_type;
	_IndexType __res = 0;
	if constexpr (sizeof...(__indices) > 0)
	  {
	    _IndexType __mult = 1;

	    auto __update_rest = [&, __pos = 1u](_IndexType __idx) mutable
	      {
		__res += __idx * __mult;
		__mult *= __exts.extent(__pos);
		++__pos;
	      };

	    auto __update = [&](_IndexType __idx, auto... __rest)
	      {
		__res += __idx;
		__mult = __stride.extent(0);
		(__update_rest(__rest), ...);
	      };
	    __update(__indices...);
	  }
	return __res;
      }

    template<typename _Extents, typename _Stride, typename... _Indices>
      constexpr typename _Extents::index_type
      __linear_index_rightpad(const _Extents& __exts, _Stride __stride,
			     _Indices... __indices)
      {
	// i[n-1] + stride*(i[n-2] + extents.extent(n-2])*...)
	using _IndexType = typename _Extents::index_type;
	_IndexType __res = 0;
	if constexpr (sizeof...(__indices) > 0)
	  {
	    _IndexType __mult = 1;
	    array<_IndexType, sizeof...(__indices)> __ind_arr{__indices...};

	    auto __update_rest = [&, __pos = __exts.rank()-1](_IndexType) mutable
	      {
		--__pos;
		__res += __ind_arr[__pos] * __mult;
		__mult *= __exts.extent(__pos);
	      };

	    auto __update = [&](_IndexType, auto... __rest)
	      {
		__res += __ind_arr[__exts.rank() - 1];
		__mult = __stride.extent(0);
		(__update_rest(__rest), ...);
	      };
	    __update(__indices...);
	  }
	return __res;
      }

    template<size_t _Rank>
      struct _LeftPaddedLayoutTraits
      {
	using _LayoutSame = layout_left;
	using _LayoutOther = layout_right;

	constexpr static const size_t _S_ext_idx = 0;
	constexpr static const size_t _S_stride_idx = 1;
	constexpr static const size_t _S_unpad_begin = 1;
	constexpr static const size_t _S_unpad_end = _Rank;

	template<typename _IndexType, size_t _StaticStride, size_t..._Extents>
	  constexpr static auto
	  _S_make_padded_extent(
	    extents<_IndexType, _StaticStride> __stride,
	    const extents<_IndexType, _Extents...>& __exts)
	  {
	    auto __impl = [&]<size_t... _Is>(integer_sequence<size_t, _Is...>)
	    {
	      return extents<_IndexType, _StaticStride,
			     (_Extents...[_Is + 1])...>{
		__stride.extent(0), __exts.extent(_Is + 1)...};
	    };
	    return __impl(make_index_sequence<sizeof...(_Extents) - 1>());
	  }
      };

    template<size_t _Rank>
      struct _RightPaddedLayoutTraits
      {
	using _LayoutSame = layout_right;
	using _LayoutOther = layout_left;

	constexpr static size_t _S_ext_idx = _Rank - 1;
	constexpr static size_t _S_stride_idx = _Rank - 2;
	constexpr static size_t _S_unpad_begin = 0;
	constexpr static size_t _S_unpad_end = _Rank - 1;

	template<typename _IndexType, size_t _StaticStride, size_t..._Extents>
	  constexpr static auto
	  _S_make_padded_extent(
	    extents<_IndexType, _StaticStride> __stride,
	    const extents<_IndexType, _Extents...>& __exts)
	  {
	    auto __impl = [&]<size_t... _Is>(integer_sequence<size_t, _Is...>)
	    {
	      return extents<_IndexType, (_Extents...[_Is])..., _StaticStride>{
		__exts.extent(_Is)..., __stride.extent(0)};
	    };
	    return __impl(make_index_sequence<sizeof...(_Extents) - 1>());
	  }
      };

    template<size_t _PaddingValue, typename _Extents, typename _LayoutTraits>
      class _PaddedStorage
      {
	using _LayoutSame = typename _LayoutTraits::_LayoutSame;

      public:
	using _IndexType = typename _Extents::index_type;
	constexpr static size_t _S_rank = _Extents::rank();

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4372. Weaken Mandates: for dynamic padding values in padded layouts
	static_assert((_PaddingValue == dynamic_extent)
	    || (cmp_less_equal(_PaddingValue,
			       __gnu_cxx::__int_traits<_IndexType>::__max)),
	  "padding_value must be representable as index_type");

	static_assert(__representable_size<_Extents, _IndexType>,
	  "The size of extents_type must be representable as index_type");

	static_assert(__valid_static_stride<_Extents, _PaddingValue,
					    _LayoutTraits>,
	  "The padded stride must be representable as size_t");

	static constexpr size_t _S_static_stride = [] consteval
	{
	  constexpr size_t __rank = _Extents::rank();
	  if constexpr (__rank <= 1)
	    return 0;
	  else
	    {
	      constexpr size_t __ext_idx = _LayoutTraits::_S_ext_idx;
	      constexpr size_t __sta_ext = _Extents::static_extent(__ext_idx);
	      if constexpr (__sta_ext == 0)
		return size_t(0);
	      else if constexpr (_PaddingValue == dynamic_extent
		  || __sta_ext == dynamic_extent)
		return dynamic_extent;
	      else
		return __least_multiple(_PaddingValue, __sta_ext);
	    }
	}();

	static_assert(_S_static_stride == dynamic_extent
	  || cmp_less_equal(_S_static_stride,
			    __gnu_cxx::__int_traits<_IndexType>::__max),
	  "Padded stride must be representable as index_type");

	static_assert(__valid_padded_size<_Extents, _S_static_stride,
					  _LayoutTraits>);

	constexpr
	_PaddedStorage() noexcept
	{
	  if constexpr (_S_rank > 1)
	    if constexpr (_S_static_stride == dynamic_extent
			  && _S_static_padextent() != dynamic_extent)
	      _M_stride = _Stride{_S_static_padextent()};
	}

	constexpr explicit
	_PaddedStorage(const _Extents& __exts)
	: _M_extents(__exts)
	{
	  if constexpr (!__all_static(__static_extents<_Extents>()))
	    __glibcxx_assert(__is_representable_extents(_M_extents));

	  if constexpr (_S_rank > 1)
	    {
	      _IndexType __stride;
	      if constexpr (_PaddingValue == dynamic_extent)
		__stride = _M_padextent();
	      else if constexpr (_S_static_padextent() != dynamic_extent)
		return;
	      else
		{
		  __glibcxx_assert(
		      __is_representable_least_multiple<_IndexType>(
			_PaddingValue, _M_padextent()));

		  __stride = static_cast<_IndexType>(
		    __least_multiple(_PaddingValue, _M_padextent()));

		  __glibcxx_assert(__is_representable_extents(
		      _LayoutTraits::_S_make_padded_extent(
			std::dextents<_IndexType, 1>{__stride},
			_M_extents)));
		}
	      _M_stride = _Stride{__stride};
	    }
	}

	constexpr explicit
	_PaddedStorage(const _Extents& __exts, _IndexType __pad)
	: _M_extents(__exts)
	{
	  if constexpr (_PaddingValue != dynamic_extent)
	    __glibcxx_assert(cmp_equal(_PaddingValue, __pad));
	  if constexpr (_S_rank > 1 && _S_static_stride == dynamic_extent)
	    {
	      __glibcxx_assert(
		__is_representable_least_multiple<_IndexType>(
		  __pad, _M_padextent()));

	      _M_stride = _Stride{static_cast<_IndexType>(
		__least_multiple(__pad, _M_padextent()))};

	      __glibcxx_assert(__is_representable_extents(
		_LayoutTraits::_S_make_padded_extent(
		  _M_stride, _M_extents)));
	    }
	}

	template<typename _OExtents>
	  constexpr explicit
	  _PaddedStorage(
	      const typename _LayoutSame::template mapping<_OExtents>& __other)
	  : _PaddedStorage(_Extents(__other.extents()))
	  {
	    constexpr size_t __stride_idx = _LayoutTraits::_S_stride_idx;
	    constexpr size_t __ext_idx = _LayoutTraits::_S_ext_idx;
	    if constexpr (_S_rank > 1 && _PaddingValue != dynamic_extent)
	      {
		static_assert(_S_static_stride == dynamic_extent
		    || _OExtents::static_extent(__ext_idx) == dynamic_extent
		    || _S_static_stride == _OExtents::static_extent(__ext_idx),
		  "The padded stride must be compatible with other");

		if constexpr (_S_static_stride == dynamic_extent
		    || _OExtents::static_extent(__stride_idx) == dynamic_extent)
		  __glibcxx_assert(std::cmp_equal(_M_padstride(),
						  _M_padextent()));
	      }
	  }

	template<typename _OExtents>
	  constexpr explicit
	  _PaddedStorage(const typename layout_stride::mapping<_OExtents>&
			 __other)
	  : _M_extents(__other.extents())
	  {
	    __glibcxx_assert(cmp_less_equal(__other.required_span_size(),
					    __gnu_cxx::__int_traits<_IndexType>
						     ::__max));

	    constexpr size_t __stride_idx = _LayoutTraits::_S_stride_idx;
	    if constexpr (_S_rank > 1)
	      {
		if constexpr (_PaddingValue != dynamic_extent)
		  __glibcxx_assert(cmp_equal(__other.stride(__stride_idx),
					     _M_calc_padstride())
		    && "The padded stride must be compatible with other");
		if constexpr (_S_static_stride == dynamic_extent)
		  _M_stride = _Stride{__other.stride(__stride_idx)};
	      }
	  }

	template<typename _SamePaddedMapping>
	  constexpr explicit
	  _PaddedStorage(_LayoutTraits::_LayoutSame,
			 const _SamePaddedMapping& __other)
	  : _M_extents(__other.extents())
	  {
	    if constexpr (_S_rank > 1)
	      {
		static_assert(_PaddingValue == dynamic_extent
		    || _SamePaddedMapping::padding_value  == dynamic_extent
		    || _PaddingValue == _SamePaddedMapping::padding_value,
		  "If neither PaddingValue is dynamic_extent, then they must "
		  "be equal");

		constexpr size_t __stride_idx = _LayoutTraits::_S_stride_idx;
		if constexpr (_PaddingValue != dynamic_extent)
		  __glibcxx_assert(cmp_equal(__other.stride(__stride_idx),
					     _M_calc_padstride())
		    && "The padded stride must be compatible with other");
		if constexpr (_S_static_stride == dynamic_extent)
		  _M_stride = _Stride{__other.stride(__stride_idx)};
	      }
	    __glibcxx_assert(cmp_less_equal(__other.required_span_size(),
		__gnu_cxx::__int_traits<_IndexType>::__max));
	  }

	template<typename _OtherPaddedMapping>
	  constexpr explicit
	  _PaddedStorage(_LayoutTraits::_LayoutOther,
			 const _OtherPaddedMapping& __other) noexcept
	  : _M_extents(__other.extents())
	  {
	    __glibcxx_assert(cmp_less_equal(__other.required_span_size(),
		__gnu_cxx::__int_traits<_IndexType>::__max));
	  }

	static constexpr bool
	_M_is_always_exhaustive() noexcept
	{
	  if constexpr (_S_rank <= 1)
	    return true;
	  else
	    return _S_static_padextent() != dynamic_extent
		   && _S_static_stride != dynamic_extent
		   && _S_static_padextent() == _S_static_stride;
	}

	constexpr bool
	_M_is_exhaustive() const noexcept
	{
	  if constexpr (_M_is_always_exhaustive())
	    return true;
	  else
	    return cmp_equal(_M_padextent(), _M_padstride());
	}

	constexpr static size_t
	_S_static_padextent() noexcept
	{ return _Extents::static_extent(_LayoutTraits::_S_ext_idx); }

	constexpr _IndexType
	_M_padextent() const noexcept
	{ return _M_extents.extent(_LayoutTraits::_S_ext_idx); }

	constexpr _IndexType
	_M_calc_padstride() const noexcept
	{
	  if constexpr (_S_static_stride != dynamic_extent)
	    return _S_static_stride;
	  else if constexpr (_PaddingValue != dynamic_extent)
	    return __least_multiple(_PaddingValue, _M_padextent());
	  else
	    return _M_padextent();
	}

	constexpr _IndexType
	_M_padstride() const noexcept
	{ return _M_stride.extent(0); }

	constexpr _IndexType
	_M_required_span_size() const noexcept
	{
	  if constexpr (_S_rank == 0)
	    return 1;
	  else if (__mdspan::__empty(_M_extents))
	    return 0;
	  else
	    {
	      size_t __stride = static_cast<size_t>(_M_padstride());
	      size_t __prod_rest = __mdspan::__fwd_prod(_M_extents,
		_LayoutTraits::_S_unpad_begin, _LayoutTraits::_S_unpad_end);
	      size_t __delta = _M_padstride() - _M_padextent();
	      return static_cast<_IndexType>(__stride * __prod_rest - __delta);
	    }
	}

	template<typename _SamePaddedMapping>
	  constexpr bool
	  _M_equal(const _SamePaddedMapping& __other) const noexcept
	  {
	    return _M_extents == __other.extents()
	      && (_S_rank < 2
		|| cmp_equal(_M_stride.extent(0),
			     __other.stride(_LayoutTraits::_S_stride_idx)));
	  }

	using _Stride = std::extents<_IndexType, _S_static_stride>;
	[[no_unique_address]] _Stride _M_stride;
	[[no_unique_address]] _Extents _M_extents;
      };
  }

  template<size_t _PaddingValue>
    template<typename _Extents>
      class layout_left_padded<_PaddingValue>::mapping
      {
      public:
	static constexpr size_t padding_value = _PaddingValue;

	using extents_type = _Extents;
	using index_type = typename extents_type::index_type;
	using size_type = typename extents_type::size_type;
	using rank_type = typename extents_type::rank_type;
	using layout_type = layout_left_padded<padding_value>;

      private:
	static constexpr size_t _S_rank = extents_type::rank();
	using _PaddedStorage = __mdspan::_PaddedStorage<_PaddingValue,
	      _Extents, __mdspan::_LeftPaddedLayoutTraits<_S_rank>>;
	[[no_unique_address]] _PaddedStorage _M_storage;

	consteval friend size_t
	__mdspan::__get_static_stride<mapping>();

	constexpr index_type
	_M_extent(size_t __r) const noexcept
	{ return _M_storage._M_extents.extent(__r); }

	constexpr index_type
	_M_padstride() const noexcept
	{ return _M_storage._M_stride.extent(0); }

      public:
	constexpr
	mapping() noexcept
	{ }

	constexpr
	mapping(const mapping&) noexcept = default;

	constexpr
	mapping(const extents_type& __exts)
	: _M_storage(__exts)
	{ }

	template<__mdspan::__valid_index_type<index_type> _OIndexType>
	  constexpr
	  mapping(const extents_type& __exts, _OIndexType __pad)
	  : _M_storage(__exts,
	      __mdspan::__index_type_cast<index_type>(std::move(__pad)))
	  { }

	template<typename _OExtents>
	  requires is_constructible_v<extents_type, _OExtents>
	  constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	  mapping(const layout_left::mapping<_OExtents>& __other)
	  : _M_storage(__other)
	  { }

	template<typename _OExtents>
	  requires is_constructible_v<_OExtents, extents_type>
	  constexpr explicit(!(_OExtents::rank() == 0
			       && is_convertible_v<_OExtents, extents_type>))
	  mapping(const typename layout_stride::mapping<_OExtents>& __other)
	  : _M_storage(__other)
	  { __glibcxx_assert(*this == __other); }

	template<typename _LeftPaddedMapping>
	  requires __mdspan::__is_left_padded_mapping<_LeftPaddedMapping>
	      && is_constructible_v<extents_type,
				    typename _LeftPaddedMapping::extents_type>
	  constexpr explicit(
	   !is_convertible_v<typename _LeftPaddedMapping::extents_type,
			     extents_type>
	   || _S_rank > 1 && (padding_value != dynamic_extent
		|| _LeftPaddedMapping::padding_value == dynamic_extent))
	  mapping(const _LeftPaddedMapping& __other)
	  : _M_storage(layout_left{}, __other)
	  { }

	template<typename _RightPaddedMapping>
	  requires (__mdspan::__is_right_padded_mapping<_RightPaddedMapping>
	      || __mdspan::__mapping_of<layout_right, _RightPaddedMapping>)
	    && (_S_rank <= 1)
	    && is_constructible_v<extents_type,
				  typename _RightPaddedMapping::extents_type>
	  constexpr explicit(!is_convertible_v<
	      typename _RightPaddedMapping::extents_type, extents_type>)
	  mapping(const _RightPaddedMapping& __other) noexcept
	  : _M_storage(layout_right{}, __other)
	  { }

	constexpr mapping&
	operator=(const mapping&) noexcept = default;

	constexpr const extents_type&
	extents() const noexcept { return _M_storage._M_extents; }

	constexpr array<index_type, _S_rank>
	strides() const noexcept
	{
	  array<index_type, _S_rank> __ret;
	  if constexpr (_S_rank > 0)
	    __ret[0] = 1;
	  if constexpr (_S_rank > 1)
	    __ret[1] = _M_padstride();
	  if constexpr (_S_rank > 2)
	    for(size_t __i = 2; __i < _S_rank; ++__i)
	      __ret[__i] = __ret[__i - 1] * _M_extent(__i - 1);
	  return __ret;
	}

	constexpr index_type
	required_span_size() const noexcept
	{ return _M_storage._M_required_span_size(); }

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4314. Missing move in mdspan layout mapping::operator()
	template<__mdspan::__valid_index_type<index_type>... _Indices>
	  requires (sizeof...(_Indices) == _S_rank)
	  constexpr index_type
	  operator()(_Indices... __indices) const noexcept
	  {
	    return __mdspan::__linear_index_leftpad(
	      extents(), _M_storage._M_stride,
	      static_cast<index_type>(std::move(__indices))...);
	  }

	static constexpr bool
	is_always_exhaustive() noexcept
	{ return _PaddedStorage::_M_is_always_exhaustive(); }

	constexpr bool
	is_exhaustive() noexcept
	{ return _M_storage._M_is_exhaustive(); }

	static constexpr bool
	is_always_unique() noexcept { return true; }

	static constexpr bool
	is_unique() noexcept { return true; }

	static constexpr bool
	is_always_strided() noexcept { return true; }

	static constexpr bool
	is_strided() noexcept { return true; }

	constexpr index_type
	stride(rank_type __r) const noexcept
	{
	  __glibcxx_assert(__r < _S_rank);
	  if (__r == 0)
	    return 1;
	  else
	    return static_cast<index_type>(
	      static_cast<size_t>(_M_padstride()) *
	      static_cast<size_t>(__mdspan::__fwd_prod(extents(), 1, __r)));
	}

	template<typename _LeftpadMapping>
	  requires(__mdspan::__is_left_padded_mapping<_LeftpadMapping>
		   && _LeftpadMapping::extents_type::rank() == _S_rank)
	  friend constexpr bool
	  operator==(const mapping& __self, const _LeftpadMapping& __other)
	  noexcept
	  { return __self._M_storage._M_equal(__other); }

      private:
#if __glibcxx_submdspan
	template<typename... _Slices>
	  requires (extents_type::rank() == sizeof...(_Slices))
	  friend constexpr auto
	  submdspan_mapping(const mapping& __mapping, _Slices... __slices)
	  { return __mdspan::__submdspan_mapping_impl(__mapping, __slices...); }
#endif // __glibcxx_submdspan
      };

  template<size_t _PaddingValue>
    template<typename _Extents>
      class layout_right_padded<_PaddingValue>::mapping {
      public:
	static constexpr size_t padding_value = _PaddingValue;
	using extents_type = _Extents;
	using index_type = typename extents_type::index_type;
	using size_type = typename extents_type::size_type;
	using rank_type = typename extents_type::rank_type;
	using layout_type = layout_right_padded<_PaddingValue>;

      private:
	static constexpr size_t _S_rank = extents_type::rank();
	using _PaddedStorage = __mdspan::_PaddedStorage<_PaddingValue,
	      _Extents, __mdspan::_RightPaddedLayoutTraits<_S_rank>>;
	[[no_unique_address]] _PaddedStorage _M_storage;

	consteval friend size_t
	__mdspan::__get_static_stride<mapping>();

	constexpr index_type
	_M_extent(size_t __r) const noexcept
	{ return _M_storage._M_extents.extent(__r); }

	constexpr index_type
	_M_padstride() const noexcept
	{ return _M_storage._M_stride.extent(0); }

      public:
	constexpr
	mapping() noexcept
	{ }

	constexpr
	mapping(const mapping&) noexcept = default;

	constexpr
	mapping(const extents_type& __exts)
	: _M_storage(__exts)
	{ }

	template<__mdspan::__valid_index_type<index_type> _OIndexType>
	  constexpr
	  mapping(const extents_type& __exts, _OIndexType __pad)
	  : _M_storage(__exts,
	      __mdspan::__index_type_cast<index_type>(std::move(__pad)))
	  { }

	template<typename _OExtents>
	  requires is_constructible_v<extents_type, _OExtents>
	  constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
	  mapping(const layout_right::mapping<_OExtents>& __other)
	  : _M_storage(__other)
	  { }

	template<typename _OExtents>
	  requires is_constructible_v<_OExtents, extents_type>
	  constexpr explicit(!(_OExtents::rank() == 0
			       && is_convertible_v<_OExtents, extents_type>))
	  mapping(const typename layout_stride::mapping<_OExtents>& __other)
	  : _M_storage(__other)
	  { __glibcxx_assert(*this == __other); }

	template<typename _RightPaddedMapping>
	  requires __mdspan::__is_right_padded_mapping<_RightPaddedMapping>
	      && is_constructible_v<extents_type,
				    typename _RightPaddedMapping::extents_type>
	  constexpr explicit(
	    !is_convertible_v<typename _RightPaddedMapping::extents_type,
			      extents_type>
	    || _S_rank > 1 && (padding_value != dynamic_extent
		 || _RightPaddedMapping::padding_value == dynamic_extent))
	  mapping(const _RightPaddedMapping& __other)
	  : _M_storage(layout_right{}, __other)
	  { }

	template<typename _LeftPaddedMapping>
	  requires (__mdspan::__is_left_padded_mapping<_LeftPaddedMapping>
	      || __mdspan::__mapping_of<layout_left, _LeftPaddedMapping>)
	    && (_S_rank <= 1)
	    && is_constructible_v<extents_type,
				  typename _LeftPaddedMapping::extents_type>
	  constexpr explicit(!is_convertible_v<
	      typename _LeftPaddedMapping::extents_type, extents_type>)
	  mapping(const _LeftPaddedMapping& __other) noexcept
	  : _M_storage(layout_left{}, __other)
	  { }

	constexpr mapping& operator=(const mapping&) noexcept = default;

	constexpr const extents_type&
	extents() const noexcept { return _M_storage._M_extents; }

	constexpr array<index_type, _S_rank>
	strides() const noexcept
	{
	  array<index_type, _S_rank> __ret;
	  if constexpr (_S_rank > 0)
	    __ret[_S_rank - 1] = 1;
	  if constexpr (_S_rank > 1)
	    __ret[_S_rank - 2] = _M_padstride();
	  if constexpr (_S_rank > 2)
	    for(size_t __i = _S_rank - 2; __i > 0; --__i)
	      __ret[__i - 1] = __ret[__i] * _M_extent(__i);
	  return __ret;
	}

	constexpr index_type
	required_span_size() const noexcept
	{ return _M_storage._M_required_span_size(); }

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4314. Missing move in mdspan layout mapping::operator()
	template<__mdspan::__valid_index_type<index_type>... _Indices>
	  requires (sizeof...(_Indices) == _S_rank)
	  constexpr index_type
	  operator()(_Indices... __indices) const noexcept
	  {
	    return __mdspan::__linear_index_rightpad(
	      extents(), _M_storage._M_stride,
	      static_cast<index_type>(std::move(__indices))...);
	  }

	static constexpr bool
	is_always_exhaustive() noexcept
	{ return _PaddedStorage::_M_is_always_exhaustive(); }

	constexpr bool
	is_exhaustive() noexcept
	{ return _M_storage._M_is_exhaustive(); }

	static constexpr bool
	is_always_unique() noexcept { return true; }

	static constexpr bool
	is_unique() noexcept { return true; }

	static constexpr bool
	is_always_strided() noexcept { return true; }

	static constexpr bool
	is_strided() noexcept { return true; }

	constexpr index_type
	stride(rank_type __r) const noexcept
	{
	  __glibcxx_assert(__r < _S_rank);
	  if constexpr (_S_rank <= 1)
	    return 1;
	  else if (__r == _S_rank - 1)
	    return 1;
	  else if (__r == _S_rank - 2)
	    return _M_padstride();
	  else
	    return static_cast<index_type>(
	      static_cast<size_t>(_M_padstride()) *
	      static_cast<size_t>(__mdspan::__fwd_prod(
		  extents(), __r + 1, _S_rank - 1)));
	}

	template<typename _RightPaddedMapping>
	  requires(__mdspan::__is_right_padded_mapping<_RightPaddedMapping>
		   && _RightPaddedMapping::extents_type::rank() == _S_rank)
	  friend constexpr bool
	  operator==(const mapping& __self, const _RightPaddedMapping& __other)
	  noexcept
	  { return __self._M_storage._M_equal(__other); }

#if __glibcxx_submdspan
      private:
	template<typename... _Slices>
	  requires (extents_type::rank() == sizeof...(_Slices))
	  friend constexpr auto
	  submdspan_mapping(const mapping& __mapping, _Slices... __slices)
	  { return __mdspan::__submdspan_mapping_impl(__mapping, __slices...); }
#endif // __glibcxx_submdspan
      };
#endif // __glibcxx_padded_layouts

  template<typename _ElementType>
    struct default_accessor
    {
      static_assert(!is_array_v<_ElementType>,
	"ElementType must not be an array type");
      static_assert(!is_abstract_v<_ElementType>,
	"ElementType must not be an abstract class type");

      using offset_policy = default_accessor;
      using element_type = _ElementType;
      using reference = element_type&;
      using data_handle_type = element_type*;

      constexpr
      default_accessor() noexcept = default;

      template<typename _OElementType>
	requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
	constexpr
	default_accessor(default_accessor<_OElementType>) noexcept
	{ }

      constexpr reference
      access(data_handle_type __p, size_t __i) const noexcept
      { return __p[__i]; }

      constexpr data_handle_type
      offset(data_handle_type __p, size_t __i) const noexcept
      { return __p + __i; }
    };

#ifdef __glibcxx_aligned_accessor
  template<typename _ElementType, size_t _ByteAlignment>
    struct aligned_accessor
    {
      static_assert(has_single_bit(_ByteAlignment),
	"ByteAlignment must be a power of two");
      static_assert(_ByteAlignment >= alignof(_ElementType));

      using offset_policy = default_accessor<_ElementType>;
      using element_type = _ElementType;
      using reference = element_type&;
      using data_handle_type = element_type*;

      static constexpr size_t byte_alignment = _ByteAlignment;

      constexpr
      aligned_accessor() noexcept = default;

      template<typename _OElementType, size_t _OByteAlignment>
	requires (_OByteAlignment >= byte_alignment)
	    && is_convertible_v<_OElementType(*)[], element_type(*)[]>
	constexpr
	aligned_accessor(aligned_accessor<_OElementType, _OByteAlignment>)
	noexcept
	{ }

      template<typename _OElementType>
	requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
	constexpr explicit
	aligned_accessor(default_accessor<_OElementType>) noexcept
	{ }

      template<typename _OElementType>
	requires is_convertible_v<element_type(*)[], _OElementType(*)[]>
	constexpr
	operator default_accessor<_OElementType>() const noexcept
	{ return {}; }

      constexpr reference
      access(data_handle_type __p, size_t __i) const noexcept
      { return std::assume_aligned<byte_alignment>(__p)[__i]; }

      constexpr typename offset_policy::data_handle_type
      offset(data_handle_type __p, size_t __i) const noexcept
      { return std::assume_aligned<byte_alignment>(__p) + __i; }
    };
#endif

  template<typename _ElementType, typename _Extents,
	   typename _LayoutPolicy = layout_right,
	   typename _AccessorPolicy = default_accessor<_ElementType>>
    class mdspan
    {
      static_assert(!is_array_v<_ElementType>,
	"ElementType must not be an array type");
      static_assert(!is_abstract_v<_ElementType>,
	"ElementType must not be an abstract class type");
      static_assert(__mdspan::__is_extents<_Extents>,
	"Extents must be a specialization of std::extents");
      static_assert(is_same_v<_ElementType,
			      typename _AccessorPolicy::element_type>);

    public:
      using extents_type = _Extents;
      using layout_type = _LayoutPolicy;
      using accessor_type = _AccessorPolicy;
      using mapping_type = typename layout_type::template mapping<extents_type>;
      using element_type = _ElementType;
      using value_type = remove_cv_t<element_type>;
      using index_type = typename extents_type::index_type;
      using size_type = typename extents_type::size_type;
      using rank_type = typename extents_type::rank_type;
      using data_handle_type = typename accessor_type::data_handle_type;
      using reference = typename accessor_type::reference;

      static constexpr rank_type
      rank() noexcept { return extents_type::rank(); }

      static constexpr rank_type
      rank_dynamic() noexcept { return extents_type::rank_dynamic(); }

      static constexpr size_t
      static_extent(rank_type __r) noexcept
      { return extents_type::static_extent(__r); }

      constexpr index_type
      extent(rank_type __r) const noexcept { return extents().extent(__r); }

      constexpr
      mdspan()
      requires (rank_dynamic() > 0)
	  && is_default_constructible_v<data_handle_type>
	  && is_default_constructible_v<mapping_type>
	  && is_default_constructible_v<accessor_type> = default;

      constexpr
      mdspan(const mdspan& __other) = default;

      constexpr
      mdspan(mdspan&& __other) = default;

      template<__mdspan::__valid_index_type<index_type>... _OIndexTypes>
	requires (sizeof...(_OIndexTypes) == rank()
		   || sizeof...(_OIndexTypes) == rank_dynamic())
		 && is_constructible_v<mapping_type, extents_type>
		 && is_default_constructible_v<accessor_type>
	constexpr explicit
	mdspan(data_handle_type __handle, _OIndexTypes... __exts)
	: _M_accessor(),
	  _M_mapping(_Extents(static_cast<index_type>(std::move(__exts))...)),
	  _M_handle(std::move(__handle))
	{ }

      template<typename _OIndexType, size_t _Nm>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
		 && (_Nm == rank() || _Nm == rank_dynamic())
		 && is_constructible_v<mapping_type, extents_type>
		 && is_default_constructible_v<accessor_type>
	constexpr explicit(_Nm != rank_dynamic())
	mdspan(data_handle_type __handle, span<_OIndexType, _Nm> __exts)
	: _M_accessor(), _M_mapping(extents_type(__exts)),
	  _M_handle(std::move(__handle))
	{ }

      template<typename _OIndexType, size_t _Nm>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
		 && (_Nm == rank() || _Nm == rank_dynamic())
		 && is_constructible_v<mapping_type, extents_type>
		 && is_default_constructible_v<accessor_type>
	constexpr explicit(_Nm != rank_dynamic())
	mdspan(data_handle_type __handle, const array<_OIndexType, _Nm>& __exts)
	: _M_accessor(), _M_mapping(extents_type(__exts)),
	  _M_handle(std::move(__handle))
	{ }

      constexpr
      mdspan(data_handle_type __handle, const extents_type& __exts)
      requires is_constructible_v<mapping_type, const extents_type&>
	       && is_default_constructible_v<accessor_type>
      : _M_accessor(), _M_mapping(__exts), _M_handle(std::move(__handle))
      { }

      constexpr
      mdspan(data_handle_type __handle, const mapping_type& __mapping)
      requires is_default_constructible_v<accessor_type>
      : _M_accessor(), _M_mapping(__mapping), _M_handle(std::move(__handle))
      { }

      constexpr
      mdspan(data_handle_type __handle, const mapping_type& __mapping,
	     const accessor_type& __accessor)
      : _M_accessor(__accessor), _M_mapping(__mapping),
	_M_handle(std::move(__handle))
      { }

      template<typename _OElementType, typename _OExtents, typename _OLayout,
	       typename _OAccessor>
	requires is_constructible_v<mapping_type,
	      const typename _OLayout::template mapping<_OExtents>&>
	  && is_constructible_v<accessor_type, const _OAccessor&>
	constexpr explicit(!is_convertible_v<
	    const typename _OLayout::template mapping<_OExtents>&, mapping_type>
	  || !is_convertible_v<const _OAccessor&, accessor_type>)
	mdspan(const mdspan<_OElementType, _OExtents, _OLayout, _OAccessor>&
		 __other)
	: _M_accessor(__other.accessor()), _M_mapping(__other.mapping()),
	  _M_handle(__other.data_handle())
	{
	  static_assert(is_constructible_v<data_handle_type,
	      const typename _OAccessor::data_handle_type&>);
	  static_assert(is_constructible_v<extents_type, _OExtents>);
	}

      constexpr mdspan&
      operator=(const mdspan& __other) = default;

      constexpr mdspan&
      operator=(mdspan&& __other) = default;

      template<__mdspan::__valid_index_type<index_type>... _OIndexTypes>
	requires (sizeof...(_OIndexTypes) == rank())
	constexpr reference
	operator[](_OIndexTypes... __indices) const
	{
	  if constexpr (rank() == 0)
	    return _M_accessor.access(_M_handle, _M_mapping());
	  else if constexpr (!(is_same_v<_OIndexTypes, index_type> && ...))
	    return operator[](
	      __mdspan::__index_type_cast<index_type>(std::move(__indices))...);
	  else
	   {
	     auto __is_multi_index = [&]<size_t... _Counts>(index_sequence<_Counts...>)
	     { return ((__indices < extents().extent(_Counts)) && ...); };

	     __glibcxx_assert(__is_multi_index(make_index_sequence<rank()>()));
	     return _M_accessor.access(_M_handle, _M_mapping(__indices...));
	   }
	}

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr reference
	operator[](span<_OIndexType, rank()> __indices) const
	{
	  auto __call = [&]<size_t... _Counts>(index_sequence<_Counts...>)
	    -> reference
	    {
	       return operator[](
		 __mdspan::__index_type_cast<index_type>(as_const(__indices[_Counts]))...);
	    };
	  return __call(make_index_sequence<rank()>());
	}

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr reference
	operator[](const array<_OIndexType, rank()>& __indices) const
	{ return operator[](span<const _OIndexType, rank()>(__indices)); }

#if __cplusplus > 202302L
      template<__mdspan::__valid_index_type<index_type>... _OIndexTypes>
	requires (sizeof...(_OIndexTypes) == rank())
	constexpr reference
	at(_OIndexTypes... __indices) const
	{
	  if constexpr (rank() == 0)
	    return _M_accessor.access(_M_handle, _M_mapping());
	  else if constexpr (!(is_integral_v<_OIndexTypes> && ...))
	    return at(__index_int_t<_OIndexTypes>(std::move(__indices))...);
	  else
	   {
	     auto __check_bound = [&]<typename _OIntType>(size_t __dim, _OIntType __index)
	     {
	       if constexpr (is_signed_v<_OIntType>)
		 if (__index < 0)
		   std::__throw_out_of_range_fmt(
		     __N("mdspan::at: %zuth index is negative"), __dim);

	       const auto __ext = extents().extent(__dim);
	       if (std::cmp_greater_equal(__index, __ext))
		 std::__throw_out_of_range_fmt(
		   __N("mdspan::at: %zuth index (which is %zu)"
		       " >= extent(%zu) (which is %zu)"),
		   __dim, size_t(__index), __dim, size_t(__ext));
	     };
	     auto __check_bounds = [&]<size_t... _Counts>(index_sequence<_Counts...>)
	     { (__check_bound(_Counts, __indices), ...); };

	     __check_bounds(make_index_sequence<rank()>());
	     auto __index = _M_mapping(static_cast<index_type>(__indices)...);
	     return _M_accessor.access(_M_handle, __index);
	   }
	}

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr reference
	at(span<_OIndexType, rank()> __indices) const
	{
	  auto __call = [&]<size_t... _Counts>(index_sequence<_Counts...>)
	    -> reference
	    {
	      return at(
		__index_int_t<_OIndexType>(as_const(__indices[_Counts]))...);
	    };
	  return __call(make_index_sequence<rank()>());
	}

      template<typename _OIndexType>
	requires __mdspan::__valid_index_type<const _OIndexType&, index_type>
	constexpr reference
	at(const array<_OIndexType, rank()>& __indices) const
	{ return at(span<const _OIndexType, rank()>(__indices)); }
#endif // C++26

      constexpr size_type
      size() const noexcept
      {
	__glibcxx_assert(cmp_less_equal(_M_mapping.required_span_size(),
					__gnu_cxx::__int_traits<size_t>
						 ::__max));
	return size_type(__mdspan::__size(extents()));
      }

      [[nodiscard]]
      constexpr bool
      empty() const noexcept
      { return __mdspan::__empty(extents()); }

      friend constexpr void
      swap(mdspan& __x, mdspan& __y) noexcept
      {
	using std::swap;
	swap(__x._M_mapping, __y._M_mapping);
	swap(__x._M_accessor, __y._M_accessor);
	swap(__x._M_handle, __y._M_handle);
      }

      constexpr const extents_type&
      extents() const noexcept { return _M_mapping.extents(); }

      constexpr const data_handle_type&
      data_handle() const noexcept { return _M_handle; }

      constexpr const mapping_type&
      mapping() const noexcept { return _M_mapping; }

      constexpr const accessor_type&
      accessor() const noexcept { return _M_accessor; }

      // Strengthened noexcept for all `is_*` methods.

      static constexpr bool
      is_always_unique() noexcept(noexcept(mapping_type::is_always_unique()))
      { return mapping_type::is_always_unique(); }

      static constexpr bool
      is_always_exhaustive()
      noexcept(noexcept(mapping_type::is_always_exhaustive()))
      { return mapping_type::is_always_exhaustive(); }

      static constexpr bool
      is_always_strided()
      noexcept(noexcept(mapping_type::is_always_strided()))
      { return mapping_type::is_always_strided(); }

      constexpr bool
      is_unique() const noexcept(noexcept(_M_mapping.is_unique()))
      { return _M_mapping.is_unique(); }

      constexpr bool
      is_exhaustive() const noexcept(noexcept(_M_mapping.is_exhaustive()))
      { return _M_mapping.is_exhaustive(); }

      constexpr bool
      is_strided() const noexcept(noexcept(_M_mapping.is_strided()))
      { return _M_mapping.is_strided(); }

      constexpr index_type
      stride(rank_type __r) const { return _M_mapping.stride(__r); }

    private:
      template<typename _OIndexType>
	using __index_int_t = std::__conditional_t<
	  is_integral_v<_OIndexType>, _OIndexType, index_type>;

      [[no_unique_address]] accessor_type _M_accessor = accessor_type();
      [[no_unique_address]] mapping_type _M_mapping = mapping_type();
      [[no_unique_address]] data_handle_type _M_handle = data_handle_type();
    };

  template<typename _CArray>
    requires is_array_v<_CArray> && (rank_v<_CArray> == 1)
    mdspan(_CArray&)
    -> mdspan<remove_all_extents_t<_CArray>,
	      extents<size_t, extent_v<_CArray, 0>>>;

  template<typename _Pointer>
    requires is_pointer_v<remove_reference_t<_Pointer>>
    mdspan(_Pointer&&)
    -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>;

  template<typename _ElementType, typename... _Integrals>
    requires (is_convertible_v<_Integrals, size_t> && ...)
	      && (sizeof...(_Integrals) > 0)
    explicit mdspan(_ElementType*, _Integrals...)
    -> mdspan<_ElementType,
	      extents<size_t, __detail::__maybe_static_ext<_Integrals>...>>;

  template<typename _ElementType, typename _OIndexType, size_t _Nm>
    mdspan(_ElementType*, span<_OIndexType, _Nm>)
    -> mdspan<_ElementType, dextents<size_t, _Nm>>;

  template<typename _ElementType, typename _OIndexType, size_t _Nm>
    mdspan(_ElementType*, const array<_OIndexType, _Nm>&)
    -> mdspan<_ElementType, dextents<size_t, _Nm>>;

  template<typename _ElementType, typename _IndexType, size_t... _ExtentsPack>
    mdspan(_ElementType*, const extents<_IndexType, _ExtentsPack...>&)
    -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>;

  template<typename _ElementType, typename _MappingType>
    mdspan(_ElementType*, const _MappingType&)
    -> mdspan<_ElementType, typename _MappingType::extents_type,
	      typename _MappingType::layout_type>;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 4511. Inconsistency between the deduction guide of std::mdspan taking...
  template<typename _MappingType, typename _AccessorType>
    mdspan(typename _AccessorType::data_handle_type, const _MappingType&,
	   const _AccessorType&)
    -> mdspan<typename _AccessorType::element_type,
	      typename _MappingType::extents_type,
	      typename _MappingType::layout_type, _AccessorType>;

#if __glibcxx_submdspan
  namespace __mdspan
  {
    template<typename _IndexType, typename _Slice>
      constexpr auto
      __canonical_index(_Slice&& __slice)
      {
	if constexpr (__detail::__integral_constant_like<_Slice>)
	  {
	    static_assert(__is_representable_integer<_IndexType>(_Slice::value));
	    static_assert(_Slice::value >= 0);
	    return std::cw<_IndexType(_Slice::value)>;
	  }
	else
	  return __mdspan::__index_type_cast<_IndexType>(std::move(__slice));
      }

    template<typename _IndexType, 
	    typename _OffsetType, typename _SpanType, typename _StrideType>
    constexpr auto
    __canonical_range_slice(_OffsetType __offset, _SpanType __span,
			    _StrideType __stride)
    {
      if constexpr (is_same_v<_SpanType, constant_wrapper<_IndexType(0)>>
		    || is_same_v<_StrideType, constant_wrapper<_IndexType(1)>>)
	return extent_slice{
	  .offset = __offset,
	  .extent = __span,
	  .stride = cw<_IndexType(1)>
	};
      else if constexpr (__is_constant_wrapper_v<_StrideType>)
	{
	  static_assert(_StrideType::value > 0);
	  if constexpr (__is_constant_wrapper_v<_SpanType>)
	    return extent_slice{
	      .offset = __offset,
	      .extent = cw<_IndexType(1 + (_SpanType::value - 1) / _StrideType::value)>,
	      .stride = __stride
	    };
	  else
	    return extent_slice{
	      .offset = __offset,
	      .extent = _IndexType(__span > 0 ? 1 + (__span - 1) / _StrideType::value : 0),
	      .stride = __stride
	    };
	}
      else if (__span == 0 || __stride == 1)
	return extent_slice{
	  .offset = __offset,
	  .extent = _IndexType(__span),
	  .stride = _IndexType(1)
	};
      else
	{
	  __glibcxx_assert(__stride > 0);
	  return extent_slice{
	    .offset = __offset,
	    .extent = _IndexType(1 + (__span - 1) / __stride),
	    .stride = __stride
	  };
	}
    }

    template<typename _IndexType, typename _Slice>
      constexpr auto
      __slice_cast(_Slice&& __slice)
      {
	using _SliceType = remove_cvref_t<_Slice>;
	if constexpr (is_convertible_v<_SliceType, full_extent_t>)
	  return static_cast<full_extent_t>(std::move(__slice));
	else if constexpr (is_convertible_v<_SliceType, _IndexType>)
	  return __mdspan::__canonical_index<_IndexType>(std::move(__slice));
	else if constexpr (__is_extent_slice<_SliceType>)
	  return extent_slice{
	    .offset = __mdspan::__canonical_index<_IndexType>(std::move(__slice.offset)),
	    .extent = __mdspan::__canonical_index<_IndexType>(std::move(__slice.extent)),
	    .stride = __mdspan::__canonical_index<_IndexType>(std::move(__slice.stride))
	  };
	else if constexpr (__is_range_slice<_SliceType>)
	  {
	    auto __first
	      = __mdspan::__canonical_index<_IndexType>(std::move(__slice.first));
	    auto __last
	      = __mdspan::__canonical_index<_IndexType>(std::move(__slice.last));
	    return __mdspan::__canonical_range_slice<_IndexType>(
		     __first,
		     __mdspan::__canonical_index<_IndexType>(__last - __first),
		     __mdspan::__canonical_index<_IndexType>(std::move(__slice.stride)));
	  }
	else
	  {
	    auto [__sbegin, __send] = std::move(__slice);
	    auto __cbegin
	      = __mdspan::__canonical_index<_IndexType>(std::move(__sbegin));
	    auto __cend
	      = __mdspan::__canonical_index<_IndexType>(std::move(__send));
	    auto __cspan
	      = __mdspan::__canonical_index<_IndexType>(__cend - __cbegin);
	    return __mdspan::__canonical_range_slice<_IndexType>(
		     __cbegin, __cspan, cw<_IndexType(1)>);
	  }
      }

   template<typename _IndexType, size_t _Extent, typename _OIndexType>
      constexpr void
      __check_inrange_index(const extents<_IndexType, _Extent>& __ext,
			   const _OIndexType& __idx)
      {
	if constexpr (__is_constant_wrapper_v<_OIndexType>
		      && _Extent != dynamic_extent)
	  {
	    static_assert(_OIndexType::value >= 0);
	    static_assert(std::cmp_less(_OIndexType::value, _Extent));
	  }
	else
	  __glibcxx_assert(__idx < __ext.extent(0));
      }

    template<typename _IndexType, size_t _Extent, typename _OIndexType>
      constexpr void
      __check_valid_index(const extents<_IndexType, _Extent>& __ext,
			   const _OIndexType& __idx)
      {
	if constexpr (__is_constant_wrapper_v<_OIndexType>
		      && _Extent != dynamic_extent)
	  {
	    static_assert(_OIndexType::value >= 0);
	    static_assert(std::cmp_less_equal(_OIndexType::value, _Extent));
	  }
	else
	  __glibcxx_assert(__idx <= __ext.extent(0));
      }

    template<typename _IndexType, size_t _Extent, typename _Slice>
      constexpr void
      __check_valid_slice(const extents<_IndexType, _Extent>& __ext,
			   const _Slice& __slice)
      {
	if constexpr (__is_extent_slice<_Slice>)
	  {
	    __mdspan::__check_valid_index(__ext, __slice.extent);
	    // DEVIATION: For empty slices, P3663r3 does not allow us to check
	    // that this is less than or equal to the k-th extent (at runtime).
	    // We're only allowed to check if __slice.offset, __slice.extent
	    // are constant wrappers and __ext is a static extent.
	    if constexpr (is_same_v<typename _Slice::extent_type,
				    constant_wrapper<_IndexType(0)>>)
	      __mdspan::__check_valid_index(__ext, __slice.offset);
	    else if constexpr (is_same_v<typename _Slice::extent_type,
					 constant_wrapper<_IndexType(1)>>)
	      __mdspan::__check_inrange_index(__ext, __slice.offset);
	    else if constexpr (__is_constant_wrapper_v<typename _Slice::extent_type>)
	      { 
	      	__mdspan::__check_inrange_index(__ext, __slice.offset);
		if constexpr (__is_constant_wrapper_v<typename _Slice::stride_type>)
		  static_assert(_Slice::stride_type::value > 0);
		else
		  __glibcxx_assert(__slice.stride > 0);

		if constexpr (_Extent != dynamic_extent
		     && __is_constant_wrapper_v<typename _Slice::offset_type>)
		  static_assert(std::cmp_greater_equal(
		    _Extent - _Slice::offset_type::value,
		    _Slice::extent_type::value));
		if constexpr (_Extent != dynamic_extent
		     && __is_constant_wrapper_v<typename _Slice::stride_type>)
		  static_assert(std::cmp_greater(
		    _Extent,
		    (_Slice::extent_type::value - 1) * _Slice::stride_type::value));

		if constexpr (_Extent != dynamic_extent
		     && __is_constant_wrapper_v<typename _Slice::offset_type>
		     && __is_constant_wrapper_v<typename _Slice::stride_type>)
		  static_assert(std::cmp_greater(
		    _Extent - _Slice::offset_type::value,
		    (_Slice::extent_type::value - 1) * _Slice::stride_type::value));
		else
		  __glibcxx_assert(std::cmp_greater(
		    __ext.extent(0) - __slice.offset,
		    (_Slice::extent_type::value - 1) * __slice.stride));
	      }
	    else if constexpr (is_same_v<typename _Slice::stride_type,
				         constant_wrapper<_IndexType(1)>>)
	      {
		__mdspan::__check_valid_index(__ext, __slice.offset);
		__glibcxx_assert(std::cmp_greater_equal(
		  __ext.extent(0) - __slice.offset,
		  __slice.extent));
	      }
	    else if (__slice.extent == 0)
	      __mdspan::__check_valid_index(__ext, __slice.offset);
	    else
	      {
		__glibcxx_assert(__slice.offset < __ext.extent(0));
		__glibcxx_assert(__slice.extent == 1 || __slice.stride > 0);
		__glibcxx_assert(__slice.extent == 1 || std::cmp_greater(
		  __ext.extent(0) - __slice.offset,
		  (__slice.extent - 1) * __slice.stride));
	      }
	  }
	else if constexpr (!is_same_v<_Slice, full_extent_t>)
	  __mdspan::__check_inrange_index(__ext, __slice);
      }

    template<typename _Extents, typename... _Slices>
      constexpr void
      __check_valid_slices(const _Extents& __exts, const _Slices&... __slices)
      {
	constexpr auto __rank = _Extents::rank();
	auto __impl = [&]<size_t... _Is>(index_sequence<_Is...>)
	{
	  ((__mdspan::__check_valid_slice(__extract_extent<_Is>(__exts),
					  __slices...[_Is])),...);
	};
	__impl(make_index_sequence<__rank>());
      }

    template<typename _Slice>
      using __full_extent_t = std::full_extent_t;

    // Enables ADL-only calls from submdspan.
    void submdspan_mapping() = delete;

    template<typename _Mapping, typename... _Slices>
      concept __sliceable_mapping = requires(const _Mapping __m, _Slices... __slices)
      {
	{ submdspan_mapping(__m, __slices...) } -> __submdspan_mapping_result;
      };

    template<typename _Mapping, typename... _Slices>
      constexpr auto
      __submapping(const _Mapping& __mapping, _Slices... __slices)
      {
	__mdspan::__check_valid_slices(__mapping.extents(), __slices...);
	return submdspan_mapping(__mapping, __slices...);
      }
  }

  template<typename _IndexType, size_t... _Extents, typename... _RawSlices>
    requires (sizeof...(_RawSlices) == sizeof...(_Extents))
    constexpr auto
    subextents(const extents<_IndexType, _Extents...>& __exts,
	       _RawSlices... __raw_slices)
    {
      auto __impl = [&__exts](auto... __slices)
      {
	__mdspan::__check_valid_slices(__exts, __slices...);
	return __mdspan::__subextents(__exts, __slices...);
      };
      return __impl(__mdspan::__slice_cast<_IndexType>(__raw_slices)...);
    }

  template<typename _IndexType, size_t... _Extents, typename... _RawSlices>
    requires (sizeof...(_Extents) == sizeof...(_RawSlices))
    constexpr auto
    canonical_slices(const extents<_IndexType, _Extents...>& __exts,
		     _RawSlices... __raw_slices)
    {
      auto __impl = [&__exts](auto... __slices)
      {
	__mdspan::__check_valid_slices(__exts, __slices...);
	return std::make_tuple(__slices...);
      };
      return __impl(__mdspan::__slice_cast<_IndexType>(__raw_slices)...);
    }

  template<typename _ElementType, typename _Extents, typename _Layout,
	   typename _Accessor, typename... _RawSlices>
    requires (sizeof...(_RawSlices) == _Extents::rank()
	&& __mdspan::__sliceable_mapping<typename _Layout::template mapping<_Extents>,
					 __mdspan::__full_extent_t<_RawSlices>...>)
    constexpr auto
    submdspan(
	const mdspan<_ElementType, _Extents, _Layout, _Accessor>& __md,
	_RawSlices... __raw_slices)
    {
      using _IndexType = typename _Extents::index_type;
      auto [__mapping, __offset] = __mdspan::__submapping(
	__md.mapping(), __mdspan::__slice_cast<_IndexType>(__raw_slices)...);
      return std::mdspan(
	       __md.accessor().offset(__md.data_handle(), __offset),
	       std::move(__mapping),
	       typename _Accessor::offset_policy(__md.accessor()));
    }
#endif // __glibcxx_submdspan

_GLIBCXX_END_NAMESPACE_VERSION
}
#endif
#endif
