Created
December 25, 2010 17:36
-
-
Save niha/754964 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
// 今手元に variadic templates をサポートした gcc がない(なんなら gcc 自体ない)からコンパイルが試せていない | |
// f 0 0 = [0] | |
// f n 0 = [] | |
// f n m = n : f n m - 1 | |
// g n = f n n | |
// h n = foldl (++) [] $ map g (0 .. n) | |
template <int... seq> | |
struct ilist; | |
template <int n, typename List> | |
struct cons; | |
template <int n, int... seq> | |
struct cons<n, ilist<seq...>> { | |
typedef ilist<n, seq...> type; | |
}; | |
template <int n, int m> | |
struct f { | |
static const int head = n; | |
typedef typename f<n, m-1>::type = tail; | |
typedef typename cons<head, tail>::type = type; | |
}; | |
template <int n> | |
struct f<n, 0> { | |
typedef ilist<> type; | |
}; | |
template <> | |
struct f<0, 0> { | |
typedef ilist<0> type; | |
}; | |
template <int n> | |
struct g { | |
typedef typename f<n, n>::type type; | |
}; | |
template <template <int> class unary_op, typename List> | |
struct map; | |
template <template <int> class unary_op, int... seq> | |
struct map<unary_op, ilist<seq...>> { | |
typedef ilist<typename unary_op<seq>::type...> type; | |
}; | |
template <typename Lhs, typename Rhs> | |
struct append; | |
template <int... lhs, int... rhs> | |
struct append<ilist<lhs...>, ilist<rhs...>> { | |
typedef ilist<lhs..., rhs...> type; | |
}; | |
template <int n> | |
struct range { | |
typedef typename range<n-1>::type tmp; | |
typedef typename append<tmp, ilist<n>>::type type; | |
}; | |
template <> | |
struct range<0> { | |
typedef ilist<0> type; | |
}; | |
template <template <typename, typename> class bin_op, int init, typename List> | |
struct foldl; | |
template <template <int, int> class bin_op, int init, int head, int... tail> | |
struct foldl<bin_op, init, ilist<head, tail...>> { | |
typedef typename bin_op<init, head>::type tmp; | |
typedef typename foldl<bin_op, tmp, ilist<tail...>>::type type; | |
}; | |
template <template <int, int> class bin_op, int init> | |
struct foldl<bin_op, init, ilist<>> { | |
typedef init type; | |
}; | |
template <int n> | |
struct h { | |
typedef typename range<n>::type tmp1; | |
typedef typename map<g, tmp1>::type tmp2; | |
typedef typename foldl<append, ilist<>, tmp2>::type type; | |
}; | |
template <typename List> | |
struct ilist_to_array; | |
template <int... seq> | |
struct ilist_to_array<ilist<seq...>> { | |
static const int array[] = { seq... }; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment