Last active
March 19, 2019 21:52
-
-
Save id-ilych/599ac6b9d0b115e0f2425d1234b60860 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <functional> | |
#include <optional> | |
#include <vector> | |
#include <iostream> | |
template<typename T> | |
using Receiver = std::function<void( T )>; | |
template<typename T, typename U> | |
using Transformer = std::function<U( T )>; | |
template<typename T, typename U> | |
using Chainer = std::function<void( T, Receiver<U> )>; | |
template<typename T> | |
using Predicat = std::function<bool( T )>; | |
template<typename It> | |
using ValueOf = typename std::iterator_traits<It>::value_type; | |
template<typename It, typename T, typename U> | |
bool for_all( It first, It last, std::function<bool( U )> predicate ) { | |
for ( ; first != last; ++first ) { | |
if ( !predicate( F( *first ) ) ) { | |
return false; | |
} | |
} | |
return true; | |
} | |
template<typename It, typename U> | |
void for_each( It first, It last, Chainer<ValueOf<It>, U> chainer, Receiver<U> func ) { | |
for ( ; first != last; ++first ) { | |
chainer( *first, func ); | |
} | |
} | |
template<typename It, typename R = Receiver<ValueOf<It>>> | |
void for_each( It first, It last, R func ) { | |
typedef ValueOf<It> Value; | |
for_each<It, Value>( first, last, []( Value t, Receiver<Value> f ) { return f( t ); }, func ); | |
} | |
template<typename T, typename U> | |
Chainer<T, U> map( Transformer<T, U> transformer ) { | |
return [=]( T value, Receiver<U> next ) { | |
next( transformer( value ) ); | |
}; | |
} | |
template<typename T> | |
Chainer<T, T> filter( Predicat<T> predicat ) { | |
return [=]( T value, Receiver<T> next ) { | |
if ( predicat( value ) ) { | |
next( value ); | |
} | |
}; | |
} | |
template<typename T> | |
Chainer<T, T> repeat( int times ) { | |
return [=]( T value, Receiver<T> next ) { | |
for ( auto i = 0; i < times; ++i ) { | |
next( value ); | |
} | |
}; | |
} | |
template<typename T, typename U, typename V> | |
Chainer<T, V> operator>>( Chainer<T, U> chainer1, Chainer<U, V> chainer2 ) { | |
return [=]( T value, Receiver<V> next ) { | |
chainer1( value, [=]( auto value2 ) { | |
chainer2( value2, next ); | |
} ); | |
}; | |
} | |
typedef std::vector<int> Vec; | |
typedef Vec::value_type Value; | |
typedef Vec::const_iterator It; | |
void print( Value value ); | |
void test1( const Vec &vec ) { | |
for_each( std::begin( vec ), std::end( vec ), []( Value value ) { | |
print( value ); | |
} ); | |
} | |
void test1_handmade( const Vec &vec ) { | |
for ( auto value : vec ) { | |
print( value ); | |
} | |
} | |
void test2( const Vec &vec ) { | |
for_each<It, int>( | |
std::begin( vec ), std::end( vec ), | |
map<int, int>( []( auto value ) { return 3 * value; } ) | |
>> map<int, int>( []( auto value ) { return 2 * value; } ), | |
[]( int value ) -> void { | |
print( value ); | |
} | |
); | |
} | |
void test2_handmade( const Vec &vec ) { | |
for ( auto value : vec ) { | |
auto a = value * 3; | |
auto b = a * 2; | |
print( b ); | |
} | |
} | |
void test3( const Vec &vec ) { | |
for_each<It, int>( | |
std::begin( vec ), std::end( vec ), | |
map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> filter<int>( []( auto value ) { return value % 2 == 0; } ) | |
>> map<int, int>( []( auto value ) { return 1 + value; } ), | |
[]( int value ) -> void { | |
print( value ); | |
} | |
); | |
} | |
void test3_handmade( const Vec &vec ) { | |
for ( auto value : vec ) { | |
auto a = 1 + value; | |
auto b = 1 + a; | |
auto c = 1 + b; | |
if ( c % 2 == 0 ) { | |
auto d = 1 + c; | |
print( d ); | |
} | |
} | |
} | |
void test4( const Vec &vec ) { | |
for_each<It, int>( | |
std::begin( vec ), std::end( vec ), | |
map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> filter<int>( []( auto value ) { return value % 2 == 0; } ) | |
>> map<int, int>( []( auto value ) { return 1 + value; } ) | |
>> repeat<int>( 3 ), | |
[]( int value ) -> void { | |
print( value ); | |
} | |
); | |
} | |
void test4_handmade( const Vec &vec ) { | |
for ( auto value : vec ) { | |
auto a = 1 + value; | |
auto b = 1 + a; | |
if ( b % 2 == 0 ) { | |
auto c = 1 + b; | |
for ( auto i = 0; i < 3; ++i ) { | |
print( c ); | |
} | |
} | |
} | |
} | |
int main() { | |
const Vec vec{ 1, 2, 3 }; | |
test1( vec ); | |
std::cout << "---" << std::endl; | |
test1_handmade( vec ); | |
std::cout << "---" << std::endl; | |
test2( vec ); | |
std::cout << "---" << std::endl; | |
test2_handmade( vec ); | |
std::cout << "---" << std::endl; | |
test3( vec ); | |
std::cout << "---" << std::endl; | |
test3_handmade( vec ); | |
std::cout << "---" << std::endl; | |
test4( vec ); | |
std::cout << "---" << std::endl; | |
test4_handmade( vec ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment