tuple_for

tupleの要素を順に処理したい場合に、どうするのが簡単なのか悩ましい。

メモ書き。ろくにテストしてないです。

#include <tuple>
#include <type_traits>
#include <utility>

template <int L, int R, int S, std::size_t... Indices>
constexpr auto tuple_for_impl() {
    if constexpr (L + sizeof...(Indices) >= R) {
        return [&](auto&& t, auto&& fn) constexpr {
            if constexpr (std::tuple_size_v<std::remove_reference_t<decltype(t)>> > 0
                       && std::is_same_v<decltype(fn(std::get<0>(t))), void>) {
                return [](auto...) constexpr {return std::tuple<>{}; }((fn(std::get<Indices>(t)), 0)...);
            } else {
                return std::make_tuple(fn(std::get<Indices>(t))...);
            }
        };
    } else {
        return tuple_for_impl<L, R, S, Indices..., L + S * sizeof...(Indices)>();
    }
}

template <int L, int R, int S = 1, std::size_t... Indices>
constexpr auto tuple_for = tuple_for_impl<L, R, S, Indices...>();

int main() {
    constexpr auto t = std::make_tuple(0, 'a', 0.1);
    constexpr auto r = tuple_for<0, 3>(t, [](const auto& arg) { return arg + 1; });
    static_assert(std::get<0>(r) == 1);
    static_assert(std::get<1>(r) == 'b');
    static_assert(std::get<2>(r) == 1.1);
}

https://wandbox.org/permlink/E9hh0AfDUxeej3cM