I tried to implement the C++14 alias template make_integer_sequence
, which simplifies the creation of the class template integer_sequence.
templ
Here is another implementation technique (for T=size_t
), it uses C++17 fold expressions and bitwise generation (i.e. O(log(N)
):
template <size_t... Is>
struct idx_seq {
template <size_t N, size_t Offset>
struct pow2_impl {
using type = typename idx_seq<Is..., (Offset + Is)...>::template pow2_impl<N - 1, Offset + sizeof...(Is)>::type;
};
template <size_t _> struct pow2_impl<0, _> { using type = idx_seq; };
template <size_t _> struct pow2_impl<(size_t)-1, _> { using type = idx_seq<>; };
template <size_t Offset>
using offset = idx_seq<(Offset + Is)...>;
};
template <size_t N>
using idx_seq_pow2 = typename idx_seq<0>::template pow2_impl<N, 1>::type;
template <size_t... Is, size_t... Js>
constexpr static auto operator,(idx_seq<Is...>, idx_seq<Js...>)
-> idx_seq<Is..., Js...>
{ return {}; }
template <size_t N, size_t Mask, size_t... Bits>
struct make_idx_seq_impl {
using type = typename make_idx_seq_impl<N, (N >= Mask ? Mask << 1 : 0), Bits..., (N & Mask)>::type;
};
template <size_t N, size_t... Bits>
struct make_idx_seq_impl<N, 0, Bits...> {
using type = decltype((idx_seq<>{}, ..., typename idx_seq_pow2<Bits>::template offset<(N & (Bits - 1))>{}));
};
template <size_t N>
using make_idx_seq = typename make_idx_seq_impl<N, 1>::type;