p1-0x.cpp revision 7d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2
3// Metafunction to extract the Nth type from a set of types.
4template<unsigned N, typename ...Types> struct get_nth_type;
5
6template<unsigned N, typename Head, typename ...Tail>
7struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
8
9template<typename Head, typename ...Tail>
10struct get_nth_type<0, Head, Tail...> {
11  typedef Head type;
12};
13
14// Placeholder type  when get_nth_type fails.
15struct no_type {};
16
17template<unsigned N>
18struct get_nth_type<N> {
19  typedef no_type type;
20};
21
22template<typename T, typename U> struct pair { };
23template<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.
29template<typename ...Args>
30typename get_nth_type<0, Args...>::type first_arg(Args...);
31
32template<typename ...Args>
33typename get_nth_type<1, Args...>::type second_arg(Args...);
34
35void 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
42template<typename ...Args>
43typename get_nth_type<0, Args...>::type first_arg_ref(Args&...);
44
45template<typename ...Args>
46typename get_nth_type<1, Args...>::type second_arg_ref(Args&...);
47
48void 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
56template<typename ...Args1, typename ...Args2>
57typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: failed template argument deduction}}
58
59template<typename ...Args1, typename ...Args2>
60typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
61
62void test_pair_deduction(int *ip, float *fp, double *dp) {
63  int *ip1 = first_arg_pair(make_pair(ip, 17));
64  int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
65  int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
66                            make_pair(dp, 17));
67  float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
68  float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
69                               make_pair(dp, 17));
70  no_type nt1 = first_arg_pair();
71  no_type nt2 = second_arg_pair();
72  no_type nt3 = second_arg_pair(make_pair(ip, 17));
73
74
75  first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
76}
77
78// For a function parameter pack that does not occur at the end of the
79// parameter-declaration-list, the type of the parameter pack is a
80// non-deduced context.
81// FIXME: We're not in a position to handle this yet.
82#if 0
83template<typename ...Types> struct tuple { };
84
85template<typename ...Types>
86void pack_not_at_end(tuple<Types...>, Types... values, int);
87
88void test_pack_not_at_end(tuple<int*, double*> t2) {
89  pack_not_at_end(t2, 0, 0, 0);
90}
91#endif
92