blob: c12a6988af8f66bf41ce763786618f1d70ff6492 [file] [log] [blame]
// { dg-do compile }
// { dg-options "-O3 -g" }
template <typename T>
T &max (T &a, T &b)
{
if (a < b) return b; else return a;
}
int foo (double);
struct S
{
struct T
{
int dims, count;
T (int, int) : dims (), count () {}
};
T *rep;
S () {}
S (int r, int c) : rep (new T (r, c)) {}
~S () { delete rep; }
};
template <typename T>
struct U
{
static T epsilon () throw ();
};
template <class T>
struct V
{
struct W
{
T * data;
int count;
W (int n) : data (new T[n]), count () {}
};
V::W *rep;
S dimensions;
int slice_len;
V (S s) : rep (new V <T>::W (get_size (s))) {}
int capacity () { return slice_len; }
int get_size (S);
};
template <class T>
struct Z : public V <T>
{
Z () : V <T> (S (0, 0)) {}
Z (int r, int c) : V <T> (S (r, c)) {}
};
template <class T>
struct A : public Z <T>
{
A () : Z <T> () {}
A (int n, int m) : Z <T> (n, m) {}
};
template <class T>
struct B : public V <T>
{
};
struct C : public A <double>
{
C () : A <double> () {}
C (int r, int c) : A <double> (r, c) {}
};
struct D : public B <double>
{
};
template <class T>
struct E
{
};
template <class T>
struct G : public E <T>
{
};
struct H : public G <double>
{
};
template <class R>
struct I
{
R scl, sum;
void accum (R val)
{
R t = __builtin_fabs (val);
if (scl == t)
sum += 1;
}
operator R () { __builtin_sqrt (sum); return R (); }
};
template <class R>
struct J
{
template < class U > void accum (U val) {}
operator R () { return R (); }
};
template <class R>
struct K
{
R max;
template <class U> void accum (U val)
{
double z = __builtin_fabs (val);
max = ::max (max, z);
}
operator R () { return max; }
};
template <class R>
struct L
{
unsigned num;
template <class U> void accum (U) {}
operator R () { return num; }
};
template <class T, class R, class S>
void bar (V <T> &v, R &res, S acc)
{
for (int i = 0; i < v.capacity (); i++)
acc.accum ((i));
res = acc;
}
template <class T, class R>
void bar (B <T> &v, R)
{
R res;
bar (v, res, I <R> ());
}
template <class T, class R>
R bar (A <T> &v, R p)
{
R res;
if (p == 2)
bar (v, res, I <R> ());
else if (p == 1)
bar (v, res, J <R> ());
else if (p == sizeof (float) ? (p) : foo (p))
{
if (p > 0)
bar (v, res, K <R> ());
}
else if (p == 0)
bar (v, res, L <R> ());
return res;
}
template <class CT, class VectorT, class R>
void
baz (CT m, R p, R tol, int maxiter, VectorT)
{
VectorT y (0, 0), z (0, 1);
R q = 0;
R gamma = 0, gamma1 = 0;
gamma = bar (y, p);
(void) (bar (z, q) <= (gamma1 <= gamma));
}
int a = 100;
template <class CT, class VectorT, class R>
void
test (CT m, R p, VectorT)
{
VectorT x;
R sqrteps (U <R>::epsilon ());
baz (m, p, sqrteps, a, x);
}
void
fn (D x, double p)
{
bar (x, p);
}
void
fn (H x, double p)
{
test (x, p, C ());
}