libstdc++: Implement new predicate concepts from P1716R3
* include/bits/iterator_concepts.h (__iter_concept_impl): Add comments. (indirect_relation): Rename to indirect_binary_predicate and adjust definition as per P1716R3. (indirect_equivalence_relation): Define. (indirectly_comparable): Adjust definition. * include/std/concepts (equivalence_relation): Define. * testsuite/std/concepts/concepts.callable/relation.cc: Add tests for equivalence_relation. From-SVN: r278256
This commit is contained in:
parent
d99828eea2
commit
270082a7e1
@ -1,5 +1,15 @@
|
||||
2019-11-14 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/iterator_concepts.h (__iter_concept_impl): Add
|
||||
comments.
|
||||
(indirect_relation): Rename to indirect_binary_predicate and adjust
|
||||
definition as per P1716R3.
|
||||
(indirect_equivalence_relation): Define.
|
||||
(indirectly_comparable): Adjust definition.
|
||||
* include/std/concepts (equivalence_relation): Define.
|
||||
* testsuite/std/concepts/concepts.callable/relation.cc: Add tests for
|
||||
equivalence_relation.
|
||||
|
||||
* include/bits/iterator_concepts.h (disable_sized_sentinel): Rename to
|
||||
disable_sized_sentinel_for.
|
||||
* testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: Adjust.
|
||||
|
@ -420,20 +420,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
namespace __detail
|
||||
{
|
||||
template<typename _Iter>
|
||||
struct __iter_concept_impl
|
||||
{ };
|
||||
struct __iter_concept_impl;
|
||||
|
||||
// ITER_CONCEPT(I) is ITER_TRAITS(I)::iterator_concept if that is valid.
|
||||
template<typename _Iter>
|
||||
requires requires { typename __iter_traits<_Iter>::iterator_concept; }
|
||||
struct __iter_concept_impl<_Iter>
|
||||
{ using type = typename __iter_traits<_Iter>::iterator_concept; };
|
||||
|
||||
// Otherwise, ITER_TRAITS(I)::iterator_category if that is valid.
|
||||
template<typename _Iter>
|
||||
requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
|
||||
&& requires { typename __iter_traits<_Iter>::iterator_category; })
|
||||
struct __iter_concept_impl<_Iter>
|
||||
{ using type = typename __iter_traits<_Iter>::iterator_category; };
|
||||
|
||||
// Otherwise, random_access_tag if iterator_traits<I> is not specialized.
|
||||
template<typename _Iter>
|
||||
requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
|
||||
&& !requires { typename __iter_traits<_Iter>::iterator_category; }
|
||||
@ -441,7 +443,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
struct __iter_concept_impl<_Iter>
|
||||
{ using type = random_access_iterator_tag; };
|
||||
|
||||
// ITER_TRAITS
|
||||
// Otherwise, there is no ITER_CONCEPT(I) type.
|
||||
template<typename _Iter>
|
||||
struct __iter_concept_impl
|
||||
{ };
|
||||
|
||||
// ITER_CONCEPT
|
||||
template<typename _Iter>
|
||||
using __iter_concept = typename __iter_concept_impl<_Iter>::type;
|
||||
} // namespace __detail
|
||||
@ -615,15 +622,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
&& predicate<_Fn&, iter_reference_t<_Iter>>
|
||||
&& predicate<_Fn&, iter_common_reference_t<_Iter>>;
|
||||
|
||||
template<typename _Fn, typename _I1, typename _I2 = _I1>
|
||||
concept indirect_relation = readable<_I1> && readable<_I2>
|
||||
template<typename _Fn, typename _I1, typename _I2>
|
||||
concept indirect_binary_predicate = readable<_I1> && readable<_I2>
|
||||
&& copy_constructible<_Fn>
|
||||
&& relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
|
||||
&& relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
|
||||
&& relation<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
|
||||
&& relation<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
|
||||
&& relation<_Fn&, iter_common_reference_t<_I1>,
|
||||
iter_common_reference_t<_I2>>;
|
||||
&& predicate<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
|
||||
&& predicate<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
|
||||
&& predicate<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
|
||||
&& predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
|
||||
&& predicate<_Fn&, iter_common_reference_t<_I1>,
|
||||
iter_common_reference_t<_I2>>;
|
||||
|
||||
template<typename _Fn, typename _I1, typename _I2 = _I1>
|
||||
concept indirect_equivalence_relation = readable<_I1> && readable<_I2>
|
||||
&& copy_constructible<_Fn>
|
||||
&& equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
|
||||
&& equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
|
||||
&& equivalence_relation<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
|
||||
&& equivalence_relation<_Fn&, iter_reference_t<_I1>,
|
||||
iter_reference_t<_I2>>
|
||||
&& equivalence_relation<_Fn&, iter_common_reference_t<_I1>,
|
||||
iter_common_reference_t<_I2>>;
|
||||
|
||||
template<typename _Fn, typename _I1, typename _I2 = _I1>
|
||||
concept indirect_strict_weak_order = readable<_I1> && readable<_I2>
|
||||
@ -767,7 +785,8 @@ namespace ranges
|
||||
template<typename _I1, typename _I2, typename _Rel, typename _P1 = identity,
|
||||
typename _P2 = identity>
|
||||
concept indirectly_comparable
|
||||
= indirect_relation<_Rel, projected<_I1, _P1>, projected<_I2, _P2>>;
|
||||
= indirect_binary_predicate<_Rel, projected<_I1, _P1>,
|
||||
projected<_I2, _P2>>;
|
||||
|
||||
/// [alg.req.permutable], concept `permutable`
|
||||
template<typename _Iter>
|
||||
|
@ -334,26 +334,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// [concepts.callable], callable concepts
|
||||
|
||||
// [concept.invocable], concept invocable
|
||||
/// [concept.invocable], concept invocable
|
||||
template<typename _Fn, typename... _Args>
|
||||
concept invocable = is_invocable_v<_Fn, _Args...>;
|
||||
|
||||
// [concept.regularinvocable], concept regular_invocable
|
||||
/// [concept.regularinvocable], concept regular_invocable
|
||||
template<typename _Fn, typename... _Args>
|
||||
concept regular_invocable = invocable<_Fn, _Args...>;
|
||||
|
||||
// [concept.predicate], concept predicate
|
||||
/// [concept.predicate], concept predicate
|
||||
template<typename _Fn, typename... _Args>
|
||||
concept predicate = regular_invocable<_Fn, _Args...>
|
||||
&& boolean<invoke_result_t<_Fn, _Args...>>;
|
||||
|
||||
// [concept.relation], concept relation
|
||||
/// [concept.relation], concept relation
|
||||
template<typename _Rel, typename _Tp, typename _Up>
|
||||
concept relation
|
||||
= predicate<_Rel, _Tp, _Tp> && predicate<_Rel, _Up, _Up>
|
||||
&& predicate<_Rel, _Tp, _Up> && predicate<_Rel, _Up, _Tp>;
|
||||
|
||||
// [concept.strictweakorder], concept strict_weak_order
|
||||
/// [concept.equiv], concept equivalence_relation
|
||||
template<typename _Rel, typename _Tp, typename _Up>
|
||||
concept equivalence_relation = relation<_Rel, _Tp, _Up>;
|
||||
|
||||
/// [concept.strictweakorder], concept strict_weak_order
|
||||
template<typename _Rel, typename _Tp, typename _Up>
|
||||
concept strict_weak_order = relation<_Rel, _Tp, _Up>;
|
||||
|
||||
|
@ -46,3 +46,8 @@ struct F
|
||||
static_assert( ! std::relation<F, long, long> );
|
||||
static_assert( std::relation<F&, int, int> );
|
||||
static_assert( std::relation<const F&, const int, const int> );
|
||||
|
||||
// [concept.equiv]
|
||||
static_assert( std::equivalence_relation<bool(*)(int, int), short, long> );
|
||||
static_assert( ! std::equivalence_relation<F, long, long> );
|
||||
static_assert( std::equivalence_relation<const F&, const int, const int> );
|
||||
|
Loading…
Reference in New Issue
Block a user