Browse Source

Math: minimal support for Half in TypeTraits.

pull/369/head
Vladimír Vondruš 6 years ago
parent
commit
10dd468eca
  1. 19
      src/Magnum/Math/Test/TypeTraitsTest.cpp
  2. 24
      src/Magnum/Math/TypeTraits.h

19
src/Magnum/Math/Test/TypeTraitsTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h> #include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h> #include <Corrade/Utility/DebugStl.h>
#include "Magnum/Math/Half.h"
#include "Magnum/Math/Math.h" #include "Magnum/Math/Math.h"
#include "Magnum/Math/TypeTraits.h" #include "Magnum/Math/TypeTraits.h"
#include "Magnum/Math/Constants.h" #include "Magnum/Math/Constants.h"
@ -48,6 +49,7 @@ struct TypeTraitsTest: Corrade::TestSuite::Tester {
void underlyingTypeOf(); void underlyingTypeOf();
template<class T> void equalsIntegral(); template<class T> void equalsIntegral();
void equalsHalf();
template<class T> void equalsFloatingPoint0(); template<class T> void equalsFloatingPoint0();
template<class T> void equalsFloatingPoint1(); template<class T> void equalsFloatingPoint1();
template<class T> void equalsFloatingPointLarge(); template<class T> void equalsFloatingPointLarge();
@ -125,6 +127,8 @@ TypeTraitsTest::TypeTraitsTest() {
&TypeTraitsTest::equalsIntegral<Long>, &TypeTraitsTest::equalsIntegral<Long>,
#endif #endif
&TypeTraitsTest::equalsHalf,
&TypeTraitsTest::equalsFloatingPoint0<Float>, &TypeTraitsTest::equalsFloatingPoint0<Float>,
&TypeTraitsTest::equalsFloatingPoint0<Double>, &TypeTraitsTest::equalsFloatingPoint0<Double>,
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
@ -191,9 +195,11 @@ void TypeTraitsTest::isScalar() {
CORRADE_VERIFY(IsScalar<char>::value); CORRADE_VERIFY(IsScalar<char>::value);
CORRADE_VERIFY(IsScalar<UnsignedShort>::value); CORRADE_VERIFY(IsScalar<UnsignedShort>::value);
CORRADE_VERIFY(IsScalar<Deg<Float>>::value); CORRADE_VERIFY(IsScalar<Deg<Float>>::value);
CORRADE_VERIFY(IsScalar<Half>::value);
CORRADE_VERIFY((IsScalar<Unit<Rad, Double>>::value)); CORRADE_VERIFY((IsScalar<Unit<Rad, Double>>::value));
CORRADE_VERIFY(!IsScalar<Vector2<Float>>::value); CORRADE_VERIFY(!IsScalar<Vector2<Float>>::value);
CORRADE_VERIFY(!IsVector<Matrix2x3<Float>>::value); CORRADE_VERIFY(!IsVector<Matrix2x3<Float>>::value);
CORRADE_VERIFY(!IsScalar<Color3<Half>>::value);
CORRADE_VERIFY(!IsScalar<char*>::value); CORRADE_VERIFY(!IsScalar<char*>::value);
CORRADE_VERIFY(!IsScalar<bool>::value); CORRADE_VERIFY(!IsScalar<bool>::value);
} }
@ -203,6 +209,7 @@ void TypeTraitsTest::isVector() {
CORRADE_VERIFY(!IsVector<Deg<UnsignedByte>>::value); CORRADE_VERIFY(!IsVector<Deg<UnsignedByte>>::value);
CORRADE_VERIFY((IsVector<Vector<2, Deg<Float>>>::value)); CORRADE_VERIFY((IsVector<Vector<2, Deg<Float>>>::value));
CORRADE_VERIFY(IsVector<Color3<UnsignedByte>>::value); CORRADE_VERIFY(IsVector<Color3<UnsignedByte>>::value);
CORRADE_VERIFY(IsVector<Color3<Half>>::value);
CORRADE_VERIFY(!IsVector<Matrix2x3<Float>>::value); CORRADE_VERIFY(!IsVector<Matrix2x3<Float>>::value);
CORRADE_VERIFY(!IsVector<char*>::value); CORRADE_VERIFY(!IsVector<char*>::value);
} }
@ -218,6 +225,7 @@ void TypeTraitsTest::isIntegral() {
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
CORRADE_VERIFY(IsIntegral<Vector2<Long>>::value); CORRADE_VERIFY(IsIntegral<Vector2<Long>>::value);
#endif #endif
CORRADE_VERIFY(!IsIntegral<Half>::value);
CORRADE_VERIFY(!IsIntegral<Deg<Float>>::value); CORRADE_VERIFY(!IsIntegral<Deg<Float>>::value);
CORRADE_VERIFY(!IsIntegral<char*>::value); CORRADE_VERIFY(!IsIntegral<char*>::value);
CORRADE_VERIFY(!IsIntegral<bool>::value); CORRADE_VERIFY(!IsIntegral<bool>::value);
@ -232,13 +240,15 @@ void TypeTraitsTest::isFloatingPoint() {
CORRADE_VERIFY(IsFloatingPoint<Vector2<long double>>::value); CORRADE_VERIFY(IsFloatingPoint<Vector2<long double>>::value);
#endif #endif
CORRADE_VERIFY(IsFloatingPoint<Deg<Float>>::value); CORRADE_VERIFY(IsFloatingPoint<Deg<Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Color4<Half>>::value);
CORRADE_VERIFY((IsFloatingPoint<Unit<Rad, Float>>::value)); CORRADE_VERIFY((IsFloatingPoint<Unit<Rad, Float>>::value));
CORRADE_VERIFY(!IsFloatingPoint<Deg<Half>>::value); CORRADE_VERIFY(IsFloatingPoint<Deg<Half>>::value);
CORRADE_VERIFY(!IsFloatingPoint<char*>::value); CORRADE_VERIFY(!IsFloatingPoint<char*>::value);
} }
void TypeTraitsTest::isUnitless() { void TypeTraitsTest::isUnitless() {
CORRADE_VERIFY(IsUnitless<Int>::value); CORRADE_VERIFY(IsUnitless<Int>::value);
CORRADE_VERIFY(IsUnitless<Half>::value);
CORRADE_VERIFY(IsUnitless<Color4<Float>>::value); CORRADE_VERIFY(IsUnitless<Color4<Float>>::value);
CORRADE_VERIFY(!IsUnitless<Deg<Float>>::value); CORRADE_VERIFY(!IsUnitless<Deg<Float>>::value);
CORRADE_VERIFY(!(IsUnitless<Unit<Rad, Double>>::value)); CORRADE_VERIFY(!(IsUnitless<Unit<Rad, Double>>::value));
@ -266,6 +276,13 @@ template<class T> void TypeTraitsTest::equalsIntegral() {
CORRADE_VERIFY(!TypeTraits<T>::equals(T(1), T(1)+TypeTraits<T>::epsilon())); CORRADE_VERIFY(!TypeTraits<T>::equals(T(1), T(1)+TypeTraits<T>::epsilon()));
} }
void TypeTraitsTest::equalsHalf() {
CORRADE_VERIFY(TypeTraits<Half>::equals(Half(UnsignedShort(0xabcd)),
Half(UnsignedShort(0xabcd))));
CORRADE_VERIFY(!TypeTraits<Half>::equals(Half(UnsignedShort(0xabcd)),
Half(UnsignedShort(0xabce))));
}
template<class T> void TypeTraitsTest::equalsFloatingPoint0() { template<class T> void TypeTraitsTest::equalsFloatingPoint0() {
setTestCaseTemplateName(TypeTraits<T>::name()); setTestCaseTemplateName(TypeTraits<T>::name());

24
src/Magnum/Math/TypeTraits.h

@ -85,9 +85,8 @@ namespace Magnum { namespace Math {
@m_since{2019,10} @m_since{2019,10}
Equivalent to @ref std::true_type for all builtin scalar integer and Equivalent to @ref std::true_type for all builtin scalar integer and
floating-point types and in addition also @ref Deg and @ref Rad; equivalent to floating-point types and in addition also @ref Half, @ref Deg and @ref Rad;
@ref std::false_type otherwise. The @ref Half type deliberately doesn't support equivalent to @ref std::false_type otherwise.
any arithmetic, so it's not treated as a scalar type.
Note that this is *different* from @ref std::is_scalar, which is @cpp true @ce Note that this is *different* from @ref std::is_scalar, which is @cpp true @ce
also for enums or pointers --- it's rather closer to @ref std::is_arithmetic, also for enums or pointers --- it's rather closer to @ref std::is_arithmetic,
@ -117,6 +116,7 @@ template<> struct IsScalar<unsigned long>: std::true_type {};
template<> struct IsScalar<long long>: std::true_type {}; template<> struct IsScalar<long long>: std::true_type {};
template<> struct IsScalar<unsigned long long>: std::true_type {}; template<> struct IsScalar<unsigned long long>: std::true_type {};
template<> struct IsScalar<float>: std::true_type {}; template<> struct IsScalar<float>: std::true_type {};
template<> struct IsScalar<Half>: std::true_type {};
template<> struct IsScalar<double>: std::true_type {}; template<> struct IsScalar<double>: std::true_type {};
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
template<> struct IsScalar<long double>: std::true_type {}; template<> struct IsScalar<long double>: std::true_type {};
@ -196,9 +196,8 @@ template<class T> struct IsIntegral<Color4<T>>: IsIntegral<T> {};
@m_since{2019,10} @m_since{2019,10}
Equivalent to @ref std::true_type for all floating-point scalar and vector Equivalent to @ref std::true_type for all floating-point scalar and vector
types supported by Magnum math including @ref Deg and @ref Rad; equivalent to types supported by Magnum math including @ref Half, @ref Deg and @ref Rad;
@ref std::false_type otherwise. The @ref Half type deliberately doesn't support equivalent to @ref std::false_type otherwise.
any arithmetic, so it's not treated as a floating-point type.
@see @ref IsIntegral, @ref IsScalar, @ref IsVector, @ref std::is_floating_point @see @ref IsIntegral, @ref IsScalar, @ref IsVector, @ref std::is_floating_point
*/ */
template<class T> struct IsFloatingPoint template<class T> struct IsFloatingPoint
@ -209,6 +208,7 @@ template<class T> struct IsFloatingPoint
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct IsFloatingPoint<Float>: std::true_type {}; template<> struct IsFloatingPoint<Float>: std::true_type {};
template<> struct IsFloatingPoint<Half>: std::true_type {};
template<> struct IsFloatingPoint<Double>: std::true_type {}; template<> struct IsFloatingPoint<Double>: std::true_type {};
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
template<> struct IsFloatingPoint<long double>: std::true_type {}; template<> struct IsFloatingPoint<long double>: std::true_type {};
@ -346,8 +346,10 @@ template<class T> struct TypeTraits: Implementation::TypeTraitsDefault<T> {
/** /**
* @brief Fuzzy compare * @brief Fuzzy compare
* *
* Uses fuzzy compare for floating-point types (using @ref epsilon() * Uses fuzzy compare for all floating-point types except @ref Half (using
* value), pure equality comparison everywhere else. Algorithm adapted from * the @ref epsilon() value), pure equality comparison everywhere else.
* The @ref Half type has representable values sparse enough that no fuzzy
* comparison needs to be done. Algorithm adapted from
* http://floating-point-gui.de/errors/comparison/. * http://floating-point-gui.de/errors/comparison/.
* @see @ref Math::equal(T, T), @ref Math::notEqual(T, T) * @see @ref Math::equal(T, T), @ref Math::notEqual(T, T)
*/ */
@ -410,6 +412,7 @@ namespace Implementation {
_c(Long) _c(Long)
#endif #endif
_c(Float) _c(Float)
_c(Half)
_c(Double) _c(Double)
#ifndef CORRADE_TARGET_EMSCRIPTEN #ifndef CORRADE_TARGET_EMSCRIPTEN
_c(long double) _c(long double)
@ -498,6 +501,11 @@ template<> struct TypeTraits<Float>: Implementation::TypeTraitsFloatingPoint<Flo
constexpr static Float epsilon() { return FLOAT_EQUALITY_PRECISION; } constexpr static Float epsilon() { return FLOAT_EQUALITY_PRECISION; }
}; };
/* A bit special -- using integer comparison for equality but presenting itself
as a floating-point type so Color's fullChannel() works correctly */
template<> struct TypeTraits<Half>: Implementation::TypeTraitsName<Half>, Implementation::TypeTraitsDefault<Half> {
typedef Half FloatingPointType;
};
template<> struct TypeTraits<Double>: Implementation::TypeTraitsFloatingPoint<Double> { template<> struct TypeTraits<Double>: Implementation::TypeTraitsFloatingPoint<Double> {
typedef Double FloatingPointType; typedef Double FloatingPointType;

Loading…
Cancel
Save