diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index b12a6a4da..cd9a8b8d6 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -74,6 +74,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void multiplyDivideIntegral(); void multiplyDivideComponentWise(); void multiplyDivideComponentWiseIntegral(); + void modulo(); void bitwise(); void compare(); @@ -128,6 +129,7 @@ VectorTest::VectorTest() { &VectorTest::multiplyDivideIntegral, &VectorTest::multiplyDivideComponentWise, &VectorTest::multiplyDivideComponentWiseIntegral, + &VectorTest::modulo, &VectorTest::bitwise, &VectorTest::compare, @@ -337,6 +339,15 @@ void VectorTest::multiplyDivideComponentWiseIntegral() { /* Using integer vector as divisor is not supported */ } +void VectorTest::modulo() { + typedef Math::Vector<2, Int> Vector2i; + + const Vector2i a(4, 13); + const Vector2i b(2, 5); + CORRADE_COMPARE(a % 2, Vector2i(0, 1)); + CORRADE_COMPARE(a % b, Vector2i(0, 3)); +} + void VectorTest::bitwise() { typedef Math::Vector<2, Int> Vector2i; @@ -479,9 +490,16 @@ void VectorTest::subclassTypes() { CORRADE_VERIFY((std::is_same::value)); CORRADE_VERIFY((std::is_same::value)); - /* Bitwise operations */ + /* Modulo operations */ const Vec2i ci; Vec2i i; + const Int j = {}; + CORRADE_VERIFY((std::is_same::value)); + CORRADE_VERIFY((std::is_same::value)); + CORRADE_VERIFY((std::is_same::value)); + CORRADE_VERIFY((std::is_same::value)); + + /* Bitwise operations */ CORRADE_VERIFY((std::is_same::value)); CORRADE_VERIFY((std::is_same::value)); CORRADE_VERIFY((std::is_same::value)); @@ -528,6 +546,10 @@ void VectorTest::subclass() { CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f), Vec2(-3.0f, -10.0f)); CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f), Vec2(-3.0f, -10.0f)); + /* Modulo operations */ + CORRADE_COMPARE(Vec2i(4, 13) % 2, Vec2i(0, 1)); + CORRADE_COMPARE(Vec2i(4, 13) % Vec2i(2, 5), Vec2i(0, 3)); + /* Bitwise operations */ CORRADE_COMPARE(~Vec2i(85, 240), Vec2i(-86, -241)); CORRADE_COMPARE(Vec2i(85, 240) & Vec2i(170, 85), Vec2i(0, 80)); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index e32c41f2d..25b0922a0 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -563,6 +563,70 @@ template inline Vector operator/( return out; } +/** @relates Vector +@brief Do modulo of integral vector and assign + +The computation is done in-place. +*/ +template inline +#ifdef DOXYGEN_GENERATING_OUTPUT +Vector& +#else +typename std::enable_if::value, Vector&>::type +#endif +operator%=(Vector& a, Integral b) { + for(std::size_t i = 0; i != size; ++i) + a[i] %= b; + + return a; +} + +/** @relates Vector +@brief Modulo of integral vector +*/ +template inline +#ifdef DOXYGEN_GENERATING_OUTPUT +Vector +#else +typename std::enable_if::value, Vector>::type +#endif +operator%(const Vector& a, Integral b) { + Vector copy(a); + return copy %= b; +} + +/** @relates Vector +@brief Do modulo of two integral vectors and assign + +The computation is done in-place. +*/ +template inline +#ifdef DOXYGEN_GENERATING_OUTPUT +Vector& +#else +typename std::enable_if::value, Vector&>::type +#endif +operator%=(Vector& a, const Vector& b) { + for(std::size_t i = 0; i != size; ++i) + a[i] %= b[i]; + + return a; +} + +/** @relates Vector +@brief Modulo of two integral vectors +*/ +template inline +#ifdef DOXYGEN_GENERATING_OUTPUT +Vector +#else +typename std::enable_if::value, Vector>::type +#endif +operator%(const Vector& a, const Vector& b) { + Vector copy(a); + return copy %= b; +} + /** @relates Vector @brief Bitwise NOT of integral vector */ @@ -1057,6 +1121,21 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit return number/static_cast&>(vector); \ } \ \ + template inline typename std::enable_if::value, Type&>::type operator%=(Type& a, Integral b) { \ + static_cast&>(a) %= b; \ + return a; \ + } \ + template inline typename std::enable_if::value, Type>::type operator%(const Type& a, Integral b) { \ + return static_cast&>(a) % b; \ + } \ + template inline typename std::enable_if::value, Type&>::type operator%=(Type& a, const Math::Vector& b) { \ + static_cast&>(a) %= b; \ + return a; \ + } \ + template inline typename std::enable_if::value, Type>::type operator%(const Type& a, const Math::Vector& b) { \ + return static_cast&>(a) % b; \ + } \ + \ template inline typename std::enable_if::value, Type>::type operator~(const Type& vector) { \ return ~static_cast&>(vector); \ } \