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