可変引数テンプレートでの型リスト - take_while

take_whileは条件を満たす間、先頭部分を取り出すメタ関数です。

template <bool Cond, class Then, class Else>
struct if_c;

template <class Then, class Else>
struct if_c<true, Then, Else> {
    typedef Then type;
};

template <class Then, class Else>
struct if_c<false, Then, Else> {
    typedef Else type;
};


template <template <class T> class P, class Seq1, class Seq2>
struct take_while_impl;

template <template <class T> class P, class... Seq, class Head, class... Tail>
struct take_while_impl<P, tuple<Seq...>, tuple<Head, Tail...>> {
    typedef
        typename if_c<P<Head>::value,
                      typename take_while_impl<P,
                                               typename concat<tuple<Seq...>, tuple<Head>>::type,
                                               tuple<Tail...>
                               >::type,
                      tuple<Seq...>
                 >::type
    type;
};

template <template <class T> class P, class... Seq>
struct take_while_impl<P, tuple<Seq...>, tuple<>> {
    typedef tuple<Seq...> type;
};


template <template <class T> class P, class Seq>
struct take_while;

template <template <class T> class P, class... Seq>
struct take_while<P, tuple<Seq...>> {
    typedef typename take_while_impl<P, tuple<>, tuple<Seq...>>::type type;
};
take_while<is_integral, tuple<int, long, char, double>>::type
→ tuple<int, long, char>