-
-
Save kikairoya/755468 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 <type_traits> | |
using std::tuple; | |
template <int n> | |
struct int_: std::integral_constant<int, n> { }; | |
typedef int_<0> zero_; | |
template <typename l> | |
struct decrement: int_<l::value-1> { | |
typedef int_<l::value-1> type; | |
}; | |
template <typename L, typename R> | |
struct append; | |
template <typename ...L, typename ...R> | |
struct append<tuple<L...>, tuple<R...>> { | |
typedef tuple<L..., R...> type; | |
}; | |
template <template <typename> class unary_op, typename Tuple> | |
struct map; | |
template <template <typename> class unary_op, typename ...seq> | |
struct map<unary_op, tuple<seq...>> { | |
typedef tuple<typename unary_op<seq>::type...> type; | |
}; | |
template <typename N, typename Tuple> | |
struct cons; | |
template <typename N, typename ...seq> | |
struct cons<N, tuple<seq...>> { typedef tuple<N, seq...> type; }; | |
template <typename n, typename m> | |
struct f { | |
typedef n head; | |
typedef typename f<n, typename decrement<m>::type>::type tail; | |
typedef typename cons<head, tail>::type type; | |
}; | |
template <typename n> | |
struct f<n, zero_> { | |
typedef tuple<> type; | |
}; | |
template <> | |
struct f<zero_, zero_> { | |
typedef tuple<zero_> type; | |
}; | |
template <typename n> | |
struct g { | |
typedef typename f<n, n>::type type; | |
}; | |
template <typename n> | |
struct range { | |
typedef typename append<typename range<typename decrement<n>::type>::type, tuple<n>>::type type; | |
}; | |
template <> | |
struct range<zero_> { | |
typedef tuple<zero_> type; | |
}; | |
template <template <typename, typename> class bin_op, typename init, typename Tuple> | |
struct foldl; | |
template <template <typename, typename> class bin_op, typename init, typename head, typename ...tail> | |
struct foldl<bin_op, init, tuple<head, tail...>> { | |
typedef typename foldl<bin_op, typename bin_op<init, head>::type, tuple<tail...>>::type type; | |
}; | |
template <template <typename, typename> class bin_op, typename init> | |
struct foldl<bin_op, init, tuple<>> { | |
typedef init type; | |
}; | |
template <typename n> | |
struct h { | |
typedef typename foldl<append, tuple<>, typename map<g, typename range<n>::type>::type>::type type; | |
}; | |
#include <array> | |
template <typename Tuple> | |
struct tuple_to_array; | |
template <int... seq> | |
struct tuple_to_array<tuple<int_<seq>...>> { | |
static std::array<int, sizeof...(seq)> exec() { return std::array<int, sizeof...(seq)>{{seq...}}; }; | |
}; | |
#include <iostream> | |
#include <algorithm> | |
int main() { | |
auto a = tuple_to_array<typename h<int_<257>>::type>::exec(); | |
std::for_each(a.begin(), a.end(), [](int n) { std::cout << n << ','; }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment