[gcc/devel/c++-coroutines] libstdc++: Fix deduction guide for std::span (PR93426)

Iain D Sandoe iains@gcc.gnu.org
Mon Jan 27 20:25:00 GMT 2020


https://gcc.gnu.org/g:389cd88ce797e2a4345eab8db478a3b8eba798e8

commit 389cd88ce797e2a4345eab8db478a3b8eba798e8
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jan 27 10:30:03 2020 +0000

    libstdc++: Fix deduction guide for std::span (PR93426)
    
    The deduction guide from an iterator and sentinel used the wrong alias
    template and so didn't work.
    
    	PR libstdc++/93426
    	* include/std/span (span): Fix deduction guide.
    	* testsuite/23_containers/span/deduction.cc: New test.

Diff:
---
 libstdc++-v3/ChangeLog                             |  6 ++
 libstdc++-v3/include/std/span                      |  4 +-
 .../testsuite/23_containers/span/deduction.cc      | 84 ++++++++++++++++++++++
 3 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0067e58..2b877a8 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-27  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/93426
+	* include/std/span (span): Fix deduction guide.
+	* testsuite/23_containers/span/deduction.cc: New test.
+
 2020-01-24  Jonathan Wakely  <jwakely@redhat.com>
 
 	* libsupc++/compare (__cmp_cat::_Eq): Remove enumeration type.
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 0dae186..0072010 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -190,7 +190,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	: span(static_cast<pointer>(__arr.data()), _ArrayExtent)
 	{ }
 
-    public:
       template<ranges::contiguous_range _Range>
 	requires (_Extent == dynamic_extent)
 	  && (!__detail::__is_std_span<remove_cvref_t<_Range>>::value)
@@ -404,6 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   // deduction guides
+
   template<typename _Type, size_t _ArrayExtent>
     span(_Type(&)[_ArrayExtent]) -> span<_Type, _ArrayExtent>;
 
@@ -416,7 +416,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<contiguous_iterator _Iter, typename _Sentinel>
     span(_Iter, _Sentinel)
-      -> span<remove_reference_t<ranges::range_reference_t<_Iter>>>;
+      -> span<remove_reference_t<iter_reference_t<_Iter>>>;
 
   template<typename _Range>
     span(_Range &&)
diff --git a/libstdc++-v3/testsuite/23_containers/span/deduction.cc b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
new file mode 100644
index 0000000..66e955e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
@@ -0,0 +1,84 @@
+// Copyright (C) 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+template<typename T, int N, typename U>
+constexpr bool is_static_span(const U&)
+{
+  return std::is_same_v<std::span<T, N>, U> && N != std::dynamic_extent;
+}
+
+template<typename T, typename U>
+constexpr bool is_dynamic_span(const U&)
+{
+  return std::is_same_v<std::span<T>, U>;
+}
+
+struct Range
+{
+  float* begin() const;
+  float* end() const;
+};
+
+void
+test01()
+{
+  const char c[] = "";
+  int i[2]{};
+  std::array<long, 3> a;
+  Range r;
+
+  std::span s1(c);
+  static_assert( is_static_span<const char, 1>(s1) );
+
+  std::span s2(i);
+  static_assert( is_static_span<int, 2>(s2) );
+
+  std::span s3(a);
+  static_assert( is_static_span<long, 3>(s3) );
+
+  std::span s4(const_cast<const std::array<long, 3>&>(a));
+  static_assert( is_static_span<const long, 3>(s4) );
+
+  std::span s5(std::begin(i), std::end(i));
+  static_assert( is_dynamic_span<int>(s5) );
+
+  std::span s6(std::cbegin(i), std::cend(i));
+  static_assert( is_dynamic_span<const int>(s6) );
+
+  std::span s7(r);
+  static_assert( is_dynamic_span<float>(s7) );
+
+  std::span s8(s1);
+  static_assert( is_static_span<const char, 1>(s8) );
+
+  std::span s9(s2);
+  static_assert( is_static_span<int, 2>(s9) );
+
+  std::span s10(const_cast<std::span<int, 2>&>(s2));
+  static_assert( is_static_span<int, 2>(s10) );
+
+  std::span s11(s5);
+  static_assert( is_dynamic_span<int>(s11) );
+
+  std::span s12(const_cast<const std::span<int>&>(s5));
+  static_assert( is_dynamic_span<int>(s12) );
+}



More information about the Libstdc++-cvs mailing list