#if __cplusplus < 201103L
#	error "C++ version too old"
#endif

#ifdef __AVR
namespace std {
	using size_t = unsigned int;
	template <typename T, size_t N>
	class array {
		public:
			T data [N];
			static constexpr size_t size () { return N; }
			constexpr const T& operator [] (size_t I) const { return data [I]; }
			T& operator [] (size_t I) { return data [I]; }
	};
}
#else
	#include <utility>
	#include <array>
	#include <cstddef>
#endif

#if (__cplusplus < 201402L) || defined(__AVR)
	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;
#else
	using std::make_index_sequence;
	using std::index_sequence;
#endif


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

template <std::size_t S, typename F>
constexpr auto generate (F&& f) -> std::array<decltype(static_cast<F&&> (f) (0)), S> {
	return generate (static_cast<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 (std::size_t i = 0; i < myLUT.size (); ++i) {
		volatile int x = myLUT [i];
	}
	return 0;
}