diff --git a/libcxx/include/span b/libcxx/include/span --- a/libcxx/include/span +++ b/libcxx/include/span @@ -199,6 +199,15 @@ is_convertible_v>(*)[], _ElementType(*)[]>; #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +template +concept __span_array_convertible = is_convertible_v<_From(*)[], _To(*)[]>; + +template +concept __span_compatible_iterator = contiguous_iterator<_It> && __span_array_convertible>, _Tp>; + +template +concept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; + #if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_ABI_SPAN_POINTER_ITERATORS) # define _LIBCPP_SPAN_USE_POINTER_ITERATOR #endif @@ -225,16 +234,13 @@ static constexpr size_type extent = _Extent; // [span.cons], span constructors, copy, assignment, and destructor - template = nullptr> + template requires(_Sz == 0) _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} constexpr span (const span&) noexcept = default; constexpr span& operator=(const span&) noexcept = default; - template && - is_convertible_v>(*)[], element_type (*)[]>, - nullptr_t> = nullptr> + template <__span_compatible_iterator _It> _LIBCPP_INLINE_VISIBILITY constexpr explicit span(_It __first, size_type __count) : __data{_VSTD::to_address(__first)} { @@ -242,11 +248,7 @@ _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); } - template < - class _It, class _End, - enable_if_t > (*)[], element_type (*)[]> && - contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>, - nullptr_t> = nullptr> + template <__span_compatible_iterator _It, __span_compatible_sentinel_for<_It> _End> _LIBCPP_INLINE_VISIBILITY constexpr explicit span(_It __first, _End __last) : __data{_VSTD::to_address(__first)} { (void)__last; @@ -257,13 +259,12 @@ _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t (&__arr)[_Extent]) noexcept : __data{__arr} {} - template , nullptr_t> = nullptr> + template <__span_array_convertible _OtherElementType> _LIBCPP_INLINE_VISIBILITY constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} - template , nullptr_t> = nullptr> + template + requires __span_array_convertible _LIBCPP_INLINE_VISIBILITY constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} @@ -288,20 +289,14 @@ } #endif - template + template <__span_array_convertible _OtherElementType> _LIBCPP_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _Extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) + constexpr span(const span<_OtherElementType, _Extent>& __other) : __data{__other.data()} {} - template + template <__span_array_convertible _OtherElementType> _LIBCPP_INLINE_VISIBILITY - constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept + constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } @@ -412,14 +407,11 @@ private: pointer __data; - }; template class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { -private: - public: // constants and types using element_type = _Tp; @@ -445,19 +437,12 @@ constexpr span (const span&) noexcept = default; constexpr span& operator=(const span&) noexcept = default; - template && - is_convertible_v > (*)[], element_type (*)[]>, - nullptr_t> = nullptr> + template <__span_compatible_iterator _It> _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, size_type __count) : __data{_VSTD::to_address(__first)}, __size{__count} {} - template < - class _It, class _End, - enable_if_t > (*)[], element_type (*)[]> && - contiguous_iterator<_It> && sized_sentinel_for<_End, _It> && !is_convertible_v<_End, size_t>, - nullptr_t> = nullptr> + template <__span_compatible_iterator _It, __span_compatible_sentinel_for<_It> _End> _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last) : __data(_VSTD::to_address(__first)), __size(__last - __first) {} @@ -466,13 +451,12 @@ _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} - template , nullptr_t> = nullptr> + template <__span_array_convertible _OtherElementType, size_t _Sz> _LIBCPP_INLINE_VISIBILITY constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - template , nullptr_t> = nullptr> + template + requires __span_array_convertible _LIBCPP_INLINE_VISIBILITY constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} @@ -491,12 +475,9 @@ constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {} #endif - template + template <__span_array_convertible _OtherElementType, size_t _OtherExtent> _LIBCPP_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, _OtherExtent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept + constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept : __data{__other.data()}, __size{__other.size()} {} // ~span() noexcept = default; @@ -615,14 +596,12 @@ // as_bytes & as_writable_bytes template _LIBCPP_INLINE_VISIBILITY -auto as_bytes(span<_Tp, _Extent> __s) noexcept --> decltype(__s.__as_bytes()) -{ return __s.__as_bytes(); } +decltype(auto) as_bytes(span<_Tp, _Extent> __s) noexcept +{ return __s.__as_bytes(); } -template +template requires(!is_const_v<_Tp>) _LIBCPP_INLINE_VISIBILITY -auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept --> enable_if_t, decltype(__s.__as_writable_bytes())> +decltype(auto) as_writable_bytes(span<_Tp, _Extent> __s) noexcept { return __s.__as_writable_bytes(); } #if _LIBCPP_STD_VER > 17