libstdc++: span's deduction-guide for built-in arrays doesn't work (LWG 3369)
authorJonathan Wakely <jwakely@redhat.com>
Wed, 19 Feb 2020 14:41:46 +0000 (14:41 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 19 Feb 2020 15:28:33 +0000 (15:28 +0000)
The 23_containers/span/deduction.cc test was already passing, but only
because I had previously implemented the original proposed resolution of
3255. As pointed out in 3255 that original P/R was incorrect because it
broke construction from array xvalues. This reverts the incorrect part
of 3255 (and adds tests for the case it broke), and implements the
resolution of 3369 instead.

* include/std/span (span(T (&)[N])): Use non-deduced context to
prevent first parameter from interfering with class template argument
deduction (LWG 3369).
* testsuite/23_containers/span/deduction.cc: Add missing 'const'.
* testsuite/23_containers/span/lwg3255.cc: Check for construction from
rvalues.

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/span
libstdc++-v3/testsuite/23_containers/span/deduction.cc
libstdc++-v3/testsuite/23_containers/span/lwg3255.cc

index f5f8b6fd5001bb511a4ece44df52a579fe56b800..18085f3d9bd09e04fcc765373be793dd208c662b 100644 (file)
@@ -1,5 +1,12 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/std/span (span(T (&)[N])): Use non-deduced context to
+       prevent first parameter from interfering with class template argument
+       deduction (LWG 3369).
+       * testsuite/23_containers/span/deduction.cc: Add missing 'const'.
+       * testsuite/23_containers/span/lwg3255.cc: Check for construction from
+       rvalues.
+
        * include/std/span (span::const_iterator, span::const_reverse_iterator)
        (span::cbegin(), span::cend(), span::crbegin(), span::crend()):
        Remove (LWG 3320).
index ccfd7db39fef7e65bd5389d98980b28ddb54aaa7..16b09a1e50cddd7c9fb5233611f7df589cbec1b3 100644 (file)
@@ -182,10 +182,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            }
        }
 
-      template<typename _Tp, size_t _ArrayExtent>
-       requires __is_compatible_array<_Tp, _ArrayExtent>::value
+      template<size_t _ArrayExtent>
+       requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
        constexpr
-       span(_Tp (&__arr)[_ArrayExtent]) noexcept
+       span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
        : span(static_cast<pointer>(__arr), _ArrayExtent)
        { }
 
index 66e955e961b1b037a9c86dcd43ba5cd38dabbb25..2fe1ac477c8261fecd712b2ee863aa68da1725b3 100644 (file)
@@ -73,7 +73,7 @@ test01()
   std::span s9(s2);
   static_assert( is_static_span<int, 2>(s9) );
 
-  std::span s10(const_cast<std::span<int, 2>&>(s2));
+  std::span s10(const_cast<const std::span<int, 2>&>(s2));
   static_assert( is_static_span<int, 2>(s10) );
 
   std::span s11(s5);
index 91edf6a04fd340d62e0508bfcac3c468d37267d2..03ced2c8710098bb7380fa11d24d964070102947 100644 (file)
@@ -57,10 +57,14 @@ static_assert( !is_constructible_v<span<const int, 1>, const array<const int, 2>
 static_assert( is_constructible_v<span<int>, int(&)[2]> );
 static_assert( is_constructible_v<span<const int>, int(&)[2]> );
 static_assert( is_constructible_v<span<const int>, const int(&)[2]> );
+static_assert( is_constructible_v<span<const int>, int[2]> );
+static_assert( is_constructible_v<span<const int>, const int[2]> );
 
 static_assert( is_constructible_v<span<int>, array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, array<const int, 2>&> );
+static_assert( is_constructible_v<span<const int>, array<int, 2>> );
+static_assert( is_constructible_v<span<const int>, array<const int, 2>> );
 
 static_assert( is_constructible_v<span<const int>, const array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, const array<const int, 2>&> );