/* VERIFY_OPTS: -o nofail:malloc */ /* PROGRAM_OPTS: --use-colour no */ #include #include #include "common.h" #include "lazy.h" #include "sequence.h" namespace { template< template< typename > class Struct > void emptyStructure() { Struct< int > data{ 1 }; Struct< int > data2; int executions = 0; auto z = lazy::zip( data.begin(), data.end(), data2.begin(), data2.end(), [&]( int, int ) { ++executions; return 1; } ); for ( int i : z ) { REQUIRE( false ); } REQUIRE( 0 == std::accumulate( z.begin(), z.end(), 0 ) ); REQUIRE( 0 == executions ); REQUIRE( z.begin() == z.end() ); } } TEST_CASE( "zip::empty" ) { SECTION( "vector" ) { ::emptyStructure< ::tests::Vector >(); } SECTION( "list" ) { ::emptyStructure< ::tests::List >(); } SECTION( "set" ) { ::emptyStructure< ::tests::Set >(); } } namespace { template< template< typename > class A, template< typename > class B > void zippedStructures() { A< int > a{ 1,-2,-3,4,5 }; B< char > b{ '+', '-', '+', '-' }; const int expected[] = { 1, -2, 3, -4 }; int executions = 0; auto z = lazy::zip( a.begin(), a.end(), b.begin(), b.end(), [&]( int a, char b ) { ++executions; if ( b == '-' ) return -std::abs( a ); if ( b == '+' ) return std::abs( a ); return 0; } ); auto i = z.begin(); const int *ex = expected; for ( ; i != z.end(); ++i, ++ex ) { REQUIRE( *i != 0 ); REQUIRE( *i == *ex ); } REQUIRE( executions == std::min( a.size(), b.size() ) ); } } TEST_CASE( "zip::zipped" ) { SECTION( "vector+list" ) { ::zippedStructures< ::tests::Vector, ::tests::List >(); ::zippedStructures< ::tests::List, ::tests::Vector >(); } SECTION( "set" ) { ::tests::Set< int > numbers{ 1,2,3,4,5 }; ::tests::Vector< int > s{1,1,1,1,1}; // auto s = sequence::infinite( []( sequence::Parameter< int > ) { // return 1; // }, 1 ); auto z = lazy::zip( numbers.begin(), numbers.end(), s.begin(), s.end(), []( int n, int l ) { return n + l; } ); std::map< int, int > occurences; for ( int i : z ) { occurences[ i ]++; } for ( int i = 2; i <= 6; ++i ) { REQUIRE( occurences[ i ] == 1 ); } REQUIRE( occurences.size() == 5 ); } } namespace { template< template< typename > class Struct > void arrow() { Struct< std::string > texts{ "a", "b", "hello", "world", "fuchsie" }; Struct< size_t > length{ 2, 2, 3, 4, 5 }; const size_t expected[] = { 1,1,3,4,5 }; size_t executions = 0; auto f = lazy::zip( texts.begin(), texts.end(), length.begin(), length.end(), [&]( const std::string &s, size_t l ) -> std::string { ++executions; return l >= s.size() ? s : s.substr( 0, l ); } ); const size_t *l = expected; for ( auto i = f.begin(); i != f.end(); ++i, ++l ) { REQUIRE( i->size() == *l ); REQUIRE( ( *i ).size() == *l ); } REQUIRE( executions == texts.size() ); } } TEST_CASE( "zip::arrow" ) { SECTION( "vector" ) { ::arrow< ::tests::Vector >(); } SECTION( "list" ) { ::arrow< ::tests::List >(); } } namespace { template< template< typename > class Struct > void operators() { Struct< std::string > data{ "hel", "dol" }; Struct< std::string > suff{ "lo", "ly" }; auto z = lazy::zip( data.begin(), data.end(), suff.begin(), suff.end(), []( const std::string &p, const std::string &s ) { return p + s; } ); ::tests::iteratorManipulation( z.begin() ); ::tests::iteratorContent( z.begin(), *data.begin() + *suff.begin() ); ::tests::iteratorContent( ++z.begin(), *++data.begin() + *++suff.begin() ); } } TEST_CASE( "zip::operators" ) { SECTION( "vector" ) { ::operators< ::tests::Vector >(); } SECTION( "list" ) { ::operators< ::tests::List >(); } }