From d95823caac3bdbe7f697d83e9bf70aaf211a2717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Fri, 14 Jun 2019 13:44:03 +0200 Subject: [PATCH 1/2] Implemented changes from P1716 The changes in this papers weakness the constrains of compare algorithm to be derived from the predicate (required invocation only in the specific direction). The IndirectRelation concept is now replaced with IndirectBinaryPredicate, that requires only single order of argument. The IndirectlyComparable concept is now derived from IndirectBinaryPredicate. Updated the following algorithms, to use IndirectRelation: * find, * adjacent_find, * count, * replace and replace_copy, * remove and remove_copy, * unique and unique_copy. In addition the following two algorithms were changed to use IndirectlyComparable as they compare elements of two different sequences: * find_first_of, * mismatch. --- include/stl2/detail/algorithm/adjacent_find.hpp | 4 ++-- include/stl2/detail/algorithm/count.hpp | 4 ++-- include/stl2/detail/algorithm/find.hpp | 4 ++-- include/stl2/detail/algorithm/find_first_of.hpp | 14 ++++++++------ include/stl2/detail/algorithm/mismatch.hpp | 13 +++++++------ include/stl2/detail/algorithm/remove.hpp | 4 ++-- include/stl2/detail/algorithm/remove_copy.hpp | 4 ++-- include/stl2/detail/algorithm/replace.hpp | 4 ++-- include/stl2/detail/algorithm/replace_copy.hpp | 4 ++-- include/stl2/detail/algorithm/unique.hpp | 4 ++-- include/stl2/detail/algorithm/unique_copy.hpp | 4 ++-- include/stl2/detail/concepts/callable.hpp | 14 +++++++------- 12 files changed, 40 insertions(+), 37 deletions(-) diff --git a/include/stl2/detail/algorithm/adjacent_find.hpp b/include/stl2/detail/algorithm/adjacent_find.hpp index 068c49c46..c6e1442a7 100644 --- a/include/stl2/detail/algorithm/adjacent_find.hpp +++ b/include/stl2/detail/algorithm/adjacent_find.hpp @@ -23,7 +23,7 @@ STL2_OPEN_NAMESPACE { struct __adjacent_find_fn : private __niebloid { template S, class Proj = identity, - IndirectRelation> Pred = equal_to> + IndirectBinaryPredicate, projected> Pred = equal_to> constexpr I operator()(I first, S last, Pred pred = {}, Proj proj = {}) const { if (first == last) { @@ -42,7 +42,7 @@ STL2_OPEN_NAMESPACE { } template, Proj>> Pred = equal_to> + IndirectBinaryPredicate, Proj>, projected, Proj>> Pred = equal_to> constexpr safe_iterator_t operator()(R&& r, Pred pred = {}, Proj proj = {}) const { return (*this)(begin(r), end(r), __stl2::ref(pred), diff --git a/include/stl2/detail/algorithm/count.hpp b/include/stl2/detail/algorithm/count.hpp index 6758b8b67..0fa8900ce 100644 --- a/include/stl2/detail/algorithm/count.hpp +++ b/include/stl2/detail/algorithm/count.hpp @@ -21,7 +21,7 @@ STL2_OPEN_NAMESPACE { struct __count_fn : private __niebloid { template S, class T, class Proj = identity> - requires IndirectRelation, const T*> + requires IndirectBinaryPredicate, const T*> constexpr iter_difference_t operator()(I first, S last, const T& value, Proj proj = {}) const { iter_difference_t n = 0; @@ -34,7 +34,7 @@ STL2_OPEN_NAMESPACE { } template - requires IndirectRelation, Proj>, const T*> + requires IndirectBinaryPredicate, Proj>, const T*> constexpr iter_difference_t> operator()(R&& r, const T& value, Proj proj = {}) const { return (*this)(begin(r), end(r), value, __stl2::ref(proj)); diff --git a/include/stl2/detail/algorithm/find.hpp b/include/stl2/detail/algorithm/find.hpp index fc88aeba4..5bce9d58f 100644 --- a/include/stl2/detail/algorithm/find.hpp +++ b/include/stl2/detail/algorithm/find.hpp @@ -21,7 +21,7 @@ STL2_OPEN_NAMESPACE { struct __find_fn : private __niebloid { template S, class T, class Proj = identity> - requires IndirectRelation, const T*> + requires IndirectBinaryPredicate, const T*> constexpr I operator()(I first, S last, const T& value, Proj proj = {}) const { for (; first != last; ++first) { @@ -33,7 +33,7 @@ STL2_OPEN_NAMESPACE { } template - requires IndirectRelation, Proj>, const T*> + requires IndirectBinaryPredicate, Proj>, const T*> constexpr safe_iterator_t operator()(R&& r, const T& value, Proj proj = {}) const { return (*this)(begin(r), end(r), value, __stl2::ref(proj)); diff --git a/include/stl2/detail/algorithm/find_first_of.hpp b/include/stl2/detail/algorithm/find_first_of.hpp index 5e597d4e9..9629a819b 100644 --- a/include/stl2/detail/algorithm/find_first_of.hpp +++ b/include/stl2/detail/algorithm/find_first_of.hpp @@ -22,8 +22,10 @@ STL2_OPEN_NAMESPACE { struct __find_first_of_fn : private __niebloid { template S1, ForwardIterator I2, Sentinel S2, - class Proj1 = identity, class Proj2 = identity, - IndirectRelation, projected> Pred = equal_to> + class Pred = equal_to, + class Proj1 = identity, class Proj2 = identity> + requires + IndirectlyComparable constexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { @@ -40,10 +42,10 @@ STL2_OPEN_NAMESPACE { } template, Proj1>, - projected, Proj2>> Pred = equal_to> + class Pred = equal_to, + class Proj1 = identity, class Proj2 = identity> + requires + IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr safe_iterator_t operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const diff --git a/include/stl2/detail/algorithm/mismatch.hpp b/include/stl2/detail/algorithm/mismatch.hpp index ebae9102a..06d059268 100644 --- a/include/stl2/detail/algorithm/mismatch.hpp +++ b/include/stl2/detail/algorithm/mismatch.hpp @@ -25,9 +25,9 @@ STL2_OPEN_NAMESPACE { struct __mismatch_fn : private __niebloid { template S1, InputIterator I2, - Sentinel S2, class Proj1 = identity, class Proj2 = identity, - IndirectRelation, - projected> Pred = equal_to> + Sentinel S2, class Pred = equal_to, class Proj1 = identity, class Proj2 = identity> + requires + IndirectlyComparable constexpr mismatch_result operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const @@ -47,9 +47,10 @@ STL2_OPEN_NAMESPACE { } template, Proj1>, - projected, Proj2>> Pred = equal_to> + class Pred = equal_to, + class Proj1 = identity, class Proj2 = identity> + requires + IndirectlyComparable, iterator_t, Pred, Proj1, Proj2> constexpr mismatch_result, safe_iterator_t> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const diff --git a/include/stl2/detail/algorithm/remove.hpp b/include/stl2/detail/algorithm/remove.hpp index cc317034b..a560b1fd3 100644 --- a/include/stl2/detail/algorithm/remove.hpp +++ b/include/stl2/detail/algorithm/remove.hpp @@ -22,7 +22,7 @@ STL2_OPEN_NAMESPACE { struct __remove_fn : private __niebloid { template S, class T, class Proj = identity> - requires IndirectRelation, const T*> + requires IndirectBinaryPredicate, const T*> constexpr I operator()(I first, S last, const T& value, Proj proj = {}) const { first = find(std::move(first), last, value, __stl2::ref(proj)); @@ -39,7 +39,7 @@ STL2_OPEN_NAMESPACE { template requires Permutable> && - IndirectRelation, Proj>, const T*> + IndirectBinaryPredicate, Proj>, const T*> constexpr safe_iterator_t operator()(Rng&& rng, const T& value, Proj proj = {}) const { return (*this)(begin(rng), end(rng), value, __stl2::ref(proj)); diff --git a/include/stl2/detail/algorithm/remove_copy.hpp b/include/stl2/detail/algorithm/remove_copy.hpp index 90fe29315..1e403d747 100644 --- a/include/stl2/detail/algorithm/remove_copy.hpp +++ b/include/stl2/detail/algorithm/remove_copy.hpp @@ -27,7 +27,7 @@ STL2_OPEN_NAMESPACE { template S, WeaklyIncrementable O, class T, class Proj = identity> requires IndirectlyCopyable && - IndirectRelation, const T*> + IndirectBinaryPredicate, const T*> constexpr remove_copy_result operator()(I first, S last, O result, const T& value, Proj proj = {}) const { for (; first != last; ++first) { @@ -42,7 +42,7 @@ STL2_OPEN_NAMESPACE { template requires IndirectlyCopyable, O> && - IndirectRelation, Proj>, const T*> + IndirectBinaryPredicate, Proj>, const T*> constexpr remove_copy_result, O> operator()(R&& r, O result, const T& value, Proj proj = {}) const { return (*this)(begin(r), end(r), std::move(result), value, __stl2::ref(proj)); diff --git a/include/stl2/detail/algorithm/replace.hpp b/include/stl2/detail/algorithm/replace.hpp index 779697ef4..4c650c9a6 100644 --- a/include/stl2/detail/algorithm/replace.hpp +++ b/include/stl2/detail/algorithm/replace.hpp @@ -23,7 +23,7 @@ STL2_OPEN_NAMESPACE { template S, class T1, class T2, class Proj = identity> requires Writable && - IndirectRelation, const T1*> + IndirectBinaryPredicate, const T1*> constexpr I operator()(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}) const { @@ -37,7 +37,7 @@ STL2_OPEN_NAMESPACE { template requires Writable, const T2&> && - IndirectRelation, Proj>, const T1*> + IndirectBinaryPredicate, Proj>, const T1*> constexpr safe_iterator_t operator()(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}) const { diff --git a/include/stl2/detail/algorithm/replace_copy.hpp b/include/stl2/detail/algorithm/replace_copy.hpp index f709f8961..2c879c126 100644 --- a/include/stl2/detail/algorithm/replace_copy.hpp +++ b/include/stl2/detail/algorithm/replace_copy.hpp @@ -27,7 +27,7 @@ STL2_OPEN_NAMESPACE { template S, class T1, class T2, OutputIterator O, class Proj = identity> requires IndirectlyCopyable && - IndirectRelation, const T1*> + IndirectBinaryPredicate, const T1*> constexpr replace_copy_result operator()(I first, S last, O result, const T1& old_value, const T2& new_value, Proj proj = {}) const @@ -46,7 +46,7 @@ STL2_OPEN_NAMESPACE { template O, class Proj = identity> requires IndirectlyCopyable, O> && - IndirectRelation, Proj>, const T1*> + IndirectBinaryPredicate, Proj>, const T1*> constexpr replace_copy_result, O> operator()(R&& r, O result, const T1& old_value, const T2& new_value, Proj proj = {}) const diff --git a/include/stl2/detail/algorithm/unique.hpp b/include/stl2/detail/algorithm/unique.hpp index 0650f5a59..abf0b952d 100644 --- a/include/stl2/detail/algorithm/unique.hpp +++ b/include/stl2/detail/algorithm/unique.hpp @@ -22,7 +22,7 @@ STL2_OPEN_NAMESPACE { struct __unique_fn : private __niebloid { template S, class Proj = identity, - IndirectRelation> Comp = equal_to> + IndirectBinaryPredicate, projected> Comp = equal_to> constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const { first = adjacent_find(std::move(first), last, __stl2::ref(comp), @@ -41,7 +41,7 @@ STL2_OPEN_NAMESPACE { } template, Proj>> Comp = equal_to> + IndirectBinaryPredicate, Proj>, projected, Proj>> Comp = equal_to> requires Permutable> constexpr safe_iterator_t operator()(R&& r, Comp comp = {}, Proj proj = {}) const { diff --git a/include/stl2/detail/algorithm/unique_copy.hpp b/include/stl2/detail/algorithm/unique_copy.hpp index 463a340f7..ea119b806 100644 --- a/include/stl2/detail/algorithm/unique_copy.hpp +++ b/include/stl2/detail/algorithm/unique_copy.hpp @@ -30,7 +30,7 @@ STL2_OPEN_NAMESPACE { struct __unique_copy_fn : private __niebloid { template S, WeaklyIncrementable O, class Proj = identity, - IndirectRelation> C = equal_to> + IndirectBinaryPredicate, projected> C = equal_to> requires IndirectlyCopyable && (ForwardIterator || __unique_copy_helper || IndirectlyCopyableStorable) @@ -82,7 +82,7 @@ STL2_OPEN_NAMESPACE { } template, Proj>> C = equal_to> + IndirectBinaryPredicate, Proj>, projected, Proj>> C = equal_to> requires IndirectlyCopyable, O> && (ForwardRange || __unique_copy_helper, O> || IndirectlyCopyableStorable, O>) diff --git a/include/stl2/detail/concepts/callable.hpp b/include/stl2/detail/concepts/callable.hpp index 1cc3e8ba3..390221de8 100644 --- a/include/stl2/detail/concepts/callable.hpp +++ b/include/stl2/detail/concepts/callable.hpp @@ -119,15 +119,15 @@ STL2_OPEN_NAMESPACE { ext::IndirectPredicate; template - META_CONCEPT IndirectRelation = + META_CONCEPT IndirectBinaryPredicate = Readable && Readable && CopyConstructible && - Relation&, iter_value_t&> && - Relation&, iter_reference_t> && - Relation, iter_value_t&> && - Relation, iter_reference_t> && - Relation, iter_common_reference_t>; + Predicate&, iter_value_t&> && + Predicate&, iter_reference_t> && + Predicate, iter_value_t&> && + Predicate, iter_reference_t> && + Predicate, iter_common_reference_t>; template META_CONCEPT IndirectStrictWeakOrder = @@ -160,7 +160,7 @@ STL2_OPEN_NAMESPACE { template META_CONCEPT IndirectlyComparable = - IndirectRelation, projected>; + IndirectBinaryPredicate, projected>; //////////////////////////////////////////////////////////////////////////// // Permutable [alg.req.permutable] From bd56497fdb0a69e19d0a4ad7b97cae6c37d84074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Sat, 15 Jun 2019 09:04:29 +0200 Subject: [PATCH 2/2] Implement EquivalenceRelation. Implemented EquivalenceRelation (and derived IndirectEquivalenceRelation) concept, that are used to properly constrain the is_permutation algorithm. In addition they are now used for unique and unique_copy to match their non-range constrains. --- include/stl2/detail/algorithm/is_permutation.hpp | 12 +++++------- include/stl2/detail/algorithm/unique.hpp | 4 ++-- include/stl2/detail/algorithm/unique_copy.hpp | 4 ++-- include/stl2/detail/concepts/callable.hpp | 11 +++++++++++ include/stl2/detail/concepts/function.hpp | 6 ++++++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/stl2/detail/algorithm/is_permutation.hpp b/include/stl2/detail/algorithm/is_permutation.hpp index a20e4d14f..2b6308acd 100644 --- a/include/stl2/detail/algorithm/is_permutation.hpp +++ b/include/stl2/detail/algorithm/is_permutation.hpp @@ -28,9 +28,8 @@ STL2_OPEN_NAMESPACE { struct __is_permutation_fn : private __niebloid { template S1, ForwardIterator I2, - Sentinel S2, class Pred = equal_to, class Proj1 = identity, - class Proj2 = identity> - requires IndirectlyComparable + Sentinel S2, class Proj1 = identity, class Proj2 = identity, + IndirectEquivalenceRelation, projected> Pred = equal_to> constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { @@ -61,10 +60,9 @@ STL2_OPEN_NAMESPACE { } } - template - requires IndirectlyComparable, iterator_t, Pred, - Proj1, Proj2> + template, Proj1>, projected, Proj2>> Pred = equal_to> constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { diff --git a/include/stl2/detail/algorithm/unique.hpp b/include/stl2/detail/algorithm/unique.hpp index abf0b952d..533048b50 100644 --- a/include/stl2/detail/algorithm/unique.hpp +++ b/include/stl2/detail/algorithm/unique.hpp @@ -22,7 +22,7 @@ STL2_OPEN_NAMESPACE { struct __unique_fn : private __niebloid { template S, class Proj = identity, - IndirectBinaryPredicate, projected> Comp = equal_to> + IndirectEquivalenceRelation> Comp = equal_to> constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const { first = adjacent_find(std::move(first), last, __stl2::ref(comp), @@ -41,7 +41,7 @@ STL2_OPEN_NAMESPACE { } template, Proj>, projected, Proj>> Comp = equal_to> + IndirectEquivalenceRelation, Proj>> Comp = equal_to> requires Permutable> constexpr safe_iterator_t operator()(R&& r, Comp comp = {}, Proj proj = {}) const { diff --git a/include/stl2/detail/algorithm/unique_copy.hpp b/include/stl2/detail/algorithm/unique_copy.hpp index ea119b806..4a45cc484 100644 --- a/include/stl2/detail/algorithm/unique_copy.hpp +++ b/include/stl2/detail/algorithm/unique_copy.hpp @@ -30,7 +30,7 @@ STL2_OPEN_NAMESPACE { struct __unique_copy_fn : private __niebloid { template S, WeaklyIncrementable O, class Proj = identity, - IndirectBinaryPredicate, projected> C = equal_to> + IndirectEquivalenceRelation> C = equal_to> requires IndirectlyCopyable && (ForwardIterator || __unique_copy_helper || IndirectlyCopyableStorable) @@ -82,7 +82,7 @@ STL2_OPEN_NAMESPACE { } template, Proj>, projected, Proj>> C = equal_to> + IndirectEquivalenceRelation, Proj>> C = equal_to> requires IndirectlyCopyable, O> && (ForwardRange || __unique_copy_helper, O> || IndirectlyCopyableStorable, O>) diff --git a/include/stl2/detail/concepts/callable.hpp b/include/stl2/detail/concepts/callable.hpp index 390221de8..c6c57d3a6 100644 --- a/include/stl2/detail/concepts/callable.hpp +++ b/include/stl2/detail/concepts/callable.hpp @@ -129,6 +129,17 @@ STL2_OPEN_NAMESPACE { Predicate, iter_reference_t> && Predicate, iter_common_reference_t>; + template + META_CONCEPT IndirectEquivalenceRelation = + Readable && + Readable && + CopyConstructible && + EquivalenceRelation&, iter_value_t&> && + EquivalenceRelation&, iter_reference_t> && + EquivalenceRelation, iter_value_t&> && + EquivalenceRelation, iter_reference_t> && + EquivalenceRelation, iter_common_reference_t>; + template META_CONCEPT IndirectStrictWeakOrder = Readable && diff --git a/include/stl2/detail/concepts/function.hpp b/include/stl2/detail/concepts/function.hpp index 361950c46..6d4218c65 100644 --- a/include/stl2/detail/concepts/function.hpp +++ b/include/stl2/detail/concepts/function.hpp @@ -66,6 +66,12 @@ STL2_OPEN_NAMESPACE { const std::remove_reference_t&, const std::remove_reference_t&>>; + /////////////////////////////////////////////////////////////////////////// + // EquivalenceRelation + // + template + META_CONCEPT EquivalenceRelation = Relation; + /////////////////////////////////////////////////////////////////////////// // StrictWeakOrder [concepts.lib.callables.strictweakorder] //