1 // RUN: %clang_cc1 -fsyntax-only -verify %s
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' which 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> >();