xref: /llvm-project/clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp (revision c6e68daac0fa6e77a89f3ca72f266a528503dd1c)
19ca5c425SRichard Smith // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2*c6e68daaSAndy Gibbs // expected-no-diagnostics
32fcb863bSDouglas Gregor 
42fcb863bSDouglas Gregor // Various tests related to partial ordering of variadic templates.
52fcb863bSDouglas Gregor template<typename ...Types> struct tuple;
62fcb863bSDouglas Gregor 
72fcb863bSDouglas Gregor template<typename Tuple>
82fcb863bSDouglas Gregor struct X1 {
92fcb863bSDouglas Gregor   static const unsigned value = 0;
102fcb863bSDouglas Gregor };
112fcb863bSDouglas Gregor 
122fcb863bSDouglas Gregor template<typename Head, typename ...Tail>
132fcb863bSDouglas Gregor struct X1<tuple<Head, Tail...> > {
142fcb863bSDouglas Gregor   static const unsigned value = 1;
152fcb863bSDouglas Gregor };
162fcb863bSDouglas Gregor 
172fcb863bSDouglas Gregor template<typename Head, typename ...Tail>
182fcb863bSDouglas Gregor struct X1<tuple<Head, Tail&...> > {
192fcb863bSDouglas Gregor   static const unsigned value = 2;
202fcb863bSDouglas Gregor };
212fcb863bSDouglas Gregor 
222fcb863bSDouglas Gregor template<typename Head, typename ...Tail>
232fcb863bSDouglas Gregor struct X1<tuple<Head&, Tail&...> > {
242fcb863bSDouglas Gregor   static const unsigned value = 3;
252fcb863bSDouglas Gregor };
262fcb863bSDouglas Gregor 
272fcb863bSDouglas Gregor int check0[X1<tuple<>>::value == 0? 1 : -1];
282fcb863bSDouglas Gregor int check1[X1<tuple<int>>::value == 2? 1 : -1];
292fcb863bSDouglas Gregor int check2[X1<tuple<int, int>>::value == 1? 1 : -1];
302fcb863bSDouglas Gregor int check3[X1<tuple<int, int&>>::value == 2? 1 : -1];
312fcb863bSDouglas Gregor int check4[X1<tuple<int&, int&>>::value == 3? 1 : -1];
32ab2ecaceSDouglas Gregor 
33ab2ecaceSDouglas Gregor // Partial ordering of function templates.
34ab2ecaceSDouglas Gregor template<typename T1, typename T2, typename ...Rest>
35cef1a03eSDouglas Gregor int &f0(T1, T2, Rest...);
36ab2ecaceSDouglas Gregor 
37ab2ecaceSDouglas Gregor template<typename T1, typename T2>
38cef1a03eSDouglas Gregor float &f0(T1, T2);
39ab2ecaceSDouglas Gregor 
test_f0()40ab2ecaceSDouglas Gregor void test_f0() {
41ab2ecaceSDouglas Gregor   int &ir1 = f0(1, 2.0, 'a');
42cef1a03eSDouglas Gregor   float &fr1 = f0(1, 2.0);
43ab2ecaceSDouglas Gregor }
44ab2ecaceSDouglas Gregor 
45ab2ecaceSDouglas Gregor template<typename T1, typename T2, typename ...Rest>
46ab2ecaceSDouglas Gregor int &f1(T1, T2, Rest...);
47ab2ecaceSDouglas Gregor 
48ab2ecaceSDouglas Gregor template<typename T1, typename T2>
49ab2ecaceSDouglas Gregor float &f1(T1, T2, ...);
50ab2ecaceSDouglas Gregor 
test_f1()51ab2ecaceSDouglas Gregor void test_f1() {
52ab2ecaceSDouglas Gregor   int &ir1 = f1(1, 2.0, 'a');
53ab2ecaceSDouglas Gregor }
54ab2ecaceSDouglas Gregor 
55ab2ecaceSDouglas Gregor template<typename T1, typename T2, typename ...Rest>
56ab2ecaceSDouglas Gregor int &f2(T1, T2, Rest...);
57ab2ecaceSDouglas Gregor 
58ab2ecaceSDouglas Gregor float &f2(...);
59ab2ecaceSDouglas Gregor 
test_f2()60ab2ecaceSDouglas Gregor void test_f2() {
61ab2ecaceSDouglas Gregor   int &ir1 = f2(1, 2.0, 'a');
62ab2ecaceSDouglas Gregor }
63