]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / CXX / temp / temp.fct.spec / temp.deduct / temp.deduct.type / p9-0x.cpp
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-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
36 }
37
38 // When a pack expansion occurs within a template argument list, the entire
39 // list is a non-deduced context. For the corresponding case in a function
40 // parameter list, only that parameter is non-deduced.
41 //
42 // FIXME: It's not clear that this difference is intended, but the wording is
43 // explicit.
44 namespace PackExpansionNotAtEndFunctionVersusTemplate {
45   template<typename ...T> struct X {};
46   template<typename ...T, typename U> void f1(void(T..., U));
47   // expected-note@+1 {{couldn't infer template argument 'U'}}
48   template<typename ...T, typename U> void f2(X<T..., U>); // FIXME: ill-formed, U is not deducible
49
50   void g(int, int, int);
51   X<int, int, int> h;
52   void test() {
53     // This is deducible: the T... parameter is a non-deduced context, but
54     // that's OK because we don't need to deduce it.
55     f1<int, int>(g);
56     // This is not deducible: the T... parameter renders the entire
57     // template-argument-list a non-deduced context, so U is not deducible.
58     f2<int, int>(h); // expected-error {{no matching function}}
59   }
60
61   template<typename T> struct Y;
62   template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
63            typename U>
64     struct Y<void(T..., U)> {}; // expected-error {{cannot be deduced}}
65   template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
66            typename U> // expected-note {{non-deducible template parameter 'U'}}
67     struct Y<X<T..., U>>; // expected-error {{cannot be deduced}}
68   // FIXME: T is not deducible here, due to [temp.deduct.call]p1:
69   //   "When a function parameter pack appears in a non-deduced context,
70   //   the type of that pack is never deduced."
71   template<typename ...T,
72            typename U>
73     struct Y<void(T..., U, T...)> {};
74 }
75
76 namespace DeduceNonTypeTemplateArgsInArray {
77   template<typename ...ArrayTypes>
78   struct split_arrays;
79
80   template<typename ...ElementTypes, unsigned ...Bounds>
81   struct split_arrays<ElementTypes[Bounds]...> {
82     typedef tuple<ElementTypes...> element_types;
83
84     // FIXME: Would like to have unsigned_tuple<Bounds...> here.
85     typedef tuple<unsigned_c<Bounds>...> bounds_types;
86   };
87
88   int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types,
89                      tuple<int, float, double>>::value? 1 : -1];
90   int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types,
91                      tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
92                      >::value? 1 : -1];
93 }
94
95 namespace DeduceWithDefaultArgs {
96   template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = X]}}
97   template<typename, typename = int> struct X {};
98   void g() {
99     // OK, use default argument for the second template parameter.
100     f(X<int>{});
101     f(X<int, int>{});
102
103     // Not OK.
104     f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}}
105   }
106 }