Skip to content

Instantly share code, notes, and snippets.

@FinalTheory
Last active May 22, 2017 13:39
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 FinalTheory/ec4b0da8447e491971f92540b4f0b8b8 to your computer and use it in GitHub Desktop.
Save FinalTheory/ec4b0da8447e491971f92540b4f0b8b8 to your computer and use it in GitHub Desktop.
C++ Template Hanoi
#include <iostream>
#include <utility>
template <int, typename T, T a, T b, T c>
struct hanoi;
template <typename seq1, typename seq2>
struct concat;
template <typename... Args>
struct sequence {};
template <typename T, T a, T b>
struct pair {
using type = T;
static constexpr auto first = a;
static constexpr auto second = b;
};
template <typename... Args1, typename... Args2>
struct concat<sequence<Args1...>, sequence<Args2...>> {
using type = sequence<Args1..., Args2...>;
};
template <typename T, T a, T b, T c>
struct hanoi<1, T, a, b, c> {
using type = sequence<pair<T, a, c>>;
};
template <int n, typename T, T a, T b, T c>
struct hanoi {
using type = typename concat<
typename concat<typename hanoi<n - 1, T, a, c, b>::type,
sequence<pair<T, a, c>>
>::type,
typename hanoi<n - 1, T, b, a, c>::type
>::type;
};
// prepend values before integer sequence
template <typename seq, typename seq::value_type...>
struct prepend;
template <typename T, T... x1, T... x2>
struct prepend<std::integer_sequence<T, x1...>, x2...> {
using type = std::integer_sequence<T, x2..., x1...>;
};
template <typename T>
struct seq2str {};
template <typename T>
struct seq2str<sequence<T>> {
using type = std::integer_sequence<typename T::type,
T::first, '-', '>', T::second, '\n'>;
};
template <typename T, typename... Args>
struct seq2str<sequence<T, Args...>> {
using type = typename prepend<
typename seq2str<sequence<Args...>>::type,
T::first, '-', '>', T::second, '\n'
>::type;
};
template <typename T, T... xs>
void print_seq(std::integer_sequence<T, xs...>) {
bool Do[] = { (std::cout << xs, true)... };
(void)Do;
}
int main(int, const char*[]) {
print_seq(typename seq2str<
typename hanoi<3, char, '1', '2', '3'>
::type
>::type ());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment