1 // { dg-do compile }
2 // { dg-options "-O3 -g" }
3 
4 template <typename T>
max(T & a,T & b)5 T &max (T &a, T &b)
6 {
7   if (a < b) return b; else return a;
8 }
9 int foo (double);
10 struct S
11 {
12   struct T
13   {
14     int dims, count;
TS::T15     T (int, int) : dims (), count () {}
16   };
17   T *rep;
SS18   S () {}
SS19   S (int r, int c) : rep (new T (r, c)) {}
~SS20   ~S () { delete rep; }
21 };
22 template <typename T>
23 struct U
24 {
25   static T epsilon () throw ();
26 };
27 template <class T>
28 struct V
29 {
30   struct W
31   {
32     T * data;
33     int count;
WV::W34     W (int n) : data (new T[n]), count () {}
35   };
36   V::W *rep;
37   S dimensions;
38   int slice_len;
VV39   V (S s) : rep (new V <T>::W (get_size (s))) {}
capacityV40   int capacity () { return slice_len; }
41   int get_size (S);
42 };
43 template <class T>
44 struct Z : public V <T>
45 {
ZZ46   Z () : V <T> (S (0, 0)) {}
ZZ47   Z (int r, int c) : V <T> (S (r, c)) {}
48 };
49 template <class T>
50 struct A : public Z <T>
51 {
AA52   A () : Z <T> () {}
AA53   A (int n, int m) : Z <T> (n, m) {}
54 };
55 template <class T>
56 struct B : public V <T>
57 {
58 };
59 struct C : public A <double>
60 {
CC61   C () : A <double> () {}
CC62   C (int r, int c) : A <double> (r, c) {}
63 };
64 struct D : public B <double>
65 {
66 };
67 template <class T>
68 struct E
69 {
70 };
71 template <class T>
72 struct G : public E <T>
73 {
74 };
75 struct H : public G <double>
76 {
77 };
78 template <class R>
79 struct I
80 {
81   R scl, sum;
accumI82   void accum (R val)
83   {
84     R t = __builtin_fabs (val);
85     if (scl == t)
86       sum += 1;
87   }
operator RI88   operator R () { __builtin_sqrt (sum); return R (); }
89 };
90 template <class R>
91 struct J
92 {
accumJ93   template < class U > void accum (U val) {}
operator RJ94   operator R () { return R (); }
95 };
96 template <class R>
97 struct K
98 {
99   R max;
accumK100   template <class U> void accum (U val)
101   {
102     double z = __builtin_fabs (val);
103     max = ::max (max, z);
104   }
operator RK105   operator R () { return max; }
106 };
107 template <class R>
108 struct L
109 {
110   unsigned num;
accumL111   template <class U> void accum (U) {}
operator RL112   operator R () { return num; }
113 };
114 template <class T, class R, class S>
bar(V<T> & v,R & res,S acc)115 void bar (V <T> &v, R &res, S acc)
116 {
117   for (int i = 0; i < v.capacity (); i++)
118     acc.accum ((i));
119   res = acc;
120 }
121 template <class T, class R>
bar(B<T> & v,R)122 void bar (B <T> &v, R)
123 {
124   R res;
125   bar (v, res, I <R> ());
126 }
127 template <class T, class R>
bar(A<T> & v,R p)128 R bar (A <T> &v, R p)
129 {
130   R res;
131   if (p == 2)
132     bar (v, res, I <R> ());
133   else if (p == 1)
134     bar (v, res, J <R> ());
135   else if (p == sizeof (float) ? (p) : foo (p))
136     {
137       if (p > 0)
138 	bar (v, res, K <R> ());
139     }
140   else if (p == 0)
141     bar (v, res, L <R> ());
142   return res;
143 }
144 template <class CT, class VectorT, class R>
145 void
baz(CT m,R p,R tol,int maxiter,VectorT)146 baz (CT m, R p, R tol, int maxiter, VectorT)
147 {
148   VectorT y (0, 0), z (0, 1);
149   R q = 0;
150   R gamma = 0, gamma1 = 0;
151   gamma = bar (y, p);
152   (void) (bar (z, q) <= (gamma1 <= gamma));
153 }
154 int a = 100;
155 template <class CT, class VectorT, class R>
156 void
test(CT m,R p,VectorT)157 test (CT m, R p, VectorT)
158 {
159   VectorT x;
160   R sqrteps (U <R>::epsilon ());
161   baz (m, p, sqrteps, a, x);
162 }
163 void
fn(D x,double p)164 fn (D x, double p)
165 {
166   bar (x, p);
167 }
168 void
fn(H x,double p)169 fn (H x, double p)
170 {
171   test (x, p, C ());
172 }
173