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