multi-level-substitution.cpp revision c7793c73ba8a343de3f2552d984851985a46f159
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2
3template<typename T, T ...Values> struct value_tuple {};
4
5template<typename T>
6struct X0 {
7  template<T ...Values>
8  void f(value_tuple<T, Values...> * = 0);
9};
10
11void test_X0() {
12  X0<int>().f<1, 2, 3, 4, 5>();
13}
14
15namespace PacksAtDifferentLevels {
16  template<typename...> struct tuple { };
17  template<typename T, typename U> struct pair { };
18
19  template<typename ...Types>
20  struct X {
21    template<typename> struct Inner {
22      static const unsigned value = 1;
23    };
24
25    template<typename ...YTypes>
26    struct Inner<tuple<pair<Types, YTypes>...> > {
27      static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
28    };
29  };
30
31  int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
32                                             pair<int, unsigned int>,
33                                             pair<long, unsigned long>>
34                                       >::value == 0? 1 : -1];
35
36  int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
37                                        pair<int, unsigned int>,
38                                        pair<long, unsigned long>>
39                                       >::value == 1? 1 : -1];
40
41  template<unsigned ...Values> struct unsigned_tuple { };
42  template<typename ...Types>
43  struct X1 {
44    template<typename, typename> struct Inner {
45      static const unsigned value = 0;
46    };
47
48    template<typename ...YTypes>
49    struct Inner<tuple<pair<Types, YTypes>...>,
50                 unsigned_tuple<sizeof(Types) + sizeof(YTypes)...>> {
51      static const unsigned value = 1;
52    };
53  };
54
55  int check2[X1<short, int, long>::Inner<tuple<pair<short, unsigned short>,
56                                               pair<int, unsigned int>,
57                                               pair<long, unsigned long>>,
58                      unsigned_tuple<sizeof(short) + sizeof(unsigned short),
59                                     sizeof(int) + sizeof(unsigned int),
60                                     sizeof(long) + sizeof(unsigned long)>
61                                       >::value == 1? 1 : -1];
62  int check3[X1<short, int>::Inner<tuple<pair<short, unsigned short>,
63                                         pair<int, unsigned int>,
64                                         pair<long, unsigned long>>,
65                      unsigned_tuple<sizeof(short) + sizeof(unsigned short),
66                                     sizeof(int) + sizeof(unsigned int),
67                                     sizeof(long) + sizeof(unsigned long)>
68                                       >::value == 0? 1 : -1];
69
70  template<typename ...Types>
71  struct X2 {
72    template<typename> struct Inner {
73      static const unsigned value = 1;
74    };
75
76    template<typename R, typename ...YTypes>
77    struct Inner<R(pair<Types, YTypes>...)> {
78      static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
79    };
80  };
81
82  int check4[X2<short, int, long>::Inner<int(pair<short, unsigned short>,
83                                            pair<int, unsigned int>,
84                                            pair<long, unsigned long>)
85                                     >::value == 0? 1 : -1];
86
87  int check5[X2<short, int>::Inner<int(pair<short, unsigned short>,
88                                       pair<int, unsigned int>,
89                                       pair<long, unsigned long>)
90                                     >::value == 1? 1 : -1];
91
92  template<typename T, typename U>
93  struct some_function_object {
94    template<typename>
95    struct result_of;
96  };
97
98  template<template<class> class...> struct metafun_tuple { };
99
100  template<typename ...Types1>
101  struct X3 {
102    template<typename, typename> struct Inner {
103      static const unsigned value = 0;
104    };
105
106    template<typename ...Types2>
107    struct Inner<tuple<pair<Types1, Types2>...>,
108                 metafun_tuple<some_function_object<Types1, Types2>::template result_of...> > {
109      static const unsigned value = 1;
110    };
111  };
112
113  int check6[X3<short, int, long>::Inner<tuple<pair<short, unsigned short>,
114                                               pair<int, unsigned int>,
115                                               pair<long, unsigned long>>,
116                                 metafun_tuple<
117                         some_function_object<short, unsigned short>::result_of,
118                         some_function_object<int, unsigned int>::result_of,
119                         some_function_object<long, unsigned long>::result_of>
120                                     >::value == 1? 1 : -1];
121  int check7[X3<short, int>::Inner<tuple<pair<short, unsigned short>,
122                                               pair<int, unsigned int>,
123                                               pair<long, unsigned long>>,
124                                 metafun_tuple<
125                         some_function_object<short, unsigned short>::result_of,
126                         some_function_object<int, unsigned int>::result_of,
127                         some_function_object<long, unsigned long>::result_of>
128                                     >::value == 0? 1 : -1];
129
130  template<unsigned I, unsigned J> struct unsigned_pair { };
131
132  template<unsigned ...Values1>
133  struct X4 {
134    template<typename> struct Inner {
135      static const unsigned value = 0;
136    };
137
138    template<unsigned ...Values2>
139    struct Inner<tuple<unsigned_pair<Values1, Values2>...>> {
140      static const unsigned value = 1;
141    };
142  };
143
144  int check8[X4<1, 3, 5>::Inner<tuple<unsigned_pair<1, 2>,
145                                      unsigned_pair<3, 4>,
146                                      unsigned_pair<5, 6>>
147                                >::value == 1? 1 : -1];
148  int check9[X4<1, 3>::Inner<tuple<unsigned_pair<1, 2>,
149                                   unsigned_pair<3, 4>,
150                                   unsigned_pair<5, 6>>
151                             >::value == 0? 1 : -1];
152}
153