Browse Source

Math: added StrictWeakOrdering for math types

simd
Borislav Stanimirov 8 years ago committed by Vladimír Vondruš
parent
commit
f7f2ab8cb5
  1. 13
      doc/snippets/MagnumMath.cpp
  2. 16
      src/Magnum/Math/Bezier.h
  3. 22
      src/Magnum/Math/BoolVector.h
  4. 1
      src/Magnum/Math/CMakeLists.txt
  5. 4
      src/Magnum/Math/Color.h
  6. 14
      src/Magnum/Math/Complex.h
  7. 17
      src/Magnum/Math/CubicHermite.h
  8. 15
      src/Magnum/Math/Dual.h
  9. 5
      src/Magnum/Math/DualComplex.h
  10. 5
      src/Magnum/Math/DualQuaternion.h
  11. 8
      src/Magnum/Math/Half.h
  12. 4
      src/Magnum/Math/Math.h
  13. 2
      src/Magnum/Math/Matrix.h
  14. 5
      src/Magnum/Math/Matrix3.h
  15. 5
      src/Magnum/Math/Matrix4.h
  16. 15
      src/Magnum/Math/Quaternion.h
  17. 13
      src/Magnum/Math/Range.h
  18. 17
      src/Magnum/Math/RectangularMatrix.h
  19. 78
      src/Magnum/Math/StrictWeakOrdering.h
  20. 20
      src/Magnum/Math/Test/BezierTest.cpp
  21. 37
      src/Magnum/Math/Test/BoolVectorTest.cpp
  22. 5
      src/Magnum/Math/Test/CMakeLists.txt
  23. 31
      src/Magnum/Math/Test/ColorTest.cpp
  24. 20
      src/Magnum/Math/Test/ComplexTest.cpp
  25. 25
      src/Magnum/Math/Test/CubicHermiteTest.cpp
  26. 20
      src/Magnum/Math/Test/DualComplexTest.cpp
  27. 20
      src/Magnum/Math/Test/DualQuaternionTest.cpp
  28. 20
      src/Magnum/Math/Test/DualTest.cpp
  29. 15
      src/Magnum/Math/Test/HalfTest.cpp
  30. 21
      src/Magnum/Math/Test/Matrix3Test.cpp
  31. 21
      src/Magnum/Math/Test/Matrix4Test.cpp
  32. 21
      src/Magnum/Math/Test/MatrixTest.cpp
  33. 21
      src/Magnum/Math/Test/QuaternionTest.cpp
  34. 21
      src/Magnum/Math/Test/RangeTest.cpp
  35. 21
      src/Magnum/Math/Test/RectangularMatrixTest.cpp
  36. 178
      src/Magnum/Math/Test/StrictWeakOrderingTest.cpp
  37. 21
      src/Magnum/Math/Test/Vector2Test.cpp
  38. 21
      src/Magnum/Math/Test/Vector3Test.cpp
  39. 21
      src/Magnum/Math/Test/Vector4Test.cpp
  40. 49
      src/Magnum/Math/Test/VectorTest.cpp
  41. 16
      src/Magnum/Math/Vector.h
  42. 2
      src/Magnum/Math/Vector2.h
  43. 2
      src/Magnum/Math/Vector3.h
  44. 2
      src/Magnum/Math/Vector4.h

13
doc/snippets/MagnumMath.cpp

@ -32,6 +32,10 @@
#include "Magnum/Math/Half.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Math/Algorithms/GramSchmidt.h"
#include "Magnum/Math/StrictWeakOrdering.h"
#include <map>
#include <set>
using namespace Magnum;
using namespace Magnum::Math::Literals;
@ -902,4 +906,13 @@ auto filterArea = Range2Di::fromSize(center, Vector2i{1}).padded(filterRadius);
static_cast<void>(filterArea);
}
{
/* [StrictWeakOrdering] */
std::set<Magnum::Vector2, Magnum::Math::StrictWeakOrdering> mySet;
std::map<Magnum::Vector4, int, Magnum::Math::StrictWeakOrdering> myMap;
/* [StrictWeakOrdering] */
static_cast<void>(myMap);
static_cast<void>(mySet);
}
}

16
src/Magnum/Math/Bezier.h

@ -317,6 +317,22 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Bezier<3, 3, Double>&);
#endif
namespace Implementation {
template<UnsignedInt order, UnsignedInt dimensions, class T> struct StrictWeakOrdering<Bezier<order, dimensions, T>> {
bool operator()(const Bezier<order, dimensions, T>& a, const Bezier<order, dimensions, T>& b) const {
StrictWeakOrdering<Vector<dimensions, T>> o;
for(std::size_t i = 0; i < order + 1; ++i) {
if(o(a[i], b[i]))
return true;
if(o(b[i], a[i]))
return false;
}
return false; // a and b are equivalent
}
};
}
}}
namespace Corrade { namespace Utility {

22
src/Magnum/Math/BoolVector.h

@ -33,6 +33,7 @@
#include <Corrade/Utility/Debug.h>
#include "Magnum/Types.h"
#include "Magnum/Math/Math.h"
#include "Magnum/Math/Tags.h"
namespace Magnum { namespace Math {
@ -303,6 +304,27 @@ template<std::size_t size> inline BoolVector<size> BoolVector<size>::operator~()
return out;
}
/* Specialization of helper types*/
namespace Implementation {
template<std::size_t size> struct StrictWeakOrdering<BoolVector<size>> {
bool operator()(const BoolVector<size>& a, const BoolVector<size>& b) const {
auto ad = a.data();
auto bd = b.data();
for(std::size_t i = 0; i < BoolVector<size>::DataSize - 1; ++i) {
if(ad[i] < bd[i])
return true;
if(ad[i] > bd[i])
return false;
}
// mask last element with to hide unused bits
constexpr UnsignedByte mask = UnsignedByte(0xFF) >> (BoolVector<size>::DataSize * 8 - size);
constexpr std::size_t i = BoolVector<size>::DataSize - 1;
return (ad[i] & mask) < (bd[i] & mask);
}
};
}
}}
#endif

1
src/Magnum/Math/CMakeLists.txt

@ -48,6 +48,7 @@ set(MagnumMath_HEADERS
Packing.h
Range.h
RectangularMatrix.h
StrictWeakOrdering.h
Swizzle.h
Tags.h
Unit.h

4
src/Magnum/Math/Color.h

@ -1272,6 +1272,10 @@ namespace Implementation {
template<class T> struct TypeForSize<3, Color4<T>> { typedef Color3<T> Type; };
template<class T> struct TypeForSize<4, Color3<T>> { typedef Color4<T> Type; };
template<class T> struct TypeForSize<4, Color4<T>> { typedef Color4<T> Type; };
template<class T> struct StrictWeakOrdering<Color3<T>> : public StrictWeakOrdering<Vector<3, T>> {};
template<class T> struct StrictWeakOrdering<Color4<T>> : public StrictWeakOrdering<Vector<4, T>> {};
}
}}

