multi-level-substitution.cpp revision 6a24bfda084f06a0b252b7befe8cbb17fce7f94e
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