On Thu, Jul 07, 2022 at 06:14:36PM +0100, Jonathan Wakely wrote: > This adds a new built-in to replace the recursive class template > instantiations done by traits such as std::tuple_element and > std::variant_alternative. The purpose is to select the Nth type from a > list of types, e.g. __builtin_type_pack_element(1, char, int, float) is > int. > > For a pathological example tuple_element_t<1000, tuple<2000 types...>> > the compilation time is reduced by more than 90% and the memory used by > the compiler is reduced by 97%. In realistic examples the gains will be > much smaller, but still relevant. > > Clang has a similar built-in, __type_pack_element<N, T...>, but that's a > "magic template" built-in using <> syntax, which GCC doesn't support. So > this provides an equivalent feature, but as a built-in function using > parens instead of <>. I don't really like the name "type pack element" > (it gives you an element from a pack of types) but the semi-consistency > with Clang seems like a reasonable argument in favour of keeping the > name. I'd be open to alternative names though, e.g. __builtin_nth_type > or __builtin_type_at_index. > > > The patch has some problems though ... > > FIXME 1: Marek pointed out that this this ICEs: > template<class... T> using type = __builtin_type_pack_element(sizeof(T), > T...); > type<int, char> c; > > The sizeof(T) expression is invalid, because T is an unexpanded pack, > but it's not rejected and instead crashes:
I think this could be fixed by if (check_for_bare_parameter_packs (n)) return error_mark_node; in finish_type_pack_element. (I haven't looked at the rest of the patch yet.) Marek