diff mbox series

[committed,3/4] libstdc++: Fix and simplify constraints on std::span constructors

Message ID 20200218175131.GG9441@redhat.com
State New
Headers show
Series [committed,1/4] libstdc++: P2116R0 Remove tuple-like protocol support from fixed-extent span | expand

Commit Message

Jonathan Wakely Feb. 18, 2020, 5:51 p.m. UTC
This makes the constraints consistent with the pre-Prague working paper.
     
     * include/std/span (span::__is_compatible_array): Simplify alias
     template by using requires-clause.
     (span::__is_compatible_ref): New alias template for constraining
     constructors.
     (span::__is_compatible_iterator, span::__is_compatible_range): Remove.
     (span(It, size_type), span(It, End)): Use __is_compatible_ref.
     (span(T(&)[N], span(array<T, N>&), span(const array<T, N>&)): Remove
     redundant parentheses.
     (span(R&&)): Add missing constraints.


Tested powerpc64le-linux, committed to trunk.
diff mbox series

Patch

commit d6c9e372372ee78283a21651313fce965d22274d
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Feb 18 13:12:44 2020 +0000

    libstdc++: Fix and simplify constraints on std::span constructors
    
    This makes the constraints consistent with the pre-Prague working paper.
    
            * include/std/span (span::__is_compatible_array): Simplify alias
            template by using requires-clause.
            (span::__is_compatible_ref): New alias template for constraining
            constructors.
            (span::__is_compatible_iterator, span::__is_compatible_range): Remove.
            (span(It, size_type), span(It, End)): Use __is_compatible_ref.
            (span(T(&)[N], span(array<T, N>&), span(const array<T, N>&)): Remove
            redundant parentheses.
            (span(R&&)): Add missing constraints.

diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index feb1c1f46ad..21114f1e038 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -123,20 +123,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 3255. span's array constructor is too strict
       template<typename _Tp, size_t _ArrayExtent>
-	using __is_compatible_array = __and_<
-	  bool_constant<(_Extent == dynamic_extent || _ArrayExtent == _Extent)>,
-	  __is_array_convertible<_Type, _Tp>>;
+	requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
+	using __is_compatible_array = __is_array_convertible<_Type, _Tp>;
 
-      template<typename _Iter, typename _Ref = iter_reference_t<_Iter>>
-	using __is_compatible_iterator = __and_<
-	  bool_constant<contiguous_iterator<_Iter>>,
-	  is_lvalue_reference<iter_reference_t<_Iter>>,
-	  is_same<iter_value_t<_Iter>, remove_cvref_t<_Ref>>,
-	  __is_array_convertible<_Type, remove_reference_t<_Ref>>>;
-
-      template<typename _Range>
-	using __is_compatible_range
-	  = __is_compatible_iterator<ranges::iterator_t<_Range>>;
+      template<typename _Ref>
+	using __is_compatible_ref
+	  = __is_array_convertible<_Type, remove_reference_t<_Ref>>;
 
     public:
       // member types
@@ -165,7 +157,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { }
 
       template<contiguous_iterator _It>
-	requires (__is_compatible_iterator<_It>::value)
+	requires __is_compatible_ref<iter_reference_t<_It>>::value
 	constexpr
 	span(_It __first, size_type __count)
 	noexcept
@@ -173,8 +165,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ __glibcxx_assert(_Extent == dynamic_extent || __count == _Extent); }
 
       template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
-	  requires (__is_compatible_iterator<_It>::value)
-	    && (!is_convertible_v<_End, size_type>)
+	requires __is_compatible_ref<iter_reference_t<_It>>::value
+	  && (!is_convertible_v<_End, size_type>)
 	constexpr
 	span(_It __first, _End __last)
 	noexcept(noexcept(__last - __first))
@@ -186,32 +178,34 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 
       template<typename _Tp, size_t _ArrayExtent>
-	requires (__is_compatible_array<_Tp, _ArrayExtent>::value)
+	requires __is_compatible_array<_Tp, _ArrayExtent>::value
 	constexpr
 	span(_Tp (&__arr)[_ArrayExtent]) noexcept
 	: span(static_cast<pointer>(__arr), _ArrayExtent)
 	{ }
 
       template<typename _Tp, size_t _ArrayExtent>
-	requires (__is_compatible_array<_Tp, _ArrayExtent>::value)
+	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)
+	requires __is_compatible_array<const _Tp, _ArrayExtent>::value
 	constexpr
 	span(const array<_Tp, _ArrayExtent>& __arr) noexcept
 	: span(static_cast<pointer>(__arr.data()), _ArrayExtent)
 	{ }
 
-      template<ranges::contiguous_range _Range>
+      template<typename _Range>
 	requires (_Extent == dynamic_extent)
+	  && ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
+	  && (ranges::safe_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_reference_t<_Range>>)
-	  && (__is_compatible_range<_Range>::value)
+	  && (!is_array_v<remove_cvref_t<_Range>>)
+	  && __is_compatible_ref<ranges::range_reference_t<_Range>>::value
 	constexpr
 	span(_Range&& __range)
 	noexcept(noexcept(ranges::data(__range))