mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-23 01:18:52 +08:00
Fix the BinaryPredicate form of std::is_permutation to not rely on operator==
According to [1], forms 2 and 4 of std::is_permutation should use the passed in binary predicate to compare elements. operator== should only be used for forms 1 and 3 which do not take a binary predicate. This CL fixes forms 2 and 4 which relied on operator== for some comparisons. [1] http://en.cppreference.com/w/cpp/algorithm/is_permutation Patch by Thomas Anderson! Differential Revision: https://reviews.llvm.org/D42518 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@323563 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1418,7 +1418,11 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
|||||||
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
|
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
|
||||||
{
|
{
|
||||||
// Have we already counted the number of *__i in [f1, l1)?
|
// Have we already counted the number of *__i in [f1, l1)?
|
||||||
if (find(__first1, __i, *__i) == __i) {
|
_ForwardIterator1 __match = __first1;
|
||||||
|
for (; __match != __i; ++__match)
|
||||||
|
if (__pred(*__match, *__i))
|
||||||
|
break;
|
||||||
|
if (__match == __i) {
|
||||||
// Count number of *__i in [f2, l2)
|
// Count number of *__i in [f2, l2)
|
||||||
_D1 __c2 = 0;
|
_D1 __c2 = 0;
|
||||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||||
@@ -1479,7 +1483,11 @@ __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
|||||||
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
|
for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
|
||||||
{
|
{
|
||||||
// Have we already counted the number of *__i in [f1, l1)?
|
// Have we already counted the number of *__i in [f1, l1)?
|
||||||
if (find(__first1, __i, *__i) == __i) {
|
_ForwardIterator1 __match = __first1;
|
||||||
|
for (; __match != __i; ++__match)
|
||||||
|
if (__pred(*__match, *__i))
|
||||||
|
break;
|
||||||
|
if (__match == __i) {
|
||||||
// Count number of *__i in [f2, l2)
|
// Count number of *__i in [f2, l2)
|
||||||
_D1 __c2 = 0;
|
_D1 __c2 = 0;
|
||||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||||
|
@@ -736,6 +736,30 @@ int main()
|
|||||||
forward_iterator<const int*>(ib),
|
forward_iterator<const int*>(ib),
|
||||||
forward_iterator<const int*>(ib + sa),
|
forward_iterator<const int*>(ib + sa),
|
||||||
std::equal_to<const int>()) == false);
|
std::equal_to<const int>()) == false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct S {
|
||||||
|
S(int i) : i_(i) {}
|
||||||
|
bool operator==(const S& other) = delete;
|
||||||
|
int i_;
|
||||||
|
};
|
||||||
|
struct eq {
|
||||||
|
bool operator()(const S& a, const S&b) { return a.i_ == b.i_; }
|
||||||
|
};
|
||||||
|
const S a[] = {S(0), S(1)};
|
||||||
|
const S b[] = {S(1), S(0)};
|
||||||
|
const unsigned sa = sizeof(a)/sizeof(a[0]);
|
||||||
|
assert(std::is_permutation(forward_iterator<const S*>(a),
|
||||||
|
forward_iterator<const S*>(a + sa),
|
||||||
|
forward_iterator<const S*>(b),
|
||||||
|
eq()));
|
||||||
|
#if TEST_STD_VER >= 14
|
||||||
|
assert(std::is_permutation(forward_iterator<const S*>(a),
|
||||||
|
forward_iterator<const S*>(a + sa),
|
||||||
|
forward_iterator<const S*>(b),
|
||||||
|
forward_iterator<const S*>(b + sa),
|
||||||
|
eq()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user