// 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>
      struct __is_std_span : false_type { };

    template<typename _Tp, size_t _Num>
      struct __is_std_span<span<_Tp, _Num>> : true_type { };

    template<typename _Tp>
      struct __is_std_array : false_type { };

    template<typename _Tp, size_t _Num>
      struct __is_std_array<std::array<_Tp, _Num>> : true_type { };

    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_std_span<remove_cvref_t<_Range>>::value)
	  && (!__detail::__is_std_array<remove_cvref_t<_Range>>::value)
	  && (!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
