1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2
3template<typename T, typename U> struct pair { };
4template<typename ...Types> struct tuple { };
5
6template<typename T, typename U>
7struct is_same {
8  static const bool value = false;
9};
10
11template<typename T>
12struct is_same<T, T> {
13  static const bool value = true;
14};
15
16namespace ExpandIntoFixed {
17  template<typename T,
18           typename U,
19           typename V = pair<T, U>,
20           typename W = V*>
21  class X0 { };
22
23  template<typename ...Ts>
24  class X1 {
25  public:
26    typedef X0<Ts...> type;
27  };
28
29  static_assert(is_same<X1<int, int>::type,
30                        X0<int, int, pair<int, int>, pair<int, int>*>>::value,
31                "fails with two default arguments");
32
33  static_assert(is_same<X1<int, int, float>::type,
34                        X0<int, int, float, float*>>::value,
35                "fails with one default argument");
36
37  static_assert(is_same<X1<int, int, float, double>::type,
38                        X0<int, int, float, double>>::value,
39                "fails with no default arguments");
40}
41
42namespace ExpandIntoFixedShifted {
43  template<typename T,
44           typename U,
45           typename V = pair<T, U>,
46           typename W = V*>
47  class X0 { };
48
49  template<typename ...Ts>
50  class X1 {
51  public:
52    typedef X0<char, Ts...> type;
53  };
54
55  static_assert(is_same<X1<int>::type,
56                        X0<char, int, pair<char, int>, pair<char, int>*>>::value,
57                "fails with two default arguments");
58
59  static_assert(is_same<X1<int, float>::type,
60                        X0<char, int, float, float*>>::value,
61                "fails with one default argument");
62
63  static_assert(is_same<X1<int, float, double>::type,
64                        X0<char, int, float, double>>::value,
65                "fails with no default arguments");
66}
67
68namespace Deduction {
69  template <typename X, typename Y = double> struct Foo {};
70  template <typename ...Args> tuple<Args...> &foo(Foo<Args...>);
71
72  void call_foo(Foo<int, float> foo_if, Foo<int> foo_i) {
73    tuple<int, float> &t1 = foo(foo_if);
74    tuple<int, double> &t2 = foo(foo_i);
75  }
76}
77
78namespace PR9021a {
79  template<typename, typename>
80  struct A { };
81
82  template<typename ...T>
83  struct B {
84    A<T...> a1;
85  };
86
87  void test() {
88    B<int, int> c;
89  }
90}
91
92namespace PR9021b {
93  template<class, class>
94  struct t2
95  {
96
97  };
98
99  template<template<class...> class M>
100  struct m
101  {
102    template<class... B>
103    using inner = M<B...>;
104  };
105
106  m<t2> sta2;
107}
108
109namespace PartialSpecialization {
110  template<typename T, typename U, typename V = U>
111  struct X0; // expected-note{{template is declared here}}
112
113  template<typename ...Ts>
114  struct X0<Ts...> {
115  };
116
117  X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
118  X0<int, float> x0if;
119  X0<int, float, double> x0ifd;
120}
121
122namespace FixedAliasTemplate {
123  template<typename,typename,typename> struct S {};
124  template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}}
125  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}}
126  S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}}
127}
128
129namespace PR18401 {
130  template<typename... Args> struct foo { };
131  template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}}
132  template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
133  // FIXME: We should still record the alias template, but mark it as invalid.
134  template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}}
135  void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}}
136}
137