diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-19 22:18:42 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-19 22:18:42 +0000 |
commit | c5452ed941909c04dcae6466677b4dffcf88e09e (patch) | |
tree | edd836cac8a816816126e530a33602ecf45cd0a6 /clang/test/SemaTemplate/alias-templates.cpp | |
parent | 01d6b963d2903977fea1950cf6b083d44be0745a (diff) | |
download | bcm5719-llvm-c5452ed941909c04dcae6466677b4dffcf88e09e.tar.gz bcm5719-llvm-c5452ed941909c04dcae6466677b4dffcf88e09e.zip |
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
Diffstat (limited to 'clang/test/SemaTemplate/alias-templates.cpp')
-rw-r--r-- | clang/test/SemaTemplate/alias-templates.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp index b7078353ff1..bcdc84e19f7 100644 --- a/clang/test/SemaTemplate/alias-templates.cpp +++ b/clang/test/SemaTemplate/alias-templates.cpp @@ -220,6 +220,23 @@ namespace PR14858 { 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 { |