Commit c5e1c1d3 by Jonathan Wakely

libstdc++: P1964R2 Wording for boolean-testable

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.
parent 7ab36231
2020-02-17 Jonathan Wakely <jwakely@redhat.com> 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 P1970R2 Consistency for size() functions: Add ranges::ssize
* include/bits/range_access.h (_SSize, ssize): Define for C++20. * include/bits/range_access.h (_SSize, ssize): Define for C++20.
* testsuite/std/ranges/access/ssize.cc: New test. * testsuite/std/ranges/access/ssize.cc: New test.
......
...@@ -206,7 +206,7 @@ namespace ranges ...@@ -206,7 +206,7 @@ namespace ranges
const _Tp& __value, _Proj __proj = {}) const const _Tp& __value, _Proj __proj = {}) const
{ {
while (__first != __last while (__first != __last
&& !(std::__invoke(__proj, *__first) == __value)) && !(bool)(std::__invoke(__proj, *__first) == __value))
++__first; ++__first;
return __first; return __first;
} }
...@@ -295,9 +295,9 @@ namespace ranges ...@@ -295,9 +295,9 @@ namespace ranges
{ {
for (; __first1 != __last1; ++__first1) for (; __first1 != __last1; ++__first1)
for (auto __iter = __first2; __iter != __last2; ++__iter) for (auto __iter = __first2; __iter != __last2; ++__iter)
if (std::__invoke(__pred, if ((bool)std::__invoke(__pred,
std::__invoke(__proj1, *__first1), std::__invoke(__proj1, *__first1),
std::__invoke(__proj2, *__iter))) std::__invoke(__proj2, *__iter)))
return __first1; return __first1;
return __first1; return __first1;
} }
...@@ -687,9 +687,9 @@ namespace ranges ...@@ -687,9 +687,9 @@ namespace ranges
auto __next = __first; auto __next = __first;
for (; ++__next != __last; __first = __next) for (; ++__next != __last; __first = __next)
{ {
if (std::__invoke(__pred, if ((bool)std::__invoke(__pred,
std::__invoke(__proj, *__first), std::__invoke(__proj, *__first),
std::__invoke(__proj, *__next))) std::__invoke(__proj, *__next)))
return __first; return __first;
} }
return __next; return __next;
......
...@@ -259,27 +259,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -259,27 +259,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [concepts.compare], comparison concepts // [concepts.compare], comparison concepts
/// [concept.boolean], concept boolean // [concept.booleantestable], Boolean testability
template<typename _Bp> namespace __detail
concept boolean {
= movable<remove_cvref_t<_Bp>> template<typename _Tp>
&& requires(__detail::__cref<_Bp> __b1, __detail::__cref<_Bp> __b2, concept __boolean_testable_impl = convertible_to<_Tp, bool>;
const bool __a) {
{ __b1 } -> convertible_to<bool>; template<typename _Tp>
{ !__b1 } -> convertible_to<bool>; concept __boolean_testable
{ __b1 && __b2 } -> same_as<bool>; = __boolean_testable_impl<_Tp>
{ __b1 && __a } -> same_as<bool>; && requires(_Tp&& __t)
{ __a && __b2 } -> same_as<bool>; { { !static_cast<_Tp&&>(__t) } -> __boolean_testable_impl; };
{ __b1 || __b2 } -> same_as<bool>; } // namespace __detail
{ __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.equalitycomparable], concept equality_comparable // [concept.equalitycomparable], concept equality_comparable
...@@ -288,10 +279,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -288,10 +279,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
concept __weakly_eq_cmp_with concept __weakly_eq_cmp_with
= requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) { = requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
{ __t == __u } -> boolean; { __t == __u } -> __boolean_testable;
{ __t != __u } -> boolean; { __t != __u } -> __boolean_testable;
{ __u == __t } -> boolean; { __u == __t } -> __boolean_testable;
{ __u != __t } -> boolean; { __u != __t } -> __boolean_testable;
}; };
} // namespace __detail } // namespace __detail
...@@ -311,10 +302,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -311,10 +302,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
concept totally_ordered concept totally_ordered
= equality_comparable<_Tp> = equality_comparable<_Tp>
&& requires(__detail::__cref<_Tp> __a, __detail::__cref<_Tp> __b) { && requires(__detail::__cref<_Tp> __a, __detail::__cref<_Tp> __b) {
{ __a < __b } -> boolean; { __a < __b } -> __detail::__boolean_testable;
{ __a > __b } -> boolean; { __a > __b } -> __detail::__boolean_testable;
{ __a <= __b } -> boolean; { __a <= __b } -> __detail::__boolean_testable;
{ __a >= __b } -> boolean; { __a >= __b } -> __detail::__boolean_testable;
}; };
template<typename _Tp, typename _Up> template<typename _Tp, typename _Up>
...@@ -325,14 +316,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -325,14 +316,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__detail::__cref<_Up>>> __detail::__cref<_Up>>>
&& equality_comparable_with<_Tp, _Up> && equality_comparable_with<_Tp, _Up>
&& requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) { && requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
{ __t < __u } -> boolean; { __t < __u } -> __detail::__boolean_testable;
{ __t > __u } -> boolean; { __t > __u } -> __detail::__boolean_testable;
{ __t <= __u } -> boolean; { __t <= __u } -> __detail::__boolean_testable;
{ __t >= __u } -> boolean; { __t >= __u } -> __detail::__boolean_testable;
{ __u < __t } -> boolean; { __u < __t } -> __detail::__boolean_testable;
{ __u > __t } -> boolean; { __u > __t } -> __detail::__boolean_testable;
{ __u <= __t } -> boolean; { __u <= __t } -> __detail::__boolean_testable;
{ __u >= __t } -> boolean; { __u >= __t } -> __detail::__boolean_testable;
}; };
template<typename _Tp> template<typename _Tp>
...@@ -351,7 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -351,7 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// [concept.predicate], concept predicate /// [concept.predicate], concept predicate
template<typename _Fn, typename... _Args> template<typename _Fn, typename... _Args>
concept predicate = regular_invocable<_Fn, _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 /// [concept.relation], concept relation
template<typename _Rel, typename _Tp, typename _Up> template<typename _Rel, typename _Tp, typename _Up>
......
...@@ -416,14 +416,14 @@ namespace std ...@@ -416,14 +416,14 @@ namespace std
concept __partially_ordered_with concept __partially_ordered_with
= requires(const remove_reference_t<_Tp>& __t, = requires(const remove_reference_t<_Tp>& __t,
const remove_reference_t<_Up>& __u) { const remove_reference_t<_Up>& __u) {
{ __t < __u } -> boolean; { __t < __u } -> __boolean_testable;
{ __t > __u } -> boolean; { __t > __u } -> __boolean_testable;
{ __t <= __u } -> boolean; { __t <= __u } -> __boolean_testable;
{ __t >= __u } -> boolean; { __t >= __u } -> __boolean_testable;
{ __u < __t } -> boolean; { __u < __t } -> __boolean_testable;
{ __u > __t } -> boolean; { __u > __t } -> __boolean_testable;
{ __u <= __t } -> boolean; { __u <= __t } -> __boolean_testable;
{ __u >= __t } -> boolean; { __u >= __t } -> __boolean_testable;
}; };
} // namespace __detail } // namespace __detail
...@@ -879,8 +879,8 @@ namespace std ...@@ -879,8 +879,8 @@ namespace std
operator()(const _Tp& __t, const _Up& __u) const operator()(const _Tp& __t, const _Up& __u) const
requires requires requires requires
{ {
{ __t < __u } -> convertible_to<bool>; { __t < __u } -> __boolean_testable;
{ __u < __t } -> convertible_to<bool>; { __u < __t } -> __boolean_testable;
} }
{ {
if constexpr (three_way_comparable_with<_Tp, _Up>) if constexpr (three_way_comparable_with<_Tp, _Up>)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment