Add optimization to sizeof...(X) handling: if none of parameter pack X's
corresponding arguments are unexpanded pack expansions, we can compute the
result without substituting them. This significantly improves the memory usage
and performance of make_integer_sequence implementations that do this kind of
thing:
using result = integer_sequence<T, Ns ..., sizeof...(Ns) + Ns ...>;
... but note that such an implementation will still perform O(sizeof...(Ns)^2)
work while building the second pack expansion (we just have a somewhat lower
constant now).
In principle we could get this down to linear time by caching whether the
number of expansions of a pack is constant, or checking whether we're within an
alias template before scanning the pack for pack expansions (since that's the
only case in which we do substitutions within a dependent context at the
moment), but this patch doesn't attempt that.
llvm-svn: 284653
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp
index b707835..bcdc84e 100644
--- a/clang/test/SemaTemplate/alias-templates.cpp
+++ b/clang/test/SemaTemplate/alias-templates.cpp
@@ -220,6 +220,23 @@
template<typename ...T, typename ...U> void h(X<T...> &) {}
template<typename ...T, typename ...U> void h(X<U...> &) {} // ok, different
+
+ template<typename ...T> void i(auto (T ...t) -> int(&)[sizeof...(t)]);
+ auto mk_arr(int, int) -> int(&)[2];
+ void test_i() { i<int, int>(mk_arr); }
+
+#if 0 // FIXME: This causes clang to assert.
+ template<typename ...T> using Z = auto (T ...p) -> int (&)[sizeof...(p)];
+ template<typename ...T, typename ...U> void j(Z<T..., U...> &) {}
+ void test_j() { j<int, int>(mk_arr); }
+#endif
+
+ template<typename ...T> struct Q {
+ template<typename ...U> using V = int[sizeof...(U)];
+ template<typename ...U> void f(V<typename U::type..., typename T::type...> *);
+ };
+ struct B { typedef int type; };
+ void test_q(int (&a)[5]) { Q<B, B, B>().f<B, B>(&a); }
}
namespace redecl {