libstdc++: enable_view has false positives (LWG 3326)
authorJonathan Wakely <jwakely@redhat.com>
Mon, 24 Feb 2020 11:45:20 +0000 (11:45 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Mon, 24 Feb 2020 12:15:05 +0000 (12:15 +0000)
* 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.

14 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/range_access.h
libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/unordered_set.h
libstdc++-v3/include/debug/multiset.h
libstdc++-v3/include/debug/set.h
libstdc++-v3/include/debug/unordered_set
libstdc++-v3/include/experimental/string_view
libstdc++-v3/include/std/ranges
libstdc++-v3/include/std/span
libstdc++-v3/include/std/string_view
libstdc++-v3/testsuite/std/ranges/view.cc

index 7e065ef3e1dfb46c4088d657a0ed78b846902b0e..457afdbadc8525c592be30aba4ffffbae57c93d4 100644 (file)
@@ -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>))
index eb91ade35ff714d433e032a97f2c68d0039ad643..8b276fd66256784773d2050266472bd2b96f18cc 100644 (file)
@@ -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>
index 3307e1c917cde4a643acc8ff18140455f1d04993..dcae83eea4e5bdee72a8bfce63a3ff048606ed7d 100644 (file)
@@ -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
index b8b82912c91a6f7d13f24921f4e972ef92ae5fa8..ab62df1e50861d71c4f90a38d221aa84a151d5c4 100644 (file)
@@ -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
index 5f3e78dc47058bfc00b48594fd4107aca4ac4ddd..4f8d631bb3bb42637cdb086d586bcf8cd855b919 100644 (file)
@@ -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
index 824eedbae3e98356e7fee539f2f698ddbe094a32..9c2cd45be9c9b6d89ab284d36271d3e4506b2cc1 100644 (file)
@@ -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
index f5b974ccdc49e31dbbc9e25b68b30db562a9e668..fcbba33947834786f2092f85e77d55a5aadd5eb9 100644 (file)
@@ -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
index f3f90476a489c4a92d3e9424317987833e269046..093ff129f3e49355fa4d681ac0ef8a69e3dcbc9c 100644 (file)
@@ -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
index 040ae7f2ad4db701d2f5ac729ca6b0cff07de0c2..9941bbe1c24f97daed56afae6da20a3b7a805555 100644 (file)
@@ -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
index 439650154aea8074814a5f3188599fc01f5fb0fd..629db577c29a3f2969c7245f7a2dcfd9a0ec1d6e 100644 (file)
@@ -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
 
index 8c925fa278b523535f0e6701d0b208ed835ca71e..0b2057c966152a89c7b78289d09caf7e20eeaeb8 100644 (file)
@@ -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
index 16b09a1e50cddd7c9fb5233611f7df589cbec1b3..f658adb04cf04259035cc95fe17ffbcdea0fbf45 100644 (file)
@@ -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
index 16687f6c352abd7ef855a66ef4c5d1ca77e0211c..ea5d547e00603c499884ec1fa412e588481d9dd6 100644 (file)
@@ -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
index d76c8013c2c73064592e2aaab6464e114493e2b4..72e8bcb50d74485f025c080ceb619ace1912bc6e 100644 (file)
 // { 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>>);