// <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


#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

  namespace __mdspan
  {
    template<typename _Extents, typename _IndexType, size_t _Nm>
      constexpr bool
      __is_multi_index(const _Extents& __exts, span<_IndexType, _Nm> __indices)
      {
	static_assert(__exts.rank() == _Nm);
	for (size_t __i = 0; __i < __exts.rank(); ++__i)
	  if (__indices[__i] >= __exts.extent(__i))
	    return false;
	return true;
      }
  }

  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
	{
	  auto __checked_call = [this](auto... __idxs) -> index_type
	    {
	      if constexpr (sizeof...(__idxs) > 0)
		__glibcxx_assert(__mdspan::__is_multi_index(extents(),
		  span<const index_type, sizeof...(__idxs)>({__idxs...})));
	      return _M_mapping(__idxs...);
	    };

	  auto __index = __checked_call(
	    static_cast<index_type>(std::move(__indices))...);
	  return _M_accessor.access(_M_handle, __index);
	}

      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 (*this)[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 (*this)[span<const _OIndexType, rank()>(__indices)]; }

      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:
      [[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
    submdspan_extents(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
    submdspan_canonicalize_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
