Home | History | Annotate | Download | only in temp.param
      1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
      2 template<typename T> struct X;
      3 template<int I> struct Y;
      4 
      5 X<X<int>> *x1;
      6 
      7 Y<(1 >> 2)> *y1;
      8 Y<1 >> 2> *y2; // FIXME: expected-error{{expected unqualified-id}}
      9 
     10 X<X<X<X<X<int>>>>> *x2;
     11 
     12 template<> struct X<int> { };
     13 typedef X<int> X_int;
     14 struct Z : X_int { };
     15 
     16 void f(const X<int> x) {
     17   (void)reinterpret_cast<X<int>>(x); // expected-error{{reinterpret_cast from}}
     18   (void)reinterpret_cast<X<X<X<int>>>>(x); // expected-error{{reinterpret_cast from}}
     19 
     20   X<X<int>> *x1;
     21 }
     22 
     23 template<typename T = void> struct X1 { };
     24 X1<X1<>> x1a;
     25 
     26 
     27 namespace ParameterPackExpansions {
     28 
     29 // A template parameter pack that [contains an unexpanded parameter pack] is a
     30 // pack expansion.
     31 
     32 template<typename...Ts> struct Outer {
     33   // From [temp.variadic]p4:
     34   //   In a template parameter pack that is a pack expansion, the pattern is
     35   //   [...the template-parameter...] without the ellipsis.
     36   // Therefore the resulting sequence of parameters is not a parameter pack,
     37   // so is not required to be the last template parameter.
     38   template<Ts ...As, template<Ts> class ...Bs, typename ...Cs> struct Inner {
     39     struct Check : Bs<As>... {
     40       Check(Cs...);
     41     };
     42   };
     43 };
     44 
     45 template<int> struct TemplateInt {};
     46 template<char> struct TemplateChar {};
     47 template<int*> struct TemplateIntPtr {};
     48 int x;
     49 
     50 Outer<int, char, int*>::
     51 Inner<12345, 'x', &x,
     52       TemplateInt, TemplateChar, TemplateIntPtr,
     53       int*>::
     54 Check check(&x);
     55 
     56 
     57 template<typename...Ts> struct types;
     58 
     59 enum place { _ };
     60 template<place...> struct places {};
     61 
     62 template<typename P1, typename P2> struct append_places;
     63 template<place...X1, place...X2>
     64 struct append_places<places<X1...>, places<X2...>> {
     65   typedef places<X1...,X2...> type;
     66 };
     67 
     68 template<unsigned N>
     69 struct make_places : append_places<typename make_places<N/2>::type,
     70                                    typename make_places<N-N/2>::type> {};
     71 template<> struct make_places<0> { typedef places<> type; };
     72 template<> struct make_places<1> { typedef places<_> type; };
     73 
     74 template<typename T> struct wrap {
     75   template<place> struct inner { typedef T type; };
     76 };
     77 
     78 template<typename T> struct takedrop_impl;
     79 template<place...X> struct takedrop_impl<places<X...>> {
     80   template<template<decltype(X)> class ...Take,
     81            template<place      > class ...Drop>
     82   struct inner { // expected-note 2{{declared}}
     83     typedef types<typename Take<_>::type...> take;
     84     typedef types<typename Drop<_>::type...> drop;
     85   };
     86 };
     87 
     88 template<unsigned N, typename...Ts> struct take {
     89   using type = typename takedrop_impl<typename make_places<N>::type>::
     90     template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}}
     91 };
     92 template<unsigned N, typename...Ts> struct drop {
     93   using type = typename takedrop_impl<typename make_places<N>::type>::
     94     template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}}
     95 };
     96 
     97 using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}}
     98 // FIXME: Desguar the types on the RHS in this diagnostic.
     99 // desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, (no argument)>'}}
    100 using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, (no argument)>'}}
    101 using D1 = drop<3, int, char, double, long>::type;
    102 using D1 = types<long>;
    103 
    104 using T2 = take<4, int, char, double, long>::type; // expected-note {{previous}}
    105 using T2 = types<int, char, double, long>;
    106 // FIXME: Desguar the types on the RHS in this diagnostic.
    107 // desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, long>'}}
    108 using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, typename inner<_>::type>'}}
    109 using D2 = drop<4, int, char, double, long>::type;
    110 using D2 = types<>;
    111 
    112 using T3 = take<5, int, char, double, long>::type; // expected-note {{in instantiation of}}
    113 using D3 = drop<5, int, char, double, long>::type; // expected-note {{in instantiation of}}
    114 
    115 
    116 // FIXME: We should accept this code. A parameter pack within a default argument
    117 // in a template template parameter pack is expanded, because the pack is
    118 // implicitly a pack expansion.
    119 template<typename ...Default> struct DefArg {
    120   template<template<typename T = Default> class ...Classes> struct Inner { // expected-error {{default argument contains unexpanded parameter pack}} expected-note {{here}}
    121     Inner(Classes<>...); // expected-error {{too few}}
    122   };
    123 };
    124 template<typename T> struct vector {};
    125 template<typename T> struct list {};
    126 vector<int> vi;
    127 list<char> lc;
    128 DefArg<int, char>::Inner<vector, list> defarg(vi, lc);
    129 
    130 
    131 // FIXME:
    132 // A template parameter pack that is a pack expansion shall not expand a
    133 // parameter pack declared in the same template-parameter-list.
    134 template<typename...Ts, Ts...Vs> void error(); // desired-error
    135 
    136 // This case should not produce an error, because in A's instantiation, Cs is
    137 // not a parameter pack.
    138 template<typename...Ts> void consume(Ts...);
    139 template<typename...Ts> struct A {
    140   template<template<typename, Ts = 0> class ...Cs, Cs<Ts> ...Vs> struct B { // ok
    141     B() {
    142       consume([]{
    143         int arr[Vs]; // expected-error {{negative size}}
    144       }...);
    145     }
    146   };
    147 };
    148 template<typename, int> using Int = int;
    149 template<typename, short> using Char = char;
    150 A<int, short>::B<Int, Char, -1, 'x'> b; // expected-note {{here}}
    151 
    152 }
    153 
    154 namespace PR9023 {
    155   template<typename ...T> struct A {
    156     template<template<T> class ...> struct B {
    157     };
    158   };
    159 
    160   template<int> struct C { };
    161   template<long> struct D { };
    162 
    163   int main() {
    164     A<int, long>::B<C, D> e;
    165   }
    166 }
    167 
    168 namespace std_examples {
    169   template <class... Types> class Tuple;
    170   template <class T, int... Dims> struct multi_array;
    171   template <class... T> struct value_holder {
    172     template<T... Values> struct apply { };
    173   };
    174   template <class... T, T... Values> struct static_array; // expected-error {{must be the last}}
    175 
    176   int n;
    177   value_holder<int, char, int*>::apply<12345, 'x', &n> test;
    178 }
    179