1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s |
2 | |
3 | template<typename T, typename U> struct pair { }; |
4 | template<typename ...Types> struct tuple { }; |
5 | |
6 | template<typename T, typename U> |
7 | struct is_same { |
8 | static const bool value = false; |
9 | }; |
10 | |
11 | template<typename T> |
12 | struct is_same<T, T> { |
13 | static const bool value = true; |
14 | }; |
15 | |
16 | namespace ExpandIntoFixed { |
17 | template<typename T, |
18 | typename U, |
19 | typename V = pair<T, U>, |
20 | typename W = V*> |
21 | class X0 { }; |
22 | |
23 | template<typename ...Ts> |
24 | class X1 { |
25 | public: |
26 | typedef X0<Ts...> type; |
27 | }; |
28 | |
29 | static_assert(is_same<X1<int, int>::type, |
30 | X0<int, int, pair<int, int>, pair<int, int>*>>::value, |
31 | "fails with two default arguments"); |
32 | |
33 | static_assert(is_same<X1<int, int, float>::type, |
34 | X0<int, int, float, float*>>::value, |
35 | "fails with one default argument"); |
36 | |
37 | static_assert(is_same<X1<int, int, float, double>::type, |
38 | X0<int, int, float, double>>::value, |
39 | "fails with no default arguments"); |
40 | } |
41 | |
42 | namespace ExpandIntoFixedShifted { |
43 | template<typename T, |
44 | typename U, |
45 | typename V = pair<T, U>, |
46 | typename W = V*> |
47 | class X0 { }; |
48 | |
49 | template<typename ...Ts> |
50 | class X1 { |
51 | public: |
52 | typedef X0<char, Ts...> type; |
53 | }; |
54 | |
55 | static_assert(is_same<X1<int>::type, |
56 | X0<char, int, pair<char, int>, pair<char, int>*>>::value, |
57 | "fails with two default arguments"); |
58 | |
59 | static_assert(is_same<X1<int, float>::type, |
60 | X0<char, int, float, float*>>::value, |
61 | "fails with one default argument"); |
62 | |
63 | static_assert(is_same<X1<int, float, double>::type, |
64 | X0<char, int, float, double>>::value, |
65 | "fails with no default arguments"); |
66 | } |
67 | |
68 | namespace Deduction { |
69 | template <typename X, typename Y = double> struct Foo {}; |
70 | template <typename ...Args> tuple<Args...> &foo(Foo<Args...>); |
71 | |
72 | void call_foo(Foo<int, float> foo_if, Foo<int> foo_i) { |
73 | tuple<int, float> &t1 = foo(foo_if); |
74 | tuple<int, double> &t2 = foo(foo_i); |
75 | } |
76 | } |
77 | |
78 | namespace PR9021a { |
79 | template<typename, typename> |
80 | struct A { }; |
81 | |
82 | template<typename ...T> |
83 | struct B { |
84 | A<T...> a1; |
85 | }; |
86 | |
87 | void test() { |
88 | B<int, int> c; |
89 | } |
90 | } |
91 | |
92 | namespace PR9021b { |
93 | template<class, class> |
94 | struct t2 |
95 | { |
96 | |
97 | }; |
98 | |
99 | template<template<class...> class M> |
100 | struct m |
101 | { |
102 | template<class... B> |
103 | using inner = M<B...>; |
104 | }; |
105 | |
106 | m<t2> sta2; |
107 | } |
108 | |
109 | namespace PartialSpecialization { |
110 | template<typename T, typename U, typename V = U> |
111 | struct X0; // expected-note 2{{template is declared here}} |
112 | |
113 | template<typename ...Ts> |
114 | struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}} |
115 | }; |
116 | |
117 | X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}} |
118 | X0<int, float> x0if; |
119 | X0<int, float, double> x0ifd; |
120 | } |
121 | |
122 | namespace FixedAliasTemplate { |
123 | template<typename,typename,typename> struct S {}; |
124 | template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}} |
125 | template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} |
126 | S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}} |
127 | } |
128 | |
129 | namespace PR18401 { |
130 | template<typename... Args> struct foo { }; |
131 | template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}} |
132 | template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}} |
133 | // FIXME: We should still record the alias template, but mark it as invalid. |
134 | template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}} |
135 | void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}} |
136 | } |
137 | |