1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3template<typename ...Types> struct tuple;
4template<unsigned> struct unsigned_c;
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 PackExpansionNotAtEnd {
17  template<typename T, typename U>
18  struct tuple_same_with_int {
19    static const bool value = false;
20  };
21
22  template<typename ...Types>
23  struct tuple_same_with_int<tuple<Types...>, tuple<Types..., int>> {
24    static const bool value = true;
25  };
26
27  int tuple_same_with_int_1[tuple_same_with_int<tuple<int, float, double>,
28                                                tuple<int, float, double, int>
29                                                >::value? 1 : -1];
30
31  template<typename ... Types> struct UselessPartialSpec;
32
33  template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
34           typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
35  struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
36}
37
38namespace DeduceNonTypeTemplateArgsInArray {
39  template<typename ...ArrayTypes>
40  struct split_arrays;
41
42  template<typename ...ElementTypes, unsigned ...Bounds>
43  struct split_arrays<ElementTypes[Bounds]...> {
44    typedef tuple<ElementTypes...> element_types;
45
46    // FIXME: Would like to have unsigned_tuple<Bounds...> here.
47    typedef tuple<unsigned_c<Bounds>...> bounds_types;
48  };
49
50  int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types,
51                     tuple<int, float, double>>::value? 1 : -1];
52  int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types,
53                     tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
54                     >::value? 1 : -1];
55}
56
57namespace DeduceWithDefaultArgs {
58  template<template<typename...> class Container> void f(Container<int>); // expected-note {{substitution failure [with Container = X]}}
59  template<typename, typename = int> struct X {};
60  void g() {
61    // OK, use default argument for the second template parameter.
62    f(X<int>{});
63    f(X<int, int>{});
64
65    // Not OK.
66    f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}}
67  }
68}
69