Created
November 13, 2010 16:08
-
-
Save niha/675446 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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