1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
277d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
377d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor// Various tests related to partial ordering of variadic templates.
477d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregortemplate<typename ...Types> struct tuple;
577d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
677d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregortemplate<typename Tuple>
777d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorstruct X1 {
877d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor  static const unsigned value = 0;
977d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor};
1077d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
1177d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregortemplate<typename Head, typename ...Tail>
1277d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorstruct X1<tuple<Head, Tail...> > {
1377d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor  static const unsigned value = 1;
1477d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor};
1577d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
1677d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregortemplate<typename Head, typename ...Tail>
1777d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorstruct X1<tuple<Head, Tail&...> > {
1877d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor  static const unsigned value = 2;
1977d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor};
2077d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
2177d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregortemplate<typename Head, typename ...Tail>
2277d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorstruct X1<tuple<Head&, Tail&...> > {
2377d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor  static const unsigned value = 3;
2477d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor};
2577d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregor
2677d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorint check0[X1<tuple<>>::value == 0? 1 : -1];
2777d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorint check1[X1<tuple<int>>::value == 2? 1 : -1];
2877d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorint check2[X1<tuple<int, int>>::value == 1? 1 : -1];
2977d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorint check3[X1<tuple<int, int&>>::value == 2? 1 : -1];
3077d6bb9e223496aa5288294f34e7225d1f65dddcDouglas Gregorint check4[X1<tuple<int&, int&>>::value == 3? 1 : -1];
31ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
32ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor// Partial ordering of function templates.
33ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregortemplate<typename T1, typename T2, typename ...Rest>
349da95e6eefc4b0ca25e18bdab1b703f5c185deabDouglas Gregorint &f0(T1, T2, Rest...);
35ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
36ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregortemplate<typename T1, typename T2>
379da95e6eefc4b0ca25e18bdab1b703f5c185deabDouglas Gregorfloat &f0(T1, T2);
38ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
39ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorvoid test_f0() {
40ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor  int &ir1 = f0(1, 2.0, 'a');
419da95e6eefc4b0ca25e18bdab1b703f5c185deabDouglas Gregor  float &fr1 = f0(1, 2.0);
42ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor}
43ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
44ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregortemplate<typename T1, typename T2, typename ...Rest>
45ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorint &f1(T1, T2, Rest...);
46ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
47ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregortemplate<typename T1, typename T2>
48ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorfloat &f1(T1, T2, ...);
49ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
50ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorvoid test_f1() {
51ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor  int &ir1 = f1(1, 2.0, 'a');
52ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor}
53ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
54ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregortemplate<typename T1, typename T2, typename ...Rest>
55ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorint &f2(T1, T2, Rest...);
56ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
57ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorfloat &f2(...);
58ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor
59ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregorvoid test_f2() {
60ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor  int &ir1 = f2(1, 2.0, 'a');
61ac6c09917eaf32a35d2c7c95856864d877ef1963Douglas Gregor}
62