mirror of https://github.com/mosra/magnum.git
5 changed files with 289 additions and 0 deletions
@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "Math/Unit.h" |
||||
|
||||
namespace Magnum { namespace Math { namespace Test { |
||||
|
||||
class UnitTest: public Corrade::TestSuite::Tester { |
||||
public: |
||||
explicit UnitTest(); |
||||
|
||||
void construct(); |
||||
void constructDefault(); |
||||
void constructConversion(); |
||||
void compare(); |
||||
|
||||
void negated(); |
||||
void addSubtract(); |
||||
void multiplyDivide(); |
||||
}; |
||||
|
||||
UnitTest::UnitTest() { |
||||
addTests(&UnitTest::construct, |
||||
&UnitTest::constructDefault, |
||||
&UnitTest::constructConversion, |
||||
&UnitTest::compare, |
||||
|
||||
&UnitTest::negated, |
||||
&UnitTest::addSubtract, |
||||
&UnitTest::multiplyDivide); |
||||
} |
||||
|
||||
template<class> struct Sec_; |
||||
typedef Unit<Sec_, float> Sec; |
||||
typedef Unit<Sec_, double> Secd; |
||||
|
||||
inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, Sec value) { |
||||
return debug << float(value); |
||||
} |
||||
|
||||
void UnitTest::construct() { |
||||
constexpr Sec a(25.0f); |
||||
CORRADE_COMPARE(float(a), 25.0f); |
||||
} |
||||
|
||||
void UnitTest::constructDefault() { |
||||
constexpr Sec b; |
||||
CORRADE_COMPARE(b, Sec(0.0f)); |
||||
} |
||||
|
||||
void UnitTest::constructConversion() { |
||||
constexpr Secd a(25.0); |
||||
constexpr Sec b(a); |
||||
CORRADE_COMPARE(b, Sec(25.0f)); |
||||
} |
||||
|
||||
void UnitTest::compare() { |
||||
CORRADE_VERIFY(Sec(25.0f + MathTypeTraits<float>::epsilon()/2) == Sec(25.0f)); |
||||
CORRADE_VERIFY(Sec(25.0f + MathTypeTraits<float>::epsilon()*2) != Sec(25.0f)); |
||||
|
||||
constexpr bool c = Sec(3.0f) < Sec(3.0f); |
||||
constexpr bool d = Sec(3.0f) <= Sec(3.0f); |
||||
constexpr bool e = Sec(3.0f) >= Sec(3.0f); |
||||
constexpr bool f = Sec(3.0f) > Sec(3.0f); |
||||
CORRADE_VERIFY(!c); |
||||
CORRADE_VERIFY(d); |
||||
CORRADE_VERIFY(e); |
||||
CORRADE_VERIFY(!f); |
||||
|
||||
constexpr bool h = Sec(2.0f) < Sec(3.0f); |
||||
constexpr bool i = Sec(2.0f) <= Sec(3.0f); |
||||
constexpr bool j = Sec(3.0f) >= Sec(2.0f); |
||||
constexpr bool k = Sec(3.0f) > Sec(2.0f); |
||||
CORRADE_VERIFY(h); |
||||
CORRADE_VERIFY(i); |
||||
CORRADE_VERIFY(j); |
||||
CORRADE_VERIFY(k); |
||||
|
||||
constexpr bool l = Sec(3.0f) < Sec(2.0f); |
||||
constexpr bool m = Sec(3.0f) <= Sec(2.0f); |
||||
constexpr bool n = Sec(2.0f) >= Sec(3.0f); |
||||
constexpr bool o = Sec(2.0f) > Sec(3.0f); |
||||
CORRADE_VERIFY(!l); |
||||
CORRADE_VERIFY(!m); |
||||
CORRADE_VERIFY(!n); |
||||
CORRADE_VERIFY(!o); |
||||
} |
||||
|
||||
void UnitTest::negated() { |
||||
constexpr Sec a(25.0f); |
||||
constexpr Sec b(-a); |
||||
CORRADE_COMPARE(b, Sec(-25.0f)); |
||||
} |
||||
|
||||
void UnitTest::addSubtract() { |
||||
constexpr Sec a(3.0f); |
||||
constexpr Sec b(-4.0f); |
||||
constexpr Sec c(-1.0f); |
||||
|
||||
constexpr Sec d = a + b; |
||||
constexpr Sec e = c - a; |
||||
CORRADE_COMPARE(d, c); |
||||
CORRADE_COMPARE(e, b); |
||||
} |
||||
|
||||
void UnitTest::multiplyDivide() { |
||||
constexpr Sec a(3.0f); |
||||
constexpr Sec b(-4.5f); |
||||
constexpr Sec c(5.0f); |
||||
|
||||
constexpr Sec d = a*-1.5f; |
||||
constexpr Sec e = -1.5f*a; |
||||
constexpr Sec f = b/-1.5f; |
||||
CORRADE_COMPARE(d, b); |
||||
CORRADE_COMPARE(e, b); |
||||
CORRADE_COMPARE(f, a); |
||||
|
||||
constexpr float g = b/a; |
||||
CORRADE_COMPARE(g, -1.5f); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Math::Test::UnitTest) |
||||
@ -0,0 +1,147 @@
|
||||
#ifndef Magnum_Math_Unit_h |
||||
#define Magnum_Math_Unit_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Math::Unit |
||||
*/ |
||||
|
||||
#include "Math/MathTypeTraits.h" |
||||
|
||||
namespace Magnum { namespace Math { |
||||
|
||||
/**
|
||||
@brief Base class for units |
||||
@tparam T Underlying data type |
||||
|
||||
@see Deg, Rad |
||||
*/ |
||||
template<template<class> class Derived, class T> class Unit { |
||||
template<template<class> class, class> friend class Unit; |
||||
|
||||
public: |
||||
typedef T Type; /**< @brief Underlying data type */ |
||||
|
||||
/** @brief Default constructor */ |
||||
inline constexpr /*implicit*/ Unit(): value(T(0)) {} |
||||
|
||||
/** @brief Explicit conversion from unitless type */ |
||||
inline constexpr explicit Unit(T value): value(value) {} |
||||
|
||||
/** @brief Construct from another underlying type */ |
||||
template<class U> inline constexpr explicit Unit(Unit<Derived, U> value): value(value.value) {} |
||||
|
||||
/** @brief Explicit conversion to underlying type */ |
||||
inline constexpr explicit operator T() const { return value; } |
||||
|
||||
/** @brief Equality comparison */ |
||||
inline constexpr bool operator==(Unit<Derived, T> other) const { |
||||
return MathTypeTraits<T>::equals(value, other.value); |
||||
} |
||||
|
||||
/** @brief Non-equality comparison */ |
||||
inline constexpr bool operator!=(Unit<Derived, T> other) const { |
||||
return !operator==(other); |
||||
} |
||||
|
||||
/** @brief Less than comparison */ |
||||
inline constexpr bool operator<(Unit<Derived, T> other) const { |
||||
return value < other.value; |
||||
} |
||||
|
||||
/** @brief Greater than comparison */ |
||||
inline constexpr bool operator>(Unit<Derived, T> other) const { |
||||
return value > other.value; |
||||
} |
||||
|
||||
/** @brief Less than or equal comparison */ |
||||
inline constexpr bool operator<=(Unit<Derived, T> other) const { |
||||
return !operator>(other); |
||||
} |
||||
|
||||
/** @brief Greater than or equal comparison */ |
||||
inline constexpr bool operator>=(Unit<Derived, T> other) const { |
||||
return !operator<(other); |
||||
} |
||||
|
||||
/** @brief Negated value */ |
||||
inline constexpr Unit<Derived, T> operator-() const { |
||||
return Unit<Derived, T>(-value); |
||||
} |
||||
|
||||
/** @brief Add and assign value */ |
||||
inline Unit<Derived, T>& operator+=(Unit<Derived, T> other) { |
||||
value += other.value; |
||||
return *this; |
||||
} |
||||
|
||||
/** @brief Add value */ |
||||
inline constexpr Unit<Derived, T> operator+(Unit<Derived, T> other) const { |
||||
return Unit<Derived, T>(value + other.value); |
||||
} |
||||
|
||||
/** @brief Subtract and assign value */ |
||||
inline Unit<Derived, T>& operator-=(Unit<Derived, T> other) { |
||||
value -= other.value; |
||||
return *this; |
||||
} |
||||
|
||||
/** @brief Subtract value */ |
||||
inline constexpr Unit<Derived, T> operator-(Unit<Derived, T> other) const { |
||||
return Unit<Derived, T>(value - other.value); |
||||
} |
||||
|
||||
/** @brief Multiply with number and assign */ |
||||
inline Unit<Derived, T>& operator*=(T number) { |
||||
value *= number; |
||||
return *this; |
||||
} |
||||
|
||||
/** @brief Multiply with number */ |
||||
inline constexpr Unit<Derived, T> operator*(T number) const { |
||||
return Unit<Derived, T>(value*number); |
||||
} |
||||
|
||||
/** @brief Divide with number and assign */ |
||||
inline Unit<Derived, T>& operator/=(T number) { |
||||
value /= number; |
||||
return *this; |
||||
} |
||||
|
||||
/** @brief Divide with number */ |
||||
inline constexpr Unit<Derived, T> operator/(T number) const { |
||||
return Unit<Derived, T>(value/number); |
||||
} |
||||
|
||||
/** @brief Ratio of two values */ |
||||
inline constexpr T operator/(Unit<Derived, T> other) const { |
||||
return value/other.value; |
||||
} |
||||
|
||||
private: |
||||
T value; |
||||
}; |
||||
|
||||
/** @relates Unit
|
||||
@brief Multiply number with value |
||||
*/ |
||||
template<template<class> class Derived, class T> inline constexpr Unit<Derived, T> operator*(typename std::common_type<T>::type number, const Unit<Derived, T>& value) { |
||||
return value*number; |
||||
} |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue