libstdc++: P1964R2 Wording for boolean-testable
authorJonathan Wakely <jwakely@redhat.com>
Mon, 17 Feb 2020 18:15:00 +0000 (18:15 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Mon, 17 Feb 2020 18:22:05 +0000 (18:22 +0000)
This removes the complicated std::boolean concept, as agreed in Prague.

* include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
(__adjacent_find_fn): Cast result of predicate to bool.
* include/std/concepts (__boolean): Remove.
(__detail::__boolean_testable_impl, __detail::__boolean_testable): Add
new helper concepts.
(__detail::__weakly_eq_cmp_with, totally_ordered, totally_ordered_with)
(predicate): Use __boolean_testable instead of boolean.
* libsupc++/compare (__detail::__partially_ordered, _Synth3way):
Likewise.

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/ranges_algo.h
libstdc++-v3/include/std/concepts
libstdc++-v3/libsupc++/compare

index 547337dda90f5b9b4c4ec3abb4b7bbcb3521174a..7e48bee2b18274465f3a0000cd6b1f0803b97b8f 100644 (file)
@@ -1,5 +1,16 @@
 2020-02-17  Jonathan Wakely  <jwakely@redhat.com>
 
+       P1964R2 Wording for boolean-testable
+       * include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
+       (__adjacent_find_fn): Cast result of predicate to bool.
+       * include/std/concepts (__boolean): Remove.
+       (__detail::__boolean_testable_impl, __detail::__boolean_testable): Add
+       new helper concepts.
+       (__detail::__weakly_eq_cmp_with, totally_ordered, totally_ordered_with)
+       (predicate): Use __boolean_testable instead of boolean.
+       * libsupc++/compare (__detail::__partially_ordered, _Synth3way):
+       Likewise.
+
        P1970R2 Consistency for size() functions: Add ranges::ssize
        * include/bits/range_access.h (_SSize, ssize): Define for C++20.
        * testsuite/std/ranges/access/ssize.cc: New test.
index f3a349ef8393b3154baa81377faac1300aefb7a9..83f295722e92985e49325f5c8d812361a171ef58 100644 (file)
@@ -206,7 +206,7 @@ namespace ranges
                 const _Tp& __value, _Proj __proj = {}) const
       {
        while (__first != __last
-           && !(std::__invoke(__proj, *__first) == __value))
+           && !(bool)(std::__invoke(__proj, *__first) == __value))
          ++__first;
        return __first;
       }
@@ -295,9 +295,9 @@ namespace ranges
       {
        for (; __first1 != __last1; ++__first1)
          for (auto __iter = __first2; __iter != __last2; ++__iter)
-           if (std::__invoke(__pred,
-                             std::__invoke(__proj1, *__first1),
-                             std::__invoke(__proj2, *__iter)))
+           if ((bool)std::__invoke(__pred,
+                                   std::__invoke(__proj1, *__first1),
+                                   std::__invoke(__proj2, *__iter)))
              return __first1;
        return __first1;
       }
@@ -687,9 +687,9 @@ namespace ranges
        auto __next = __first;
        for (; ++__next != __last; __first = __next)
          {
-           if (std::__invoke(__pred,
-                             std::__invoke(__proj, *__first),
-                             std::__invoke(__proj, *__next)))
+           if ((bool)std::__invoke(__pred,
+                                   std::__invoke(__proj, *__first),
+                                   std::__invoke(__proj, *__next)))
              return __first;
          }
        return __next;
index acc9dd2599da27762ea6d887fc644277c1d9734b..f3db40b798fe23005d7ec56aa0b2e0272f42b75b 100644 (file)
@@ -259,27 +259,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // [concepts.compare], comparison concepts
 
-  /// [concept.boolean], concept boolean
-  template<typename _Bp>
-    concept boolean
-      = movable<remove_cvref_t<_Bp>>
-      && requires(__detail::__cref<_Bp> __b1, __detail::__cref<_Bp> __b2,
-                 const bool __a) {
-       { __b1 } -> convertible_to<bool>;
-       { !__b1 } -> convertible_to<bool>;
-       { __b1 && __b2 } -> same_as<bool>;
-       { __b1 && __a  } -> same_as<bool>;
-       { __a  && __b2 } -> same_as<bool>;
-       { __b1 || __b2 } -> same_as<bool>;
-       { __b1 || __a  } -> same_as<bool>;
-       { __a  || __b2 } -> same_as<bool>;
-       { __b1 == __b2 } -> convertible_to<bool>;
-       { __b1 == __a  } -> convertible_to<bool>;
-       { __a  == __b2 } -> convertible_to<bool>;
-       { __b1 != __b2 } -> convertible_to<bool>;
-       { __b1 != __a  } -> convertible_to<bool>;
-       { __a  != __b2 } -> convertible_to<bool>;
-      };
+  // [concept.booleantestable], Boolean testability
+  namespace __detail
+  {
+    template<typename _Tp>
+      concept __boolean_testable_impl = convertible_to<_Tp, bool>;
+
+    template<typename _Tp>
+      concept __boolean_testable
+       = __boolean_testable_impl<_Tp>
+         && requires(_Tp&& __t)
+         { { !static_cast<_Tp&&>(__t) } -> __boolean_testable_impl; };
+  } // namespace __detail
 
   // [concept.equalitycomparable], concept equality_comparable
 
