Browse Source

Math: recognize Nanoseconds and Seconds in type traits.

Which in turn makes them usable with various math functions. Test
them all as well.
pull/638/head
Vladimír Vondruš 2 years ago
parent
commit
ec788f313c
  1. 30
      src/Magnum/Math/Test/FunctionsTest.cpp
  2. 12
      src/Magnum/Math/Test/TypeTraitsTest.cpp
  3. 27
      src/Magnum/Math/TypeTraits.h

30
src/Magnum/Math/Test/FunctionsTest.cpp

@ -29,6 +29,7 @@
#include <Corrade/Utility/DebugStl.h> #include <Corrade/Utility/DebugStl.h>
#include "Magnum/Math/Functions.h" #include "Magnum/Math/Functions.h"
#include "Magnum/Math/Time.h"
#include "Magnum/Math/Vector4.h" #include "Magnum/Math/Vector4.h"
namespace Magnum { namespace Math { namespace Test { namespace { namespace Magnum { namespace Math { namespace Test { namespace {
@ -93,6 +94,7 @@ using namespace Literals;
using Magnum::Constants; using Magnum::Constants;
using Magnum::Deg; using Magnum::Deg;
using Magnum::Rad; using Magnum::Rad;
using Magnum::Seconds;
using Magnum::Vector2; using Magnum::Vector2;
using Magnum::Vector3; using Magnum::Vector3;
using Magnum::Vector4; using Magnum::Vector4;
@ -196,6 +198,7 @@ void FunctionsTest::min() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::min(5.0_degf, 9.0_degf), 5.0_degf); CORRADE_COMPARE(Math::min(5.0_degf, 9.0_degf), 5.0_degf);
CORRADE_COMPARE(Math::min(6.0_sec, 5500.0_msec), 5.5_sec);
} }
void FunctionsTest::max() { void FunctionsTest::max() {
@ -205,6 +208,7 @@ void FunctionsTest::max() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::max(5.0_degf, 9.0_degf), 9.0_degf); CORRADE_COMPARE(Math::max(5.0_degf, 9.0_degf), 9.0_degf);
CORRADE_COMPARE(Math::max(6.0_sec, 5500.0_msec), 6000.0_msec);
} }
void FunctionsTest::minmax() { void FunctionsTest::minmax() {
@ -220,6 +224,7 @@ void FunctionsTest::minmax() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::minmax(4.0_degf, 5.0_degf), Containers::pair(4.0_degf, 5.0_degf)); CORRADE_COMPARE(Math::minmax(4.0_degf, 5.0_degf), Containers::pair(4.0_degf, 5.0_degf));
CORRADE_COMPARE(Math::minmax(6.0_sec, 5500.0_msec), Containers::pair(5.5_sec, 6.0_sec));
} }
void FunctionsTest::clamp() { void FunctionsTest::clamp() {
@ -237,6 +242,7 @@ void FunctionsTest::clamp() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::clamp(0.5_degf, 0.75_degf, 1.0_degf), 0.75_degf); CORRADE_COMPARE(Math::clamp(0.5_degf, 0.75_degf, 1.0_degf), 0.75_degf);
CORRADE_COMPARE(Math::clamp(0.5_sec, 0.75_sec, 799.9_msec), 0.75_sec);
} }
void FunctionsTest::nanPropagation() { void FunctionsTest::nanPropagation() {
@ -268,6 +274,7 @@ void FunctionsTest::sign() {
angle value back. With returning the type itself such operation wouldn't angle value back. With returning the type itself such operation wouldn't
have any definable unit. */ have any definable unit. */
CORRADE_COMPARE(Math::sign(-3.7_degf), -1.0f); CORRADE_COMPARE(Math::sign(-3.7_degf), -1.0f);
CORRADE_COMPARE(Math::sign(-2.5_usec), -1.0f);
CORRADE_COMPARE(Math::sign(Math::Vector2<Deg>{3.5_degf, -1.9_degf}), (Vector2{1.0f, -1.0f})); CORRADE_COMPARE(Math::sign(Math::Vector2<Deg>{3.5_degf, -1.9_degf}), (Vector2{1.0f, -1.0f}));
} }
@ -278,6 +285,7 @@ void FunctionsTest::abs() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::abs(-5.0_degf), 5.0_degf); CORRADE_COMPARE(Math::abs(-5.0_degf), 5.0_degf);
CORRADE_COMPARE(Math::abs(-5.0_msec), 5.0_msec);
} }
void FunctionsTest::floor() { void FunctionsTest::floor() {
@ -286,6 +294,8 @@ void FunctionsTest::floor() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::floor(2.7_degf), 2.0_degf); CORRADE_COMPARE(Math::floor(2.7_degf), 2.0_degf);
/* Nanoseconds are an integer type */
CORRADE_COMPARE(Math::floor(Seconds{2.7_sec}), Seconds{2.0_sec});
} }
void FunctionsTest::round() { void FunctionsTest::round() {
@ -303,6 +313,8 @@ void FunctionsTest::round() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::round(2.7_degf), 3.0_degf); CORRADE_COMPARE(Math::round(2.7_degf), 3.0_degf);
/* Nanoseconds are an integer type */
CORRADE_COMPARE(Math::round(Seconds{2.7_sec}), Seconds{3.0_sec});
} }
void FunctionsTest::ceil() { void FunctionsTest::ceil() {
@ -311,6 +323,8 @@ void FunctionsTest::ceil() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::ceil(2.7_degf), 3.0_degf); CORRADE_COMPARE(Math::ceil(2.7_degf), 3.0_degf);
/* Nanoseconds are an integer type */
CORRADE_COMPARE(Math::ceil(Seconds{2.7_sec}), Seconds{3.0_sec});
} }
void FunctionsTest::binomialCoefficient() { void FunctionsTest::binomialCoefficient() {
@ -347,6 +361,8 @@ void FunctionsTest::fmod() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::fmod(2.7_degf, 1.3_degf), 0.1_degf); CORRADE_COMPARE(Math::fmod(2.7_degf, 1.3_degf), 0.1_degf);
/* Nanoseconds are an integer type */
CORRADE_COMPARE(Math::fmod(Seconds{2.7_sec}, Seconds{1.3_sec}), Seconds{0.1_sec});
} }
void FunctionsTest::sqrt() { void FunctionsTest::sqrt() {
@ -383,6 +399,7 @@ void FunctionsTest::lerp() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::lerp(2.0_degf, 5.0_degf, 0.5f), 3.5_degf); CORRADE_COMPARE(Math::lerp(2.0_degf, 5.0_degf, 0.5f), 3.5_degf);
CORRADE_COMPARE(Math::lerp(2.0_usec, 5.0_usec, 0.5f), 3.5_usec);
} }
void FunctionsTest::lerpBool() { void FunctionsTest::lerpBool() {
@ -396,6 +413,7 @@ void FunctionsTest::lerpBool() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::lerp(2.0_degf, 5.0_degf, true), 5.0_degf); CORRADE_COMPARE(Math::lerp(2.0_degf, 5.0_degf, true), 5.0_degf);
CORRADE_COMPARE(Math::lerp(2.0_msec, 5.0_msec, true), 5.0_msec);
} }
void FunctionsTest::lerpInverted() { void FunctionsTest::lerpInverted() {
@ -409,6 +427,12 @@ void FunctionsTest::lerpInverted() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::lerpInverted(2.0_degf, 5.0_degf, 3.5_degf), 0.5f); CORRADE_COMPARE(Math::lerpInverted(2.0_degf, 5.0_degf, 3.5_degf), 0.5f);
/* Nanoseconds are an integer type */
CORRADE_COMPARE(Math::lerpInverted(Seconds{2.0_sec}, Seconds{5.0_sec}, Seconds{3.5_sec}), 0.5f);
{
CORRADE_EXPECT_FAIL("This doesn't work correctly with (integer) Nanoseconds.");
CORRADE_COMPARE(Math::lerpInverted(2.0_sec, 5.0_sec, 3.5_sec), 0.5f);
}
} }
void FunctionsTest::select() { void FunctionsTest::select() {
@ -429,6 +453,7 @@ void FunctionsTest::select() {
/* Wrapped types */ /* Wrapped types */
CORRADE_COMPARE(Math::select(2.0_degf, 5.0_degf, 0.5f), 2.0_degf); CORRADE_COMPARE(Math::select(2.0_degf, 5.0_degf, 0.5f), 2.0_degf);
CORRADE_COMPARE(Math::select(2.0_msec, 5.0_msec, 0.5f), 2.0_msec);
} }
void FunctionsTest::selectBool() { void FunctionsTest::selectBool() {
@ -476,7 +501,10 @@ void FunctionsTest::isInf() {
/* Wrapped types */ /* Wrapped types */
CORRADE_VERIFY(Math::isInf(-Rad(Constants::inf()))); CORRADE_VERIFY(Math::isInf(-Rad(Constants::inf())));
CORRADE_VERIFY(Math::isInf(Seconds{-Constants::inf()}));
CORRADE_VERIFY(!Math::isInf(5.3_degf)); CORRADE_VERIFY(!Math::isInf(5.3_degf));
/* Nanoseconds are an integer type */
CORRADE_VERIFY(!Math::isInf(Seconds{5.3_msec}));
} }
void FunctionsTest::isInfVector() { void FunctionsTest::isInfVector() {
@ -492,7 +520,9 @@ void FunctionsTest::isNan() {
/* Wrapped types */ /* Wrapped types */
CORRADE_VERIFY(Math::isNan(-Rad(Constants::nan()))); CORRADE_VERIFY(Math::isNan(-Rad(Constants::nan())));
CORRADE_VERIFY(Math::isNan(Seconds(Constants::nan())));
CORRADE_VERIFY(!Math::isNan(5.3_degf)); CORRADE_VERIFY(!Math::isNan(5.3_degf));
CORRADE_VERIFY(!Math::isNan(Seconds{5.3_usec}));
} }
void FunctionsTest::isNanfVector() { void FunctionsTest::isNanfVector() {

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

@ -172,6 +172,8 @@ void TypeTraitsTest::isScalar() {
CORRADE_VERIFY(IsScalar<Deg<Float>>::value); CORRADE_VERIFY(IsScalar<Deg<Float>>::value);
CORRADE_VERIFY(IsScalar<Half>::value); CORRADE_VERIFY(IsScalar<Half>::value);
CORRADE_VERIFY(IsScalar<Unit<Rad, Double>>::value); CORRADE_VERIFY(IsScalar<Unit<Rad, Double>>::value);
CORRADE_VERIFY(IsScalar<Nanoseconds<Long>>::value);
CORRADE_VERIFY(IsScalar<Unit<Seconds, Float>>::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<Color3<Half>>::value);
@ -182,6 +184,7 @@ void TypeTraitsTest::isScalar() {
void TypeTraitsTest::isVector() { void TypeTraitsTest::isVector() {
CORRADE_VERIFY(!IsVector<UnsignedByte>::value); CORRADE_VERIFY(!IsVector<UnsignedByte>::value);
CORRADE_VERIFY(!IsVector<Deg<UnsignedByte>>::value); CORRADE_VERIFY(!IsVector<Deg<UnsignedByte>>::value);
CORRADE_VERIFY(!IsVector<Seconds<Float>>::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<Color3<Half>>::value);
@ -198,8 +201,10 @@ void TypeTraitsTest::isIntegral() {
CORRADE_VERIFY(IsIntegral<Int>::value); CORRADE_VERIFY(IsIntegral<Int>::value);
CORRADE_VERIFY(IsIntegral<Vector<7, UnsignedInt>>::value); CORRADE_VERIFY(IsIntegral<Vector<7, UnsignedInt>>::value);
CORRADE_VERIFY(IsIntegral<Vector2<Long>>::value); CORRADE_VERIFY(IsIntegral<Vector2<Long>>::value);
CORRADE_VERIFY(IsIntegral<Nanoseconds<Long>>::value);
CORRADE_VERIFY(!IsIntegral<Half>::value); CORRADE_VERIFY(!IsIntegral<Half>::value);
CORRADE_VERIFY(!IsIntegral<Deg<Float>>::value); CORRADE_VERIFY(!IsIntegral<Deg<Float>>::value);
CORRADE_VERIFY(!IsIntegral<Seconds<Float>>::value);
CORRADE_VERIFY(!IsIntegral<char*>::value); CORRADE_VERIFY(!IsIntegral<char*>::value);
CORRADE_VERIFY(!IsIntegral<bool>::value); CORRADE_VERIFY(!IsIntegral<bool>::value);
} }
@ -207,12 +212,15 @@ void TypeTraitsTest::isIntegral() {
void TypeTraitsTest::isFloatingPoint() { void TypeTraitsTest::isFloatingPoint() {
CORRADE_VERIFY(!IsFloatingPoint<Int>::value); CORRADE_VERIFY(!IsFloatingPoint<Int>::value);
CORRADE_VERIFY(!IsFloatingPoint<Vector<7, UnsignedInt>>::value); CORRADE_VERIFY(!IsFloatingPoint<Vector<7, UnsignedInt>>::value);
CORRADE_VERIFY(!IsFloatingPoint<Nanoseconds<Long>>::value);
CORRADE_VERIFY(IsFloatingPoint<Double>::value); CORRADE_VERIFY(IsFloatingPoint<Double>::value);
CORRADE_VERIFY(IsFloatingPoint<Vector<2, Float>>::value); CORRADE_VERIFY(IsFloatingPoint<Vector<2, Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Vector2<long double>>::value); CORRADE_VERIFY(IsFloatingPoint<Vector2<long double>>::value);
CORRADE_VERIFY(IsFloatingPoint<Deg<Float>>::value); CORRADE_VERIFY(IsFloatingPoint<Deg<Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Seconds<Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Color4<Half>>::value); CORRADE_VERIFY(IsFloatingPoint<Color4<Half>>::value);
CORRADE_VERIFY(IsFloatingPoint<Unit<Rad, Float>>::value); CORRADE_VERIFY(IsFloatingPoint<Unit<Rad, Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Unit<Seconds, Float>>::value);
CORRADE_VERIFY(IsFloatingPoint<Deg<Half>>::value); CORRADE_VERIFY(IsFloatingPoint<Deg<Half>>::value);
CORRADE_VERIFY(!IsFloatingPoint<char*>::value); CORRADE_VERIFY(!IsFloatingPoint<char*>::value);
} }
@ -223,6 +231,8 @@ void TypeTraitsTest::isUnitless() {
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);
CORRADE_VERIFY(!IsUnitless<Nanoseconds<Long>>::value);
CORRADE_VERIFY(!IsUnitless<Unit<Seconds, Float>>::value);
CORRADE_VERIFY(!IsUnitless<char*>::value); CORRADE_VERIFY(!IsUnitless<char*>::value);
} }
@ -230,7 +240,9 @@ void TypeTraitsTest::underlyingTypeOf() {
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Int>, Int>::value); 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<Deg<Float>>, Float>::value);
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Nanoseconds<Long>>, Long>::value);
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Unit<Rad, Double>>, Double>::value); CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Unit<Rad, Double>>, Double>::value);
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Unit<Seconds, Float>>, Float>::value);
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Vector2<UnsignedByte>>, UnsignedByte>::value); CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Vector2<UnsignedByte>>, UnsignedByte>::value);
CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Color3<Float>>, Float>::value); CORRADE_VERIFY(std::is_same<UnderlyingTypeOf<Color3<Float>>, Float>::value);

