From 52f3fc7eb04fe59fbfa0d05aa3908a567e5c37ba Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 15 Jul 2014 23:45:14 +0000 Subject: [PATCH] math: try to get proper EBCO from that fucking Visual Studio piece of shit. --- src/lol/math/ops.h | 51 ++++++++++++++++++++++++++++++------------- src/lol/math/vector.h | 15 ++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/lol/math/ops.h b/src/lol/math/ops.h index 066bfbd2..a5545853 100644 --- a/src/lol/math/ops.h +++ b/src/lol/math/ops.h @@ -22,14 +22,45 @@ #include #include +namespace lol +{ + /* * Utility namespaces for traits -- this file uses a combination of * ADL black magic and enable_if to ensure that only the expected type * conversions are done. + * + * vec_t (swizzle) needs swizzle_ops + * vec_t (generic) needs linear_ops + componentwise_ops + * vec_t (specialisation) needs swizzle_ops + linear_ops + componentwise_ops + * mat_t (all) needs linear_ops + * cmplx_t quat_t need linear_ops + * + * We can only inherit from one class, because Visual Studio will not + * perform EBCO (empty base class optimisation) when there is multiple + * inheritance. */ -namespace lol +namespace linear_ops { + template + struct base {}; +} + +namespace componentwise_ops +{ + template + struct base : public linear_ops::base {}; +} + +namespace swizzle_ops +{ + template + struct base {}; + + template + struct base : public componentwise_ops::base {}; +} /* * Operators for swizzled vectors. Since template deduction cannot be @@ -40,20 +71,16 @@ namespace lol namespace swizzle_ops { -template -struct base {}; - - template -static inline typename std::enable_if::type operator ==(vec_t const &a, - vec_t const &b) +static inline typename std::enable_if::type +operator ==(vec_t const &a, vec_t const &b) { return vec_t(a) == vec_t(b); } template -static inline typename std::enable_if::type operator !=(vec_t const &a, - vec_t const &b) +static inline typename std::enable_if::type +operator !=(vec_t const &a, vec_t const &b) { return vec_t(a) != vec_t(b); } @@ -105,9 +132,6 @@ LOL_SWIZZLE_V_VV_OP(/) namespace linear_ops { -template -struct base {}; - /* * Comparisons */ @@ -255,9 +279,6 @@ operator /=(V &a, typename V::element const &val) namespace componentwise_ops { -template -struct base {}; - template static inline typename std::enable_if, V>::value, typename V::type>::type operator *(V const &a, V const &b) diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 6fcce81a..0367cc00 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -102,8 +102,7 @@ struct vec_t * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */ template struct vec_t - : public linear_ops::base, - public componentwise_ops::base + : public componentwise_ops::base { static int const count = N; typedef T element; @@ -176,9 +175,7 @@ private: template struct vec_t - : public swizzle_ops::base, - public linear_ops::base, - public componentwise_ops::base + : public swizzle_ops::base { static int const count = 2; typedef T element; @@ -285,9 +282,7 @@ static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16"); template struct vec_t - : public swizzle_ops::base, - public linear_ops::base, - public componentwise_ops::base + : public swizzle_ops::base { static int const count = 3; typedef T element; @@ -524,9 +519,7 @@ static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24"); template struct vec_t - : public swizzle_ops::base, - public linear_ops::base, - public componentwise_ops::base + : public swizzle_ops::base { static int const count = 4; typedef T element;