Browse Source

Math: properly test constexpr in all Vector classes.

* Merged constExpressions() into other test cases, simplified the test
   a lot and removing duplicate code.
 * Fixed Vector3::xy(), Vector3::xy() and Vector3::xyz() constexpr
   overloads, they now return copy instead of reinterpret_cast
   reference. The copy is const to make constexpr operations working
   even on returned subclass, e.g.:

    constexpr Vector4 a;
    constexpr Float b = a.xyz().y();
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
fc538c3a57
  1. 66
      src/Math/Test/Vector2Test.cpp
  2. 95
      src/Math/Test/Vector3Test.cpp
  3. 91
      src/Math/Test/Vector4Test.cpp
  4. 87
      src/Math/Test/VectorTest.cpp
  5. 2
      src/Math/Vector3.h
  6. 4
      src/Math/Vector4.h

66
src/Math/Test/Vector2Test.cpp

@ -26,6 +26,11 @@ class Vector2Test: public Corrade::TestSuite::Tester {
Vector2Test();
void construct();
void constructDefault();
void constructOneValue();
void constructConversion();
void constructCopy();
void access();
void axes();
void scales();
@ -35,9 +40,15 @@ class Vector2Test: public Corrade::TestSuite::Tester {
};
typedef Math::Vector2<Float> Vector2;
typedef Math::Vector2<Int> Vector2i;
Vector2Test::Vector2Test() {
addTests(&Vector2Test::construct,
&Vector2Test::constructDefault,
&Vector2Test::constructOneValue,
&Vector2Test::constructConversion,
&Vector2Test::constructCopy,
&Vector2Test::access,
&Vector2Test::axes,
&Vector2Test::scales,
@ -46,27 +57,64 @@ Vector2Test::Vector2Test() {
}
void Vector2Test::construct() {
CORRADE_COMPARE(Vector2(1, 2), (Vector<2, Float>(1.0f, 2.0f)));
constexpr Vector2 a(1.5f, 2.5f);
CORRADE_COMPARE(a, (Vector<2, Float>(1.5f, 2.5f)));
}
void Vector2Test::constructDefault() {
constexpr Vector2 a;
CORRADE_COMPARE(a, Vector2(0.0f, 0.0f));
}
void Vector2Test::constructOneValue() {
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector2 a(3.0f);
#else
Vector2 a(3.0f); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(a, Vector2(3.0f, 3.0f));
}
void Vector2Test::constructConversion() {
constexpr Vector2 a(1.5f, 2.5f);
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector2i b(a);
#else
Vector2i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Vector2i(1, 2));
}
void Vector2Test::constructCopy() {
constexpr Vector2 a(1.5f, 2.5f);
constexpr Vector2 b(a);
CORRADE_COMPARE(b, Vector2(1.5f, 2.5f));
}
void Vector2Test::access() {
Vector2 vec(1.0f, -2.0f);
const Vector2 cvec(1.0f, -2.0f);
CORRADE_COMPARE(vec.x(), 1.0f);
CORRADE_COMPARE(vec.y(), -2.0f);
CORRADE_COMPARE(cvec.x(), 1.0f);
CORRADE_COMPARE(cvec.y(), -2.0f);
constexpr Vector2 cvec(1.0f, -2.0f);
constexpr Float x = cvec.x();
constexpr Float y = cvec.y();
CORRADE_COMPARE(x, 1.0f);
CORRADE_COMPARE(y, -2.0f);
}
void Vector2Test::axes() {
CORRADE_COMPARE(Vector2::xAxis(5.0f), Vector2(5.0f, 0.0f));
CORRADE_COMPARE(Vector2::yAxis(6.0f), Vector2(0.0f, 6.0f));
constexpr Vector2 x = Vector2::xAxis(5.0f);
constexpr Vector2 y = Vector2::yAxis(6.0f);
CORRADE_COMPARE(x, Vector2(5.0f, 0.0f));
CORRADE_COMPARE(y, Vector2(0.0f, 6.0f));
}
void Vector2Test::scales() {
CORRADE_COMPARE(Vector2::xScale(-5.0f), Vector2(-5.0f, 1.0f));
CORRADE_COMPARE(Vector2::yScale(-0.2f), Vector2(1.0f, -0.2f));
constexpr Vector2 x = Vector2::xScale(-5.0f);
constexpr Vector2 y = Vector2::yScale(-0.2f);
CORRADE_COMPARE(x, Vector2(-5.0f, 1.0f));
CORRADE_COMPARE(y, Vector2(1.0f, -0.2f));
}
void Vector2Test::debug() {

95
src/Math/Test/Vector3Test.cpp

@ -26,6 +26,12 @@ class Vector3Test: public Corrade::TestSuite::Tester {
Vector3Test();
void construct();
void constructDefault();
void constructOneValue();
void constructParts();
void constructConversion();
void constructCopy();
void access();
void cross();
void axes();
@ -37,35 +43,81 @@ class Vector3Test: public Corrade::TestSuite::Tester {
};
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector3<Int> Vector3i;
typedef Math::Vector2<Float> Vector2;
Vector3Test::Vector3Test() {
addTests(&Vector3Test::construct,
&Vector3Test::constructDefault,
&Vector3Test::constructOneValue,
&Vector3Test::constructParts,
&Vector3Test::constructConversion,
&Vector3Test::constructCopy,
&Vector3Test::access,
&Vector3Test::cross,
&Vector3Test::axes,
&Vector3Test::scales,
&Vector3Test::twoComponent,
&Vector3Test::debug,
&Vector3Test::configuration);
}
void Vector3Test::construct() {
CORRADE_COMPARE(Vector3(), Vector3(0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(Vector3(1, 2, 3), (Vector<3, Float>(1.0f, 2.0f, 3.0f)));
CORRADE_COMPARE(Vector3(Vector<2, Float>(1.0f, 2.0f), 3), (Vector<3, Float>(1.0f, 2.0f, 3.0f)));
constexpr Vector3 a(1.0f, 2.5f, -3.0f);
CORRADE_COMPARE(a, (Vector<3, Float>(1.0f, 2.5f, -3.0f)));
}
void Vector3Test::constructDefault() {
constexpr Vector3 a;
CORRADE_COMPARE(a, Vector3(0.0f, 0.0f, 0.0f));
}
void Vector3Test::constructOneValue() {
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector3 a(-3.0f);
#else
Vector3 a(-3.0f); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(a, Vector3(-3.0f, -3.0f, -3.0f));
}
void Vector3Test::constructParts() {
constexpr Vector2 a(1.0f, 2.0f);
constexpr Vector3 b(a, 3.0f);
CORRADE_COMPARE(b, Vector3(1.0f, 2.0f, 3.0f));
}
void Vector3Test::constructConversion() {
constexpr Vector3 a(1.0f, 2.5f, -3.0f);
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector3i b(a);
#else
Vector3i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Vector3i(1, 2, -3));
}
void Vector3Test::constructCopy() {
constexpr Vector3 a(1.0f, 2.5f, -3.0f);
constexpr Vector3 b(a);
CORRADE_COMPARE(b, Vector3(1.0f, 2.5f, -3.0f));
}
void Vector3Test::access() {
Vector3 vec(1.0f, -2.0f, 5.0f);
const Vector3 cvec(1.0f, -2.0f, 5.0f);
CORRADE_COMPARE(vec.x(), 1.0f);
CORRADE_COMPARE(vec.y(), -2.0f);
CORRADE_COMPARE(vec.z(), 5.0f);
CORRADE_COMPARE(cvec.x(), 1.0f);
CORRADE_COMPARE(cvec.y(), -2.0f);
CORRADE_COMPARE(cvec.z(), 5.0f);
constexpr Vector3 cvec(1.0f, -2.0f, 5.0f);
constexpr Float x = cvec.x();
constexpr Float y = cvec.y();
constexpr Float z = cvec.z();
CORRADE_COMPARE(x, 1.0f);
CORRADE_COMPARE(y, -2.0f);
CORRADE_COMPARE(z, 5.0f);
}
void Vector3Test::cross() {
@ -76,19 +128,32 @@ void Vector3Test::cross() {
}
void Vector3Test::axes() {
CORRADE_COMPARE(Vector3::xAxis(5.0f), Vector3(5.0f, 0.0f, 0.0f));
CORRADE_COMPARE(Vector3::yAxis(6.0f), Vector3(0.0f, 6.0f, 0.0f));
CORRADE_COMPARE(Vector3::zAxis(7.0f), Vector3(0.0f, 0.0f, 7.0f));
constexpr Vector3 x = Vector3::xAxis(5.0f);
constexpr Vector3 y = Vector3::yAxis(6.0f);
constexpr Vector3 z = Vector3::zAxis(7.0f);
CORRADE_COMPARE(x, Vector3(5.0f, 0.0f, 0.0f));
CORRADE_COMPARE(y, Vector3(0.0f, 6.0f, 0.0f));
CORRADE_COMPARE(z, Vector3(0.0f, 0.0f, 7.0f));
}
void Vector3Test::scales() {
CORRADE_COMPARE(Vector3::xScale(-5.0f), Vector3(-5.0f, 1.0f, 1.0f));
CORRADE_COMPARE(Vector3::yScale(-0.2f), Vector3(1.0f, -0.2f, 1.0f));
CORRADE_COMPARE(Vector3::zScale(71.0f), Vector3(1.0f, 1.0f, 71.0f));
constexpr Vector3 x = Vector3::xScale(-5.0f);
constexpr Vector3 y = Vector3::yScale(-0.2f);
constexpr Vector3 z = Vector3::zScale(71.0f);
CORRADE_COMPARE(x, Vector3(-5.0f, 1.0f, 1.0f));
CORRADE_COMPARE(y, Vector3(1.0f, -0.2f, 1.0f));
CORRADE_COMPARE(z, Vector3(1.0f, 1.0f, 71.0f));
}
void Vector3Test::twoComponent() {
CORRADE_COMPARE(Vector3(1.0f, 2.0f, 3.0f).xy(), Vector2(1.0f, 2.0f));
Vector3 a(1.0f, 2.0f, 3.0f);
CORRADE_COMPARE(a.xy(), Vector2(1.0f, 2.0f));
constexpr Vector3 b(1.0f, 2.0f, 3.0f);
constexpr Vector2 c = b.xy();
constexpr Float d = b.xy().y();
CORRADE_COMPARE(c, Vector2(1.0f, 2.0f));
CORRADE_COMPARE(d, 2.0f);
}
void Vector3Test::debug() {

91
src/Math/Test/Vector4Test.cpp

@ -25,8 +25,14 @@ class Vector4Test: public Corrade::TestSuite::Tester {
public:
Vector4Test();
void access();
void construct();
void constructDefault();
void constructOneValue();
void constructParts();
void constructConversion();
void constructCopy();
void access();
void threeComponent();
void twoComponent();
@ -35,44 +41,105 @@ class Vector4Test: public Corrade::TestSuite::Tester {
};
typedef Math::Vector4<Float> Vector4;
typedef Math::Vector4<Int> Vector4i;
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector2<Float> Vector2;
Vector4Test::Vector4Test() {
addTests(&Vector4Test::construct,
&Vector4Test::constructDefault,
&Vector4Test::constructOneValue,
&Vector4Test::constructParts,
&Vector4Test::constructConversion,
&Vector4Test::constructCopy,
&Vector4Test::access,
&Vector4Test::threeComponent,
&Vector4Test::twoComponent,
&Vector4Test::debug,
&Vector4Test::configuration);
}
void Vector4Test::construct() {
CORRADE_COMPARE(Vector4(), Vector4(0.0f, 0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(Vector4(1, 2, 3, 4), (Vector<4, Float>(1.0f, 2.0f, 3.0f, 4.0f)));
CORRADE_COMPARE(Vector4(Vector<3, Float>(1.0f, 2.0f, 3.0f), 4), (Vector<4, Float>(1.0f, 2.0f, 3.0f, 4.0f)));
constexpr Vector4 a(1.0f, -2.5f, 3.0f, 4.1f);
CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f)));
}
void Vector4Test::constructDefault() {
constexpr Vector4 a;
CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
}
void Vector4Test::constructOneValue() {
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4 a(4.3f);
#else
Vector4 a(4.3f); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(a, Vector4(4.3f, 4.3f, 4.3f, 4.3f));
}
void Vector4Test::constructParts() {
constexpr Vector3 a(1.0f, 2.0f, 3.0f);
constexpr Vector4 b(a, 4.0f);
CORRADE_COMPARE(b, Vector4(1.0f, 2.0f, 3.0f, 4.0f));
}
void Vector4Test::constructConversion() {
constexpr Vector4 a(1.0f, -2.5f, 3.0f, 4.1f);
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4i b(a);
#else
Vector4i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Vector4i(1, -2, 3, 4));
}
void Vector4Test::constructCopy() {
constexpr Vector4 a(1.0f, -2.5f, 3.0f, 4.1f);
constexpr Vector4 b(a);
CORRADE_COMPARE(b, Vector4(1.0f, -2.5f, 3.0f, 4.1f));
}
void Vector4Test::access() {
Vector4 vec(1.0f, -2.0f, 5.0f, 0.5f);
const Vector4 cvec(1.0f, -2.0f, 5.0f, 0.5f);
CORRADE_COMPARE(vec.x(), 1.0f);
CORRADE_COMPARE(vec.y(), -2.0f);
CORRADE_COMPARE(vec.z(), 5.0f);
CORRADE_COMPARE(vec.w(), 0.5f);
CORRADE_COMPARE(cvec.x(), 1.0f);
CORRADE_COMPARE(cvec.y(), -2.0f);
CORRADE_COMPARE(cvec.z(), 5.0f);
CORRADE_COMPARE(cvec.w(), 0.5f);
constexpr Vector4 cvec(1.0f, -2.0f, 5.0f, 0.5f);
constexpr Float x = cvec.x();
constexpr Float y = cvec.y();
constexpr Float z = cvec.z();
constexpr Float w = cvec.w();
CORRADE_COMPARE(x, 1.0f);
CORRADE_COMPARE(y, -2.0f);
CORRADE_COMPARE(z, 5.0f);
CORRADE_COMPARE(w, 0.5f);
}
void Vector4Test::threeComponent() {
CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).xyz(), Vector3(1.0f, 2.0f, 3.0f));
Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.xyz(), Vector3(1.0f, 2.0f, 3.0f));
constexpr Vector4 b(1.0f, 2.0f, 3.0f, 4.0f);
constexpr Vector3 c = b.xyz();
constexpr Float d = b.xyz().y();
CORRADE_COMPARE(c, Vector3(1.0f, 2.0f, 3.0f));
CORRADE_COMPARE(d, 2.0f);
}
void Vector4Test::twoComponent() {
CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).xy(), Vector2(1.0f, 2.0f));
Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.xy(), Vector2(1.0f, 2.0f));
constexpr Vector4 b(1.0f, 2.0f, 3.0f, 4.0f);
constexpr Vector2 c = b.xy();
constexpr Float d = b.xy().x();
CORRADE_COMPARE(c, Vector2(1.0f, 2.0f));
CORRADE_COMPARE(d, 1.0f);
}
void Vector4Test::debug() {

87
src/Math/Test/VectorTest.cpp

@ -25,15 +25,15 @@ class VectorTest: public Corrade::TestSuite::Tester {
public:
VectorTest();
void construct();
void constructFromData();
void constructDefault();
void constructOneValue();
void constructOneComponent();
void constructConversion();
void constructCopy();
void data();
void constExpressions();
void negative();
void addSubtract();
void multiplyDivide();
@ -68,15 +68,15 @@ typedef Vector<4, Float> Vector4;
typedef Vector<4, Int> Vector4i;
VectorTest::VectorTest() {
addTests(&VectorTest::constructFromData,
addTests(&VectorTest::construct,
&VectorTest::constructFromData,
&VectorTest::constructDefault,
&VectorTest::constructOneValue,
&VectorTest::constructOneComponent,
&VectorTest::constructConversion,
&VectorTest::constructCopy,
&VectorTest::data,
&VectorTest::constExpressions,
&VectorTest::negative,
&VectorTest::addSubtract,
&VectorTest::multiplyDivide,
@ -105,34 +105,54 @@ VectorTest::VectorTest() {
&VectorTest::configuration);
}
void VectorTest::constructFromData() {
Float data[] = { 1.0f, 2.0f, 3.0f, 4.0f };
CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f));
void VectorTest::construct() {
constexpr Vector4 a(1.0f, 2.0f, -3.0f, 4.5f);
CORRADE_COMPARE(a, Vector4(1.0f, 2.0f, -3.0f, 4.5f));
}
void VectorTest::constructDefault() {
CORRADE_COMPARE(Vector4(), Vector4(0.0f, 0.0f, 0.0f, 0.0f));
constexpr Vector4 a;
CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
}
void VectorTest::constructFromData() {
Float data[] = { 1.0f, 2.0f, 3.0f, 4.0f };
CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f));
}
void VectorTest::constructOneValue() {
CORRADE_COMPARE(Vector4(7.25f), Vector4(7.25f, 7.25f, 7.25f, 7.25f));
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4 a(7.25f);
#else
Vector4 a(7.25f); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(a, Vector4(7.25f, 7.25f, 7.25f, 7.25f));
}
void VectorTest::constructOneComponent() {
typedef Vector<1, Float> Vector1;
/* Implicit constructor must work */
Vector1 vec = 1;
constexpr Vector1 vec = 1.0f;
CORRADE_COMPARE(vec, Vector1(1));
}
void VectorTest::constructConversion() {
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);
constexpr Vector4 a(1.3f, 2.7f, -15.0f, 7.0f);
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4i b(a);
#else
Vector4i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(Vector4i(FloatingPoint), integral);
CORRADE_COMPARE(Vector4(integral), FloatingPointRounded);
CORRADE_COMPARE(b, Vector4i(1, 2, -15, 7));
}
void VectorTest::constructCopy() {
constexpr Vector4 a(1.0f, 3.5f, 4.0f, -2.7f);
constexpr Vector4 b(a);
CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f));
}
void VectorTest::data() {
@ -143,37 +163,12 @@ void VectorTest::data() {
CORRADE_COMPARE(vector[2], 1.0f);
CORRADE_COMPARE(vector[3], 1.5f);
CORRADE_COMPARE(vector, Vector4(4.0f, 5.0f, 1.0f, 1.5f));
}
void VectorTest::constExpressions() {
/* Default constructor */
constexpr Vector4 a;
CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
/* Value constructor */
constexpr Vector4 b(1.0f, 3.5f, 4.0f, -2.7f);
CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f));
/* One-value constructor, not constexpr under GCC < 4.7 */
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4 c(7.0f);
CORRADE_COMPARE(c, Vector4(7.0f, 7.0f, 7.0f, 7.0f));
#endif
/* Conversion constructor, not constexpr under GCC < 4.7 */
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Vector4i d(b);
CORRADE_COMPARE(d, Vector4i(1, 3, 4, -2));
#endif
/* Copy constructor */
constexpr Vector4 e(b);
CORRADE_COMPARE(e, Vector4(1.0f, 3.5f, 4.0f, -2.7f));
/* Data access, pointer chasings, i.e. *(b.data()[3]), are not possible */
constexpr Float f = b[3];
constexpr Float g = *b.data();
CORRADE_COMPARE(f, -2.7f);
/* Pointer chasings, i.e. *(b.data()[3]), are not possible */
constexpr Vector4 a(1.0f, 2.0f, -3.0f, 4.5f);
constexpr Float f = a[3];
constexpr Float g = *a.data();
CORRADE_COMPARE(f, 4.5f);
CORRADE_COMPARE(g, 1.0f);
}