@@ -288,10 +279,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Tp, typename _Up>
       concept __weakly_eq_cmp_with
        = requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
-         { __t == __u } -> boolean;
-         { __t != __u } -> boolean;
-         { __u == __t } -> boolean;
-         { __u != __t } -> boolean;
+         { __t == __u } -> __boolean_testable;
+         { __t != __u } -> __boolean_testable;
+         { __u == __t } -> __boolean_testable;
+         { __u != __t } -> __boolean_testable;
        };
   } // namespace __detail
 
@@ -311,10 +302,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     concept totally_ordered
       = equality_comparable<_Tp>
       && requires(__detail::__cref<_Tp> __a, __detail::__cref<_Tp> __b) {
-       { __a <  __b } -> boolean;
-       { __a >  __b } -> boolean;
-       { __a <= __b } -> boolean;
-       { __a >= __b } -> boolean;
+       { __a <  __b } -> __detail::__boolean_testable;
+       { __a >  __b } -> __detail::__boolean_testable;
+       { __a <= __b } -> __detail::__boolean_testable;
+       { __a >= __b } -> __detail::__boolean_testable;
       };
 
   template<typename _Tp, typename _Up>
@@ -325,14 +316,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                            __detail::__cref<_Up>>>
       && equality_comparable_with<_Tp, _Up>
       && requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
-       { __t <  __u } -> boolean;
-       { __t >  __u } -> boolean;
-       { __t <= __u } -> boolean;
-       { __t >= __u } -> boolean;
-       { __u <  __t } -> boolean;
-       { __u >  __t } -> boolean;
-       { __u <= __t } -> boolean;
-       { __u >= __t } -> boolean;
+       { __t <  __u } -> __detail::__boolean_testable;
+       { __t >  __u } -> __detail::__boolean_testable;
+       { __t <= __u } -> __detail::__boolean_testable;
+       { __t >= __u } -> __detail::__boolean_testable;
+       { __u <  __t } -> __detail::__boolean_testable;
+       { __u >  __t } -> __detail::__boolean_testable;
+       { __u <= __t } -> __detail::__boolean_testable;
+       { __u >= __t } -> __detail::__boolean_testable;
       };
 
   template<typename _Tp>
@@ -351,7 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// [concept.predicate], concept predicate
   template<typename _Fn, typename... _Args>
     concept predicate = regular_invocable<_Fn, _Args...>
-      && boolean<invoke_result_t<_Fn, _Args...>>;
+      && __detail::__boolean_testable<invoke_result_t<_Fn, _Args...>>;
 
   /// [concept.relation], concept relation
   template<typename _Rel, typename _Tp, typename _Up>
index b2d64ef74a4795e01151fc4262d4304e089a9d70..ba7db316486894826be77cc80da6a63e4532b109 100644 (file)
@@ -416,14 +416,14 @@ namespace std
       concept __partially_ordered_with
        = requires(const remove_reference_t<_Tp>& __t,
                   const remove_reference_t<_Up>& __u) {
-         { __t <  __u } -> boolean;
-         { __t >  __u } -> boolean;
-         { __t <= __u } -> boolean;
-         { __t >= __u } -> boolean;
-         { __u <  __t } -> boolean;
-         { __u >  __t } -> boolean;
-         { __u <= __t } -> boolean;
-         { __u >= __t } -> boolean;
+         { __t <  __u } -> __boolean_testable;
+         { __t >  __u } -> __boolean_testable;
+         { __t <= __u } -> __boolean_testable;
+         { __t >= __u } -> __boolean_testable;
+         { __u <  __t } -> __boolean_testable;
+         { __u >  __t } -> __boolean_testable;
+         { __u <= __t } -> __boolean_testable;
+         { __u >= __t } -> __boolean_testable;
        };
   } // namespace __detail
 
@@ -879,8 +879,8 @@ namespace std
        operator()(const _Tp& __t, const _Up& __u) const
        requires requires
        {
-         { __t < __u } -> convertible_to<bool>;
-         { __u < __t } -> convertible_to<bool>;
+         { __t < __u } -> __boolean_testable;
+         { __u < __t } -> __boolean_testable;
        }
        {
          if constexpr (three_way_comparable_with<_Tp, _Up>)