Home | History | Annotate | Download | only in SemaTemplate
      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 };
     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);
     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}}
    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: can't deduce a type for 'T' that would make 'const T' equal 'char'}}
    111   char *char_maker();
    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]);
    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 
    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:
    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 {};
    158   template <E e> void foo(const A<e> &a) {}
    159 
    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, "");
    170     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...>);
    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