| | #include <type_traits>
#include <functional>
#include <iostream>
#include <ostream>
#include <utility>
using namespace std;
template<bool condition,typename T>
using static_if = typename enable_if<condition,T>::type;
template<typename F> struct func_args;
template<typename Result,typename ...Params>
struct func_args<Result(&)(Params...)>
{
enum{value=sizeof...(Params)};
};
template<unsigned TotalArgs,typename Func,typename Head,typename ...Tail>
class defaults_set: defaults_set<TotalArgs,Func,Tail...>
{
typedef defaults_set<TotalArgs,Func,Tail...> parent;
Head data;
public:
template<typename F,typename Arg,typename ...Args>
defaults_set(F &&f,Arg &&arg,Args&&... args)
: parent{forward<F>(f),forward<Args>(args)...}, data{forward<Arg>(arg)}
{}
template<typename ...Args>
auto operator()(Args&&... args) ->
static_if
<
sizeof...(Tail)+1+sizeof...(Args) == TotalArgs,
typename result_of<Func(Args&&...,Head,Tail...)>::type
>
{
return parent::operator()(forward<Args>(args)...,data);
}
using parent::operator();
};
template<unsigned TotalArgs,typename Func,typename Head>
class defaults_set<TotalArgs,Func,Head>
{
typename conditional
<
is_function< typename remove_reference<Func>::type >::value,
Func,
typename remove_reference<Func>::type
>::type func;
Head data;
public:
template<typename F,typename Arg,typename ...Args>
defaults_set(F &&f,Arg &&arg)
: func{forward<F>(f)}, data{forward<Arg>(arg)}
{}
template<typename ...Args>
auto operator()(Args&&... args) ->
static_if
<
1+sizeof...(Args) == TotalArgs,
decltype(func(forward<Args>(args)...,data))
>
{
return func(forward<Args>(args)...,data);
}
template<typename ...Args>
auto operator()(Args&&... args) ->
static_if
<
sizeof...(Args) == TotalArgs,
decltype(func(forward<Args>(args)...))
>
{
return func(forward<Args>(args)...);
}
};
template<typename Func,typename ...Args>
defaults_set<func_args<Func>::value,Func,Args...> defaults(Func &&f,Args&&... args)
{
return {forward<Func>(f),forward<Args>(args)...};
}
template<unsigned TotalArgs,typename Func,typename ...Args>
defaults_set<TotalArgs,Func,Args...> defaults_n(Func &&f,Args&&... args)
{
return {forward<Func>(f),forward<Args>(args)...};
}
// _________________________________________________ //
void f(int a,int b,int c)
{
cout << a << " " << b << " " << c << endl;
}
int main()
{
{
auto &&d=defaults(f,11,22,33);
d();
d(1);
d(2,3);
d(3,4,5);
}
{
function<void(int,int,int)> general_case{f};
auto &&d=defaults_n<3>(general_case,11,22,33);
d();
d(1);
d(2,3);
d(3,4,5);
}
}
|