From 10dd468ecaa8a229077d57adea5fdcbc4e5487f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 22 Feb 2020 22:53:40 +0100 Subject: [PATCH] Math: minimal support for Half in TypeTraits. --- src/Magnum/Math/Test/TypeTraitsTest.cpp | 19 ++++++++++++++++++- src/Magnum/Math/TypeTraits.h | 24 ++++++++++++++++-------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Magnum/Math/Test/TypeTraitsTest.cpp b/src/Magnum/Math/Test/TypeTraitsTest.cpp index b9b64ba94..41cb71115 100644 --- a/src/Magnum/Math/Test/TypeTraitsTest.cpp +++ b/src/Magnum/Math/Test/TypeTraitsTest.cpp @@ -27,6 +27,7 @@ #include #include +#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 void equalsIntegral(); + void equalsHalf(); template void equalsFloatingPoint0(); template void equalsFloatingPoint1(); template void equalsFloatingPointLarge(); @@ -125,6 +127,8 @@ TypeTraitsTest::TypeTraitsTest() { &TypeTraitsTest::equalsIntegral, #endif + &TypeTraitsTest::equalsHalf, + &TypeTraitsTest::equalsFloatingPoint0, &TypeTraitsTest::equalsFloatingPoint0, #ifndef CORRADE_TARGET_EMSCRIPTEN @@ -191,9 +195,11 @@ void TypeTraitsTest::isScalar() { CORRADE_VERIFY(IsScalar::value); CORRADE_VERIFY(IsScalar::value); CORRADE_VERIFY(IsScalar>::value); + CORRADE_VERIFY(IsScalar::value); CORRADE_VERIFY((IsScalar>::value)); CORRADE_VERIFY(!IsScalar>::value); CORRADE_VERIFY(!IsVector>::value); + CORRADE_VERIFY(!IsScalar>::value); CORRADE_VERIFY(!IsScalar::value); CORRADE_VERIFY(!IsScalar::value); } @@ -203,6 +209,7 @@ void TypeTraitsTest::isVector() { CORRADE_VERIFY(!IsVector>::value); CORRADE_VERIFY((IsVector>>::value)); CORRADE_VERIFY(IsVector>::value); + CORRADE_VERIFY(IsVector>::value); CORRADE_VERIFY(!IsVector>::value); CORRADE_VERIFY(!IsVector::value); } @@ -218,6 +225,7 @@ void TypeTraitsTest::isIntegral() { #ifndef CORRADE_TARGET_EMSCRIPTEN CORRADE_VERIFY(IsIntegral>::value); #endif + CORRADE_VERIFY(!IsIntegral::value); CORRADE_VERIFY(!IsIntegral>::value); CORRADE_VERIFY(!IsIntegral::value); CORRADE_VERIFY(!IsIntegral::value); @@ -232,13 +240,15 @@ void TypeTraitsTest::isFloatingPoint() { CORRADE_VERIFY(IsFloatingPoint>::value); #endif CORRADE_VERIFY(IsFloatingPoint>::value); + CORRADE_VERIFY(IsFloatingPoint>::value); CORRADE_VERIFY((IsFloatingPoint>::value)); - CORRADE_VERIFY(!IsFloatingPoint>::value); + CORRADE_VERIFY(IsFloatingPoint>::value); CORRADE_VERIFY(!IsFloatingPoint::value); } void TypeTraitsTest::isUnitless() { CORRADE_VERIFY(IsUnitless::value); + CORRADE_VERIFY(IsUnitless::value); CORRADE_VERIFY(IsUnitless>::value); CORRADE_VERIFY(!IsUnitless>::value); CORRADE_VERIFY(!(IsUnitless>::value)); @@ -266,6 +276,13 @@ template void TypeTraitsTest::equalsIntegral() { CORRADE_VERIFY(!TypeTraits::equals(T(1), T(1)+TypeTraits::epsilon())); } +void TypeTraitsTest::equalsHalf() { + CORRADE_VERIFY(TypeTraits::equals(Half(UnsignedShort(0xabcd)), + Half(UnsignedShort(0xabcd)))); + CORRADE_VERIFY(!TypeTraits::equals(Half(UnsignedShort(0xabcd)), + Half(UnsignedShort(0xabce)))); +} + template void TypeTraitsTest::equalsFloatingPoint0() { setTestCaseTemplateName(TypeTraits::name()); diff --git a/src/Magnum/Math/TypeTraits.h b/src/Magnum/Math/TypeTraits.h index 4b3b31728..b9412a2ba 100644 --- a/src/Magnum/Math/TypeTraits.h +++ b/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: std::true_type {}; template<> struct IsScalar: std::true_type {}; template<> struct IsScalar: std::true_type {}; template<> struct IsScalar: std::true_type {}; +template<> struct IsScalar: std::true_type {}; template<> struct IsScalar: std::true_type {}; #ifndef CORRADE_TARGET_EMSCRIPTEN template<> struct IsScalar: std::true_type {}; @@ -196,9 +196,8 @@ template struct IsIntegral>: IsIntegral {}; @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 struct IsFloatingPoint @@ -209,6 +208,7 @@ template struct IsFloatingPoint #ifndef DOXYGEN_GENERATING_OUTPUT template<> struct IsFloatingPoint: std::true_type {}; +template<> struct IsFloatingPoint: std::true_type {}; template<> struct IsFloatingPoint: std::true_type {}; #ifndef CORRADE_TARGET_EMSCRIPTEN template<> struct IsFloatingPoint: std::true_type {}; @@ -346,8 +346,10 @@ template struct TypeTraits: Implementation::TypeTraitsDefault { /** * @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: Implementation::TypeTraitsFloatingPoint struct TypeTraits: Implementation::TypeTraitsName, Implementation::TypeTraitsDefault { + typedef Half FloatingPointType; +}; template<> struct TypeTraits: Implementation::TypeTraitsFloatingPoint { typedef Double FloatingPointType;