2
src/Math/Vector3.h

@ -147,7 +147,7 @@ template<class T> class Vector3: public Vector<3, T> {
* @see swizzle()
*/
inline Vector2<T>& xy() { return Vector2<T>::from(Vector<3, T>::data()); }
inline constexpr Vector2<T> xy() const { return Vector2<T>::from(Vector<3, T>::data()); } /**< @overload */
inline constexpr const Vector2<T> xy() const { return {x(), y()}; } /**< @overload */
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector3, 3)
};

4
src/Math/Vector4.h

@ -79,7 +79,7 @@ template<class T> class Vector4: public Vector<4, T> {
* @see swizzle()
*/
inline Vector3<T>& xyz() { return Vector3<T>::from(Vector<4, T>::data()); }
inline constexpr Vector3<T> xyz() const { return Vector3<T>::from(Vector<4, T>::data()); } /**< @overload */
inline constexpr const Vector3<T> xyz() const { return {x(), y(), z()}; } /**< @overload */
/**
* @brief XY part of the vector
@ -88,7 +88,7 @@ template<class T> class Vector4: public Vector<4, T> {
* @see swizzle()
*/
inline Vector2<T>& xy() { return Vector2<T>::from(Vector<4, T>::data()); }
inline constexpr Vector2<T> xy() const { return Vector2<T>::from(Vector<4, T>::data()); } /**< @overload */
inline constexpr const Vector2<T> xy() const { return {x(), y()}; } /**< @overload */
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector4, 4)
};

Loading…
Cancel
Save