27
src/Magnum/Math/TypeTraits.h

@ -93,8 +93,9 @@ 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 Half, @ref Deg and @ref Rad; floating-point types and in addition also @ref Half, @ref Deg, @ref Rad,
equivalent to @ref std::false_type otherwise. @ref Nanoseconds and @ref Seconds; equivalent to @ref std::false_type
otherwise.
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,
@ -130,6 +131,8 @@ template<> struct IsScalar<long double>: std::true_type {};
template<template<class> class Derived, class T> struct IsScalar<Unit<Derived, T>>: std::true_type {}; template<template<class> class Derived, class T> struct IsScalar<Unit<Derived, T>>: std::true_type {};
template<class T> struct IsScalar<Deg<T>>: std::true_type {}; template<class T> struct IsScalar<Deg<T>>: std::true_type {};
template<class T> struct IsScalar<Rad<T>>: std::true_type {}; template<class T> struct IsScalar<Rad<T>>: std::true_type {};
template<> struct IsScalar<Nanoseconds<Long>>: std::true_type {};
template<> struct IsScalar<Seconds<Float>>: std::true_type {};
#endif #endif
/** /**
@ -162,7 +165,8 @@ template<class T> struct IsVector<Color4<T>>: std::true_type {};
@m_since{2019,10} @m_since{2019,10}
Equivalent to @ref std::true_type for all integral scalar and vector types Equivalent to @ref std::true_type for all integral scalar and vector types
supported by Magnum math; equivalent to @ref std::false_type otherwise. supported by Magnum math including @ref Magnum::Nanoseconds; equivalent to
@ref std::false_type otherwise.
Unlike @ref std::is_integral this is @ref std::false_type for @cpp bool @ce. Unlike @ref std::is_integral this is @ref std::false_type for @cpp bool @ce.
@see @ref IsFloatingPoint, @ref IsScalar, @ref IsVector @see @ref IsFloatingPoint, @ref IsScalar, @ref IsVector
@ -189,6 +193,7 @@ template<> struct IsIntegral<unsigned long>: std::true_type {};
template<> struct IsIntegral<long long>: std::true_type {}; template<> struct IsIntegral<long long>: std::true_type {};
template<> struct IsIntegral<unsigned long long>: std::true_type {}; template<> struct IsIntegral<unsigned long long>: std::true_type {};
template<std::size_t size, class T> struct IsIntegral<Vector<size, T>>: IsIntegral<T> {}; template<std::size_t size, class T> struct IsIntegral<Vector<size, T>>: IsIntegral<T> {};
template<> struct IsIntegral<Nanoseconds<Long>>: std::true_type {};
template<class T> struct IsIntegral<Vector2<T>>: IsIntegral<T> {}; template<class T> struct IsIntegral<Vector2<T>>: IsIntegral<T> {};
template<class T> struct IsIntegral<Vector3<T>>: IsIntegral<T> {}; template<class T> struct IsIntegral<Vector3<T>>: IsIntegral<T> {};
template<class T> struct IsIntegral<Vector4<T>>: IsIntegral<T> {}; template<class T> struct IsIntegral<Vector4<T>>: IsIntegral<T> {};
@ -202,8 +207,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 Half, @ref Deg and @ref Rad; types supported by Magnum math including @ref Half, @ref Deg, @ref Rad and
equivalent to @ref std::false_type otherwise. @ref Seconds; equivalent to @ref std::false_type otherwise.
@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
@ -228,6 +233,7 @@ template<class T> struct IsFloatingPoint<Color4<T>>: IsFloatingPoint<T> {};
template<template<class> class Derived, class T> struct IsFloatingPoint<Unit<Derived, T>>: IsFloatingPoint<T> {}; template<template<class> class Derived, class T> struct IsFloatingPoint<Unit<Derived, T>>: IsFloatingPoint<T> {};
template<class T> struct IsFloatingPoint<Deg<T>>: IsFloatingPoint<T> {}; template<class T> struct IsFloatingPoint<Deg<T>>: IsFloatingPoint<T> {};
template<class T> struct IsFloatingPoint<Rad<T>>: IsFloatingPoint<T> {}; template<class T> struct IsFloatingPoint<Rad<T>>: IsFloatingPoint<T> {};
template<> struct IsFloatingPoint<Seconds<Float>>: std::true_type {};
#endif #endif
/** /**
@ -235,9 +241,10 @@ template<class T> struct IsFloatingPoint<Rad<T>>: IsFloatingPoint<T> {};
@m_since{2019,10} @m_since{2019,10}
Equivalent to @ref std::true_type for scalar or vector types that have an Equivalent to @ref std::true_type for scalar or vector types that have an
unitless underlying type (i.e., not @ref Deg or @ref Rad); @ref std::false_type unitless underlying type (i.e., not @ref Deg, @ref Rad, @ref Nanoseconds or
otherwise. Some math functions such as @ref sqrt() or @ref log() work only with @ref Seconds); @ref std::false_type otherwise. Some math functions such as
unitless types because the resulting unit couldn't be expressed otherwise. @ref sqrt() or @ref log() work only with unitless types because the resulting
unit couldn't be expressed otherwise.
@see @ref IsScalar, @ref IsVector @see @ref IsScalar, @ref IsVector
*/ */
template<class T> struct IsUnitless template<class T> struct IsUnitless
@ -248,6 +255,8 @@ template<class T> struct IsUnitless
template<template<class> class Derived, class T> struct IsUnitless<Unit<Derived, T>>: std::false_type {}; template<template<class> class Derived, class T> struct IsUnitless<Unit<Derived, T>>: std::false_type {};
template<class T> struct IsUnitless<Deg<T>>: std::false_type {}; template<class T> struct IsUnitless<Deg<T>>: std::false_type {};
template<class T> struct IsUnitless<Rad<T>>: std::false_type {}; template<class T> struct IsUnitless<Rad<T>>: std::false_type {};
template<class T> struct IsUnitless<Nanoseconds<T>>: std::false_type {};
template<class T> struct IsUnitless<Seconds<T>>: std::false_type {};
namespace Implementation { namespace Implementation {
template<class T> struct UnderlyingType { template<class T> struct UnderlyingType {
@ -259,6 +268,8 @@ namespace Implementation {
}; };
template<class T> struct UnderlyingType<Deg<T>> { typedef T Type; }; template<class T> struct UnderlyingType<Deg<T>> { typedef T Type; };
template<class T> struct UnderlyingType<Rad<T>> { typedef T Type; }; template<class T> struct UnderlyingType<Rad<T>> { typedef T Type; };
template<class T> struct UnderlyingType<Nanoseconds<T>> { typedef T Type; };
template<class T> struct UnderlyingType<Seconds<T>> { typedef T Type; };
template<std::size_t size, class T> struct UnderlyingType<Vector<size, T>> { template<std::size_t size, class T> struct UnderlyingType<Vector<size, T>> {
typedef T Type; typedef T Type;
}; };

Loading…
Cancel
Save