// Components for manipulating non-owning sequences of objects -*- C++ -*-

// Copyright (C) 2019-2026 Free Software Foundation, Inc.
//
// 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 span
 *  This is a Standard C++ Library header.
 */

//
// P0122 span library
// Contributed by ThePhD
//

#ifndef _GLIBCXX_SPAN
#define _GLIBCXX_SPAN 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#define __glibcxx_want_span
#define __glibcxx_want_span_initializer_list
#define __glibcxx_want_hardened_span
#include <bits/version.h>

#ifdef __cpp_lib_span // C++ >= 20 && concepts
#include <array>
#include <cstddef>
#include <bits/stl_iterator.h>
#include <bits/ranges_base.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  inline constexpr size_t dynamic_extent = static_cast<size_t>(-1);

  template<typename _Type, size_t _Extent>
    class span;

  namespace __detail
  {
    template<typename _Tp>
      inline constexpr bool __is_span = false;

    template<typename _Tp, size_t _Num>
      inline constexpr bool __is_span<span<_Tp, _Num>> = true;

    template<typename _Tp>
      inline constexpr bool __is_std_array = false;

    template<typename _Tp, size_t _Num>
      inline constexpr bool __is_std_array<std::array<_Tp, _Num>> = true;

    template<size_t _Extent>
      class __extent_storage
      {
      public:
	// Used for runtime sizes that must satisfy the precondition.
	constexpr
	__extent_storage([[maybe_unused]] size_t __n) noexcept
	{ __glibcxx_assert(__n == _Extent); }

	// Used for constant sizes that are already known to be correct.
	consteval
	__extent_storage(integral_constant<size_t, _Extent>) noexcept
	{ }

	// "I've made a huge mistake" - George Oscar Bluth II
	template<size_t _Gob>
	  __extent_storage(integral_constant<size_t, _Gob>) = delete;

	[[__gnu__::__always_inline__]]
	static constexpr size_t
	_M_extent() noexcept
	{ return _Extent; }
      };

    template<>
      class __extent_storage<dynamic_extent>
      {
      public:
	[[__gnu__::__always_inline__]]
	constexpr
	__extent_storage(size_t __extent) noexcept
	: _M_extent_value(__extent)
	{ }

	[[__gnu__::__always_inline__]]
	constexpr size_t
	_M_extent() const noexcept
	{ return this->_M_extent_value; }

      private:
	size_t _M_extent_value;
      };

    template<typename _Type> struct __span_ptr { _Type* const _M_ptr; };

  } // namespace __detail

  template<typename _Type, size_t _Extent = dynamic_extent>
    class span
    {
      template<size_t _Offset, size_t _Count>
	static constexpr size_t
	_S_subspan_extent()
	{
	  if constexpr (_Count != dynamic_extent)
	    return _Count;
	  else if constexpr (extent != dynamic_extent)
	    return _Extent - _Offset;
	  else
	    return dynamic_extent;
	}

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3255. span's array constructor is too strict
      template<typename _Tp, size_t _ArrayExtent>
	requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
	using __is_compatible_array = __is_array_convertible<_Type, _Tp>;

      template<typename _Ref>
	using __is_compatible_ref
	  = __is_array_convertible<_Type, remove_reference_t<_Ref>>;

      // Nested type so that _Type is not an associated class of iterator.
      struct __iter_tag;

      template<size_t _Nm>
	static inline constexpr integral_constant<size_t, _Nm> __v{};

    public:
      // member types
      using element_type           = _Type;
      using value_type             = remove_cv_t<_Type>;
      using size_type              = size_t;
      using difference_type        = ptrdiff_t;
      using pointer                = _Type*;
      using const_pointer          = const _Type*;
      using reference              = element_type&;
      using const_reference        = const element_type&;
      using iterator = __gnu_cxx::__normal_iterator<pointer, __iter_tag>;
      using reverse_iterator       = std::reverse_iterator<iterator>;
#if __cplusplus > 202002L
      using const_iterator         = std::const_iterator<iterator>;
      using const_reverse_iterator = std::const_iterator<reverse_iterator>;
#endif

      // member constants
      static constexpr size_t extent = _Extent;

      // constructors, copy and assignment

      constexpr
      span() noexcept
      requires (_Extent == dynamic_extent || _Extent == 0)
      : _M_ptr(nullptr), _M_extent(__v<0>)
      { }

      template<contiguous_iterator _It>
	requires __is_compatible_ref<iter_reference_t<_It>>::value
	constexpr explicit(extent != dynamic_extent)
	span(_It __first, size_type __count)
	noexcept
	: _M_ptr(std::to_address(__first)), _M_extent(__count)
	{ __glibcxx_requires_valid_range(__first, __first + __count); }

      template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
	requires __is_compatible_ref<iter_reference_t<_It>>::value
	  && (!is_convertible_v<_End, size_type>)
	constexpr explicit(extent != dynamic_extent)
	span(_It __first, _End __last)
	noexcept(noexcept(__last - __first))
	: _M_ptr(std::to_address(__first)),
	  _M_extent(static_cast<size_type>(__last - __first))
	{ __glibcxx_requires_valid_range(__first, __last); }

      template<size_t _ArrayExtent>
	requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
	constexpr
	span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
	: _M_ptr(__arr), _M_extent(__v<_ArrayExtent>)
	{ }

      template<typename _Tp, size_t _ArrayExtent>
	requires __is_compatible_array<_Tp, _ArrayExtent>::value
	constexpr
	span(array<_Tp, _ArrayExtent>& __arr) noexcept
	: _M_ptr(__arr.data()), _M_extent(__v<_ArrayExtent>)
	{ }

      template<typename _Tp, size_t _ArrayExtent>
	requires __is_compatible_array<const _Tp, _ArrayExtent>::value
	constexpr
	span(const array<_Tp, _ArrayExtent>& __arr) noexcept
	: _M_ptr(__arr.data()), _M_extent(__v<_ArrayExtent>)
	{ }

      template<typename _Range>
	requires (!__detail::__is_span<remove_cvref_t<_Range>>)
	  && (!__detail::__is_std_array<remove_cvref_t<_Range>>)
	  && (!is_array_v<remove_cvref_t<_Range>>)
	  && ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
	  && (ranges::borrowed_range<_Range> || is_const_v<element_type>)
	  && __is_compatible_ref<ranges::range_reference_t<_Range>>::value
	constexpr explicit(extent != dynamic_extent)
	span(_Range&& __range)
	noexcept(noexcept(ranges::data(__range))
		  && noexcept(ranges::size(__range)))
	: _M_ptr(ranges::data(__range)), _M_extent(ranges::size(__range))
	{ }

      constexpr
      span(const span&) noexcept = default;

      template<typename _OType, size_t _OExtent>
	requires (_Extent == dynamic_extent || _OExtent == dynamic_extent
		  || _Extent == _OExtent)
	  && (__is_array_convertible<_Type, _OType>::value)
	constexpr
	explicit(extent != dynamic_extent && _OExtent == dynamic_extent)
	span(const span<_OType, _OExtent>& __s) noexcept
	: _M_ptr(__s.data()), _M_extent(__s.size())
	{ }

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

      // observers

      [[nodiscard]]
      constexpr size_type
      size() const noexcept
      { return this->_M_extent._M_extent(); }

      [[nodiscard]]
      constexpr size_type
      size_bytes() const noexcept
      { return this->_M_extent._M_extent() * sizeof(element_type); }

      [[nodiscard]]
      constexpr bool
      empty() const noexcept
      { return size() == 0; }

      // element access

      [[nodiscard]]
      constexpr reference
      front() const noexcept
      {
	__glibcxx_assert(!empty());
	return *this->_M_ptr;
      }

      [[nodiscard]]
      constexpr reference
      back() const noexcept
      {
	__glibcxx_assert(!empty());
	return *(this->_M_ptr + (size() - 1));
      }

      [[nodiscard]]
      constexpr reference
      operator[](size_type __idx) const noexcept
      {
	__glibcxx_assert(__idx < size());
	return *(this->_M_ptr + __idx);
      }

#if __cpp_lib_span >= 202311L // >= C++26
      [[nodiscard]]
      constexpr reference
      at(size_type __idx) const
      {
	if (__idx >= size())
	  __throw_out_of_range_fmt(__N("span::at(%zu) out-of-range for span "
				       "of size %zu"), __idx, this->size());
	return *(this->_M_ptr + __idx);
      }
#endif

      [[nodiscard]]
      constexpr pointer
      data() const noexcept
      { return this->_M_ptr; }

      // iterator support

      [[nodiscard]]
      constexpr iterator
      begin() const noexcept
      { return iterator(this->_M_ptr); }

      [[nodiscard]]
      constexpr iterator
      end() const noexcept
      { return iterator(this->_M_ptr + this->size()); }

      [[nodiscard]]
      constexpr reverse_iterator
      rbegin() const noexcept
      { return reverse_iterator(this->end()); }

      [[nodiscard]]
      constexpr reverse_iterator
      rend() const noexcept
      { return reverse_iterator(this->begin()); }

#if __cplusplus > 202002L
      [[nodiscard]]
      constexpr const_iterator
      cbegin() const noexcept
      { return begin(); }

      [[nodiscard]]
      constexpr const_iterator
      cend() const noexcept
      { return end(); }

      [[nodiscard]]
      constexpr const_reverse_iterator
      crbegin() const noexcept
      { return rbegin(); }

      [[nodiscard]]
      constexpr const_reverse_iterator
      crend() const noexcept
      { return rend(); }
#endif

      // subviews

      template<size_t _Count>
	[[nodiscard]]
	constexpr span<element_type, _Count>
	first() const noexcept
	{
	  if constexpr (_Extent == dynamic_extent)
	    __glibcxx_assert(_Count <= size());
	  else
	    static_assert(_Count <= extent);
	  using _Sp = span<element_type, _Count>;
	  return _Sp(_SizedPtr{this->data()});
	}

      [[nodiscard]]
      constexpr span<element_type, dynamic_extent>
      first(size_type __count) const noexcept
      {
	__glibcxx_assert(__count <= size());
	return span<element_type>(this->data(), __count);
      }

      template<size_t _Count>
	[[nodiscard]]
	constexpr span<element_type, _Count>
	last() const noexcept
	{
	  if constexpr (_Extent == dynamic_extent)
	    __glibcxx_assert(_Count <= size());
	  else
	    static_assert(_Count <= extent);
	  using _Sp = span<element_type, _Count>;
	  return _Sp(_SizedPtr{this->data() + (this->size() - _Count)});
	}

      [[nodiscard]]
      constexpr span<element_type, dynamic_extent>
      last(size_type __count) const noexcept
      {
	__glibcxx_assert(__count <= size());
	return span<element_type>(this->data() + (this->size() - __count),
				  __count);
      }

      template<size_t _Offset, size_t _Count = dynamic_extent>
	[[nodiscard]]
	constexpr auto
	subspan() const noexcept
	-> span<element_type, _S_subspan_extent<_Offset, _Count>()>
	{
	  if constexpr (_Extent == dynamic_extent)
	    {
	      __glibcxx_assert(_Offset <= size());
	    }
	  else
	    static_assert(_Offset <= extent);

	  using _Sp = span<element_type, _S_subspan_extent<_Offset, _Count>()>;

	  if constexpr (_Count == dynamic_extent)
	    return _Sp(this->data() + _Offset, this->size() - _Offset);
	  else
	    {
	      if constexpr (_Extent == dynamic_extent)
		{
		  __glibcxx_assert(_Count <= size());
		  __glibcxx_assert(_Count <= (size() - _Offset));
		}
	      else
		{
		  static_assert(_Count <= extent);
		  static_assert(_Count <= (extent - _Offset));
		}
	      return _Sp(_SizedPtr{this->data() + _Offset});
	    }
	}

      [[nodiscard]]
      constexpr span<element_type, dynamic_extent>
      subspan(size_type __offset, size_type __count = dynamic_extent) const
      noexcept
      {
	__glibcxx_assert(__offset <= size());
	if (__count == dynamic_extent)
	  __count = this->size() - __offset;
	else
	  {
	    __glibcxx_assert(__count <= size());
	    __glibcxx_assert(__offset + __count <= size());
	  }
	return span<element_type>(this->data() + __offset, __count);
      }

    private:
      template<typename, size_t> friend class span;

      // Tag type for pointer that has known extent.
      using _SizedPtr = __detail::__span_ptr<_Type>;

      // Private constructor with an implied extent.
      [[__gnu__::__always_inline__]]
      constexpr explicit
      span(_SizedPtr __ptr) noexcept
      requires (extent != dynamic_extent)
      : _M_ptr(__ptr._M_ptr), _M_extent(__v<extent>)
      { }

      pointer _M_ptr;
      [[no_unique_address]] __detail::__extent_storage<extent> _M_extent;
    };

  // deduction guides
  namespace __detail
  {
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 4351. integral-constant-like needs more remove_cvref_t
    // 4486. integral-constant-like and constexpr-wrapper-like exposition-only
    //       concept duplication
    template<typename _Tp>
      concept __integral_constant_like =
	is_integral_v<remove_cvref_t<decltype(_Tp::value)>>
	&& !is_same_v<bool, remove_cvref_t<decltype(_Tp::value)>>
	&& __constexpr_wrapper_like<_Tp>;

    template<typename _Tp>
      constexpr size_t __maybe_static_ext = dynamic_extent;

    template<__integral_constant_like _Tp>
      constexpr size_t __maybe_static_ext<_Tp> = {_Tp::value};
  }

  template<typename _Type, size_t _ArrayExtent>
    span(_Type(&)[_ArrayExtent]) -> span<_Type, _ArrayExtent>;

  template<typename _Type, size_t _ArrayExtent>
    span(array<_Type, _ArrayExtent>&) -> span<_Type, _ArrayExtent>;

  template<typename _Type, size_t _ArrayExtent>
    span(const array<_Type, _ArrayExtent>&)
      -> span<const _Type, _ArrayExtent>;

  template<contiguous_iterator _Iter, typename _End>
    span(_Iter, _End)
      -> span<remove_reference_t<iter_reference_t<_Iter>>,
				 __detail::__maybe_static_ext<_End>>;

  template<ranges::contiguous_range _Range>
    span(_Range &&)
      -> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 4243. as_bytes/as_writable_bytes is broken with span<volatile T>
  template<typename _Type, size_t _Extent>
    requires (!is_volatile_v<_Type>)
    [[nodiscard]]
    inline
    span<const byte, _Extent == dynamic_extent
	? dynamic_extent : _Extent * sizeof(_Type)>
    as_bytes(span<_Type, _Extent> __sp) noexcept
    {
      auto data = reinterpret_cast<const byte*>(__sp.data());
      auto size = __sp.size_bytes();
      constexpr auto extent = _Extent == dynamic_extent
	? dynamic_extent : _Extent * sizeof(_Type);
      return span<const byte, extent>{data, size};
    }

  template<typename _Type, size_t _Extent>
    requires (!is_const_v<_Type> && !is_volatile_v<_Type>)
    inline
    span<byte, _Extent == dynamic_extent
       ? dynamic_extent : _Extent * sizeof(_Type)>
    as_writable_bytes [[nodiscard]] (span<_Type, _Extent> __sp) noexcept
    {
      auto data = reinterpret_cast<byte*>(__sp.data());
      auto size = __sp.size_bytes();
      constexpr auto extent = _Extent == dynamic_extent
	? dynamic_extent : _Extent * sizeof(_Type);
      return span<byte, extent>{data, size};
    }

  namespace ranges
  {
    // Opt-in to borrowed_range concept
    template<typename _ElementType, size_t _Extent>
      inline constexpr bool
	enable_borrowed_range<span<_ElementType, _Extent>> = true;

    // Opt-in to view concept
    template<typename _ElementType, size_t _Extent>
      inline constexpr bool
	enable_view<span<_ElementType, _Extent>> = true;
  }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_span
#endif // _GLIBCXX_SPAN
