Merge pull request #100 from jgopel/copy-if-while

Implement copy_if_while and copy_if_until
This commit is contained in:
Marshall Clow
2022-06-28 17:46:45 -07:00
committed by GitHub
3 changed files with 328 additions and 7 deletions

View File

@ -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 );
}