Browse Source

Math: base class for units.

pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
f1e3453517
  1. 1
      src/Math/CMakeLists.txt
  2. 2
      src/Math/Math.h
  3. 1
      src/Math/Test/CMakeLists.txt
  4. 138
      src/Math/Test/UnitTest.cpp
  5. 147
      src/Math/Unit.h

1
src/Math/CMakeLists.txt

@ -15,6 +15,7 @@ set(MagnumMath_HEADERS
Quaternion.h
RectangularMatrix.h
Swizzle.h
Unit.h
Vector.h
Vector2.h
Vector3.h

2
src/Math/Math.h

@ -41,6 +41,8 @@ template<class> class Quaternion;
template<std::size_t, std::size_t, class> class RectangularMatrix;
template<template<class> class, class> class Unit;
template<std::size_t, class> class Vector;
template<class> class Vector2;
template<class> class Vector3;

1
src/Math/Test/CMakeLists.txt

@ -16,6 +16,7 @@ corrade_add_test(MathMatrix3Test Matrix3Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathMatrix4Test Matrix4Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathSwizzleTest SwizzleTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathUnitTest UnitTest.cpp)
corrade_add_test(MathComplexTest ComplexTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathDualTest DualTest.cpp)

138
src/Math/Test/UnitTest.cpp

@ -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)

147
src/Math/Unit.h

@ -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…
Cancel
Save