14
src/Magnum/Math/Complex.h

@ -620,6 +620,20 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Complex<Double>&);
#endif
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<Complex<T>> {
bool operator()(const Complex<T>& a, const Complex<T>& b) const {
if(a.real() < b.real())
return true;
if(a.real() > b.real())
return false;
return a.imaginary() < b.imaginary();
}
};
}
}}
namespace Corrade { namespace Utility {

17
src/Magnum/Math/CubicHermite.h

@ -538,6 +538,23 @@ template<class T> inline bool CubicHermite<T>::operator==(const CubicHermite<T>&
TypeTraits<T>::equals(_outTangent, other._outTangent);
}
namespace Implementation {
template<class T> struct StrictWeakOrdering<CubicHermite<T>> {
bool operator()(const CubicHermite<T>& a, const CubicHermite<T>& b) const {
StrictWeakOrdering<T> o;
if(o(a.inTangent(), b.inTangent()))
return true;
if(o(b.inTangent(), a.inTangent()))
return false;
if(o(a.point(), b.point()))
return true;
if(o(b.point(), a.point()))
return false;
return o(a.outTangent(), b.outTangent());
}
};
}
}}
#endif

15
src/Magnum/Math/Dual.h

@ -395,6 +395,21 @@ template<class T> std::pair<Dual<T>, Dual<T>> sincos(const Dual<Unit<Rad, T>>& a
template<class T> std::pair<Dual<T>, Dual<T>> sincos(const Dual<Unit<Deg, T>>& angle) { return sincos(Dual<Rad<T>>(angle)); }
#endif
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<Dual<T>> {
bool operator()(const Dual<T>& a, const Dual<T>& b) const {
StrictWeakOrdering<T> o;
if(o(a.real(), b.real()))
return true;
if(o(b.real(), a.real()))
return false;
return o(a.dual(), b.dual());
}
};
}
}}
#endif

5
src/Magnum/Math/DualComplex.h

@ -385,6 +385,11 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const DualComplex<Double>&);
#endif
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<DualComplex<T>>: public StrictWeakOrdering<Dual<Complex<T>>> {};
}
}}
namespace Corrade { namespace Utility {

5
src/Magnum/Math/DualQuaternion.h

@ -545,6 +545,11 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const DualQuaternion<Double>&);
#endif
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<DualQuaternion<T>>: public StrictWeakOrdering<Dual<Quaternion<T>>> {};
}
}}
namespace Corrade { namespace Utility {

8
src/Magnum/Math/Half.h

@ -161,6 +161,14 @@ Prints the value with 4 significant digits.
*/
MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, Half value);
namespace Implementation {
template <> struct StrictWeakOrdering<Half> {
bool operator()(Half a, Half b) const {
return a.data() < b.data(); // Not mathematically equivalent to <, but does order
}
};
}
}}
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)

4
src/Magnum/Math/Math.h

@ -101,6 +101,10 @@ template<UnsignedInt, class> class Range;
template<class T> using Range1D = Range<1, T>;
template<class> class Range2D;
template<class> class Range3D;
namespace Implementation {
template <class T> struct StrictWeakOrdering;
}
#endif
}}

2
src/Magnum/Math/Matrix.h

@ -321,6 +321,8 @@ template<class T> struct MatrixDeterminant<1, T> {
}
};
template<std::size_t size, class T> struct StrictWeakOrdering<Matrix<size, T>>: public StrictWeakOrdering<RectangularMatrix<size, size, T>> {};
}
#endif

5
src/Magnum/Math/Matrix3.h

