1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 
3 // Metafunction to extract the Nth type from a set of types.
4 template<unsigned N, typename ...Types> struct get_nth_type;
5 
6 template<unsigned N, typename Head, typename ...Tail>
7 struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
8 
9 template<typename Head, typename ...Tail>
10 struct get_nth_type<0, Head, Tail...> {
11   typedef Head type;
12 };
13 
14 // Placeholder type  when get_nth_type fails.
15 struct no_type {};
16 
17 template<unsigned N>
18 struct get_nth_type<N> {
19   typedef no_type type;
20 };
21 
22 template<typename T, typename U> struct pair { };
23 template<typename T, typename U> pair<T, U> make_pair(T, U);
24 
25 // For a function parameter pack that occurs at the end of the
26 // parameter-declaration-list, the type A of each remaining argument
27 // of the call is compared with the type P of the declarator-id of the
28 // function parameter pack.
29 template<typename ...Args>
30 typename get_nth_type<0, Args...>::type first_arg(Args...);
31 
32 template<typename ...Args>
33 typename get_nth_type<1, Args...>::type second_arg(Args...);
34 
test_simple_deduction(int * ip,float * fp,double * dp)35 void test_simple_deduction(int *ip, float *fp, double *dp) {
36   int *ip1 = first_arg(ip);
37   int *ip2 = first_arg(ip, fp);
38   int *ip3 = first_arg(ip, fp, dp);
39   no_type nt1 = first_arg();
40 }
41 
42 template<typename ...Args>
43 typename get_nth_type<0, Args...>::type first_arg_ref(Args&...);
44 
45 template<typename ...Args>
46 typename get_nth_type<1, Args...>::type second_arg_ref(Args&...);
47 
test_simple_ref_deduction(int * ip,float * fp,double * dp)48 void test_simple_ref_deduction(int *ip, float *fp, double *dp) {
49   int *ip1 = first_arg_ref(ip);
50   int *ip2 = first_arg_ref(ip, fp);
51   int *ip3 = first_arg_ref(ip, fp, dp);
52   no_type nt1 = first_arg_ref();
53 }
54 
55 
56 // FIXME: Use the template parameter names in this diagnostic.
57 template<typename ...Args1, typename ...Args2>
58 typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'int'}}
59 
60 template<typename ...Args1, typename ...Args2>
61 typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
62 
test_pair_deduction(int * ip,float * fp,double * dp)63 void test_pair_deduction(int *ip, float *fp, double *dp) {
64   int *ip1 = first_arg_pair(make_pair(ip, 17));
65   int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
66   int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
67                             make_pair(dp, 17));
68   float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
69   float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
70                                make_pair(dp, 17));
71   no_type nt1 = first_arg_pair();
72   no_type nt2 = second_arg_pair();
73   no_type nt3 = second_arg_pair(make_pair(ip, 17));
74 
75 
76   first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
77 }
78 
79 // A function parameter pack not at the end of the parameter list is never
80 // deduced. We interpret this as meaning the types within it are never
81 // deduced, and thus must match explicitly-specified values.
82 template<typename ...Types> struct tuple { };
83 
84 template<typename ...Types>
85 void pack_not_at_end(tuple<Types...>, Types... values, int); // expected-note {{<int *, double *> vs. <>}}
86 
test_pack_not_at_end(tuple<int *,double * > t2)87 void test_pack_not_at_end(tuple<int*, double*> t2) {
88   pack_not_at_end(t2, 0, 0, 0); // expected-error {{no match}}
89   // FIXME: Should the "original argument type must match deduced parameter
90   // type" rule apply here?
91   pack_not_at_end<int*, double*>(t2, 0, 0, 0); // ok
92 }
93