Better 'is_permutation' implementation, tests

[SVN r84389]
This commit is contained in:
Marshall Clow
2013-05-20 15:37:50 +00:00
parent a4b907197e
commit b9d89c559b
5 changed files with 414 additions and 341 deletions

View File

@ -24,9 +24,9 @@ bool never_eq ( const T&, const T& ) { return false; }
int comparison_count = 0;
template <typename T>
bool counting_equals ( const T &a, const T &b ) {
++comparison_count;
return a == b;
}
++comparison_count;
return a == b;
}
namespace ba = boost::algorithm;
@ -37,86 +37,89 @@ void test_equal ()
const int sz = sizeof (num)/sizeof(num[0]);
// Empty sequences are equal to each other, but not to non-empty sequences
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num),
never_eq<int> ));
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num),
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
never_eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
input_iterator<int *>(num), input_iterator<int *>(num)));
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
// Empty sequences are equal to each other, but not to non-empty sequences
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num),
never_eq<int> ));
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num),
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
never_eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
input_iterator<int *>(num), input_iterator<int *>(num)));
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
// Single element sequences are equal if they contain the same value
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
eq<int> ));
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
never_eq<int> ));
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
never_eq<int> ));
// Single element sequences are equal if they contain the same value
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
eq<int> ));
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
never_eq<int> ));
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
never_eq<int> ));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
eq<int> ));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
eq<int> ));
// Identical long sequences are equal.
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
never_eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1),
eq<int> ));
// Identical long sequences are equal.
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
never_eq<int> ));
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
eq<int> ));
// different sequences are different
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
eq<int> ));
// different sequences are different
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
eq<int> ));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1)));
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
eq<int> ));
// When there's a cheap check, bail early
comparison_count = 0;
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz - 1),
counting_equals<int> ));
BOOST_CHECK ( comparison_count == 0 );
// And when there's not, we can't
comparison_count = 0;
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
counting_equals<int> ));
BOOST_CHECK ( comparison_count > 0 );
// When there's a cheap check, bail early
comparison_count = 0;
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz - 1),
counting_equals<int> ));
BOOST_CHECK ( comparison_count == 0 );
// And when there's not, we can't
comparison_count = 0;
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
counting_equals<int> ));
BOOST_CHECK ( comparison_count > 0 );
}