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

// Copyright (C) 2019-2021 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

#pragma GCC system_header

#if __cplusplus > 201703L

#include <array>
#include <cstddef>
#include <bits/stl_iterator.h>
#include <bits/ranges_base.h>

#if __cpp_lib_concepts
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#define __cpp_lib_span 202002L

  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:
	constexpr
	__extent_storage(size_t) noexcept
	{ }

	static constexpr size_t
	_M_extent() noexcept
	{ return _Extent; }
      };

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

	constexpr size_t
	_M_extent() const noexcept
	{ return this->_M_extent_value; }

      private:
	size_t _M_extent_value;
      };
  } // 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>>;

    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, span>;
      using reverse_iterator       = std::reverse_iterator<iterator>;

      // member constants
      static constexpr size_t extent = _Extent;

      // constructors, copy and assignment

      constexpr
      span() noexcept
      requires ((_Extent + 1u) <= 1u)
      : _M_ptr(nullptr), _M_extent(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)
	{
	  if constexpr (_Extent != dynamic_extent)
	    {
	      __glibcxx_assert(__count == _Extent);
	    }
	  __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))
	{
	  if constexpr (_Extent != dynamic_extent)
	    {
	      __glibcxx_assert((__last - __first) == _Extent);
	    }
	  __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
	: span(static_cast<pointer>(__arr), _ArrayExtent)
	{ }

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

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

      template<typename _Range>
	requires ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
	  && (ranges::borrowed_range<_Range> || is_const_v<element_type>)
	  && (!__detail::__is_span<remove_cvref_t<_Range>>)
	  && (!__detail::__is_std_array<remove_cvref_t<_Range>>)
	  && (!is_array_v<remove_cvref_t<_Range>>)
	  && __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)))
	: span(ranges::data(__range), ranges::size(__range))
	{
	  if constexpr (extent != dynamic_extent)
	    {
	      __glibcxx_assert(ranges::size(__range) == extent);
	    }
	}

      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_extent(__s.size()), _M_ptr(__s.data())
	{
	  if constexpr (extent != dynamic_extent)
	    {
	      __glibcxx_assert(__s.size() == extent);
	    }
	}

      ~span() noexcept = default;

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

      // observers

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

      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

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

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

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

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

      // iterator support

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

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

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

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

      // subviews

      template<size_t _Count>
	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{ this->data(), _Count };
	}

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

      template<size_t _Count>
	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{ this->data() + (this->size() - _Count), _Count };
	}

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

      template<size_t _Offset, size_t _Count = dynamic_extent>
	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{ this->data() + _Offset, _Count };
	    }
	}

      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 {this->data() + __offset, __count};
      }

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

  // deduction guides

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

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

  template<typename _Type, size_t _Extent>
    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>)
    inline
    span<byte, _Extent == dynamic_extent
       ? dynamic_extent : _Extent * sizeof(_Type)>
    as_writable_bytes(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 // concepts
#endif // C++20
#endif // _GLIBCXX_SPAN
