namespace expt { template struct BinOp { const Ta & a; const Tb & b; BinOp (const Ta & x, const Tb & y) : a(x), b(y) {} float Ex () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ex(), b.Ex())); } float Ey () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ey(), b.Ey())); } float Ez () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ez(), b.Ez())); } }; template struct BinOp { const Ta & a; const float b; BinOp (const Ta & x, const float & y) : a(x), b(y) {} float Ex () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ex(), b)); } float Ey () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ey(), b)); } float Ez () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ez(), b)); } }; template struct BinOp { const float a; const Tb & b; BinOp (const float & x, const Tb & y) : a(x), b(y) {} float Ex () const GCC_ATTR_INLINE { return INFO(Teval::E (a, b.Ex())); } float Ey () const GCC_ATTR_INLINE { return INFO(Teval::E (a, b.Ey())); } float Ez () const GCC_ATTR_INLINE { return INFO(Teval::E (a, b.Ez())); } }; template struct UnOp { const Ta & a; UnOp (const Ta & x) : a(x) {} float Ex () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ex())); } float Ey () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ey())); } float Ez () const GCC_ATTR_INLINE { return INFO(Teval::E (a.Ez())); } }; template struct UnOp { const float a; UnOp (const float & x) : a(Teval::E (x)) {} // Umm - precomputing value - bullshit?! float Ex () const GCC_ATTR_INLINE { return INFO(a); } float Ey () const GCC_ATTR_INLINE { return INFO(a); } float Ez () const GCC_ATTR_INLINE { return INFO(a); } }; struct V3 { float x; float y; float z; V3 (const float & a, const float & b, const float & c) : x(a), y(b), z(c) {} template V3 (const BinOp & o) : x(o.Ex()), y(o.Ey()), z(o.Ez()) {} template V3 (const UnOp & o) : x(o.Ex()), y(o.Ey()), z(o.Ez()) {} const float & Ex () const GCC_ATTR_INLINE { return x; } const float & Ey () const GCC_ATTR_INLINE { return y; } const float & Ez () const GCC_ATTR_INLINE { return z; } } __attribute__ ((aligned(16))); struct Neg { static float E (const float & a) GCC_ATTR_INLINE { return - a; } }; template inline const UnOp operator - (const Ta & a) { return UnOp (a); } struct Add { static float E (const float & a, const float & b) GCC_ATTR_INLINE { return a + b; } }; template inline const BinOp operator + (const Ta & a, const Tb & b) { return BinOp (a, b); } struct Sub { static float E (const float & a, const float & b) GCC_ATTR_INLINE { return a - b; } }; template inline const BinOp operator - (const Ta & a, const Tb & b) { return BinOp (a, b); } struct Mul { static float E (const float & a, const float & b) GCC_ATTR_INLINE { return a * b; } }; template inline const BinOp operator * (const Ta & a, const Tb & b) { return BinOp (a, b); } struct Div { static float E (const float & a, const float & b) GCC_ATTR_INLINE { return a / b; } }; template inline const BinOp operator / (const Ta & a, const Tb & b) { return BinOp (a, b); } template inline const BinOp operator / (const Ta & a, const float & b) { return BinOp (a, 1.f / b); } } // namespace expt