1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
3 // Template argument deduction with template template parameters.
4 template<typename T, template<T> class A>
6 static const unsigned value = 0;
9 template<template<int> class A>
11 static const unsigned value = 1;
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];
19 template<typename T, typename U>
21 static const bool value = false;
25 struct is_same<T, T> {
26 static const bool value = true;
29 template<typename T> struct allocator { };
30 template<typename T, typename Alloc = allocator<T> > struct vector {};
32 // Fun with meta-lambdas!
36 // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
37 template<typename T, typename Arg1, typename Arg2>
42 // Replacement of the whole type.
43 template<typename Arg1, typename Arg2>
44 struct Replace<_1, Arg1, Arg2> {
48 template<typename Arg1, typename Arg2>
49 struct Replace<_2, Arg1, Arg2> {
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;
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;
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;
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;
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];
86 template <typename T, int N> void f(const T (&a)[N]);
88 void test_PR5911() { f(iarr); }
90 // Must not examine base classes of incomplete type during template argument
93 template <typename T> struct X {
94 template <typename U> X(const X<U>& u);
98 void f(const X<A>& a);
99 void test(A& a) { (void)f(a); }
105 template <typename T_> void g (T_&); // expected-note{{T_ = int}}
106 void h (void) { g(f()); } // expected-error{{no matching function for call}}
110 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'}}
113 make(char_maker); // expected-error {{no matching function for call to 'make'}}
118 template<typename T> void foo(const T a[3][3]);
127 template<typename T> struct Const { typedef void const type; };
129 template<typename T> void f(T, typename Const<T>::type*);
130 template<typename T> void f(T, void const *);
138 // rdar://problem/8537391
141 template <void F(char)> static inline void foo();
145 template<typename T> static inline void wobble(T ch);
148 static void madness() {
149 Foo::foo<wobble<char> >();
154 // Verify that we can deduce enum-typed arguments correctly.
157 template <E> struct A {};
158 template <E e> void foo(const A<e> &a) {}
167 template<typename ...T> struct X;
168 template<typename A, typename ...B> struct S {
169 static_assert(sizeof...(B) == 1, "");
178 template<typename ...T> void f(S<T...>);
179 void g() { f(S<int, int>()); }
183 template <template<typename...> class C, typename ...Us> struct BindBack {
184 template <typename ...Ts> using apply = C<Ts..., Us...>;
186 template <typename, typename...> struct Y;
187 template <typename ...Ts> using Z = Y<Ts...>;
189 using T = BindBack<Z, int>::apply<>;
192 using U = BindBack<Z, int, int>::apply<char>;
193 using U = Z<char, int, int>;
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}}
202 using T = S<int, int>;
207 template<typename F> F Quux(F &&f);
208 auto Baz = Quux(Quux<float>);