libstdc++: Fix and simplify constraints on std::span constructors
authorJonathan Wakely <jwakely@redhat.com>
Tue, 18 Feb 2020 13:12:44 +0000 (13:12 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Tue, 18 Feb 2020 17:42:54 +0000 (17:42 +0000)
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.

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/span

index 6ae3955d2cef5d7d18a33ea3421808f98b5fce62..de0995264a011c3311b82292e0ad113e3da54242 100644 (file)
@@ -1,5 +1,15 @@
 2020-02-18  Jonathan Wakely  <jwakely@redhat.com>
 
+       * 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.
+
        * include/std/span (span): Reorder members and rename template
        parameters to match declarations in the C++2a working paper.
 
index feb1c1f46ad10413482362f3cbc44995dfb9328f..21114f1e03836fdff931385b2af29be2dc159f97 100644 (file)
@@ -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))