関数テンプレートを使ってメタ関数の実装を書く

特にメリットとか無いのですが、こういう風にも書けるわなと思ったので書いてみました。

#include <type_traits>

template<std::size_t... Indices>
struct index_tuple {};

template<std::size_t M, std::size_t N>
struct index_range {
  private:
    template<std::size_t STEP, std::size_t LAST, std::size_t... Indices>
    static auto impl(typename std::enable_if<(STEP < LAST)>::type* = 0) {
        using type = decltype(impl<STEP + 1, N, Indices..., STEP>());
        return type();
    }
    
    template<std::size_t STEP, std::size_t LAST, std::size_t... Indices>
    static auto impl(typename std::enable_if<(STEP >= LAST)>::type* = 0) {
        using type = index_tuple<Indices...>;
        return type();
    }
    
  public:
    using type = decltype(impl<M, N>());
};

int main() {
    static_assert(std::is_same<typename index_range<0, 5>::type, index_tuple<0, 1, 2, 3, 4>>::value, "");
}