[gcc(refs/vendors/ibm/heads/perf)] libstdc++: enable_view has false positives (LWG 3326)

Jiu Fu Guo guojiufu@gcc.gnu.org
Thu Mar 19 05:48:49 GMT 2020


https://gcc.gnu.org/g:3841739c29a54c0141c3156cdd47891c258b2b88

commit 3841739c29a54c0141c3156cdd47891c258b2b88
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 24 11:45:20 2020 +0000

    libstdc++: enable_view has false positives (LWG 3326)
    
            * include/std/ranges (__deep_const_range, __enable_view_impl): Remove.
            (ranges::enable_view): Simplify (LWG 3326).
            * include/bits/range_access.h (ranges::enable_view): Declare.
            * include/bits/regex.h (__enable_view_impl): Remove partial
            specialization.
            * include/bits/stl_multiset.h (__enable_view_impl): Likewise.
            * include/bits/stl_set.h (__enable_view_impl): Likewise.
            * include/bits/unordered_set.h (__enable_view_impl): Likewise.
            * include/debug/multiset.h (__enable_view_impl): Likewise.
            * include/debug/set.h (__enable_view_impl): Likewise.
            * include/debug/unordered_set (__enable_view_impl): Likewise.
            * include/experimental/string_view (ranges::enable_view): Define
            partial specialization.
            * include/std/span (ranges::enable_view): Likewise.
            * include/std/string_view (ranges::enable_view): Likewise.
            * testsuite/std/ranges/view.cc: Check satisfaction of updated concept.

Diff:
---
 libstdc++-v3/ChangeLog                        | 19 +++++++++++++++++++
 libstdc++-v3/include/bits/range_access.h      |  3 +++
 libstdc++-v3/include/bits/regex.h             | 10 ----------
 libstdc++-v3/include/bits/stl_multiset.h      | 11 -----------
 libstdc++-v3/include/bits/stl_set.h           |  9 ---------
 libstdc++-v3/include/bits/unordered_set.h     | 15 ---------------
 libstdc++-v3/include/debug/multiset.h         | 13 -------------
 libstdc++-v3/include/debug/set.h              | 12 ------------
 libstdc++-v3/include/debug/unordered_set      | 16 ----------------
 libstdc++-v3/include/experimental/string_view |  6 +++++-
 libstdc++-v3/include/std/ranges               | 19 +------------------
 libstdc++-v3/include/std/span                 |  7 ++++++-
 libstdc++-v3/include/std/string_view          |  6 +++++-
 libstdc++-v3/testsuite/std/ranges/view.cc     | 12 +++++++++++-
 14 files changed, 50 insertions(+), 108 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7e065ef3e1d..457afdbadc8 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,22 @@
+2020-02-24  Jonathan Wakely  <jwakely@redhat.com>
+
+	* include/std/ranges (__deep_const_range, __enable_view_impl): Remove.
+	(ranges::enable_view): Simplify (LWG 3326).
+	* include/bits/range_access.h (ranges::enable_view): Declare.
+	* include/bits/regex.h (__enable_view_impl): Remove partial
+	specialization.
+	* include/bits/stl_multiset.h (__enable_view_impl): Likewise.
+	* include/bits/stl_set.h (__enable_view_impl): Likewise.
+	* include/bits/unordered_set.h (__enable_view_impl): Likewise.
+	* include/debug/multiset.h (__enable_view_impl): Likewise.
+	* include/debug/set.h (__enable_view_impl): Likewise.
+	* include/debug/unordered_set (__enable_view_impl): Likewise.
+	* include/experimental/string_view (ranges::enable_view): Define
+	partial specialization.
+	* include/std/span (ranges::enable_view): Likewise.
+	* include/std/string_view (ranges::enable_view): Likewise.
+	* testsuite/std/ranges/view.cc: Check satisfaction of updated concept.
+
 2020-02-21  Jonathan Wakely  <jwakely@redhat.com>
 
 	* include/std/optional (operator<=>(optional<T>, optional<U>))
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index eb91ade35ff..8b276fd6625 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -346,6 +346,9 @@ namespace ranges
   template<typename _Tp>
     inline constexpr bool enable_borrowed_range = false;
 
