// <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 _OIndexType>
      constexpr _IndexType
      __index_type_cast(_OIndexType&& __other)
      {
	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
	  {
	    auto __ret = static_cast<_IndexType>(std::move(__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 strided_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 _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_strided_slice = false;

    template<typename _OffsetType, typename _ExtentType, typename _StrideType>
      constexpr bool __is_strided_slice<strided_slice<_OffsetType,
	  _ExtentType, _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<typename _Tp>
      constexpr bool __is_constant_wrapper = false;

    template<_CwFixedValue _Xv, typename _Tp>
      constexpr bool __is_constant_wrapper<constant_wrapper<_Xv, _Tp>>
	= true;

    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<_Slice>
	  || __is_strided_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_strided_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<typename _Slice::extent_type>
			&& __is_constant_wrapper<typename _Slice::stride_type>)
	  return 1 + ((typename _Slice::extent_type{}) - 1)
		   / (typename _Slice::stride_type{});
	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_strided_slice<_Slice>)
	  return __slice.extent == 0 ? 0 : 1 + (__slice.extent - 1) / __slice.stride;
	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_strided_slice<decltype(__slice)>)
		if (__slice.stride < __slice.extent)
		  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_strided_slice<decltype(__slice)>)
		  {
		    if (__slice.stride < __slice.extent)
		      __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_strided_slice<_Slice>
	  && __mdspan::__is_constant_wrapper<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_strided_slice: strided_slice{a, b, cw<1>}, but not `full`,
    //  - strided_slice: strided_slice{a, b, c} with c != cw<1>.
    enum class _SliceKind
    {
      __strided_slice,
      __unit_strided_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_strided_slice<_Slice>)
	  {
	    if constexpr (__mdspan::__is_unit_stride_slice<_Slice>)
	      return _SliceKind::__unit_strided_slice;
	    else
	      return _SliceKind::__strided_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_strided_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_strided_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_strided_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_strided_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>;

  template<typename _MappingType, typename _AccessorType>
    mdspan(const 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 _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_strided_slice<_SliceType>)
	  {
	    auto __extent
	      = __mdspan::__canonical_index<_IndexType>(std::move(__slice.extent));
	    auto __offset
	      = __mdspan::__canonical_index<_IndexType>(std::move(__slice.offset));
	    if constexpr (is_same_v<decltype(__extent),
				    constant_wrapper<_IndexType(0)>>)
	      return strided_slice{
		.offset = __offset,
		.extent = __extent,
		.stride = cw<_IndexType(1)>
	      };
	    else
	      return strided_slice{
		.offset = __offset,
		.extent = __extent,
		.stride
		  = __mdspan::__canonical_index<_IndexType>(std::move(__slice.stride))
	      };
	  }
	else
	  {
	    auto [__sbegin, __send] = std::move(__slice);
	    auto __offset
	      = __mdspan::__canonical_index<_IndexType>(std::move(__sbegin));
	    auto __end
	      = __mdspan::__canonical_index<_IndexType>(std::move(__send));
	    return strided_slice{
	      .offset = __offset,
	      .extent = __mdspan::__canonical_index<_IndexType>(__end - __offset),
	      .stride = cw<_IndexType(1)>
	    };
	  }
      }

    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<_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_strided_slice<_Slice>)
	  {
	    // 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.
	    __mdspan::__check_valid_index(__ext, __slice.offset);
	    __mdspan::__check_valid_index(__ext, __slice.extent);

	    if constexpr (__is_constant_wrapper<typename _Slice::extent_type>
			  && __is_constant_wrapper<typename _Slice::stride_type>)
	      static_assert(_Slice::stride_type::value > 0);
	    else
	      __glibcxx_assert(__slice.extent == 0 || __slice.stride > 0);

	    if constexpr (__is_constant_wrapper<typename _Slice::offset_type>
		&& __is_constant_wrapper<typename _Slice::extent_type>
		&& _Extent != dynamic_extent)
	      static_assert(std::cmp_greater_equal(
		  _Extent - _Slice::offset_type::value,
		  _Slice::extent_type::value));
	    else
	      __glibcxx_assert(__ext.extent(0) - __slice.offset
			       >= __slice.extent);
	  }
	else if constexpr (__is_constant_wrapper<_Slice>
			   && _Extent != dynamic_extent)
	  static_assert(std::cmp_less(_Slice::value, _Extent));
	else if constexpr (convertible_to<_Slice, _IndexType>)
	  __glibcxx_assert(__slice < __ext.extent(0));
      }

    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
