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

// Copyright (C) 2019-2020 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 <type_traits>
#include <array>
#include <bits/stl_iterator.h>
#include <bits/range_access.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<_GLIBCXX_STD_C::array<_Tp, _Num>> : true_type { };

#ifdef _GLIBCXX_DEBUG
    template<typename _Tp, size_t _Num>
      struct __is_std_array<__debug::array<_Tp, _Num>> : true_type { };
#endif

    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_extent(0), _M_ptr(nullptr)
      { }

      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_extent(__count), _M_ptr(std::to_address(__first))
	{
	  if constexpr (_Extent != dynamic_extent)
	    {
	      __glibcxx_assert(__count == _Extent);
	    }
	}

      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_extent(static_cast<size_type>(__last - __first)),
	  _M_ptr(std::to_address(__first))
	{
	  if constexpr (_Extent != dynamic_extent)
	    {
	      __glibcxx_assert((__last - __first) == _Extent);
	    }
	}

      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
      {
	static_assert(extent != 0);
	__glibcxx_assert(!empty());
	return *this->_M_ptr;
      }

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

      constexpr reference
      operator[](size_type __idx) const noexcept
      {
	static_assert(extent != 0);
	__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:
      [[no_unique_address]] __detail::__extent_storage<extent> _M_extent;
      pointer _M_ptr;
    };

  // 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<typename _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>
    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>>
	  = _Extent == 0 || _Extent == dynamic_extent;
  }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // concepts
#endif // C++20
#endif // _GLIBCXX_SPAN
