diff --git a/libs/math/include/math/TVecHelpers.h b/libs/math/include/math/TVecHelpers.h index 03867d8b2b..405d87dfb5 100644 --- a/libs/math/include/math/TVecHelpers.h +++ b/libs/math/include/math/TVecHelpers.h @@ -79,8 +79,8 @@ public: /* compound assignment from a another vector of the same size but different * element type. */ - template - constexpr VECTOR& operator+=(const VECTOR& v) { + template + constexpr VECTOR& operator+=(const VECTOR& v) { VECTOR& lhs = static_cast&>(*this); for (size_t i = 0; i < lhs.size(); i++) { lhs[i] += v[i]; @@ -88,8 +88,13 @@ public: return lhs; } - template - constexpr VECTOR& operator-=(const VECTOR& v) { + template> + constexpr VECTOR& operator+=(U v) { + return operator+=(VECTOR(v)); + } + + template + constexpr VECTOR& operator-=(const VECTOR& v) { VECTOR& lhs = static_cast&>(*this); for (size_t i = 0; i < lhs.size(); i++) { lhs[i] -= v[i]; @@ -97,25 +102,9 @@ public: return lhs; } - /* compound assignment from a another vector of the same type. - * These operators can be used for implicit conversion and handle operations - * like "vector *= scalar" by letting the compiler implicitly convert a scalar - * to a vector (assuming the BASE allows it). - */ - constexpr VECTOR& operator+=(const VECTOR& v) { - VECTOR& lhs = static_cast&>(*this); - for (size_t i = 0; i < lhs.size(); i++) { - lhs[i] += v[i]; - } - return lhs; - } - - constexpr VECTOR& operator-=(const VECTOR& v) { - VECTOR& lhs = static_cast&>(*this); - for (size_t i = 0; i < lhs.size(); i++) { - lhs[i] -= v[i]; - } - return lhs; + template> + constexpr VECTOR& operator-=(U v) { + return operator-=(VECTOR(v)); } /* @@ -126,9 +115,6 @@ public: * (the first one, BASE being known). */ - /* The operators below handle operation between vectors of the same size - * but of a different element type. - */ template friend inline constexpr VECTOR> MATH_PURE operator+(const VECTOR& lv, const VECTOR& rv) { @@ -137,6 +123,12 @@ public: return res; } + template> + friend inline constexpr + VECTOR> MATH_PURE operator+(const VECTOR& lv, U rv) { + return lv + VECTOR(rv); + } + template friend inline constexpr VECTOR> MATH_PURE operator-(const VECTOR& lv, const VECTOR& rv) { @@ -145,20 +137,10 @@ public: return res; } - /* The operators below (which are not templates once this class is instanced, - * i.e.: BASE is known) can be used for implicit conversion on both sides. - * These handle operations like "vector + scalar" and "scalar + vector" by - * letting the compiler implicitly convert a scalar to a vector (assuming - * the BASE allows it). - */ - friend inline constexpr VECTOR MATH_PURE operator+(VECTOR lv, const VECTOR& rv) { - // don't pass lv by reference because we need a copy anyways - return lv += rv; - } - - friend inline constexpr VECTOR MATH_PURE operator-(VECTOR lv, const VECTOR& rv) { - // don't pass lv by reference because we need a copy anyways - return lv -= rv; + template> + friend inline constexpr + VECTOR> MATH_PURE operator-(const VECTOR& lv, U rv) { + return lv - VECTOR(rv); } }; @@ -168,8 +150,8 @@ public: /* compound assignment from a another vector of the same size but different * element type. */ - template - constexpr VECTOR& operator*=(const VECTOR& v) { + template + constexpr VECTOR& operator*=(const VECTOR& v) { VECTOR& lhs = static_cast&>(*this); for (size_t i = 0; i < lhs.size(); i++) { lhs[i] *= v[i]; @@ -177,8 +159,13 @@ public: return lhs; } - template - constexpr VECTOR& operator/=(const VECTOR& v) { + template> + constexpr VECTOR& operator*=(U v) { + return operator*=(VECTOR(v)); + } + + template + constexpr VECTOR& operator/=(const VECTOR& v) { VECTOR& lhs = static_cast&>(*this); for (size_t i = 0; i < lhs.size(); i++) { lhs[i] /= v[i]; @@ -186,25 +173,9 @@ public: return lhs; } - /* compound assignment from a another vector of the same type. - * These operators can be used for implicit conversion and handle operations - * like "vector *= scalar" by letting the compiler implicitly convert a scalar - * to a vector (assuming the BASE allows it). - */ - constexpr VECTOR& operator*=(const VECTOR& v) { - VECTOR& lhs = static_cast&>(*this); - for (size_t i = 0; i < lhs.size(); i++) { - lhs[i] *= v[i]; - } - return lhs; - } - - constexpr VECTOR& operator/=(const VECTOR& v) { - VECTOR& lhs = static_cast&>(*this); - for (size_t i = 0; i < lhs.size(); i++) { - lhs[i] /= v[i]; - } - return lhs; + template> + constexpr VECTOR& operator/=(U v) { + return operator/=(VECTOR(v)); } /* @@ -215,9 +186,6 @@ public: * (the first one, BASE being known). */ - /* The operators below handle operation between vectors of the same size - * but of a different element type. - */ template friend inline constexpr VECTOR> MATH_PURE operator*(const VECTOR& lv, const VECTOR& rv) { @@ -226,28 +194,26 @@ public: return res; } + template> + friend inline constexpr + VECTOR> MATH_PURE operator*(const VECTOR& lv, U rv) { + VECTOR> res(lv); + return res * VECTOR(rv); + } + template friend inline constexpr VECTOR> MATH_PURE operator/(const VECTOR& lv, const VECTOR& rv) { - arithmetic_result_t res(lv); + VECTOR> res(lv); res /= rv; return res; } - /* The operators below (which are not templates once this class is instanced, - * i.e.: BASE is known) can be used for implicit conversion on both sides. - * These handle operations like "vector * scalar" and "scalar * vector" by - * letting the compiler implicitly convert a scalar to a vector (assuming - * the BASE allows it). - */ - friend inline constexpr VECTOR MATH_PURE operator*(VECTOR lv, const VECTOR& rv) { - // don't pass lv by reference because we need a copy anyways - return lv *= rv; - } - - friend inline constexpr VECTOR MATH_PURE operator/(VECTOR lv, const VECTOR& rv) { - // don't pass lv by reference because we need a copy anyways - return lv /= rv; + template> + friend inline constexpr + VECTOR> MATH_PURE operator/(const VECTOR& lv, U rv) { + VECTOR> res(lv); + return res / VECTOR(rv); } }; diff --git a/libs/math/tests/test_vec.cpp b/libs/math/tests/test_vec.cpp index afd3e93182..99fb6a0d60 100644 --- a/libs/math/tests/test_vec.cpp +++ b/libs/math/tests/test_vec.cpp @@ -31,6 +31,8 @@ TEST_F(VecTest, Constexpr) { constexpr float2 A2 = a; constexpr float2 B2 = { a, a }; constexpr float2 C2 = A2; + constexpr float2 E2 = A2 + 0.5f; + constexpr float2 F2 = A2 + 0.5 - 1.0 + (1 + A2); constexpr float3 D2 = cross(A2, C2); constexpr float3 A3 = a; @@ -64,7 +66,8 @@ TEST_F(VecTest, Constexpr) { constexpr float4 S0 = A4 + B4; constexpr float4 S1 = C4 - D4; - constexpr float4 S2 = A4 * a; + constexpr float4 S2 = (a * A4) + (A4 * a); + constexpr float4 S7 = (a / A4) + (A4 / a); constexpr float4 S3 = A4 * A4; constexpr float4 S4 = A4 / a; constexpr float4 S5 = A4 / A4;