Skip to content

Instantly share code, notes, and snippets.

@Garciat
Last active December 14, 2015 06:29
Show Gist options
  • Save Garciat/5042828 to your computer and use it in GitHub Desktop.
Save Garciat/5042828 to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <array>
#include <climits>
#include <iostream>
#include <algorithm>
#include <tuple>
template<size_t... Vals>
struct Sequence { };
template<typename Seq>
struct SequenceArray;
template<size_t... Vals>
struct SequenceArray<Sequence<Vals...>> {
static const std::array<size_t, sizeof...(Vals)> arr;
};
template<typename Seq1, typename Seq2>
struct Concat;
template<size_t... Vals1, size_t... Vals2>
struct Concat<Sequence<Vals1...>, Sequence<Vals2...>> {
typedef Sequence<Vals1..., Vals2...> type;
};
template<size_t I>
struct LeonardoNumber
: std::integral_constant<size_t, LeonardoNumber<I - 2>::value + LeonardoNumber<I - 1>::value + 1> { };
template<>
struct LeonardoNumber<0>
: std::integral_constant<size_t, 1> { };
template<>
struct LeonardoNumber<1>
: std::integral_constant<size_t, 1> { };
template<size_t... Vals>
const std::array<size_t, sizeof...(Vals)> SequenceArray<Sequence<Vals...>>::arr = { { Vals... } };
template<size_t I = 2, bool Go = true>
struct MaxLeonardoSequenceHelper;
template<size_t I>
struct MaxLeonardoSequenceHelper<I, true> {
static const size_t Next = LeonardoNumber<I>::value;
// If the last Leonardo Number's size exceeds MAX(size_t)/2, then we have
// found the last LN in the sequence below MAX(size_t). Stop!
static const bool Go = LeonardoNumber<I - 1>::value < (size_t() - 1)/2;
typedef typename Concat<Sequence<Next>, typename MaxLeonardoSequenceHelper<I + 1, Go>::type>::type type;
};
template<size_t I>
struct MaxLeonardoSequenceHelper<I, false> {
typedef Sequence<> type;
};
struct MaxLeonardoSequence {
typedef Concat<Sequence<1, 1>, MaxLeonardoSequenceHelper<>::type>::type type;
};
int main() {
using namespace std;
typedef SequenceArray<MaxLeonardoSequence::type> Leos;
for (const auto &e : Leos::arr) {
cout << e << endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment