1/* { dg-do run } */ 2 3#include <stdlib.h> 4 5struct null_type {}; 6 7inline const null_type cnull() { return null_type(); } 8 9template <class TT> struct cons; 10class tuple; 11 12template< int N > 13struct get_class { 14 template<class TT > 15 inline static int& get(cons<TT>& t) 16 { 17 return get_class<N-1>::template get(t.tail); 18 } 19}; 20 21template<> 22struct get_class<0> { 23 template<class TT> 24 inline static int& get(cons<TT>& t) 25 { 26 return t.head; 27 } 28}; 29 30template<int N, class T> 31struct element 32{ 33private: 34 typedef typename T::tail_type Next; 35public: 36 typedef typename element<N-1, Next>::type type; 37}; 38 39template<class T> 40struct element<0,T> 41{ 42 typedef int type; 43}; 44 45template<int N, class TT> 46inline int& get(cons<TT>& c) { 47 return get_class<N>::template get(c); 48} 49 50template <class TT> 51struct cons { 52 typedef TT tail_type; 53 54 int head; 55 tail_type tail; 56 57 cons() : head(), tail() {} 58 59 template <class T1, class T2, class T3, class T4> 60 cons( T1& t1, T2& t2, T3& t3, T4& t4 ) 61 : head (t1), 62 tail (t2, t3, t4, cnull()) 63 {} 64}; 65 66template <> 67struct cons<null_type> { 68 typedef null_type tail_type; 69 70 int head; 71 72 cons() : head() {} 73 74 template<class T1> 75 cons(T1& t1, const null_type&, const null_type&, const null_type&) 76 : head (t1) {} 77}; 78 79template <class T0, class T1, class T2, class T3> 80struct map_tuple_to_cons 81{ 82 typedef cons<typename map_tuple_to_cons<T1, T2, T3, null_type>::type> type; 83}; 84 85template <> 86struct map_tuple_to_cons<null_type, null_type, null_type, null_type> 87{ 88 typedef null_type type; 89}; 90 91class tuple : 92 public map_tuple_to_cons<int, int, int, int>::type 93{ 94public: 95 typedef typename 96 map_tuple_to_cons<int, int, int, int>::type inherited; 97 98 tuple(const int &t0, 99 const int &t1, 100 const int &t2, 101 const int &t3) 102 : inherited(t0, t1, t2, t3) {} 103}; 104 105void foo(void (*boo)(int, int, int, int), tuple t) 106{ 107 boo(get<0>(t), get<1>(t), get<2>(t), get<3>(t)); 108} 109 110int tailcalled_t1; 111int tailcalled_t2; 112int tailcalled_t3; 113int tailcalled_t4; 114 115void print(int t1, int t2, int t3, int t4) 116{ 117 tailcalled_t1 = t1; 118 tailcalled_t2 = t2; 119 tailcalled_t3 = t3; 120 tailcalled_t4 = t4; 121} 122 123int main () 124{ 125 tuple t(1,2,3,4); 126 foo(print, t); 127 128 if( (get<0>(t) != tailcalled_t1) 129 ||(get<1>(t) != tailcalled_t2) 130 ||(get<2>(t) != tailcalled_t3) 131 ||(get<3>(t) != tailcalled_t4)) 132 abort(); 133 134 return 0; 135} 136