@ -692,6 +692,11 @@ template<class T> inline Matrix3<T> Matrix3<T>::invertedRigid() const {
return from(inverseRotation, inverseRotation*-translation());
}
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<Matrix3<T>>: public StrictWeakOrdering<RectangularMatrix<3, 3, T>> {};
}
}}
namespace Corrade { namespace Utility {

5
src/Magnum/Math/Matrix4.h

@ -1024,6 +1024,11 @@ template<class T> Matrix4<T> Matrix4<T>::invertedRigid() const {
return from(inverseRotation, inverseRotation*-translation());
}
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<Matrix4<T>>: public StrictWeakOrdering<RectangularMatrix<4, 4, T>> {};
}
}}
namespace Corrade { namespace Utility {

15
src/Magnum/Math/Quaternion.h

@ -739,6 +739,21 @@ template<class T> inline Vector3<T> Quaternion<T>::transformVectorNormalized(con
return vector + _scalar*t + Math::cross(_vector, t);
}
/* Specialization of helper types*/
namespace Implementation {
template<class T> struct StrictWeakOrdering<Quaternion<T>> {
bool operator()(const Quaternion<T>& a, const Quaternion<T>& b) const {
StrictWeakOrdering<Vector3<T>> o;
if(o(a.vector(), b.vector()))
return true;
if(o(b.vector(), a.vector()))
return false;
return a.scalar() < b.scalar();
}
};
}
}}
namespace Corrade { namespace Utility {

13
src/Magnum/Math/Range.h

@ -759,6 +759,19 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Range<3, Double>&);
#endif
namespace Implementation {
template<UnsignedInt dimensions, class T> struct StrictWeakOrdering<Range<dimensions, T>> {
bool operator()(const Range<dimensions, T>& a, const Range<dimensions, T>& b) const {
StrictWeakOrdering<typename Range<dimensions, T>::VectorType> o;
if(o(a.min(), b.min()))
return true;
if(o(b.min(), a.min()))
return false;
return o(a.max(), b.max());
}
};
}
}}
namespace Corrade { namespace Utility {

17
src/Magnum/Math/RectangularMatrix.h

@ -760,6 +760,23 @@ template<std::size_t cols, std::size_t rows, class T> template<std::size_t ...se
}
#endif
/* Specialization of helper types*/
namespace Implementation {
template<std::size_t cols, std::size_t rows, class T> struct StrictWeakOrdering<RectangularMatrix<cols, rows, T>> {
bool operator()(const RectangularMatrix<cols, rows, T>& a, const RectangularMatrix<cols, rows, T>& b) const {
StrictWeakOrdering<Vector<rows, T>> o;
for(std::size_t i = 0; i < cols; ++i) {
if(o(a[i], b[i]))
return true;
if(o(b[i], a[i]))
return false;
}
return false; // a and b are equivalent
}
};
}
}}
namespace Corrade { namespace Utility {

78
src/Magnum/Math/StrictWeakOrdering.h

@ -0,0 +1,78 @@
#ifndef Magnum_Math_StrictWeakOrdering_h
#define Magnum_Math_StrictWeakOrdering_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Math::StrictWeakOrdering
*/
namespace Magnum { namespace Math {
namespace Implementation {
template <class T> struct StrictWeakOrdering { // Specialized for supported types
bool operator()(const T& a, const T& b) const {
return a < b;
}
};
}
/**
@brief A functor which implements strict weak ordering for all types in the Math library.
A strict weak ordering enables a comparison operator between to elements of a
set. With it an ordering can be achieved between the elements.
This is useful mainly for interoperability with ordering containers from the
C++ standard library, like @ref std::map and @ref std::set.
@snippet MagnumMath.cpp StrictWeakOrdering
Check the source for defails if you want to create an implementation for your
own types.
*/
struct StrictWeakOrdering {
/**
* @brief Compares two items.
*
* Returns true if a is less than b.
*
* Returns false if a is equivalent to b or greater.
*
* For scalar types this is equivalent to operator <
*/
template <class T> bool operator()(const T& a, const T& b) const {
// Instantiate a specialization of Implementation::StrictWeakOrdering
// If users want to enable this for their own types, they must create
// a specialization of Magnum::Math::Implementation::StrictWeakOrdering
// for them.
Implementation::StrictWeakOrdering<T> o;
return o(a, b);
}
};
}}
#endif

20
src/Magnum/Math/Test/BezierTest.cpp

@ -32,6 +32,7 @@
#include "Magnum/Math/CubicHermite.h"
#include "Magnum/Math/Vector2.h"
#include "Magnum/Math/Functions.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct QBezier2D {
float x0, x1, x2, y0, y1, y2;
@ -85,6 +86,8 @@ struct BezierTest: Corrade::TestSuite::Tester {
void subdivideQuadratic();
void subdivideCubic();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -109,6 +112,8 @@ BezierTest::BezierTest() {
&BezierTest::subdivideQuadratic,
&BezierTest::subdivideCubic,
&BezierTest::strictWeakOrdering,
&BezierTest::debug,
&BezierTest::configuration});
}
@ -312,6 +317,21 @@ void BezierTest::subdivideCubic() {
CORRADE_COMPARE(right, (CubicBezier2D{Vector2{7.10938f, 6.57812f}, Vector2{13.4375f, 8.6875f}, Vector2{16.25f, -2.0f}, Vector2{5.0f, -20.0f}}));
}
void BezierTest::strictWeakOrdering() {
StrictWeakOrdering o;
CubicBezier2D a{Vector2{0.0f, 0.0f}, Vector2{10.0f, 15.0f}, Vector2{20.0f, 4.0f}, Vector2{5.0f, -20.0f}};
CubicBezier2D b{Vector2{1.0f, 0.0f}, Vector2{10.0f, 15.0f}, Vector2{20.0f, 4.0f}, Vector2{5.0f, -20.0f}};
CubicBezier2D c{Vector2{0.0f, 0.0f}, Vector2{10.0f, 15.0f}, Vector2{20.0f, 4.0f}, Vector2{5.0f, 20.0f}};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(a, a));
}
void BezierTest::debug() {
std::ostringstream out;
Debug(&out) << CubicBezier2D{Vector2{0.0f, 1.0f}, Vector2{1.5f, -0.3f}, Vector2{2.1f, 0.5f}, Vector2{0.0f, 2.0f}};

37
src/Magnum/Math/Test/BoolVectorTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/BoolVector.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct BVec3 {
bool x, y, z;
@ -73,6 +74,8 @@ struct BoolVectorTest: Corrade::TestSuite::Tester {
void bitInverse();
void bitAndOrXor();
void strictWeakOrdering();
void debug();
};
@ -103,6 +106,8 @@ BoolVectorTest::BoolVectorTest() {
&BoolVectorTest::bitInverse,
&BoolVectorTest::bitAndOrXor,
&BoolVectorTest::strictWeakOrdering,
&BoolVectorTest::debug});
}
@ -290,6 +295,38 @@ void BoolVectorTest::bitAndOrXor() {
CORRADE_COMPARE(a ^ b, BoolVector19(0x92, 0xac, 0x05));
}
void BoolVectorTest::strictWeakOrdering() {
BoolVector<11> a, b, c;
a.set(0, true);
a.set(1, true);
c.set(7, true);
b.set(8, true);
StrictWeakOrdering o;
CORRADE_VERIFY( o(b, a));
CORRADE_VERIFY(!o(a, b));
CORRADE_VERIFY(!o(c, b));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY(!o(a, a));
// check uninitialized padding reads
a.set(8, true);
a.set(10, true);
b = a;
a.data()[1] |= 0x08;
b.data()[1] |= 0x20;
a.data()[1] |= 0x40;
b.data()[1] |= 0x80;
CORRADE_VERIFY(!o(a, b));
CORRADE_VERIFY(!o(b, a));
}
void BoolVectorTest::debug() {
std::ostringstream o;

5
src/Magnum/Math/Test/CMakeLists.txt

@ -63,6 +63,8 @@ corrade_add_test(MathIntersectionBenchmark IntersectionBenchmark.cpp LIBRARIES M
corrade_add_test(MathInterpolationBenchmark InterpolationBenchmark.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathStrictWeakOrderingTest StrictWeakOrderingTest.cpp LIBRARIES MagnumMathTestLib)
set_property(TARGET
MathVectorTest
MathMatrixTest
@ -110,9 +112,12 @@ set_target_properties(
MathDualQuaternionTest
MathBezierTest
MathCubicHermiteTest
MathFrustumTest
MathDistanceTest
MathIntersectionTest
MathIntersectionBenchmark
MathStrictWeakOrderingTest
PROPERTIES FOLDER "Magnum/Math/Test")

31
src/Magnum/Math/Test/ColorTest.cpp

@ -33,6 +33,7 @@
#endif
#include "Magnum/Math/Color.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Vec3 {
float x, y, z;
@ -105,6 +106,8 @@ struct ColorTest: Corrade::TestSuite::Tester {
void fromXyzDefaultAlpha();
void xyY();
void strictWeakOrdering();
void swizzleType();
void debug();
void debugUb();
@ -217,6 +220,8 @@ ColorTest::ColorTest() {
&ColorTest::fromXyzDefaultAlpha,
&ColorTest::xyY,
&ColorTest::strictWeakOrdering,
&ColorTest::swizzleType,
&ColorTest::debug,
&ColorTest::debugUb,
@ -850,6 +855,32 @@ void ColorTest::xyY() {
CORRADE_COMPARE(xyYToXyz(xyY), xyz);
}
void ColorTest::strictWeakOrdering() {
StrictWeakOrdering o;
auto r = Color4::red();
auto g = Color4::green();
auto b = Color4::blue();
CORRADE_VERIFY( o(b, r));
CORRADE_VERIFY( o(g, r));
CORRADE_VERIFY( o(b, g));
CORRADE_VERIFY(!o(r, r));
auto ba = b;
ba.a() = 0.5f;
CORRADE_VERIFY(o(ba, b));
auto r3 = r.rgb();
auto g3 = g.rgb();
auto b3 = b.rgb();
CORRADE_VERIFY( o(b3, r3));
CORRADE_VERIFY( o(g3, r3));
CORRADE_VERIFY( o(b3, g3));
CORRADE_VERIFY(!o(r3, r3));
}
void ColorTest::swizzleType() {
constexpr Color3 origColor3;
constexpr Color4ub origColor4;

20
src/Magnum/Math/Test/ComplexTest.cpp

@ -29,6 +29,7 @@
#include "Magnum/Math/Complex.h"
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Cmpl {
float re, im;
@ -98,6 +99,8 @@ struct ComplexTest: Corrade::TestSuite::Tester {
void slerpNotNormalized();
void transformVector();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -150,6 +153,8 @@ ComplexTest::ComplexTest() {
&ComplexTest::slerpNotNormalized,
&ComplexTest::transformVector,
&ComplexTest::strictWeakOrdering,
&ComplexTest::debug,
&ComplexTest::configuration});
}
@ -529,6 +534,21 @@ void ComplexTest::transformVector() {
CORRADE_COMPARE(rotated, Vector2(-3.58733f, -0.762279f));
}
void ComplexTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Complex a{1.0f, 2.0f};
const Complex b{2.0f, 3.0f};
const Complex c{1.0f, 3.0f};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void ComplexTest::debug() {
std::ostringstream o;

25
src/Magnum/Math/Test/CubicHermiteTest.cpp

@ -30,6 +30,8 @@
#include "Magnum/Math/CubicHermite.h"
#include "Magnum/Math/Functions.h"
#include "Magnum/Math/Vector2.h"
#include "Magnum/Math/StrictWeakOrdering.h"
namespace Magnum { namespace Math { namespace Test {
@ -112,6 +114,8 @@ struct CubicHermiteTest: Corrade::TestSuite::Tester {
void splerpQuaternion();
void splerpQuaternionNotNormalized();
void strictWeakOrdering();
void debugScalar();
void debugVector();
void debugComplex();
@ -195,6 +199,8 @@ CubicHermiteTest::CubicHermiteTest() {
&CubicHermiteTest::splerpQuaternion,
&CubicHermiteTest::splerpQuaternionNotNormalized,
&CubicHermiteTest::strictWeakOrdering,
&CubicHermiteTest::debugScalar,
&CubicHermiteTest::debugVector,
&CubicHermiteTest::debugComplex,
@ -1129,6 +1135,25 @@ void CubicHermiteTest::splerpQuaternionNotNormalized() {
"Math::splerp(): quaternion spline points Quaternion({0, 0, 0}, 2) and Quaternion({0, 0, 0}, 1) are not normalized\n");
}
void CubicHermiteTest::strictWeakOrdering() {
StrictWeakOrdering o;
const CubicHermite1D a{1.0f, 2.0f, 3.0f};
const CubicHermite1D b{2.0f, 3.0f, 4.0f};
const CubicHermite1D c{1.0f, 2.0f, 4.0f};
const CubicHermite1D d{1.0f, 5.0f, 4.0f};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY( o(a, d));
CORRADE_VERIFY(!o(d, a));
CORRADE_VERIFY(!o(a, a));
}
void CubicHermiteTest::debugScalar() {
std::ostringstream out;
Debug{&out} << CubicHermite1D{2.0f, 3.0f, -1.0f};

20
src/Magnum/Math/Test/DualComplexTest.cpp

@ -29,6 +29,7 @@
#include "Magnum/Math/DualComplex.h"
#include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct DualCmpl {
float re, im, x, y;
@ -91,6 +92,8 @@ struct DualComplexTest: Corrade::TestSuite::Tester {
void matrixNotOrthogonal();
void transformPoint();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -147,6 +150,8 @@ DualComplexTest::DualComplexTest() {
&DualComplexTest::matrixNotOrthogonal,
&DualComplexTest::transformPoint,
&DualComplexTest::strictWeakOrdering,
&DualComplexTest::debug,
&DualComplexTest::configuration});
}
@ -445,6 +450,21 @@ void DualComplexTest::transformPoint() {
CORRADE_COMPARE(transformedB, Vector2(-2.918512f, 2.780698f));
}
void DualComplexTest::strictWeakOrdering() {
StrictWeakOrdering o;
const DualComplex a{{1.0f, 0.0f}, {1.0f, 3.0f}};
const DualComplex b{{1.0f, 2.0f}, {3.0f, 4.0f}};
const DualComplex c{{1.0f, 0.0f}, {1.0f, 4.0f}};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void DualComplexTest::debug() {
std::ostringstream o;

20
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct DualQuat {
struct { float x, y, z, w; } re;
@ -98,6 +99,8 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester {
void sclerp();
void sclerpShortestPath();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -159,6 +162,8 @@ DualQuaternionTest::DualQuaternionTest() {
&DualQuaternionTest::sclerp,
&DualQuaternionTest::sclerpShortestPath,
&DualQuaternionTest::strictWeakOrdering,
&DualQuaternionTest::debug,
&DualQuaternionTest::configuration});
}
@ -620,6 +625,21 @@ void DualQuaternionTest::sclerpShortestPath() {
CORRADE_COMPARE(sclerpShortestPath.translation().z(), 0.25f);
}
void DualQuaternionTest::strictWeakOrdering() {
StrictWeakOrdering o;
const DualQuaternion a{{{1.0f, 2.0f, 3.0f}, 0.0f}, {{1.0f, 2.0f, 3.0f}, 3.0f}};
const DualQuaternion b{{{1.0f, 2.0f, 3.0f}, 2.0f}, {{3.0f, 2.0f, 3.0f}, 4.0f}};
const DualQuaternion c{{{1.0f, 2.0f, 3.0f}, 0.0f}, {{1.0f, 2.0f, 3.0f}, 4.0f}};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void DualQuaternionTest::debug() {
std::ostringstream o;

20
src/Magnum/Math/Test/DualTest.cpp

@ -29,6 +29,7 @@
#include "Magnum/Math/Dual.h"
#include "Magnum/Math/Quaternion.h"
#include "Magnum/Math/Vector2.h"
#include "Magnum/Math/StrictWeakOrdering.h"
namespace Magnum { namespace Math { namespace Test {
@ -58,6 +59,8 @@ struct DualTest: Corrade::TestSuite::Tester {
void sincos();
void sincosWithBase();
void strictWeakOrdering();
void subclassTypes();
void subclass();
@ -97,6 +100,8 @@ DualTest::DualTest() {
&DualTest::sincos,
&DualTest::sincosWithBase,
&DualTest::strictWeakOrdering,
&DualTest::subclassTypes,
&DualTest::subclass,
@ -278,6 +283,21 @@ void DualTest::sincosWithBase() {
CORRADE_COMPARE(Math::sincos(2*Math::Dual<Rad>(Rad(Constants::pi()/12), Rad(Constants::pi()/4))), result);
}
void DualTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Dual a{1.0f, 2.0f};
const Dual b{2.0f, 3.0f};
const Dual c{1.0f, 3.0f};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
namespace {
template<class T> class BasicDualVec2: public Math::Dual<Math::Vector2<T>> {

15
src/Magnum/Math/Test/HalfTest.cpp

@ -33,6 +33,7 @@
#include "Magnum/Math/Half.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/Math/StrictWeakOrdering.h"
namespace Magnum { namespace Math { namespace Test {
@ -62,6 +63,8 @@ struct HalfTest: Corrade::TestSuite::Tester {
void promotion();
void negation();
void strictWeakOrdering();
void literal();
void debug();
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
@ -153,6 +156,8 @@ HalfTest::HalfTest() {
addTests({&HalfTest::promotion,
&HalfTest::negation,
&HalfTest::strictWeakOrdering,
&HalfTest::literal,
&HalfTest::debug});
@ -651,6 +656,16 @@ void HalfTest::negation() {
CORRADE_COMPARE(-b, a);
}
void HalfTest::strictWeakOrdering() {
StrictWeakOrdering o;
constexpr Half a{UnsignedShort(0x4300)};
constexpr Half b{UnsignedShort(0x5100)};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY(!o(a, a));
}
void HalfTest::literal() {
Half a = 3.5_h;
CORRADE_COMPARE(a, Half{UnsignedShort(0x4300)});

21
src/Magnum/Math/Test/Matrix3Test.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Mat3 {
float a[9];
@ -96,6 +97,8 @@ struct Matrix3Test: Corrade::TestSuite::Tester {
void invertedRigidNotRigid();
void transform();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -145,6 +148,8 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::invertedRigidNotRigid,
&Matrix3Test::transform,
&Matrix3Test::strictWeakOrdering,
&Matrix3Test::debug,
&Matrix3Test::configuration});
}
@ -592,6 +597,22 @@ void Matrix3Test::transform() {
CORRADE_COMPARE(a.transformPoint(v), Vector2(3.0f, -4.0f));
}
void Matrix3Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Matrix3 a(Vector3{1.0f, 1.0f, 2.0f}, Vector3{5.0f, 5.0f, 5.0f}, Vector3{3.0f, 1.0f, 4.0f});
const Matrix3 b(Vector3{2.0f, 1.0f, 3.0f}, Vector3{5.0f, 5.0f, 5.0f}, Vector3{4.0f, 1.0f, 5.0f});
const Matrix3 c(Vector3{1.0f, 1.0f, 2.0f}, Vector3{5.0f, 5.0f, 5.0f}, Vector3{3.0f, 1.0f, 5.0f});
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void Matrix3Test::debug() {
Matrix3 m({3.0f, 5.0f, 8.0f},
{4.0f, 4.0f, 7.0f},

21
src/Magnum/Math/Test/Matrix4Test.cpp

@ -29,6 +29,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Matrix4.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Mat4 {
float a[16];
@ -110,6 +111,8 @@ struct Matrix4Test: Corrade::TestSuite::Tester {
void transform();
void transformProjection();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -174,6 +177,8 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::transform,
&Matrix4Test::transformProjection,
&Matrix4Test::strictWeakOrdering,
&Matrix4Test::debug,
&Matrix4Test::configuration});
}
@ -770,6 +775,22 @@ void Matrix4Test::transformProjection() {
CORRADE_COMPARE(a.transformPoint(v), Vector3(0.0f, 0.0f, 1.0f));
}
void Matrix4Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Matrix4 a(Vector4{1.0f, 1.0f, 2.0f, 2.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{3.0f, 1.0f, 2.0f, 4.0f});
const Matrix4 b(Vector4{2.0f, 1.0f, 2.0f, 3.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{4.0f, 1.0f, 2.0f, 5.0f});
const Matrix4 c(Vector4{1.0f, 1.0f, 2.0f, 2.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{5.0f, 5.0f, 6.0f, 5.0f}, Vector4{3.0f, 1.0f, 2.0f, 5.0f});
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void Matrix4Test::lookAt() {
Vector3 translation{5.3f, -8.9f, -10.0f};
Vector3 target{19.0f, 29.3f, 0.0f};

21
src/Magnum/Math/Test/MatrixTest.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Matrix.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Mat3 {
float a[9];
@ -79,6 +80,8 @@ struct MatrixTest: Corrade::TestSuite::Tester {
void invertedOrthogonal();
void invertedOrthogonalNotOrthogonal();
void strictWeakOrdering();
void subclassTypes();
void subclass();
@ -117,6 +120,8 @@ MatrixTest::MatrixTest() {
&MatrixTest::invertedOrthogonal,
&MatrixTest::invertedOrthogonalNotOrthogonal,
&MatrixTest::strictWeakOrdering,
&MatrixTest::subclassTypes,
&MatrixTest::subclass,
@ -385,6 +390,22 @@ void MatrixTest::invertedOrthogonalNotOrthogonal() {
" 0, 0, 2)\n");
}
void MatrixTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Matrix2x2 a{Vector2{1.0f, 2.0f}, Vector2{3.0f, 4.0f}};
const Matrix2x2 b{Vector2{2.0f, 3.0f}, Vector2{4.0f, 5.0f}};
const Matrix2x2 c{Vector2{1.0f, 2.0f}, Vector2{3.0f, 5.0f}};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
template<class T> class BasicVec2: public Math::Vector<2, T> {
public:
template<class ...U> constexpr BasicVec2(U&&... args): Math::Vector<2, T>{args...} {}

21
src/Magnum/Math/Test/QuaternionTest.cpp

@ -30,6 +30,7 @@
#include "Magnum/Math/Matrix4.h"
#include "Magnum/Math/Quaternion.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Quat {
float x, y, z, w;
@ -111,6 +112,8 @@ struct QuaternionTest: Corrade::TestSuite::Tester {
void transformVectorNormalized();
void transformVectorNormalizedNotNormalized();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -185,6 +188,8 @@ QuaternionTest::QuaternionTest() {
&QuaternionTest::transformVectorNormalized,
&QuaternionTest::transformVectorNormalizedNotNormalized,
&QuaternionTest::strictWeakOrdering,
&QuaternionTest::debug,
&QuaternionTest::configuration});
}
@ -716,6 +721,22 @@ void QuaternionTest::transformVectorNormalizedNotNormalized() {
CORRADE_COMPARE(out.str(), "Math::Quaternion::transformVectorNormalized(): Quaternion({0.398736, 0, 0}, 1.95985) is not normalized\n");
}
void QuaternionTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Quaternion a{{1.0f, 2.0f, 3.0f}, 4.0f};
const Quaternion b{{2.0f, 3.0f, 4.0f}, 5.0f};
const Quaternion c{{1.0f, 2.0f, 3.0f}, 5.0f};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void QuaternionTest::debug() {
std::ostringstream o;

21
src/Magnum/Math/Test/RangeTest.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Range.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Dim {
float offset, size;
@ -134,6 +135,8 @@ struct RangeTest: Corrade::TestSuite::Tester {
void join();
void join1D();
void strictWeakOrdering();
void subclassTypes();
void subclass();
@ -185,6 +188,8 @@ RangeTest::RangeTest() {
&RangeTest::join,
&RangeTest::join1D,
&RangeTest::strictWeakOrdering,
&RangeTest::subclassTypes,
&RangeTest::subclass,
@ -824,6 +829,22 @@ void RangeTest::join1D() {
CORRADE_COMPARE(Math::join(c, a), a);
}
void RangeTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Range1D a{1.0f, 2.0f};
const Range1D b{2.0f, 3.0f};
const Range1D c{1.0f, 3.0f};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
template<class T> class BasicRect: public Math::Range<2, T> {
public:
template<class ...U> constexpr BasicRect(U&&... args): Math::Range<2, T>{args...} {}

21
src/Magnum/Math/Test/RectangularMatrixTest.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/RectangularMatrix.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Mat2x3 {
float a[6];
@ -90,6 +91,8 @@ struct RectangularMatrixTest: Corrade::TestSuite::Tester {
void subclassTypes();
void subclass();
void strictWeakOrdering();
void debug();
void configuration();
};
@ -142,6 +145,8 @@ RectangularMatrixTest::RectangularMatrixTest() {
&RectangularMatrixTest::subclassTypes,
&RectangularMatrixTest::subclass,
&RectangularMatrixTest::strictWeakOrdering,
&RectangularMatrixTest::debug,
&RectangularMatrixTest::configuration});
}
@ -674,6 +679,22 @@ void RectangularMatrixTest::subclass() {
Vector2{-2.0f, 7.0f}}));
}
void RectangularMatrixTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Matrix2x2 a{Vector2{1.0f, 2.0f}, Vector2{3.0f, 4.0f}};
const Matrix2x2 b{Vector2{2.0f, 3.0f}, Vector2{4.0f, 5.0f}};
const Matrix2x2 c{Vector2{1.0f, 2.0f}, Vector2{3.0f, 5.0f}};
CORRADE_VERIFY( o(a, b));
CORRADE_VERIFY(!o(b, a));
CORRADE_VERIFY( o(a, c));
CORRADE_VERIFY(!o(c, a));
CORRADE_VERIFY( o(c, b));
CORRADE_VERIFY(!o(b, c));
CORRADE_VERIFY(!o(a, a));
}
void RectangularMatrixTest::debug() {
Matrix3x4 m(Vector4(3.0f, 5.0f, 8.0f, 4.0f),
Vector4(4.0f, 4.0f, 7.0f, 3.0f),

178
src/Magnum/Math/Test/StrictWeakOrderingTest.cpp

@ -0,0 +1,178 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <map>
#include <set>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Vector2.h"
#include "Magnum/Math/StrictWeakOrdering.h"
namespace std
{
template <> struct less<Magnum::Math::Vector2<float>>
: public Magnum::Math::Implementation::StrictWeakOrdering<Magnum::Math::Vector2<float>>
{};
}
namespace Magnum {
namespace Math {
namespace Test {
using Vector2 = Magnum::Math::Vector2<float>;
struct StrictWeakOrderingTest : Corrade::TestSuite::Tester {
explicit StrictWeakOrderingTest();
void base();
void set();
void setShort();
void setLess();
void map();
void mapShort();
void mapLess();
};
StrictWeakOrderingTest::StrictWeakOrderingTest() {
addTests({ &StrictWeakOrderingTest::base,
&StrictWeakOrderingTest::set,
&StrictWeakOrderingTest::setShort,
&StrictWeakOrderingTest::setLess,
&StrictWeakOrderingTest::map,
&StrictWeakOrderingTest::mapShort,
&StrictWeakOrderingTest::mapLess});
}
void StrictWeakOrderingTest::base() {
Implementation::StrictWeakOrdering<int> o;
CORRADE_VERIFY(o(1, 2));
CORRADE_VERIFY(!o(2, 2));
CORRADE_VERIFY(!o(3, 2));
StrictWeakOrdering of;
CORRADE_VERIFY(of(1, 2));
CORRADE_VERIFY(!of(2.5, 2.5));
CORRADE_VERIFY(!of('z', 'h'));
}
void StrictWeakOrderingTest::set() {
std::set<Vector2, Implementation::StrictWeakOrdering<Vector2>> s;
s.insert({1, 2});
s.insert({2, 3});
CORRADE_VERIFY(s.size() == 2);
CORRADE_VERIFY(*s.begin() == Vector2(1, 2));
CORRADE_VERIFY(*s.rbegin() == Vector2(2, 3));
s.insert({1, 2});
CORRADE_VERIFY(s.size() == 2);
}
void StrictWeakOrderingTest::setShort() {
std::set<Vector2, StrictWeakOrdering> s;
s.insert({1, 2});
s.insert({2, 3});
CORRADE_VERIFY(s.size() == 2);
CORRADE_VERIFY(*s.begin() == Vector2(1, 2));
CORRADE_VERIFY(*s.rbegin() == Vector2(2, 3));
s.insert({1, 2});
CORRADE_VERIFY(s.size() == 2);
}
void StrictWeakOrderingTest::setLess() {
std::set<Vector2> s;
s.insert({1, 2});
s.insert({2, 3});
CORRADE_VERIFY(s.size() == 2);
CORRADE_VERIFY(*s.begin() == Vector2(1, 2));
CORRADE_VERIFY(*s.rbegin() == Vector2(2, 3));
s.insert({1, 2});
CORRADE_VERIFY(s.size() == 2);
}
void StrictWeakOrderingTest::map() {
std::map<Vector2, int, Implementation::StrictWeakOrdering<Vector2>> m;
m[Vector2{1, 2}] = 23;
m[Vector2{4, 5}] = 55;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 23);
CORRADE_VERIFY(m.rbegin()->second == 55);
m[Vector2{1, 2}] = 99;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 99);
}
void StrictWeakOrderingTest::mapShort() {
std::map<Vector2, int, StrictWeakOrdering> m;
m[Vector2{1, 2}] = 23;
m[Vector2{4, 5}] = 55;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 23);
CORRADE_VERIFY(m.rbegin()->second == 55);
m[Vector2{1, 2}] = 99;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 99);
}
void StrictWeakOrderingTest::mapLess() {
std::map<Vector2, int> m;
m[Vector2{1, 2}] = 23;
m[Vector2{4, 5}] = 55;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 23);
CORRADE_VERIFY(m.rbegin()->second == 55);
m[Vector2{1, 2}] = 99;
CORRADE_VERIFY(m.size() == 2);
CORRADE_VERIFY(m.begin()->second == 99);
}
}
}
}
CORRADE_TEST_MAIN(Magnum::Math::Test::StrictWeakOrderingTest)

21
src/Magnum/Math/Test/Vector2Test.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Vector3.h" /* Vector3 used in Vector2Test::cross() */
#include "Magnum/Math/StrictWeakOrdering.h"
struct Vec2 {
float x, y;
@ -69,6 +70,8 @@ struct Vector2Test: Corrade::TestSuite::Tester {
void perpendicular();
void aspectRatio();
void strictWeakOrdering();
void swizzleType();
void debug();
void configuration();
@ -94,6 +97,8 @@ Vector2Test::Vector2Test() {
&Vector2Test::perpendicular,
&Vector2Test::aspectRatio,
&Vector2Test::strictWeakOrdering,
&Vector2Test::swizzleType,
&Vector2Test::debug,
&Vector2Test::configuration});
@ -226,6 +231,22 @@ void Vector2Test::aspectRatio() {
CORRADE_COMPARE(Vector2(3.0f, 4.0f).aspectRatio(), 0.75f);
}
void Vector2Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Vector2 v2a{1.0f, 2.0f};
const Vector2 v2b{2.0f, 3.0f};
const Vector2 v2c{1.0f, 3.0f};
CORRADE_VERIFY( o(v2a, v2b));
CORRADE_VERIFY(!o(v2b, v2a));
CORRADE_VERIFY( o(v2a, v2c));
CORRADE_VERIFY(!o(v2c, v2a));
CORRADE_VERIFY( o(v2c, v2b));
CORRADE_VERIFY(!o(v2b, v2c));
CORRADE_VERIFY(!o(v2a, v2a));
}
void Vector2Test::swizzleType() {
constexpr Vector<4, Int> orig;
constexpr auto a = swizzle<'y', 'a'>(orig);

21
src/Magnum/Math/Test/Vector3Test.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Vector3.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Vec3 {
float x, y, z;
@ -69,6 +70,8 @@ struct Vector3Test: Corrade::TestSuite::Tester {
void scales();
void twoComponent();
void strictWeakOrdering();
void swizzleType();
void debug();
void configuration();
@ -94,6 +97,8 @@ Vector3Test::Vector3Test() {
&Vector3Test::scales,
&Vector3Test::twoComponent,
&Vector3Test::strictWeakOrdering,
&Vector3Test::swizzleType,
&Vector3Test::debug,
&Vector3Test::configuration});
@ -250,6 +255,22 @@ void Vector3Test::twoComponent() {
CORRADE_COMPARE(d, 2.0f);
}
void Vector3Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Vector3 v3a{1.0f, 2.0f, 3.0f};
const Vector3 v3b{2.0f, 3.0f, 4.0f};
const Vector3 v3c{1.0f, 2.0f, 4.0f};
CORRADE_VERIFY( o(v3a, v3b));
CORRADE_VERIFY(!o(v3b, v3a));
CORRADE_VERIFY( o(v3a, v3c));
CORRADE_VERIFY(!o(v3c, v3a));
CORRADE_VERIFY( o(v3c, v3b));
CORRADE_VERIFY(!o(v3b, v3c));
CORRADE_VERIFY(!o(v3a, v3a));
}
void Vector3Test::swizzleType() {
constexpr Vector<4, Int> orig;
constexpr auto b = swizzle<'y', 'z', 'a'>(orig);

21
src/Magnum/Math/Test/Vector4Test.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Vector4.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Vec4 {
float x, y, z, w;
@ -71,6 +72,8 @@ struct Vector4Test: Corrade::TestSuite::Tester {
void planeEquationThreePoints();
void planeEquationNormalPoint();
void strictWeakOrdering();
void swizzleType();
void debug();
void configuration();
@ -99,6 +102,8 @@ Vector4Test::Vector4Test() {
&Vector4Test::planeEquationThreePoints,
&Vector4Test::planeEquationNormalPoint,
&Vector4Test::strictWeakOrdering,
&Vector4Test::swizzleType,
&Vector4Test::debug,
&Vector4Test::configuration});
@ -293,6 +298,22 @@ void Vector4Test::planeEquationNormalPoint() {
CORRADE_COMPARE(eq, (Vector4{-0.9045340f, 0.3015113f, -0.3015113f, 1.658312f}));
}
void Vector4Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Vector4 v4a{1.0f, 2.0f, 3.0f, 4.0f};
const Vector4 v4b{2.0f, 3.0f, 4.0f, 5.0f};
const Vector4 v4c{1.0f, 2.0f, 3.0f, 5.0f};
CORRADE_VERIFY( o(v4a, v4b));
CORRADE_VERIFY(!o(v4b, v4a));
CORRADE_VERIFY( o(v4a, v4c));
CORRADE_VERIFY(!o(v4c, v4a));
CORRADE_VERIFY( o(v4c, v4b));
CORRADE_VERIFY(!o(v4b, v4c));
CORRADE_VERIFY(!o(v4a, v4a));
}
void Vector4Test::swizzleType() {
constexpr Vector4i orig;
constexpr auto c = swizzle<'y', 'a', 'y', 'x'>(orig);

49
src/Magnum/Math/Test/VectorTest.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Math/Vector.h"
#include "Magnum/Math/StrictWeakOrdering.h"
struct Vec3 {
float x, y, z;
@ -107,11 +108,14 @@ struct VectorTest: Corrade::TestSuite::Tester {
void subclassTypes();
void subclass();
void strictWeakOrdering();
void debug();
void configuration();
};
typedef Math::Rad<Float> Rad;
typedef Vector<2, Float> Vector2;
typedef Vector<3, Float> Vector3;
typedef Vector<4, Float> Vector4;
typedef Vector<4, Int> Vector4i;
@ -170,6 +174,8 @@ VectorTest::VectorTest() {
&VectorTest::subclassTypes,
&VectorTest::subclass,
&VectorTest::strictWeakOrdering,
&VectorTest::debug,
&VectorTest::configuration});
}
@ -695,6 +701,49 @@ void VectorTest::subclass() {
CORRADE_COMPARE(flipped, (Vec2{0.4f, 1.0f}));
}
void VectorTest::strictWeakOrdering() {
StrictWeakOrdering o;
const Vector2 v2a{1.0f, 2.0f};
const Vector2 v2b{2.0f, 3.0f};
const Vector2 v2c{1.0f, 3.0f};
CORRADE_VERIFY( o(v2a, v2b));
CORRADE_VERIFY(!o(v2b, v2a));
CORRADE_VERIFY( o(v2a, v2c));
CORRADE_VERIFY(!o(v2c, v2a));
CORRADE_VERIFY( o(v2c, v2b));
CORRADE_VERIFY(!o(v2b, v2c));
CORRADE_VERIFY(!o(v2a, v2a));
const Vector3 v3a{1.0f, 2.0f, 3.0f};
const Vector3 v3b{2.0f, 3.0f, 4.0f};
const Vector3 v3c{1.0f, 2.0f, 4.0f};
CORRADE_VERIFY( o(v3a, v3b));
CORRADE_VERIFY(!o(v3b, v3a));
CORRADE_VERIFY( o(v3a, v3c));
CORRADE_VERIFY(!o(v3c, v3a));
CORRADE_VERIFY( o(v3c, v3b));
CORRADE_VERIFY(!o(v3b, v3c));
CORRADE_VERIFY(!o(v3a, v3a));
const Vector4 v4a{1.0f, 2.0f, 3.0f, 4.0f};
const Vector4 v4b{2.0f, 3.0f, 4.0f, 5.0f};
const Vector4 v4c{1.0f, 2.0f, 3.0f, 5.0f};
CORRADE_VERIFY( o(v4a, v4b));
CORRADE_VERIFY(!o(v4b, v4a));
CORRADE_VERIFY( o(v4a, v4c));
CORRADE_VERIFY(!o(v4c, v4a));
CORRADE_VERIFY( o(v4c, v4b));
CORRADE_VERIFY(!o(v4b, v4c));
CORRADE_VERIFY(!o(v4a, v4a));
}
void VectorTest::debug() {
std::ostringstream o;
Debug(&o) << Vector4(0.5f, 15.0f, 1.0f, 1.0f);

16
src/Magnum/Math/Vector.h

@ -1413,6 +1413,22 @@ template<std::size_t size, class T> inline std::pair<T, T> Vector<size, T>::minm
return {min, max};
}
/* Specialization of helper types*/
namespace Implementation {
template<std::size_t size, class T> struct StrictWeakOrdering<Vector<size, T>> {
bool operator()(const Vector<size, T>& a, const Vector<size, T>& b) const {
for(std::size_t i = 0; i < size; ++i) {
if(a[i] < b[i])
return true;
if(a[i] > b[i])
return false;
}
return false; // a and b are equivalent
}
};
}
}}
namespace Corrade { namespace Utility {

2
src/Magnum/Math/Vector2.h

@ -190,6 +190,8 @@ MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(2, Vector2)
namespace Implementation {
template<std::size_t, class> struct TypeForSize;
template<class T> struct TypeForSize<2, T> { typedef Math::Vector2<typename T::Type> Type; };
template<class T> struct StrictWeakOrdering<Vector2<T>>: public StrictWeakOrdering<Vector<2, T>> {};
}
}}

2
src/Magnum/Math/Vector3.h

@ -245,6 +245,8 @@ MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(3, Vector3)
namespace Implementation {
template<class T> struct TypeForSize<3, T> { typedef Math::Vector3<typename T::Type> Type; };
template<class T> struct StrictWeakOrdering<Vector3<T>>: public StrictWeakOrdering<Vector<3, T>> {};
}
}}

2
src/Magnum/Math/Vector4.h

@ -254,6 +254,8 @@ MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, Vector4)
namespace Implementation {
template<class T> struct TypeForSize<4, T> { typedef Math::Vector4<typename T::Type> Type; };
template<class T> struct StrictWeakOrdering<Vector4<T>>: public StrictWeakOrdering<Vector<4, T>> {};
}
}}

Loading…
Cancel
Save