forked from boostorg/algorithm
Merge pull request #100 from jgopel/copy-if-while
Implement copy_if_while and copy_if_until
This commit is contained in:
@ -34,13 +34,15 @@ BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_odd ( int v ) { return v % 2 == 1; }
|
||||
BOOST_CXX14_CONSTEXPR bool is_zero ( int v ) { return v == 0; }
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool less_than_ten ( int v ) { return v < 10; }
|
||||
BOOST_CXX14_CONSTEXPR bool greater_than_ten ( int v ) { return v > 10; }
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_if ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
std::vector<value_type> v;
|
||||
|
||||
|
||||
// None of the elements
|
||||
v.clear ();
|
||||
ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_false);
|
||||
@ -118,6 +120,160 @@ void test_copy_while ( Container const &c ) {
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_if_while ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typename Container::const_iterator it;
|
||||
|
||||
// Terminate immediately
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_true, is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c, back_inserter ( v ), is_true, is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
|
||||
// Copy nothing - never terminate
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_false, is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c, back_inserter ( v ), is_false, is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
|
||||
// Copy everything
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_true, is_true);
|
||||
BOOST_CHECK ( v.size () == c.size() );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c, back_inserter ( v ), is_true, is_true);
|
||||
BOOST_CHECK ( v.size () == c.size() );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
|
||||
// Copy all evens
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_even, is_true);
|
||||
BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_while ( c, back_inserter ( v ), is_even, is_true);
|
||||
BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
|
||||
// Copy some until termination
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
typename Container::const_iterator it = ba::copy_if_while (
|
||||
c.begin (), c.end (), back_inserter ( v ), is_even, less_than_ten).first;
|
||||
BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
typename Container::const_iterator it = ba::copy_if_while (
|
||||
c, back_inserter ( v ), is_even, less_than_ten).first;
|
||||
BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_if_until ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typename Container::const_iterator it;
|
||||
|
||||
// Terminate immediately
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_true, is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c, back_inserter ( v ), is_true, is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
|
||||
// Copy nothing - never terminate
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_false, is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c, back_inserter ( v ), is_false, is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
}
|
||||
|
||||
// Copy everything
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_true, is_false);
|
||||
BOOST_CHECK ( v.size () == c.size() );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c, back_inserter ( v ), is_true, is_false);
|
||||
BOOST_CHECK ( v.size () == c.size() );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
|
||||
// Copy all evens
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_even, is_false);
|
||||
BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
ba::copy_if_until ( c, back_inserter ( v ), is_even, is_false);
|
||||
BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
|
||||
// Copy some until termination
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
typename Container::const_iterator it = ba::copy_if_until (
|
||||
c.begin (), c.end (), back_inserter ( v ), is_even, greater_than_ten).first;
|
||||
BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
{
|
||||
std::vector<value_type> v;
|
||||
typename Container::const_iterator it = ba::copy_if_until (
|
||||
c, back_inserter ( v ), is_even, greater_than_ten).first;
|
||||
BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_until ( Container const &c ) {
|
||||
|
||||
@ -224,8 +380,77 @@ BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_until() {
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if_while() {
|
||||
const int sz = 64;
|
||||
int in_data[sz] = {0};
|
||||
bool res = true;
|
||||
|
||||
const int* from = in_data;
|
||||
const int* to = in_data + sz;
|
||||
|
||||
// Terminate immediately
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_while ( from, to, out, is_true, is_false ).second;
|
||||
res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
|
||||
}
|
||||
// Copy nothing
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_while ( from, to, out, is_false, is_true ).second;
|
||||
res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
|
||||
}
|
||||
// Copy everything
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_while ( from, to, out, is_true, is_true ).second;
|
||||
res = (res && out == out_data + sz
|
||||
&& ba::equal( input_iterator<const int *>(out_data), input_iterator<const int *>(out_data + sz),
|
||||
input_iterator<const int *>(from), input_iterator<const int *>(to)));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if_until() {
|
||||
const int sz = 64;
|
||||
int in_data[sz] = {0};
|
||||
bool res = true;
|
||||
|
||||
const int* from = in_data;
|
||||
const int* to = in_data + sz;
|
||||
|
||||
// Terminate immediately
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_until ( from, to, out, is_true, is_true ).second;
|
||||
res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
|
||||
}
|
||||
// Copy nothing
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_until ( from, to, out, is_false, is_false ).second;
|
||||
res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
|
||||
}
|
||||
// Copy everything
|
||||
{
|
||||
int out_data[sz] = {0};
|
||||
int* out = out_data;
|
||||
out = ba::copy_if_until ( from, to, out, is_true, is_false ).second;
|
||||
res = (res && out == out_data + sz
|
||||
&& ba::equal( input_iterator<const int *>(out_data), input_iterator<const int *>(out_data + sz),
|
||||
input_iterator<const int *>(from), input_iterator<const int *>(to)));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void test_sequence1 () {
|
||||
std::vector<int> v;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
@ -233,20 +458,26 @@ void test_sequence1 () {
|
||||
test_copy_if ( v );
|
||||
test_copy_while ( v );
|
||||
test_copy_until ( v );
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool constexpr_res_if = constexpr_test_copy_if();
|
||||
BOOST_CHECK ( constexpr_res_if );
|
||||
BOOST_CXX14_CONSTEXPR bool constexpr_res_while = constexpr_test_copy_while();
|
||||
BOOST_CHECK ( constexpr_res_while );
|
||||
BOOST_CXX14_CONSTEXPR bool constexpr_res_until = constexpr_test_copy_until();
|
||||
BOOST_CHECK ( constexpr_res_until );
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool constexpr_res_if_while = constexpr_test_copy_if_while();
|
||||
BOOST_CHECK ( constexpr_res_if_while );
|
||||
BOOST_CXX14_CONSTEXPR bool constexpr_res_if_until = constexpr_test_copy_if_until();
|
||||
BOOST_CHECK ( constexpr_res_if_until );
|
||||
|
||||
std::list<int> l;
|
||||
for ( int i = 25; i > 15; --i )
|
||||
l.push_back ( i );
|
||||
test_copy_if ( l );
|
||||
test_copy_while ( l );
|
||||
test_copy_until ( l );
|
||||
test_copy_if_while ( l );
|
||||
test_copy_if_until ( l );
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user