1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 
3 template<typename ...Types> struct tuple;
4 template<unsigned> struct unsigned_c;
5 
6 template<typename T, typename U>
7 struct is_same {
8   static const bool value = false;
9 };
10 
11 template<typename T>
12 struct is_same<T, T> {
13   static const bool value = true;
14 };
15 
16 namespace 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 
38 namespace 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 
57 namespace 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 {};
g()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