Skip to content

Instantly share code, notes, and snippets.

@donkaban
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donkaban/601bc99a5e84bc9e493d to your computer and use it in GitHub Desktop.
Save donkaban/601bc99a5e84bc9e493d to your computer and use it in GitHub Desktop.
callable method
template<int...> struct seq {};
template<int N, int ...M> struct gen : gen<N-1, N-1, M...> { };
template<int ...N> struct gen<0, N...> {typedef seq<N...> type;};
template <typename T> class method;
template <typename R, typename... A> class method<R(A...)>
{
public:
using F = std::function<R(A...)>;
using P = std::tuple<A...>;
using L = std::function<void(R)>;
method() {}
method(const F &f) : _func(f) {}
R operator() (A && ... args) {return _func(args ...);}
method & operator() (A && ... args, const L &l)
{
_lambda = l;
_params = std::make_tuple(args...);
return *this;
}
method & param(A && ... args) {_params = std::make_tuple(args...);return *this;}
method & lambda(const L &l) {_lambda=l;return *this;}
R call()
{
auto res = _apply(typename gen<sizeof...(A)>::type());
if(_lambda) _lambda(res);
return res;
}
private:
template<int ...N> R _apply(seq<N...>) {return _func(std::get<N>(_params)... );}
F _func {};
P _params {};
L _lambda {};
};
int main()
{
auto f1 = [](int a,int b,int c)->int {return a + b + c;};
method<int(int,int,int)> test1(f1);
logger::warning("direct call : %d", test1(1,2,3));
test1
.param(1,2,3)
.lambda([](int i){logger::error("lambda call : %d",i+10);});
logger::warning("indirect call : %d", test1.call());
test1(3,4,5,[](int i){logger::error("lambda2 call : %d",i);}).call();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment