1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2*67e74705SXin Li
3*67e74705SXin Li // Template argument deduction with template template parameters.
4*67e74705SXin Li template<typename T, template<T> class A>
5*67e74705SXin Li struct X0 {
6*67e74705SXin Li static const unsigned value = 0;
7*67e74705SXin Li };
8*67e74705SXin Li
9*67e74705SXin Li template<template<int> class A>
10*67e74705SXin Li struct X0<int, A> {
11*67e74705SXin Li static const unsigned value = 1;
12*67e74705SXin Li };
13*67e74705SXin Li
14*67e74705SXin Li template<int> struct X0i;
15*67e74705SXin Li template<long> struct X0l;
16*67e74705SXin Li int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
17*67e74705SXin Li int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
18*67e74705SXin Li
19*67e74705SXin Li template<typename T, typename U>
20*67e74705SXin Li struct is_same {
21*67e74705SXin Li static const bool value = false;
22*67e74705SXin Li };
23*67e74705SXin Li
24*67e74705SXin Li template<typename T>
25*67e74705SXin Li struct is_same<T, T> {
26*67e74705SXin Li static const bool value = true;
27*67e74705SXin Li };
28*67e74705SXin Li
29*67e74705SXin Li template<typename T> struct allocator { };
30*67e74705SXin Li template<typename T, typename Alloc = allocator<T> > struct vector {};
31*67e74705SXin Li
32*67e74705SXin Li // Fun with meta-lambdas!
33*67e74705SXin Li struct _1 {};
34*67e74705SXin Li struct _2 {};
35*67e74705SXin Li
36*67e74705SXin Li // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
37*67e74705SXin Li template<typename T, typename Arg1, typename Arg2>
38*67e74705SXin Li struct Replace {
39*67e74705SXin Li typedef T type;
40*67e74705SXin Li };
41*67e74705SXin Li
42*67e74705SXin Li // Replacement of the whole type.
43*67e74705SXin Li template<typename Arg1, typename Arg2>
44*67e74705SXin Li struct Replace<_1, Arg1, Arg2> {
45*67e74705SXin Li typedef Arg1 type;
46*67e74705SXin Li };
47*67e74705SXin Li
48*67e74705SXin Li template<typename Arg1, typename Arg2>
49*67e74705SXin Li struct Replace<_2, Arg1, Arg2> {
50*67e74705SXin Li typedef Arg2 type;
51*67e74705SXin Li };
52*67e74705SXin Li
53*67e74705SXin Li // Replacement through cv-qualifiers
54*67e74705SXin Li template<typename T, typename Arg1, typename Arg2>
55*67e74705SXin Li struct Replace<const T, Arg1, Arg2> {
56*67e74705SXin Li typedef typename Replace<T, Arg1, Arg2>::type const type;
57*67e74705SXin Li };
58*67e74705SXin Li
59*67e74705SXin Li // Replacement of templates
60*67e74705SXin Li template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
61*67e74705SXin Li struct Replace<TT<T1>, Arg1, Arg2> {
62*67e74705SXin Li typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
63*67e74705SXin Li };
64*67e74705SXin Li
65*67e74705SXin Li template<template<typename, typename> class TT, typename T1, typename T2,
66*67e74705SXin Li typename Arg1, typename Arg2>
67*67e74705SXin Li struct Replace<TT<T1, T2>, Arg1, Arg2> {
68*67e74705SXin Li typedef TT<typename Replace<T1, Arg1, Arg2>::type,
69*67e74705SXin Li typename Replace<T2, Arg1, Arg2>::type> type;
70*67e74705SXin Li };
71*67e74705SXin Li
72*67e74705SXin Li // Just for kicks...
73*67e74705SXin Li template<template<typename, typename> class TT, typename T1,
74*67e74705SXin Li typename Arg1, typename Arg2>
75*67e74705SXin Li struct Replace<TT<T1, _2>, Arg1, Arg2> {
76*67e74705SXin Li typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
77*67e74705SXin Li };
78*67e74705SXin Li
79*67e74705SXin Li int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
80*67e74705SXin Li int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
81*67e74705SXin Li int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
82*67e74705SXin Li int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
83*67e74705SXin Li int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
84*67e74705SXin Li
85*67e74705SXin Li // PR5911
86*67e74705SXin Li template <typename T, int N> void f(const T (&a)[N]);
87*67e74705SXin Li int iarr[] = { 1 };
test_PR5911()88*67e74705SXin Li void test_PR5911() { f(iarr); }
89*67e74705SXin Li
90*67e74705SXin Li // Must not examine base classes of incomplete type during template argument
91*67e74705SXin Li // deduction.
92*67e74705SXin Li namespace PR6257 {
93*67e74705SXin Li template <typename T> struct X {
94*67e74705SXin Li template <typename U> X(const X<U>& u);
95*67e74705SXin Li };
96*67e74705SXin Li struct A;
97*67e74705SXin Li void f(A& a);
98*67e74705SXin Li void f(const X<A>& a);
test(A & a)99*67e74705SXin Li void test(A& a) { (void)f(a); }
100*67e74705SXin Li }
101*67e74705SXin Li
102*67e74705SXin Li // PR7463
103*67e74705SXin Li namespace PR7463 {
104*67e74705SXin Li const int f ();
105*67e74705SXin Li template <typename T_> void g (T_&); // expected-note{{T_ = int}}
h(void)106*67e74705SXin Li void h (void) { g(f()); } // expected-error{{no matching function for call}}
107*67e74705SXin Li }
108*67e74705SXin Li
109*67e74705SXin Li namespace test0 {
110*67e74705SXin Li template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
111*67e74705SXin Li char *char_maker();
test()112*67e74705SXin Li void test() {
113*67e74705SXin Li make(char_maker); // expected-error {{no matching function for call to 'make'}}
114*67e74705SXin Li }
115*67e74705SXin Li }
116*67e74705SXin Li
117*67e74705SXin Li namespace test1 {
118*67e74705SXin Li template<typename T> void foo(const T a[3][3]);
test()119*67e74705SXin Li void test() {
120*67e74705SXin Li int a[3][3];
121*67e74705SXin Li foo(a);
122*67e74705SXin Li }
123*67e74705SXin Li }
124*67e74705SXin Li
125*67e74705SXin Li // PR7708
126*67e74705SXin Li namespace test2 {
127*67e74705SXin Li template<typename T> struct Const { typedef void const type; };
128*67e74705SXin Li
129*67e74705SXin Li template<typename T> void f(T, typename Const<T>::type*);
130*67e74705SXin Li template<typename T> void f(T, void const *);
131*67e74705SXin Li
test()132*67e74705SXin Li void test() {
133*67e74705SXin Li void *p = 0;
134*67e74705SXin Li f(0, p);
135*67e74705SXin Li }
136*67e74705SXin Li }
137*67e74705SXin Li
138*67e74705SXin Li // rdar://problem/8537391
139*67e74705SXin Li namespace test3 {
140*67e74705SXin Li struct Foo {
141*67e74705SXin Li template <void F(char)> static inline void foo();
142*67e74705SXin Li };
143*67e74705SXin Li
144*67e74705SXin Li class Bar {
145*67e74705SXin Li template<typename T> static inline void wobble(T ch);
146*67e74705SXin Li
147*67e74705SXin Li public:
madness()148*67e74705SXin Li static void madness() {
149*67e74705SXin Li Foo::foo<wobble<char> >();
150*67e74705SXin Li }
151*67e74705SXin Li };
152*67e74705SXin Li }
153*67e74705SXin Li
154*67e74705SXin Li // Verify that we can deduce enum-typed arguments correctly.
155*67e74705SXin Li namespace test14 {
156*67e74705SXin Li enum E { E0, E1 };
157*67e74705SXin Li template <E> struct A {};
foo(const A<e> & a)158*67e74705SXin Li template <E e> void foo(const A<e> &a) {}
159*67e74705SXin Li
test()160*67e74705SXin Li void test() {
161*67e74705SXin Li A<E0> a;
162*67e74705SXin Li foo(a);
163*67e74705SXin Li }
164*67e74705SXin Li }
165*67e74705SXin Li
166*67e74705SXin Li namespace PR21536 {
167*67e74705SXin Li template<typename ...T> struct X;
168*67e74705SXin Li template<typename A, typename ...B> struct S {
169*67e74705SXin Li static_assert(sizeof...(B) == 1, "");
fPR21536::S170*67e74705SXin Li void f() {
171*67e74705SXin Li using T = A;
172*67e74705SXin Li using T = int;
173*67e74705SXin Li
174*67e74705SXin Li using U = X<B...>;
175*67e74705SXin Li using U = X<int>;
176*67e74705SXin Li }
177*67e74705SXin Li };
178*67e74705SXin Li template<typename ...T> void f(S<T...>);
g()179*67e74705SXin Li void g() { f(S<int, int>()); }
180*67e74705SXin Li }
181*67e74705SXin Li
182*67e74705SXin Li namespace PR19372 {
183*67e74705SXin Li template <template<typename...> class C, typename ...Us> struct BindBack {
184*67e74705SXin Li template <typename ...Ts> using apply = C<Ts..., Us...>;
185*67e74705SXin Li };
186*67e74705SXin Li template <typename, typename...> struct Y;
187*67e74705SXin Li template <typename ...Ts> using Z = Y<Ts...>;
188*67e74705SXin Li
189*67e74705SXin Li using T = BindBack<Z, int>::apply<>;
190*67e74705SXin Li using T = Z<int>;
191*67e74705SXin Li
192*67e74705SXin Li using U = BindBack<Z, int, int>::apply<char>;
193*67e74705SXin Li using U = Z<char, int, int>;
194*67e74705SXin Li
195*67e74705SXin Li namespace BetterReduction {
196*67e74705SXin Li template<typename ...> struct S;
197*67e74705SXin Li template<typename ...A> using X = S<A...>; // expected-note {{parameter}}
198*67e74705SXin Li template<typename ...A> using Y = X<A..., A...>;
199*67e74705SXin Li template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}
200*67e74705SXin Li
201*67e74705SXin Li using T = Y<int>;
202*67e74705SXin Li using T = S<int, int>;
203*67e74705SXin Li }
204*67e74705SXin Li }
205*67e74705SXin Li
206*67e74705SXin Li namespace PR18645 {
207*67e74705SXin Li template<typename F> F Quux(F &&f);
208*67e74705SXin Li auto Baz = Quux(Quux<float>);
209*67e74705SXin Li }
210*67e74705SXin Li
211*67e74705SXin Li namespace NonDeducedNestedNameSpecifier {
212*67e74705SXin Li template<typename T> struct A {
213*67e74705SXin Li template<typename U> struct B {
BNonDeducedNestedNameSpecifier::A::B214*67e74705SXin Li B(int) {}
215*67e74705SXin Li };
216*67e74705SXin Li };
217*67e74705SXin Li
218*67e74705SXin Li template<typename T> int f(A<T>, typename A<T>::template B<T>);
219*67e74705SXin Li int k = f(A<int>(), 0);
220*67e74705SXin Li }
221*67e74705SXin Li
222*67e74705SXin Li namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity {
223*67e74705SXin Li namespace ns1 {
224*67e74705SXin Li
225*67e74705SXin Li template<class...> struct B { };
226*67e74705SXin Li template<class H, class ... Ts> struct B<H, Ts...> : B<> { };
227*67e74705SXin Li template<class ... Ts> struct D : B<Ts...> { };
228*67e74705SXin Li
f(B<T,Ts...> &)229*67e74705SXin Li template<class T, class ... Ts> void f(B<T, Ts...> &) { }
230*67e74705SXin Li
main()231*67e74705SXin Li int main() {
232*67e74705SXin Li D<int, char> d;
233*67e74705SXin Li f<int>(d);
234*67e74705SXin Li }
235*67e74705SXin Li } //end ns1
236*67e74705SXin Li
237*67e74705SXin Li namespace ns2 {
238*67e74705SXin Li
239*67e74705SXin Li template <int i, typename... Es> struct tup_impl;
240*67e74705SXin Li
241*67e74705SXin Li template <int i> struct tup_impl<i> {}; // empty tail
242*67e74705SXin Li
243*67e74705SXin Li template <int i, typename Head, typename... Tail>
244*67e74705SXin Li struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> {
245*67e74705SXin Li using value_type = Head;
246*67e74705SXin Li Head head;
247*67e74705SXin Li };
248*67e74705SXin Li
249*67e74705SXin Li template <typename... Es> struct tup : tup_impl<0, Es...> {};
250*67e74705SXin Li
251*67e74705SXin Li template <typename Head, int i, typename... Tail>
get_helper(tup_impl<i,Head,Tail...> & t)252*67e74705SXin Li Head &get_helper(tup_impl<i, Head, Tail...> &t) {
253*67e74705SXin Li return t.head;
254*67e74705SXin Li }
255*67e74705SXin Li
256*67e74705SXin Li template <typename Head, int i, typename... Tail>
get_helper(tup_impl<i,Head,Tail...> const & t)257*67e74705SXin Li Head const &get_helper(tup_impl<i, Head, Tail...> const &t) {
258*67e74705SXin Li return t.head;
259*67e74705SXin Li }
260*67e74705SXin Li
main()261*67e74705SXin Li int main() {
262*67e74705SXin Li tup<int, double, char> t;
263*67e74705SXin Li get_helper<double>(t);
264*67e74705SXin Li return 0;
265*67e74705SXin Li }
266*67e74705SXin Li } // end ns2
267*67e74705SXin Li }