72 lines
1.8 KiB
C++
72 lines
1.8 KiB
C++
#include <utility> // For declval.
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <iterator>
|
|
#include <iostream>
|
|
|
|
/* Partial application helper. */
|
|
template< class F, class Arg >
|
|
struct PApply
|
|
{
|
|
F f;
|
|
Arg arg;
|
|
|
|
template< class F_, class Arg_ >
|
|
PApply( F_&& f, Arg_&& arg )
|
|
: f(std::forward<F_>(f)), arg(std::forward<Arg_>(arg))
|
|
{
|
|
}
|
|
|
|
/*
|
|
* The return type of F only gets deduced based on the number of arguments
|
|
* supplied. PApply otherwise has no idea whether f takes 1 or 10 args.
|
|
*/
|
|
template< class ... Args >
|
|
auto operator() ( Args&& ...args )
|
|
-> decltype( f(arg,std::declval<Args>()...) )
|
|
{
|
|
return f( arg, std::forward<Args>(args)... );
|
|
}
|
|
};
|
|
|
|
template< class F, class Arg >
|
|
PApply<F,Arg> papply( F&& f, Arg&& arg )
|
|
{
|
|
return PApply<F,Arg>( std::forward<F>(f), std::forward<Arg>(arg) );
|
|
}
|
|
|
|
/* Apply f to cont. */
|
|
template< class F >
|
|
std::array<int,4> fs( F&& f, std::array<int,4> cont )
|
|
{
|
|
std::transform( std::begin(cont), std::end(cont), std::begin(cont),
|
|
std::forward<F>(f) );
|
|
return cont;
|
|
}
|
|
|
|
std::ostream& operator << ( std::ostream& out, const std::array<int,4>& c )
|
|
{
|
|
std::copy( std::begin(c), std::end(c),
|
|
std::ostream_iterator<int>(out, ", ") );
|
|
return out;
|
|
}
|
|
|
|
int f1( int x ) { return x * 2; }
|
|
int f2( int x ) { return x * x; }
|
|
|
|
int main()
|
|
{
|
|
std::array<int,4> xs = {{ 0, 1, 2, 3 }};
|
|
std::array<int,4> ys = {{ 2, 4, 6, 8 }};
|
|
|
|
auto fsf1 = papply( fs<decltype(f1)>, f1 );
|
|
auto fsf2 = papply( fs<decltype(f2)>, f2 );
|
|
|
|
std::cout << "xs:\n"
|
|
<< "\tfsf1: " << fsf1(xs) << '\n'
|
|
<< "\tfsf2: " << fsf2(xs) << "\n\n"
|
|
<< "ys:\n"
|
|
<< "\tfsf1: " << fsf1(ys) << '\n'
|
|
<< "\tfsf2: " << fsf2(ys) << '\n';
|
|
}
|