Skip to content

Instantly share code, notes, and snippets.

@niha
Created November 13, 2010 16:08
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 niha/675446 to your computer and use it in GitHub Desktop.
Save niha/675446 to your computer and use it in GitHub Desktop.
#include <tuple>
#include <functional>
#include <cstdio>
using namespace std;
template <typename T>
struct tuple_head;
template <typename Head, typename... Tail>
struct tuple_head<tuple<Head, Tail...>> { typedef Head type; };
template <typename T>
struct tuple_tail;
template <typename Head, typename... Tail>
struct tuple_tail<tuple<Head, Tail...>> { typedef tuple<Tail...> type; };
template <size_t index, typename Target, typename Head, typename Tail>
struct tuple_index_impl;
template <size_t index, typename Target, typename Head, typename Tail>
struct tuple_index_impl {
typedef typename tuple_head<Tail>::type head;
typedef typename tuple_tail<Tail>::type rest;
static const size_t value = tuple_index_impl<index + 1, Target, head, rest>::value;
};
template <size_t index, typename Target, typename Tail>
struct tuple_index_impl<index, Target, Target, Tail> {
static const size_t value = index;
};
template <typename Target, typename... Types>
struct tuple_index {
typedef tuple<Types...> tuple_type;
typedef typename tuple_head<tuple_type>::type head;
typedef typename tuple_tail<tuple_type>::type tail;
static const size_t value = tuple_index_impl<0, Target, head, tail>::value;
};
template <typename Ret, typename... Args>
class overload_functor {
typedef tuple<function<auto (Args) -> Ret>...> tuple_type;
public:
template <typename... T>
/* implicit */ overload_functor(const T&... fun) : funs(fun...) { }
overload_functor(const tuple_type& funs) : funs(funs) { }
overload_functor(tuple_type&& funs) : funs(funs) { }
template <typename T>
auto operator()(T t) -> Ret {
return get<tuple_index<T, Args...>::value>(funs)(t);
}
private:
tuple<function<auto (Args) -> Ret>...> funs;
};
int main(){
overload_functor<void, int, double> f = {
[](int i){ printf("%d\n", i); },
[](double d){ printf("%lf\n", d); },
};
f(1);
f(1.0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment