Skip to content

Instantly share code, notes, and snippets.

@niha
Created December 25, 2010 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save niha/754964 to your computer and use it in GitHub Desktop.
Save niha/754964 to your computer and use it in GitHub Desktop.
// 今手元に 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