目录
管道运算符
Subject&
operator|( Subject&, Callable)
柯里化
CurriedCallable&
operator()( tokenFunction&&, Args&&...args )
class-functor version impl...
调用链
concat(func1->func2->func3)
template < typename _Callable,
typename _Ty,
typename = std::enable_if<
std::is_invocable< _Callable, _Ty >
::value > >
std::vector< _Ty >&
operator|( ::std::vector< _Ty >& _Vec, _Callable func ){
for( auto& element : _Vec ) func( element );
return _Vec;
}
int main( void ){
std::vector< int > vec( 3, 0 );
auto incrementer = []( int& v) { ++v; };
auto sequentializer = [] ( int& v)
{ static int inc { 0 }; v = ++inc; };
auto reducer = []( int& v) { --v; };
auto printer = []( int v) { std::cout << v << ' '; };
vec | sequentializer | printer;
endl( std::cout );
std::puts("------------------");
vec | incrementer | printer;
endl( std::cout );
std::puts("------------------");
vec | reducer | printer;
return 0;
}
template
constexpr auto curry(_Callable&& f, _Args&&... args) {
return [=]
(_OtherArgs&&... otherArgs)mutable
requires std::invocable,
_Args..., _OtherArgs...>
{
return f(std::forward<_Args>(args)...,
std::forward<_OtherArgs>(otherArgs)...);
};
}
template < typename _Callable >
struct Curry{
_Callable functor;
template < typename _Functor >
constexpr explicit
Curry( _Functor&& __f )
: functor( std::forward< _Functor >( __f ) )
{ }
template < typename... _Args >
auto operator()( _Args&&... args ) const {
std::tuple< _Args... > __args
{ std::forward< _Args >( args )... };
return Curry( [&]< typename..._RestArgs >
( _RestArgs...rest )
mutable
requires std::invocable<
typename std::decay<_Callable>::type,
_Args...,
_RestArgs...>{
std::tuple< _RestArgs... >
__r_args { std::forward< _RestArgs >( rest )... };
auto __n_args { std::tuple_cat(__args, __r_args ) };
if constexpr (sizeof...( _Args )
+ sizeof...( _RestArgs)
>= std::tuple_size_v< decltype(__n_args) > )
return std::apply( functor, __n_args );
else
return (*this)( __n_args );
} );
}
};
template < typename _Functor >
Curry( _Functor&& )
-> Curry< _Functor >;
int add( int a, int b, int c) {
return a + b + c;
}
int main() {
auto result = curry( curry( curry( add , 1 ), 2 ), 3 );
std::cout << "Result: " << result() << std::endl;
return 0;
}
template < typename _First, typename ..._Rest >
auto concat( _First first, _Rest... rest ){
if constexpr( sizeof...(_Rest) > 0)
return [=]< typename ...Args >( Args...args ){
return first( concat( rest...)( args... ) );
};
else return [=]< typename ...Args >( Args...args ){
return first( args... );
};
}
int main( void ){
auto f = concat([](int v)->int{ std::cout << "f1\n"; return v; },
[](int v)->int{ std::cout << "f2->"; return v*v; },
[](int v)->int{ std::cout << "f3->"; return v+v; } );
std::cout << f( 2 ) << '\n';
return 0;
}