samedi 2 septembre 2017

How to expand Tuple to Match Arguments Provided?

I have a function that (after simplifying the logic) takes the form

std::tuple<font_heap, font_heap> get_font_heaps(std::vector<uint8_t> const& a, std::vector<uint8_t> const& b) {
    return std::make_tuple(get_font_heap_from_data(a), get_font_heap_from_data(b));
}

I'd like to templatize this function so that it can handle as many or as few datasets as the user passes in.

auto [serif, sansserif, monospace] = get_font_heaps(serif_data, sansserif_data, monospace_data);
auto [comic_sans] = get_font_heaps(comic_sans_data);

I've started by trying to rewrite the logic like so:

template<typename ... FontDatas>
auto get_font_heaps(std::vector<uint8_t> const& data, FontData&& ...datas) {
    if constexpr(sizeof...(FontDatas) == 0) {
        return std::make_tuple(get_font_heap_from_data(data));
    else {
        return std::make_tuple(get_font_heap_from_data(data), get_font_heaps(std::forward<FontDatas>(datas)...);
}

But obviously, even if this compiles, it doesn't quite do what I want: it creates a nested tuple out of this code, in the form std::tuple<font_heap, std::tuple<font_heap, std::tuple<font_heap>>>, whereas what I want is std::tuple<font_heap, font_heap, font_heap>

How can I rewrite this logic to do what I intend? I'm using MSVC 2017.3, so I have access to a lot of C++17 features, but not Fold Expressions (which I suspect would simplify the logic greatly).

Aucun commentaire:

Enregistrer un commentaire