とりあえずメモ

http://twitter.com/Cryolite/status/1571598248 のやつ
一部抜けている定義とかあるけど気にしない。あと完全にコピーで作ってるけどこれも気にしない。

template<typename T> struct sizeof_;

template<typename ...T, template<typename ...> class TT>
struct sizeof_<TT<T...> > {
    constexpr size_t const value = sizeof...(T);
};

template<typename T>
struct quote_t {
    T val;
    explicit quote_t(T val) : val(val) {}
};

template<typename T>
quote_t quote(T val) {
    return quote_t<T>(val);
}

template<typename ...T>
[]apply(tuple<T...> pack)
    -> decltype(apply_impl<
                    typename make_counting_range<
                        sizeof_<
                            tuple<T...>>::value - 1>::type>(pack))
{
    return
        apply_impl<
            typename make_counting_range<
                sizeof_<
                    tuple<T...>>::value - 1>::type>(pack);
};

template<typename T>
T apply(T val) {
    return val;
}

template<typename T>
T apply(quote_t<T> q) {
    return q.val;
}

template<size_t ...N, typename F, typename ...T>
[]apply_impl<counting_range<N...>>(tuple<F, T...> pack)
    -> decltype(apply(get<0>(pack))(apply(get<N + 1>(pack)...)))
{
    return apply(get<0>(pack))(apply(get<N + 1>(pack)...));
}