From d8bf8b2cfc9d6615a4228d9585eeaca1d7983f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 12 Feb 2024 18:42:13 +0100 Subject: [PATCH] Math: workaround MSVC2015's inability to pick up the float*Unit operator. Basically the same workaround as was done for Vector in 9cb623eaf9661eeb350a1e557f6237aa8e3b492b, except that here it doesn't need the macros for subclasses. --- src/Magnum/Math/Unit.h | 16 ++++++++++++++++ src/Magnum/Math/Vector.h | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Magnum/Math/Unit.h b/src/Magnum/Math/Unit.h index 25e338fd9..1e45fdcbb 100644 --- a/src/Magnum/Math/Unit.h +++ b/src/Magnum/Math/Unit.h @@ -184,6 +184,10 @@ template class Derived, class T> class Unit { * Similar to @ref operator*(T) const, except that the multiplication * is done in floating-point. */ + /* Note that this one isn't correctly picked up on MSVC 2015, there's + an out-of-class overload wrapped in CORRADE_MSVC2015_COMPATIBILITY + which is (and the two don't conflict, apparently, so both are + present) */ #ifdef DOXYGEN_GENERATING_OUTPUT template constexpr Unit #else @@ -292,6 +296,18 @@ template class Derived, class T> class Unit { T _value; }; +#ifdef CORRADE_MSVC2015_COMPATIBILITY +/* MSVC 2015 doesn't correctly pick up the in-class inline friend that does + this, resulting in float*Unit expressions being wrongly executed as + int*Unit due to an implicit conversion fallback. This overload is + picked up correctly (and doesn't conflict with the in-class one). See + UnitTest::multiplyDivideIntegral() for regression tests, the same issue and + a matching workaround is done in Vector as well. */ +template class Derived, class FloatingPoint, class Integral> constexpr typename std::enable_if::value && std::is_floating_point::value, Unit>::type operator*(FloatingPoint number, const Unit& value) { + return value*number; +} +#endif + }} #endif diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index a7febf529..4f55f4b4c 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -1509,7 +1509,8 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& need to use the MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION() overloads as well to return a correct subtype. See VectorTest::multiplyDivideIntegral(), VectorTest::subclass() and corresponding cases in Vector2Test, Vector3Test, - Vector4Test and ColorTest for regression tests. */ + Vector4Test and ColorTest for regression tests. The same issue and a + matching workaround is done in Unit as well. */ template constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type operator*(FloatingPoint scalar, const Vector& vector) { return vector*scalar; }