From fec65aa6f5a0b2a264ae065f8e45d4bed5809a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 16 Aug 2012 17:51:19 +0200 Subject: [PATCH] Ability to construct Vector from another of different type. --- src/Math/Test/VectorTest.cpp | 11 +++++++++++ src/Math/Test/VectorTest.h | 1 + src/Math/Vector.h | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 41bd037ec..eb9c09d87 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -28,10 +28,12 @@ using namespace Corrade::Utility; namespace Magnum { namespace Math { namespace Test { typedef Vector<4, float> Vector4; +typedef Vector<4, int> Vector4i; typedef Vector<3, float> Vector3; VectorTest::VectorTest() { addTests(&VectorTest::construct, + &VectorTest::constructFrom, &VectorTest::data, &VectorTest::copy, &VectorTest::dot, @@ -56,6 +58,15 @@ void VectorTest::construct() { CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f)); } +void VectorTest::constructFrom() { + Vector4 floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + Vector4 floatingPointRounded(1.0f, 2.0f, -15.0f, 7.0f); + Vector4i integral(1, 2, -15, 7); + + CORRADE_COMPARE(Vector4i::from(floatingPoint), integral); + CORRADE_COMPARE(Vector4::from(integral), floatingPointRounded); +} + void VectorTest::data() { Vector4 v; v[2] = 1.5f; diff --git a/src/Math/Test/VectorTest.h b/src/Math/Test/VectorTest.h index bbf02d783..29404c289 100644 --- a/src/Math/Test/VectorTest.h +++ b/src/Math/Test/VectorTest.h @@ -24,6 +24,7 @@ class VectorTest: public Corrade::TestSuite::Tester { VectorTest(); void construct(); + void constructFrom(); void data(); void copy(); void dot(); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 9e7800cdd..e24ac6659 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -27,6 +27,8 @@ namespace Magnum { namespace Math { +template class Vector; + #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { template struct Sequence {}; @@ -38,6 +40,11 @@ namespace Implementation { template struct GenerateSequence<0, sequence...> { typedef Sequence Type; }; + + /* Implementation for Vector::from(const Vector&) */ + template inline constexpr Math::Vector vectorFrom(Sequence, const Math::Vector& vector) { + return {T(vector[sequence])...}; + } } #endif @@ -65,6 +72,21 @@ template class Vector { return *reinterpret_cast*>(data); } + /** + * @brief %Vector from another of different type + * + * Performs only default casting on the values, no rounding or + * anything else. Example usage: + * @code + * Vector<4, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + * Vector<4, int> integral(Vector<4, int>::from(floatingPoint)); + * // integral == {1, 2, -15, 7} + * @endcode + */ + template inline constexpr static Vector from(const Vector& other) { + return Implementation::vectorFrom(typename Implementation::GenerateSequence::Type(), other); + } + /** * @brief Dot product * @@ -338,6 +360,9 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili } \ inline constexpr static const Type& from(const T* data) { \ return *reinterpret_cast*>(data); \ + } \ + template inline constexpr static Type from(const Vector& other) { \ + return Vector::from(other); \ } \ \ inline Type& operator=(const Type& other) { \