p21.cpp revision 2e996d929d2593e5131640e774d04fe433ba5f89
12e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
22e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
32e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor// Note: Template argument deduction involving parameter packs
42e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor// (14.5.3) can deduce zero or more arguments for each parameter pack.
52e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
62e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregortemplate<class> struct X {
72e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor  static const unsigned value = 0;
82e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor};
92e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
102e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregortemplate<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> {
112e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor  static const unsigned value = 1;
122e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor};
132e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
142e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregortemplate<class ... Types> struct Y {
152e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor  static const unsigned value = 0;
162e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor};
172e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
182e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregortemplate<class T, class ... Types> struct Y<T, Types& ...> {
192e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor  static const unsigned value = 1;
202e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor};
212e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
222e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregortemplate<class ... Types> int f(void (*)(Types ...));
232e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorvoid g(int, float);
242e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregor
252e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check0[X<int>::value == 0? 1 : -1]; // uses primary template
262e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check1[X<int(int, float, double)>::value == 1? 1 : -1]; // uses partial specialization
272e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check2[X<int(float, int)>::value == 0? 1 : -1]; // uses primary template
282e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check3[Y<>::value == 0? 1 : -1]; // uses primary template
292e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check4[Y<int&, float&, double&>::value == 1? 1 : -1]; // uses partial specialization
302e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint check5[Y<int, float, double>::value == 0? 1 : -1]; // uses primary template
312e996d929d2593e5131640e774d04fe433ba5f89Douglas Gregorint fv = f(g); // okay
32