+  template<typename _Tp>
+    extern const bool enable_view;
+
   namespace __detail
   {
     template<integral _Tp>
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 3307e1c917c..dcae83eea4e 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -2058,16 +2058,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
 _GLIBCXX_END_NAMESPACE_CXX11
 
-#if __cplusplus > 201703L
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Bi_iter, typename _Alloc>
-    inline constexpr bool __enable_view_impl<match_results<_Bi_iter, _Alloc>>
-      = false;
-} // namespace ranges::__detail
-#endif // C++20
-
   // [28.11.2] Function template regex_match
   /**
    * @name Matching, Searching, and Replacing
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index b8b82912c91..ab62df1e508 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -1038,17 +1038,6 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
       _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
       { return __set._M_t; }
     };
-
-#if __cplusplus > 201703L
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Key, typename _Compare, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<_GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>>
-	= false;
-} // namespace ranges::__detail
-#endif // C++20
 #endif // C++17
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 5f3e78dc470..4f8d631bb3b 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -1051,15 +1051,6 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
       _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
       { return __set._M_t; }
     };
-#if __cplusplus > 201703L
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Key, typename _Compare, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<_GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>> = false;
-} // namespace ranges::__detail
-#endif // C++20
 #endif // C++17
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index 824eedbae3e..9c2cd45be9c 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -1771,21 +1771,6 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
       _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
       { return __set._M_h; }
     };
-
-#if __cplusplus > 201703L
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<_GLIBCXX_STD_C::unordered_set<_Val, _Hash, _Eq,
-						       _Alloc>> = false;
-  template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<_GLIBCXX_STD_C::unordered_multiset<_Val, _Hash, _Eq,
-							    _Alloc>> = false;
-} // namespace ranges::__detail
-#endif // C++20
 #endif // C++17
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index f5b974ccdc4..fcbba339478 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -630,19 +630,6 @@ namespace __debug
     { return __x.swap(__y); }
 
 } // namespace __debug
-
-#if __cplusplus > 201703L
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Key, typename _Compare, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<std::__debug::multiset<_Key, _Compare, _Alloc>>
-	= false;
-} // namespace ranges::__detail
-_GLIBCXX_END_NAMESPACE_VERSION
-#endif // C++20
 } // namespace std
 
 #endif
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index f3f90476a48..093ff129f3e 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -641,18 +641,6 @@ namespace __debug
     { return __x.swap(__y); }
 
 } // namespace __debug
-
-#if __cplusplus > 201703L
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Key, typename _Compare, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<std::__debug::set<_Key, _Compare, _Alloc>> = false;
-} // namespace ranges::__detail
-_GLIBCXX_END_NAMESPACE_VERSION
-#endif // C++20
 } // namespace std
 
 #endif
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 040ae7f2ad4..9941bbe1c24 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -1183,22 +1183,6 @@ namespace __debug
     { return !(__x == __y); }
 
 } // namespace __debug
-#if __cplusplus > 201703L
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-namespace ranges::__detail
-{
-  template<typename _Tp> extern inline const bool __enable_view_impl;
-  template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<std::__debug::unordered_set<_Val, _Hash, _Eq, _Alloc>>
-	= false;
-  template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
-    inline constexpr bool
-      __enable_view_impl<std::__debug::unordered_multiset<_Val, _Hash, _Eq,
-							  _Alloc>> = false;
-} // namespace ranges::__detail
-_GLIBCXX_END_NAMESPACE_VERSION
-#endif // C++20
 } // namespace std
 
 #endif // C++11
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index 439650154ae..629db577c29 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -694,12 +694,16 @@ namespace experimental
 #if __cpp_lib_concepts
   namespace ranges
   {
-    template<typename> extern inline const bool enable_borrowed_range;
     // Opt-in to borrowed_range concept
     template<typename _CharT, typename _Traits>
       inline constexpr bool
 	enable_borrowed_range<experimental::basic_string_view<_CharT, _Traits>>
 	  = true;
+
+    // Opt-in to view concept
+    template<typename _CharT, typename _Traits>
+      inline constexpr bool
+	enable_view<experimental::basic_string_view<_CharT, _Traits>> = true;
   }
 #endif
 
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 8c925fa278b..0b2057c9661 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -65,25 +65,8 @@ namespace ranges
 
   struct view_base { };
 
-  namespace __detail
-  {
-    template<typename _Tp>
-      concept __deep_const_range = range<_Tp> && range<const _Tp>
-	&& same_as<range_reference_t<_Tp>, range_reference_t<const _Tp>>;
-
-    template<typename _Tp>
-      inline constexpr bool __enable_view_impl
-	= derived_from<_Tp, view_base> || (!__deep_const_range<_Tp>);
-
-    template<typename _Tp>
-      inline constexpr bool __enable_view_impl<std::initializer_list<_Tp>>
-	= false;
-
-  } // namespace __detail
-
   template<typename _Tp>
-    inline constexpr bool enable_view
-      = __detail::__enable_view_impl<remove_cv_t<_Tp>>;
+    inline constexpr bool enable_view = derived_from<_Tp, view_base>;
 
   template<typename _Tp>
     concept view
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 16b09a1e50c..f658adb04cf 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -447,11 +447,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   namespace ranges
   {
-    template<typename> extern inline const bool enable_borrowed_range;
     // Opt-in to borrowed_range concept
     template<typename _ElementType, size_t _Extent>
       inline constexpr bool
 	enable_borrowed_range<span<_ElementType, _Extent>> = true;
+
+    // Opt-in to view concept
+    template<typename _ElementType, size_t _Extent>
+      inline constexpr bool
+	enable_view<span<_ElementType, _Extent>>
+	  = _Extent == 0 || _Extent == dynamic_extent;
   }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 16687f6c352..ea5d547e006 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -727,11 +727,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cpp_lib_concepts
   namespace ranges
   {
-    template<typename> extern inline const bool enable_borrowed_range;
     // Opt-in to borrowed_range concept
     template<typename _CharT, typename _Traits>
       inline constexpr bool
 	enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
+
+    // Opt-in to view concept
+    template<typename _CharT, typename _Traits>
+      inline constexpr bool
+	enable_view<basic_string_view<_CharT, _Traits>> = true;
   }
 #endif
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/std/ranges/view.cc b/libstdc++-v3/testsuite/std/ranges/view.cc
index d76c8013c2c..72e8bcb50d7 100644
--- a/libstdc++-v3/testsuite/std/ranges/view.cc
+++ b/libstdc++-v3/testsuite/std/ranges/view.cc
@@ -19,13 +19,23 @@
 // { dg-do compile { target c++2a } }
 
 #include <ranges>
+#include <span>
+#include <string_view>
+#include <experimental/string_view>
+#include <vector>
 #include <vector>
 #include <set>
 #include <unordered_set>
 #include <regex>
 #include <testsuite_iterators.h>
 
-static_assert(std::ranges::view<std::vector<int>>);
+static_assert(std::ranges::view<std::span<int>>);
+static_assert(std::ranges::view<std::span<int, 0>>);
+static_assert(!std::ranges::view<std::span<int, 1>>);
+static_assert(std::ranges::view<std::string_view>);
+static_assert(std::ranges::view<std::experimental::string_view>);
+
+static_assert(!std::ranges::view<std::vector<int>>);
 static_assert(!std::ranges::view<const std::vector<int>>);
 static_assert(!std::ranges::view<std::initializer_list<int>>);
 static_assert(!std::ranges::view<const std::initializer_list<int>>);


More information about the Libstdc++-cvs mailing list