C++14 で Boost.Fusion の invoke と make_fused 書いてみた

C++14 で Boost.Fusion の invokemake_fused を簡単に書いてみました。

[ソース]

#include <tuple>
#include <array>
#include <utility>
#include <iostream>


template<
    typename F,
    typename Seq,
    std::size_t ...Indexes
>
constexpr auto
invoke_impl(
    F func,
    Seq const& seq,
    std::index_sequence<Indexes...>
){
    return func(std::get<Indexes>(seq)...);
}


template<typename F, typename Seq>
constexpr auto
invoke(F func, Seq const& seq){
    return invoke_impl(func, seq, std::make_index_sequence<std::tuple_size<Seq>{}>{});
}


template<typename F>
auto
make_fused(F func){
    return [=](auto seq){
        return invoke(func, seq);
    };
}


struct disp{
    void
    operator()() const{}

    template<typename T, typename ...Args>
    void
    operator()(T t, Args... args) const{
        std::cout << t << std::endl;
        (*this)(args...);
    }
};


int
main(){
    invoke(disp{}, std::make_tuple(1, 2, 3));
    auto f = make_fused(disp{});
    f(std::make_tuple(1, 2, 3));
    f(std::make_tuple(1, "homu", 3.14));
    
    return 0;
}

[出力]

1
2
3
1
2
3
1
homu
3.14

http://melpon.org/wandbox/permlink/7EHCtHou4ZWMiyg2


invoke は以前 C++11 で constexpr 版を書いた事があるんですが、make_fused を書いたのは初めてかな。
多相ラムダと関数の戻り値型の推論の組み合わせが便利そすぎる…。
これであとは constexpr だと最強なんだけど。
あと C++14 だと 標準ライブラリに std::make_index_sequence にあるので、invoke の実装も楽ですね。


余談ですが手元の clang の調子が悪かったので wandbox 使ってみたんですけど便利。