#include <iostream>
#include <utility>
#include <array>
#include <cstddef>

template <std::size_t... I>
struct index_sequence {};

template<class S1, class S2> struct concat;

template<std::size_t... I1, std::size_t... I2>
struct concat<index_sequence<I1...>, index_sequence<I2...>> {
	using Type = index_sequence<I1..., (sizeof...(I1)+I2)...>;
};

template<std::size_t N>
struct gen_seq {
	using Type = typename concat<typename gen_seq<N/2>::Type, typename gen_seq<N - N/2>::Type>::Type;
};

template<> struct gen_seq<0> { using Type = index_sequence<>; };
template<> struct gen_seq<1> { using Type = index_sequence<0>; };

template <std::size_t N>
using make_index_sequence = typename gen_seq<N>::Type;

template <typename F, std::size_t... I>
constexpr auto generate (F&& f, index_sequence<I...>) -> std::array<decltype(std::forward<F> (f) (0)), sizeof...(I)> {
	return {{ std::forward<F> (f) (I) ... }};
}

template <std::size_t S, typename F>
constexpr auto generate (F&& f) -> std::array<decltype(std::forward<F> (f) (0)), S> {
	return generate (std::forward<F> (f), make_index_sequence<S> {});
}

constexpr int myLutCalc (std::size_t index) {
	return index * 2;
}

constexpr auto myLUT = generate<10> (myLutCalc);

int main() {
	for (auto& x : myLUT) {
		std::cout << x << ", ";
	}
	std::cout << std::endl;
	return 0;
}