Browse Source

Math: added UnderlyingTypeOf.

pull/342/head
Vladimír Vondruš 7 years ago
parent
commit
19844352ff
  1. 3
      doc/changelog.dox
  2. 10
      src/Magnum/Math/Test/TypeTraitsTest.cpp
  3. 27
      src/Magnum/Math/TypeTraits.h

3
doc/changelog.dox

@ -124,7 +124,8 @@ See also:
- Added convenience @ref BoolVector2, @ref BoolVector3 and @ref BoolVector4
typedefs to the root namespace
- New @ref Math::IsScalar, @ref Math::IsVector, @ref Math::IsIntegral and
@ref Math::IsFloatingPoint type traits
@ref Math::IsFloatingPoint type traits and a @ref Math::UnderlyingTypeOf
utility
@subsubsection changelog-latest-new-platform Platform libraries

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

@ -44,6 +44,8 @@ struct TypeTraitsTest: Corrade::TestSuite::Tester {
void isIntegral();
void isFloatingPoint();
void underlyingTypeOf();
template<class T> void equalsIntegral();
template<class T> void equalsFloatingPoint0();
template<class T> void equalsFloatingPoint1();
@ -106,6 +108,8 @@ TypeTraitsTest::TypeTraitsTest() {
&TypeTraitsTest::isIntegral,
&TypeTraitsTest::isFloatingPoint,
&TypeTraitsTest::underlyingTypeOf,
&TypeTraitsTest::equalsIntegral<UnsignedByte>,
&TypeTraitsTest::equalsIntegral<Byte>,
&TypeTraitsTest::equalsIntegral<UnsignedShort>,
@ -227,6 +231,12 @@ void TypeTraitsTest::isFloatingPoint() {
CORRADE_VERIFY(!IsFloatingPoint<char*>::value);
}
void TypeTraitsTest::underlyingTypeOf() {
CORRADE_VERIFY((std::is_same<UnderlyingTypeOf<Int>, Int>::value));
CORRADE_VERIFY((std::is_same<UnderlyingTypeOf<Deg<Float>>, Float>::value));
CORRADE_VERIFY((std::is_same<UnderlyingTypeOf<Unit<Rad, Double>>, Double>::value));
}
template<class T> void TypeTraitsTest::equalsIntegral() {
setTestCaseName(std::string{"equalsIntegral<"} + TypeTraits<T>::name() + ">");

27
src/Magnum/Math/TypeTraits.h

@ -87,7 +87,7 @@ 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,
except that it doesn't give @ref std::true_type for @cpp bool @ce. The name is
chosen particularly for the @ref IsVector / @ref IsScalar distinction.
@see @ref IsFloatingPoint, @ref IsIntegral
@see @ref IsFloatingPoint, @ref IsIntegral, @ref UnderlyingTypeOf
*/
template<class T> struct IsScalar
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -217,6 +217,31 @@ template<class T> struct IsFloatingPoint<Deg<T>>: IsFloatingPoint<T> {};
template<class T> struct IsFloatingPoint<Rad<T>>: IsFloatingPoint<T> {};
#endif
namespace Implementation {
template<class T> struct UnderlyingType {
static_assert(IsScalar<T>::value, "type is not scalar");
typedef T Type;
};
template<template<class> class Derived, class T> struct UnderlyingType<Unit<Derived, T>> {
typedef T Type;
};
template<class T> struct UnderlyingType<Deg<T>> { typedef T Type; };
template<class T> struct UnderlyingType<Rad<T>> { typedef T Type; };
}
/**
@brief Underlying builtin type for a scalar type
For builtin types returns the type itself, for wrapped types like @ref Deg or
@ref Rad returns the underlying builtin type. It's guaranteed that the input
type is always explicitly convertible to the output type and the output type
is usable with standard APIs such as @ref std::isinf().
Passed types are required to satisfy @ref IsScalar. All non-scalar Magnum math
types have a member @cpp typedef @ce ``Type`` containing the underlying type.
*/
template<class T> using UnderlyingTypeOf = typename Implementation::UnderlyingType<T>::Type;
namespace Implementation {
template<class T> struct TypeTraitsDefault {
TypeTraitsDefault() = delete;

Loading…
Cancel
Save