Conversion operation slow to compile for longer lists N>=12
Hi, Thank you for a really neat and concise library.
I ran into an issue with compilation time when using the conversion to/to_tuple operator. The compilation time seems to grow exponentially and is noticed for lists beyond just a few elements.
I want to document that here and the workarounds I tried to inform anyone else running into the same thing but also to hopefully resolve the long compilation time issue without needing to resort to workarounds.
The problem code:
#include <string>
//List of 13 types
using types = tl::type_list<int, bool, long, int, bool, char, size_t, long, std::string, size_t, char, std::string, bool>;
//1. Using tl::to<> (12s)
using tup = types::to_tuple;
At 13 elements this takes over 10s to compile. An extra element and it's 20.
Workaround 1:
//2. Using specialization (< 1s)
//Need to write one of these for each target type
template <typename... Args>
struct wrap_as_tuple;
template <typename... Args>
struct wrap_as_tuple<tl::type_list<Args...>>
{
using type = std::tuple<Args...>;
};
template <typename... Args>
using wrap_as_tuple_t = typename wrap_as_tuple<Args...>::type;
using tup = wrap_as_tuple_t<types>;
This workaround is fast but it is not generic enough: you have to write one of these for every target type.
Workaround 2:
//3. Using this external helper template (< 1s)
//Works similarly to tl::to<> in terms of using a variadic template template parameters
//however is more general and somehow compiles faster
template<template<typename...> class, typename>
struct _apply_tmpl_args_of;
template<template<typename...> class OtherTmpl, template<typename...> class Tmpl, typename... Args>
struct _apply_tmpl_args_of<OtherTmpl, Tmpl<Args...>>
{
using type = OtherTmpl<Args...>;
};
template<template<typename...> class OtherTmpl, typename T>
using apply_tmpl_args_of_t = typename _apply_tmpl_args_of<OtherTmpl, T>::type;
using tup = apply_tmpl_args_of_t<std::tuple, types>;
This workaround is generic and also performs fast. What baffles me is that it is not fundamentally that different to tl::to<> in the sense that both use variadic template template parameters.
Any ideas on how to<> can integrate the above idea and preserve compilation speed? MyTypeList::to<> is nicer to write than the above.
Link with examples above: https://gcc.godbolt.org/z/6hYqc7Mv5
Thank you