1 /* { dg-do run } */
2
3 #include <stdlib.h>
4
5 struct null_type {};
6
cnull()7 inline const null_type cnull() { return null_type(); }
8
9 template <class TT> struct cons;
10 class tuple;
11
12 template< int N >
13 struct get_class {
14 template<class TT >
getget_class15 inline static int& get(cons<TT>& t)
16 {
17 return get_class<N-1>::template get(t.tail);
18 }
19 };
20
21 template<>
22 struct get_class<0> {
23 template<class TT>
24 inline static int& get(cons<TT>& t)
25 {
26 return t.head;
27 }
28 };
29
30 template<int N, class T>
31 struct element
32 {
33 private:
34 typedef typename T::tail_type Next;
35 public:
36 typedef typename element<N-1, Next>::type type;
37 };
38
39 template<class T>
40 struct element<0,T>
41 {
42 typedef int type;
43 };
44
45 template<int N, class TT>
46 inline int& get(cons<TT>& c) {
47 return get_class<N>::template get(c);
48 }
49
50 template <class TT>
51 struct 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
66 template <>
67 struct 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
79 template <class T0, class T1, class T2, class T3>
80 struct map_tuple_to_cons
81 {
82 typedef cons<typename map_tuple_to_cons<T1, T2, T3, null_type>::type> type;
83 };
84
85 template <>
86 struct map_tuple_to_cons<null_type, null_type, null_type, null_type>
87 {
88 typedef null_type type;
89 };
90
91 class tuple :
92 public map_tuple_to_cons<int, int, int, int>::type
93 {
94 public:
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
105 void 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
110 int tailcalled_t1;
111 int tailcalled_t2;
112 int tailcalled_t3;
113 int tailcalled_t4;
114
115 void 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
123 int 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