2014-04-07 Charles Baylis <charles.baylis@linaro.org>
[official-gcc.git] / gcc / testsuite / g++.dg / torture / pr49519.C
blob2888709d99f5bd20e69103f3fa988768d41a1b8e
1 /* { dg-do run } */
3 #include <stdlib.h>
5 struct null_type {};
7 inline const null_type cnull() { return null_type(); }
9 template <class TT> struct cons;
10 class tuple;
12 template< int N >
13 struct 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   }
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   }
30 template<int N, class T>
31 struct element
33 private:
34   typedef typename T::tail_type Next;
35 public:
36   typedef typename element<N-1, Next>::type type;
39 template<class T>
40 struct element<0,T>
42   typedef int type;
45 template<int N, class TT>
46 inline int& get(cons<TT>& c) {
47   return get_class<N>::template get(c);
50 template <class TT>
51 struct cons {
52   typedef TT tail_type;
54   int head;
55   tail_type tail;
57   cons() : head(), tail() {}
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       {}
66 template <>
67 struct cons<null_type> {
68   typedef null_type tail_type;
70   int head;
72   cons() : head() {}
74   template<class T1>
75   cons(T1& t1, const null_type&, const null_type&, const null_type&)
76   : head (t1) {}
79 template <class T0, class T1, class T2, class T3>
80 struct map_tuple_to_cons
82   typedef cons<typename map_tuple_to_cons<T1, T2, T3, null_type>::type> type;
85 template <>
86 struct map_tuple_to_cons<null_type, null_type, null_type, null_type>
88   typedef null_type type;
91 class tuple :
92   public map_tuple_to_cons<int, int, int, int>::type
94 public:
95   typedef typename
96     map_tuple_to_cons<int, int, int, int>::type inherited;
98   tuple(const int &t0,
99         const int &t1,
100         const int &t2,
101         const int &t3)
102     : inherited(t0, t1, t2, t3) {}
105 void foo(void (*boo)(int, int, int, int), tuple t)
107   boo(get<0>(t), get<1>(t), get<2>(t), get<3>(t));
110 int tailcalled_t1;
111 int tailcalled_t2;
112 int tailcalled_t3;
113 int tailcalled_t4;
115 void print(int t1, int t2, int t3, int t4)
117   tailcalled_t1 = t1;
118   tailcalled_t2 = t2;
119   tailcalled_t3 = t3;
120   tailcalled_t4 = t4;
123 int main ()
125   tuple t(1,2,3,4);
126   foo(print, t);
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();
134   return 0;