1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 // expected-no-diagnostics
4 // Metafunction to extract the Nth type from a set of types.
5 template<unsigned N
, typename
...Types
> struct get_nth_type
;
7 template<unsigned N
, typename Head
, typename
...Tail
>
8 struct get_nth_type
<N
, Head
, Tail
...> : get_nth_type
<N
-1, Tail
...> { };
10 template<typename Head
, typename
...Tail
>
11 struct get_nth_type
<0, Head
, Tail
...> {
15 // Placeholder type when get_nth_type fails.
19 struct get_nth_type
<N
> {
23 template<typename
...Args
>
24 typename get_nth_type
<0, Args
...>::type
first_arg(Args
...);
26 template<typename
...Args
>
27 typename get_nth_type
<1, Args
...>::type
second_arg(Args
...);
29 // Test explicit specification of function template arguments.
30 void test_explicit_spec_simple() {
31 int *ip1
= first_arg
<int *>(0);
32 int *ip2
= first_arg
<int *, float*>(0, 0);
33 float *fp1
= first_arg
<float *, double*, int*>(0, 0, 0);
36 // Template argument deduction can extend the sequence of template
37 // arguments corresponding to a template parameter pack, even when the
38 // sequence contains explicitly specified template arguments.
39 void test_explicit_spec_extension(double *dp
) {
40 int *ip1
= first_arg
<int *>(0, 0);
41 int *ip2
= first_arg
<int *, float*>(0, 0, 0, 0);
42 float *fp1
= first_arg
<float *, double*, int*>(0, 0, 0);
43 int *i1
= second_arg
<float *>(0, (int*)0, 0);
44 double *dp1
= first_arg
<>(dp
);
47 template<typename
...Types
>
50 template<typename
...Types
>
51 void accept_tuple(tuple
<Types
...>);
53 void test_explicit_spec_extension_targs(tuple
<int, float, double> t3
) {
55 accept_tuple
<int, float, double>(t3
);
56 accept_tuple
<int>(t3
);
57 accept_tuple
<int, float>(t3
);
60 template<typename R
, typename
...ParmTypes
>
61 void accept_function_ptr(R(*)(ParmTypes
...));
63 void test_explicit_spec_extension_funcparms(int (*f3
)(int, float, double)) {
64 accept_function_ptr(f3
);
65 accept_function_ptr
<int>(f3
);
66 accept_function_ptr
<int, int>(f3
);
67 accept_function_ptr
<int, int, float>(f3
);
68 accept_function_ptr
<int, int, float, double>(f3
);