委譲コンストラクタで再帰する

委譲コンストラクタで引数を増やしながら再帰してみました。
enablerを用いたSFINAEを使って再帰するコンストラクタから脱出します。

サンプルはとても雑な例なのですが、工夫すれば何かに使えるかもしれません。

#include <type_traits>
#include <iostream>
#include "sprout/array.hpp"

extern void* enabler;

template<class T, std::size_t N>
struct nog
{
public:
    template<class... Types, typename std::enable_if<(sizeof...(Types) < N)>::type*& = enabler>
    constexpr nog(Types... Args) : nog(Args..., Args...) {};

    template<class... Types, typename std::enable_if<(sizeof...(Types) == N)>::type*& = enabler>
    constexpr nog(Types... Args) : data(sprout::make_array<T>(Args...)) {};
    
    const sprout::array<T, N> data;
};

int main()
{
    constexpr nog<int, 8> test(0);
    
    for(auto i = 0; i < 8; ++i)
        std::cout << test.data[i] << std::endl;
}

あと関係ないですけどindex_tupleを作って別のコンストラクタに委譲するとか出来ますね

#include <type_traits>
#include "sprout/index_tuple.hpp"
#include "sprout/array.hpp"

template<std::size_t M, std::size_t N>
struct range
{
public:
    constexpr range(void) : range(sprout::index_range<M, N>::make()) {};

    template<sprout::index_t... Indices>
    constexpr range(sprout::index_tuple<Indices...>) : data(sprout::make_array<sprout::index_t>(Indices...)) {};
    
    const sprout::array<sprout::index_t, N - M> data;
};

int main()
{
    constexpr auto test = range<0, 9>();
    static_assert(test.data[0] == 0, "");
    static_assert(test.data[1] == 1, "");
    static_assert(test.data[2] == 2, "");
    static_assert(test.data[3] == 3, "");
    static_assert(test.data[4] == 4, "");
    static_assert(test.data[5] == 5, "");
    static_assert(test.data[6] == 6, "");
    static_assert(test.data[7] == 7, "");
    static_assert(test.data[8] == 8, "");
}