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

24
src/Magnum/Math/TypeTraits.h

@ -85,9 +85,8 @@ namespace Magnum { namespace Math {
@m_since{2019,10}
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
@ref std::false_type otherwise. The @ref Half type deliberately doesn't support
any arithmetic, so it's not treated as a scalar type.
floating-point types and in addition also @ref Half, @ref Deg and @ref Rad;
equivalent to @ref std::false_type otherwise.
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,
@ -117,6 +116,7 @@ template<> struct IsScalar<unsigned long>: std::true_type {};
template<> struct IsScalar<long long>: std::true_type {};
template<> struct IsScalar<unsigned long long>: std::true_type {};
template<> struct IsScalar<float>: std::true_type {};
template<> struct IsScalar<Half>: std::true_type {};
template<> struct IsScalar<double>: std::true_type {};
#ifndef CORRADE_TARGET_EMSCRIPTEN
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}
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
@ref std::false_type otherwise. The @ref Half type deliberately doesn't support
any arithmetic, so it's not treated as a floating-point type.
types supported by Magnum math including @ref Half, @ref Deg and @ref Rad;
equivalent to @ref std::false_type otherwise.
@see @ref IsIntegral, @ref IsScalar, @ref IsVector, @ref std::is_floating_point
*/
template<class T> struct IsFloatingPoint
@ -209,6 +208,7 @@ template<class T> struct IsFloatingPoint
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct IsFloatingPoint<Float>: std::true_type {};
template<> struct IsFloatingPoint<Half>: std::true_type {};
template<> struct IsFloatingPoint<Double>: std::true_type {};
#ifndef CORRADE_TARGET_EMSCRIPTEN
template<> struct IsFloatingPoint<long double>: std::true_type {};
@ -346,8 +346,10 @@ template<class T> struct TypeTraits: Implementation::TypeTraitsDefault<T> {
/**
* @brief Fuzzy compare
*
* Uses fuzzy compare for floating-point types (using @ref epsilon()
* value), pure equality comparison everywhere else. Algorithm adapted from
* Uses fuzzy compare for all floating-point types except @ref Half (using
* 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/.
* @see @ref Math::equal(T, T), @ref Math::notEqual(T, T)
*/
@ -410,6 +412,7 @@ namespace Implementation {
_c(Long)
#endif
_c(Float)
_c(Half)
_c(Double)
#ifndef CORRADE_TARGET_EMSCRIPTEN
_c(long double)
@ -498,6 +501,11 @@ template<> struct TypeTraits<Float>: Implementation::TypeTraitsFloatingPoint<Flo
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> {
typedef Double FloatingPointType;

Loading…
Cancel
Save