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