Browse Source

Math: C++14 constexpr in Vector.

pull/276/head
Vladimír Vondruš 12 years ago
parent
commit
7f662f2c3e
  1. 226
      src/Magnum/Math/Test/VectorTest.cpp
  2. 212
      src/Magnum/Math/Vector.h

226
src/Magnum/Math/Test/VectorTest.cpp

@ -245,8 +245,8 @@ void VectorTest::data() {
/* Pointer chasings, i.e. *(b.data()[3]), are not possible */
constexpr Vector4 a(1.0f, 2.0f, -3.0f, 4.5f);
constexpr Float f = a[3];
constexpr Float g = *a.data();
constexpr auto f = a[3];
constexpr auto g = *a.data();
CORRADE_COMPARE(f, 4.5f);
CORRADE_COMPARE(g, 1.0f);
}
@ -261,101 +261,145 @@ void VectorTest::compare() {
void VectorTest::compareComponentWise() {
typedef BoolVector<3> BoolVector3;
CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) < Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x1));
CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) <= Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x3));
CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) >= Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x6));
CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) > Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x4));
constexpr auto a = Vector3(1.0f, -1.0f, 5.0f) < Vector3(1.1f, -1.0f, 3.0f);
constexpr auto b = Vector3(1.0f, -1.0f, 5.0f) <= Vector3(1.1f, -1.0f, 3.0f);
constexpr auto c = Vector3(1.0f, -1.0f, 5.0f) >= Vector3(1.1f, -1.0f, 3.0f);
constexpr auto d = Vector3(1.0f, -1.0f, 5.0f) > Vector3(1.1f, -1.0f, 3.0f);
CORRADE_COMPARE(a, BoolVector3(0x1));
CORRADE_COMPARE(b, BoolVector3(0x3));
CORRADE_COMPARE(c, BoolVector3(0x6));
CORRADE_COMPARE(d, BoolVector3(0x4));
}
void VectorTest::negative() {
CORRADE_COMPARE(-Vector4(1.0f, -3.0f, 5.0f, -10.0f), Vector4(-1.0f, 3.0f, -5.0f, 10.0f));
constexpr auto a = -Vector4(1.0f, -3.0f, 5.0f, -10.0f);
CORRADE_COMPARE(a, Vector4(-1.0f, 3.0f, -5.0f, 10.0f));
}
void VectorTest::addSubtract() {
Vector4 a(1.0f, -3.0f, 5.0f, -10.0f);
Vector4 b(7.5f, 33.0f, -15.0f, 0.0f);
Vector4 c(8.5f, 30.0f, -10.0f, -10.0f);
constexpr Vector4 a(1.0f, -3.0f, 5.0f, -10.0f);
constexpr Vector4 b(7.5f, 33.0f, -15.0f, 0.0f);
constexpr Vector4 c(8.5f, 30.0f, -10.0f, -10.0f);
constexpr auto d = a + b;
constexpr auto e = c - b;
CORRADE_COMPARE(a + b, c);
CORRADE_COMPARE(c - b, a);
CORRADE_COMPARE(d, c);
CORRADE_COMPARE(e, a);
}
void VectorTest::multiplyDivide() {
Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f);
Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f);
constexpr Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f);
constexpr Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f);
CORRADE_COMPARE(vector*-1.5f, multiplied);
CORRADE_COMPARE(-1.5f*vector, multiplied);
CORRADE_COMPARE(multiplied/-1.5f, vector);
constexpr auto a = vector*-1.5f;
constexpr auto b = -1.5f*vector;
constexpr auto c = multiplied/-1.5f;
CORRADE_COMPARE(a, multiplied);
CORRADE_COMPARE(b, multiplied);
CORRADE_COMPARE(c, vector);
/* Divide vector with number and invert */
Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f);
Vector4 result(1.0f, 0.5f, -0.25f, 0.125f);
CORRADE_COMPARE(1.0f/divisor, result);
constexpr Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f);
constexpr auto d = 1.0f/divisor;
CORRADE_COMPARE(d, Vector4(1.0f, 0.5f, -0.25f, 0.125f));
}
void VectorTest::multiplyDivideIntegral() {
Vector4i vector(32, 10, -6, 2);
Vector4i multiplied(-48, -15, 9, -3);
constexpr Vector4i vector(32, 10, -6, 2);
constexpr Vector4i multiplied(-48, -15, 9, -3);
CORRADE_COMPARE(vector*-1.5f, multiplied);
CORRADE_COMPARE(-1.5f*vector, multiplied);
constexpr auto a = vector*-1.5f;
constexpr auto b = -1.5f*vector;
CORRADE_COMPARE(multiplied/-1.5f, vector);
CORRADE_COMPARE(a, multiplied);
CORRADE_COMPARE(b, multiplied);
constexpr auto c = multiplied/-1.5f;
CORRADE_COMPARE(c, vector);
/* Using integer vector as divisor is not supported */
}
void VectorTest::multiplyDivideComponentWise() {
Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f);
Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f);
Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f);
constexpr Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f);
constexpr Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f);
constexpr Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f);
constexpr auto a = vec*multiplier;
constexpr auto b = multiplied/multiplier;
CORRADE_COMPARE(vec*multiplier, multiplied);
CORRADE_COMPARE(multiplied/multiplier, vec);
CORRADE_COMPARE(a, multiplied);
CORRADE_COMPARE(b, vec);
}
void VectorTest::multiplyDivideComponentWiseIntegral() {
Vector4i vec(7, 2, -16, -1);
Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f);
Vector4i multiplied(14, -3, -8, -10);
constexpr Vector4i vec(7, 2, -16, -1);
constexpr Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f);
constexpr Vector4i multiplied(14, -3, -8, -10);
constexpr auto a = vec*multiplier;
constexpr auto b = multiplier*vec;
CORRADE_COMPARE(a, multiplied);
CORRADE_COMPARE(b, multiplied);
CORRADE_COMPARE(vec*multiplier, multiplied);
CORRADE_COMPARE(multiplier*vec, multiplied);
constexpr auto c = multiplied/multiplier;
CORRADE_COMPARE(multiplied/multiplier, vec);
CORRADE_COMPARE(c, vec);
/* Using integer vector as divisor is not supported */
}
void VectorTest::modulo() {
typedef Math::Vector<2, Int> Vector2i;
const Vector2i a(4, 13);
const Vector2i b(2, 5);
CORRADE_COMPARE(a % 2, Vector2i(0, 1));
CORRADE_COMPARE(a % b, Vector2i(0, 3));
constexpr Vector2i a(4, 13);
constexpr Vector2i b(2, 5);
constexpr auto c = a % 2;
constexpr auto d = a % b;
CORRADE_COMPARE(c, Vector2i(0, 1));
CORRADE_COMPARE(d, Vector2i(0, 3));
}
void VectorTest::bitwise() {
typedef Math::Vector<2, Int> Vector2i;
const Vector2i a(85, 240);
const Vector2i b(170, 85);
CORRADE_COMPARE(~a, Vector2i(-86, -241));
CORRADE_COMPARE(a & b, Vector2i(0, 80));
CORRADE_COMPARE(a | b, Vector2i(255, 245));
CORRADE_COMPARE(a ^ b, Vector2i(255, 165));
constexpr Vector2i a(85, 240);
constexpr Vector2i b(170, 85);
constexpr auto c = ~a;
constexpr auto d = a & b;
constexpr auto e = a | b;
constexpr auto f = a ^ b;
CORRADE_COMPARE(c, Vector2i(-86, -241));
CORRADE_COMPARE(d, Vector2i(0, 80));
CORRADE_COMPARE(e, Vector2i(255, 245));
CORRADE_COMPARE(f, Vector2i(255, 165));
constexpr Vector2i g(7, 32);
const Vector2i c(7, 32);
CORRADE_COMPARE(c << 2, Vector2i(28, 128));
CORRADE_COMPARE(c >> 2, Vector2i(1, 8));
constexpr auto h = g << 2;
constexpr auto i = g >> 2;
CORRADE_COMPARE(h, Vector2i(28, 128));
CORRADE_COMPARE(i, Vector2i(1, 8));
}
void VectorTest::dot() {
CORRADE_COMPARE(Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f);
constexpr auto a = Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f});
CORRADE_COMPARE(a, 15.25f);
}
void VectorTest::dotSelf() {
CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).dot(), 30.0f);
constexpr auto a = Vector4(1.0f, 2.0f, 3.0f, 4.0f).dot();
CORRADE_COMPARE(a, 30.0f);
}
void VectorTest::length() {
@ -379,11 +423,13 @@ void VectorTest::resized() {
}
void VectorTest::sum() {
CORRADE_COMPARE(Vector3(1.0f, 2.0f, 4.0f).sum(), 7.0f);
constexpr auto a = Vector3(1.0f, 2.0f, 4.0f).sum();
CORRADE_COMPARE(a, 7.0f);
}
void VectorTest::product() {
CORRADE_COMPARE(Vector3(1.0f, 2.0f, 3.0f).product(), 6.0f);
constexpr auto a = Vector3(1.0f, 2.0f, 3.0f).product();
CORRADE_COMPARE(a, 6.0f);
}
void VectorTest::min() {
@ -522,38 +568,60 @@ void VectorTest::subclass() {
const Float cdata[] = {1.0f, -2.0f};
CORRADE_COMPARE(Vec2::from(cdata), Vec2(1.0f, -2.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f), Vec2(-1.0f, 2.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f), Vec2(-3.0f, 8.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*2.0f, Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(2.0f*Vec2(-2.0f, 5.0f), Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/0.5f, Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(2.0f/Vec2(-2.0f, 5.0f), Vec2(-1.0f, 0.4f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f), Vec2(-3.0f, -10.0f));
CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f), Vec2(-3.0f, -10.0f));
constexpr auto a = Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f);
constexpr auto b = Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f);
CORRADE_COMPARE(a, Vec2(-1.0f, 2.0f));
CORRADE_COMPARE(b, Vec2(-3.0f, 8.0f));
constexpr auto c = Vec2(-2.0f, 5.0f)*2.0f;
constexpr auto d = 2.0f*Vec2(-2.0f, 5.0f);
constexpr auto e = Vec2(-2.0f, 5.0f)/0.5f;
constexpr auto f = 2.0f/Vec2(-2.0f, 5.0f);
CORRADE_COMPARE(c, Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(d, Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(e, Vec2(-4.0f, 10.0f));
CORRADE_COMPARE(f, Vec2(-1.0f, 0.4f));
constexpr auto g = Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f);
constexpr auto h = Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f);
CORRADE_COMPARE(g, Vec2(-3.0f, -10.0f));
CORRADE_COMPARE(h, Vec2(-3.0f, -10.0f));
/* Modulo operations */
CORRADE_COMPARE(Vec2i(4, 13) % 2, Vec2i(0, 1));
CORRADE_COMPARE(Vec2i(4, 13) % Vec2i(2, 5), Vec2i(0, 3));
constexpr auto i = Vec2i(4, 13) % 2;
constexpr auto j = Vec2i(4, 13) % Vec2i(2, 5);
CORRADE_COMPARE(i, Vec2i(0, 1));
CORRADE_COMPARE(j, Vec2i(0, 3));
/* Bitwise operations */
CORRADE_COMPARE(~Vec2i(85, 240), Vec2i(-86, -241));
CORRADE_COMPARE(Vec2i(85, 240) & Vec2i(170, 85), Vec2i(0, 80));
CORRADE_COMPARE(Vec2i(85, 240) | Vec2i(170, 85), Vec2i(255, 245));
CORRADE_COMPARE(Vec2i(85, 240) ^ Vec2i(170, 85), Vec2i(255, 165));
CORRADE_COMPARE(Vec2i(7, 32) << 2, Vec2i(28, 128));
CORRADE_COMPARE(Vec2i(7, 32) >> 2, Vec2i(1, 8));
constexpr auto k = ~Vec2i(85, 240);
constexpr auto l = Vec2i(85, 240) & Vec2i(170, 85);
constexpr auto m = Vec2i(85, 240) | Vec2i(170, 85);
constexpr auto n = Vec2i(85, 240) ^ Vec2i(170, 85);
CORRADE_COMPARE(k, Vec2i(-86, -241));
CORRADE_COMPARE(l, Vec2i(0, 80));
CORRADE_COMPARE(m, Vec2i(255, 245));
CORRADE_COMPARE(n, Vec2i(255, 165));
constexpr auto o = Vec2i(7, 32) << 2;
constexpr auto p = Vec2i(7, 32) >> 2;
CORRADE_COMPARE(o, Vec2i(28, 128));
CORRADE_COMPARE(p, Vec2i(1, 8));
/* Integral multiplication/division */
CORRADE_COMPARE(Vec2i(2, 4)*1.5f, Vec2i(3, 6));
CORRADE_COMPARE(1.5f*Vec2i(2, 4), Vec2i(3, 6));
CORRADE_COMPARE(Vec2i(2, 4)/(2.0f/3.0f), Vec2i(3, 6));
CORRADE_COMPARE(Vec2i(2, 4)*Vec2(-1.5f, 0.5f), Vec2i(-3, 2));
CORRADE_COMPARE(Vec2(-1.5f, 0.5f)*Vec2i(2, 4), Vec2i(-3, 2));
CORRADE_COMPARE(Vec2i(2, 4)/Vec2(-2.0f/3.0f, 2.0f), Vec2i(-3, 2));
constexpr auto q = Vec2i(2, 4)*1.5f;
constexpr auto r = 1.5f*Vec2i(2, 4);
constexpr auto s = Vec2i(2, 4)/(2.0f/3.0f);
CORRADE_COMPARE(q, Vec2i(3, 6));
CORRADE_COMPARE(r, Vec2i(3, 6));
CORRADE_COMPARE(s, Vec2i(3, 6));
constexpr auto t = Vec2i(2, 4)*Vec2(-1.5f, 0.5f);
constexpr auto u = Vec2(-1.5f, 0.5f)*Vec2i(2, 4);
constexpr auto v = Vec2i(2, 4)/Vec2(-2.0f/3.0f, 2.0f);
CORRADE_COMPARE(t, Vec2i(-3, 2));
CORRADE_COMPARE(u, Vec2i(-3, 2));
CORRADE_COMPARE(v, Vec2i(-3, 2));
/* Functions */
CORRADE_COMPARE(Vec2(3.0f, 0.0f).normalized(), Vec2(1.0f, 0.0f));

212
src/Magnum/Math/Vector.h

@ -91,7 +91,7 @@ template<std::size_t size, class T> class Vector {
* @ref Vector2::perpendicular()
* @todoc Explicit reference when Doxygen can handle const
*/
static T dot(const Vector<size, T>& a, const Vector<size, T>& b) {
constexpr static T dot(const Vector<size, T>& a, const Vector<size, T>& b) {
return (a*b).sum();
}
@ -155,7 +155,7 @@ template<std::size_t size, class T> class Vector {
constexpr Vector(const Vector<size, T>&) = default;
/** @brief Assignment operator */
Vector<size, T>& operator=(const Vector<size, T>&) = default;
constexpr Vector<size, T>& operator=(const Vector<size, T>&) = default;
/** @brief Convert vector to external representation */
template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::to(std::declval<Vector<size, T>>()))> constexpr explicit operator U() const {
@ -168,7 +168,7 @@ template<std::size_t size, class T> class Vector {
*
* @see @ref operator[]()
*/
T* data() { return _data; }
constexpr T* data() { return _data; }
constexpr const T* data() const { return _data; } /**< @overload */
/**
@ -176,7 +176,7 @@ template<std::size_t size, class T> class Vector {
*
* @see @ref data()
*/
T& operator[](std::size_t pos) { return _data[pos]; }
constexpr T& operator[](std::size_t pos) { return _data[pos]; }
constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */
/** @brief Equality comparison */
@ -193,16 +193,16 @@ template<std::size_t size, class T> class Vector {
}
/** @brief Component-wise less than */
BoolVector<size> operator<(const Vector<size, T>& other) const;
constexpr BoolVector<size> operator<(const Vector<size, T>& other) const;
/** @brief Component-wise less than or equal */
BoolVector<size> operator<=(const Vector<size, T>& other) const;
constexpr BoolVector<size> operator<=(const Vector<size, T>& other) const;
/** @brief Component-wise greater than or equal */
BoolVector<size> operator>=(const Vector<size, T>& other) const;
constexpr BoolVector<size> operator>=(const Vector<size, T>& other) const;
/** @brief Component-wise greater than */
BoolVector<size> operator>(const Vector<size, T>& other) const;
constexpr BoolVector<size> operator>(const Vector<size, T>& other) const;
/**
* @brief Whether the vector is zero
@ -236,7 +236,7 @@ template<std::size_t size, class T> class Vector {
* @f]
* @see @ref Vector2::perpendicular()
*/
Vector<size, T> operator-() const;
constexpr Vector<size, T> operator-() const;
/**
* @brief Add and assign vector
@ -245,7 +245,7 @@ template<std::size_t size, class T> class Vector {
* \boldsymbol a_i = \boldsymbol a_i + \boldsymbol b_i
* @f]
*/
Vector<size, T>& operator+=(const Vector<size, T>& other) {
constexpr Vector<size, T>& operator+=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
_data[i] += other._data[i];
@ -257,7 +257,7 @@ template<std::size_t size, class T> class Vector {
*
* @see @ref operator+=(), @ref sum()
*/
Vector<size, T> operator+(const Vector<size, T>& other) const {
constexpr Vector<size, T> operator+(const Vector<size, T>& other) const {
return Vector<size, T>(*this) += other;
}
@ -268,7 +268,7 @@ template<std::size_t size, class T> class Vector {
* \boldsymbol a_i = \boldsymbol a_i - \boldsymbol b_i
* @f]
*/
Vector<size, T>& operator-=(const Vector<size, T>& other) {
constexpr Vector<size, T>& operator-=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
_data[i] -= other._data[i];
@ -280,7 +280,7 @@ template<std::size_t size, class T> class Vector {
*
* @see @ref operator-=()
*/
Vector<size, T> operator-(const Vector<size, T>& other) const {
constexpr Vector<size, T> operator-(const Vector<size, T>& other) const {
return Vector<size, T>(*this) -= other;
}
@ -293,7 +293,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref operator*=(const Vector<size, T>&),
* @ref operator*=(Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T>& operator*=(T number) {
constexpr Vector<size, T>& operator*=(T number) {
for(std::size_t i = 0; i != size; ++i)
_data[i] *= number;
@ -307,7 +307,7 @@ template<std::size_t size, class T> class Vector {
* @ref operator*=(T), operator*(T, const Vector<size, T>&),
* @ref operator*(const Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T> operator*(T number) const {
constexpr Vector<size, T> operator*(T number) const {
return Vector<size, T>(*this) *= number;
}
@ -320,7 +320,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref operator/=(const Vector<size, T>&),
* @ref operator/=(Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T>& operator/=(T number) {
constexpr Vector<size, T>& operator/=(T number) {
for(std::size_t i = 0; i != size; ++i)
_data[i] /= number;
@ -334,7 +334,7 @@ template<std::size_t size, class T> class Vector {
* @ref operator/=(T), operator/(T, const Vector<size, T>&),
* @ref operator/(const Vector<size, Integral>&, FloatingPoint)
*/
Vector<size, T> operator/(T number) const {
constexpr Vector<size, T> operator/(T number) const {
return Vector<size, T>(*this) /= number;
}
@ -347,7 +347,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref operator*=(T),
* @ref operator*=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T>& operator*=(const Vector<size, T>& other) {
constexpr Vector<size, T>& operator*=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
_data[i] *= other._data[i];
@ -361,7 +361,7 @@ template<std::size_t size, class T> class Vector {
* @ref operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&),
* @ref product()
*/
Vector<size, T> operator*(const Vector<size, T>& other) const {
constexpr Vector<size, T> operator*(const Vector<size, T>& other) const {
return Vector<size, T>(*this) *= other;
}
@ -374,7 +374,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref operator/=(T),
* @ref operator/=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T>& operator/=(const Vector<size, T>& other) {
constexpr Vector<size, T>& operator/=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i)
_data[i] /= other._data[i];
@ -387,7 +387,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref operator/(T) const, @ref operator/=(const Vector<size, T>&),
* @ref operator/(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
*/
Vector<size, T> operator/(const Vector<size, T>& other) const {
constexpr Vector<size, T> operator/(const Vector<size, T>& other) const {
return Vector<size, T>(*this) /= other;
}
@ -401,7 +401,7 @@ template<std::size_t size, class T> class Vector {
* @see @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref isNormalized()
*/
T dot() const { return dot(*this, *this); }
constexpr T dot() const { return dot(*this, *this); }
/**
* @brief %Vector length
@ -479,14 +479,14 @@ template<std::size_t size, class T> class Vector {
*
* @see @ref operator+()
*/
T sum() const;
constexpr T sum() const;
/**
* @brief Product of values in the vector
*
* @see @ref operator*(const Vector<size, T>&) const
*/
T product() const;
constexpr T product() const;
/**
* @brief Minimal value in the vector
@ -517,7 +517,7 @@ template<std::size_t size, class T> class Vector {
Same as @ref Vector::operator*(T) const.
*/
template<std::size_t size, class T> inline Vector<size, T> operator*(
template<std::size_t size, class T> inline constexpr Vector<size, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT
T
#else
@ -536,7 +536,7 @@ template<std::size_t size, class T> inline Vector<size, T> operator*(
@f]
@see @ref Vector::operator/(T) const
*/
template<std::size_t size, class T> inline Vector<size, T> operator/(
template<std::size_t size, class T> inline constexpr Vector<size, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT
T
#else
@ -544,7 +544,7 @@ template<std::size_t size, class T> inline Vector<size, T> operator/(
#endif
number, const Vector<size, T>& vector)
{
Vector<size, T> out;
Vector<size, T> out{};
for(std::size_t i = 0; i != size; ++i)
out[i] = number/vector[i];
@ -557,7 +557,7 @@ template<std::size_t size, class T> inline Vector<size, T> operator/(
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -573,7 +573,7 @@ operator%=(Vector<size, Integral>& a, Integral b) {
/** @relates Vector
@brief Modulo of integral vector
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -589,7 +589,7 @@ operator%(const Vector<size, Integral>& a, Integral b) {
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -605,7 +605,7 @@ operator%=(Vector<size, Integral>& a, const Vector<size, Integral>& b) {
/** @relates Vector
@brief Modulo of two integral vectors
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -619,14 +619,14 @@ operator%(const Vector<size, Integral>& a, const Vector<size, Integral>& b) {
/** @relates Vector
@brief Bitwise NOT of integral vector
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
typename std::enable_if<std::is_integral<Integral>::value, Vector<size, Integral>>::type
#endif
operator~(const Vector<size, Integral>& vector) {
Vector<size, Integral> out;
Vector<size, Integral> out{};
for(std::size_t i = 0; i != size; ++i)
out[i] = ~vector[i];
@ -639,7 +639,7 @@ operator~(const Vector<size, Integral>& vector) {
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -655,7 +655,7 @@ operator&=(Vector<size, Integral>& a, const Vector<size, Integral>& b) {
/** @relates Vector
@brief Bitwise AND of two integral vectors
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -671,7 +671,7 @@ operator&(const Vector<size, Integral>& a, const Vector<size, Integral>& b) {
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -687,7 +687,7 @@ operator|=(Vector<size, Integral>& a, const Vector<size, Integral>& b) {
/** @relates Vector
@brief Bitwise OR of two integral vectors
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -703,7 +703,7 @@ operator|(const Vector<size, Integral>& a, const Vector<size, Integral>& b) {
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -719,7 +719,7 @@ operator^=(Vector<size, Integral>& a, const Vector<size, Integral>& b) {
/** @relates Vector
@brief Bitwise XOR of two integral vectors
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -735,7 +735,7 @@ operator^(const Vector<size, Integral>& a, const Vector<size, Integral>& b) {
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -758,7 +758,7 @@ operator<<=(Vector<size, Integral>& vector,
/** @relates Vector
@brief Bitwise left shift of integral vector
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -781,7 +781,7 @@ operator<<(const Vector<size, Integral>& vector,
The computation is done in-place.
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -803,7 +803,7 @@ operator>>=(Vector<size, Integral>& vector,
/** @relates Vector
@brief Bitwise left shift of integral vector
*/
template<std::size_t size, class Integral> inline
template<std::size_t size, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -826,7 +826,7 @@ operator>>(const Vector<size, Integral>& vector,
Similar to @ref Vector::operator*=(T), except that the multiplication is done
in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -845,7 +845,7 @@ operator*=(Vector<size, Integral>& vector, FloatingPoint number) {
Similar to @ref Vector::operator*(T) const, except that the multiplication is
done in floating-point.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -861,7 +861,7 @@ operator*(const Vector<size, Integral>& vector, FloatingPoint number) {
Same as @ref operator*(const Vector<size, Integral>&, FloatingPoint).
*/
template<std::size_t size, class FloatingPoint, class Integral> inline
template<std::size_t size, class FloatingPoint, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -877,7 +877,7 @@ operator*(FloatingPoint number, const Vector<size, Integral>& vector) {
Similar to @ref Vector::operator/=(T), except that the division is done in
floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -896,7 +896,7 @@ operator/=(Vector<size, Integral>& vector, FloatingPoint number) {
Similar to @ref Vector::operator/(T) const, except that the division is done in
floating-point.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -913,7 +913,7 @@ operator/(const Vector<size, Integral>& vector, FloatingPoint number) {
Similar to @ref Vector::operator*=(const Vector<size, T>&), except that the
multiplication is done in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -934,7 +934,7 @@ the multiplication is done in floating-point. The result is always integral
vector, convert both arguments to the same floating-point type to have
floating-point result.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -950,7 +950,7 @@ operator*(const Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b)
Same as @ref operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&).
*/
template<std::size_t size, class FloatingPoint, class Integral> inline
template<std::size_t size, class FloatingPoint, class Integral> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -966,7 +966,7 @@ operator*(const Vector<size, FloatingPoint>& a, const Vector<size, Integral>& b)
Similar to @ref Vector::operator/=(const Vector<size, T>&), except that the
division is done in floating-point. The computation is done in-place.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>&
#else
@ -987,7 +987,7 @@ the division is done in floating-point. The result is always integral vector,
convert both arguments to the same floating-point type to have floating-point
result.
*/
template<std::size_t size, class Integral, class FloatingPoint> inline
template<std::size_t size, class Integral, class FloatingPoint> inline constexpr
#ifdef DOXYGEN_GENERATING_OUTPUT
Vector<size, Integral>
#else
@ -1038,54 +1038,54 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit
return *reinterpret_cast<const Type<T>*>(data); \
} \
\
Type<T>& operator=(const Type<T>& other) { \
constexpr Type<T>& operator=(const Type<T>& other) { \
Math::Vector<size, T>::operator=(other); \
return *this; \
} \
\
Type<T> operator-() const { \
constexpr Type<T> operator-() const { \
return Math::Vector<size, T>::operator-(); \
} \
Type<T>& operator+=(const Math::Vector<size, T>& other) { \
constexpr Type<T>& operator+=(const Math::Vector<size, T>& other) { \
Math::Vector<size, T>::operator+=(other); \
return *this; \
} \
Type<T> operator+(const Math::Vector<size, T>& other) const { \
constexpr Type<T> operator+(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator+(other); \
} \
Type<T>& operator-=(const Math::Vector<size, T>& other) { \
constexpr Type<T>& operator-=(const Math::Vector<size, T>& other) { \
Math::Vector<size, T>::operator-=(other); \
return *this; \
} \
Type<T> operator-(const Math::Vector<size, T>& other) const { \
constexpr Type<T> operator-(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator-(other); \
} \
Type<T>& operator*=(T number) { \
constexpr Type<T>& operator*=(T number) { \
Math::Vector<size, T>::operator*=(number); \
return *this; \
} \
Type<T> operator*(T number) const { \
constexpr Type<T> operator*(T number) const { \
return Math::Vector<size, T>::operator*(number); \
} \
Type<T>& operator/=(T number) { \
constexpr Type<T>& operator/=(T number) { \
Math::Vector<size, T>::operator/=(number); \
return *this; \
} \
Type<T> operator/(T number) const { \
constexpr Type<T> operator/(T number) const { \
return Math::Vector<size, T>::operator/(number); \
} \
Type<T>& operator*=(const Math::Vector<size, T>& other) { \
constexpr Type<T>& operator*=(const Math::Vector<size, T>& other) { \
Math::Vector<size, T>::operator*=(other); \
return *this; \
} \
Type<T> operator*(const Math::Vector<size, T>& other) const { \
constexpr Type<T> operator*(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator*(other); \
} \
Type<T>& operator/=(const Math::Vector<size, T>& other) { \
constexpr Type<T>& operator/=(const Math::Vector<size, T>& other) { \
Math::Vector<size, T>::operator/=(other); \
return *this; \
} \
Type<T> operator/(const Math::Vector<size, T>& other) const { \
constexpr Type<T> operator/(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator/(other); \
} \
\
@ -1103,99 +1103,99 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit
}
#define MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(size, Type) \
template<class T> inline Type<T> operator*(typename std::common_type<T>::type number, const Type<T>& vector) { \
template<class T> inline constexpr Type<T> operator*(typename std::common_type<T>::type number, const Type<T>& vector) { \
return number*static_cast<const Math::Vector<size, T>&>(vector); \
} \
template<class T> inline Type<T> operator/(typename std::common_type<T>::type number, const Type<T>& vector) { \
template<class T> inline constexpr Type<T> operator/(typename std::common_type<T>::type number, const Type<T>& vector) { \
return number/static_cast<const Math::Vector<size, T>&>(vector); \
} \
\
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, Integral b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, Integral b) { \
static_cast<Math::Vector<size, Integral>&>(a) %= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, Integral b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, Integral b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) % b; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator%=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) %= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator%(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) % b; \
} \
\
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator~(const Type<Integral>& vector) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator~(const Type<Integral>& vector) { \
return ~static_cast<const Math::Vector<size, Integral>&>(vector); \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator&=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator&=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) &= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator&(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator&(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) & b; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator|=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator|=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) |= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator|(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator|(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) | b; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator^=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator^=(Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) ^= b; \
return a; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator^(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator^(const Type<Integral>& a, const Math::Vector<size, Integral>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a) ^ b; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator<<=(Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator<<=(Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
static_cast<Math::Vector<size, Integral>&>(vector) <<= shift; \
return vector; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator<<(const Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator<<(const Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
return static_cast<const Math::Vector<size, Integral>&>(vector) << shift; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator>>=(Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>&>::type operator>>=(Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
static_cast<Math::Vector<size, Integral>&>(vector) >>= shift; \
return vector; \
} \
template<class Integral> inline typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator>>(const Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
template<class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value, Type<Integral>>::type operator>>(const Type<Integral>& vector, typename std::common_type<Integral>::type shift) { \
return static_cast<const Math::Vector<size, Integral>&>(vector) >> shift; \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator*=(Type<Integral>& vector, FloatingPoint number) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator*=(Type<Integral>& vector, FloatingPoint number) { \
static_cast<Math::Vector<size, Integral>&>(vector) *= number; \
return vector; \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Type<Integral>& vector, FloatingPoint number) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Type<Integral>& vector, FloatingPoint number) { \
return static_cast<const Math::Vector<size, Integral>&>(vector)*number; \
} \
template<class FloatingPoint, class Integral> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(FloatingPoint number, const Type<Integral>& vector) { \
template<class FloatingPoint, class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(FloatingPoint number, const Type<Integral>& vector) { \
return number*static_cast<const Math::Vector<size, Integral>&>(vector); \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator/=(Type<Integral>& vector, FloatingPoint number) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator/=(Type<Integral>& vector, FloatingPoint number) { \
static_cast<Math::Vector<size, Integral>&>(vector) /= number; \
return vector; \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator/(const Type<Integral>& vector, FloatingPoint number) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator/(const Type<Integral>& vector, FloatingPoint number) { \
return static_cast<const Math::Vector<size, Integral>&>(vector)/number; \
} \
\
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator*=(Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator*=(Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) *= b; \
return a; \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a)*b; \
} \
template<class FloatingPoint, class Integral> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Math::Vector<size, FloatingPoint>& a, const Type<Integral>& b) { \
template<class FloatingPoint, class Integral> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator*(const Math::Vector<size, FloatingPoint>& a, const Type<Integral>& b) { \
return a*static_cast<const Math::Vector<size, Integral>&>(b); \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator/=(Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>&>::type operator/=(Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
static_cast<Math::Vector<size, Integral>&>(a) /= b; \
return a; \
} \
template<class Integral, class FloatingPoint> inline typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator/(const Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
template<class Integral, class FloatingPoint> inline constexpr typename std::enable_if<std::is_integral<Integral>::value && std::is_floating_point<FloatingPoint>::value, Type<Integral>>::type operator/(const Type<Integral>& a, const Math::Vector<size, FloatingPoint>& b) { \
return static_cast<const Math::Vector<size, Integral>&>(a)/b; \
}
#endif
@ -1206,8 +1206,8 @@ template<std::size_t size, class T> inline Rad<T> Vector<size, T>::angle(const V
return Rad<T>(std::acos(dot(normalizedA, normalizedB)));
}
template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::operator<(const Vector<size, T>& other) const {
BoolVector<size> out;
template<std::size_t size, class T> inline constexpr BoolVector<size> Vector<size, T>::operator<(const Vector<size, T>& other) const {
BoolVector<size> out{};
for(std::size_t i = 0; i != size; ++i)
out.set(i, _data[i] < other._data[i]);
@ -1215,8 +1215,8 @@ template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::ope
return out;
}
template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::operator<=(const Vector<size, T>& other) const {
BoolVector<size> out;
template<std::size_t size, class T> inline constexpr BoolVector<size> Vector<size, T>::operator<=(const Vector<size, T>& other) const {
BoolVector<size> out{};
for(std::size_t i = 0; i != size; ++i)
out.set(i, _data[i] <= other._data[i]);
@ -1224,8 +1224,8 @@ template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::ope
return out;
}
template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::operator>=(const Vector<size, T>& other) const {
BoolVector<size> out;
template<std::size_t size, class T> inline constexpr BoolVector<size> Vector<size, T>::operator>=(const Vector<size, T>& other) const {
BoolVector<size> out{};
for(std::size_t i = 0; i != size; ++i)
out.set(i, _data[i] >= other._data[i]);
@ -1233,8 +1233,8 @@ template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::ope
return out;
}
template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::operator>(const Vector<size, T>& other) const {
BoolVector<size> out;
template<std::size_t size, class T> inline constexpr BoolVector<size> Vector<size, T>::operator>(const Vector<size, T>& other) const {
BoolVector<size> out{};
for(std::size_t i = 0; i != size; ++i)
out.set(i, _data[i] > other._data[i]);
@ -1242,8 +1242,8 @@ template<std::size_t size, class T> inline BoolVector<size> Vector<size, T>::ope
return out;
}
template<std::size_t size, class T> inline Vector<size, T> Vector<size, T>::operator-() const {
Vector<size, T> out;
template<std::size_t size, class T> inline constexpr Vector<size, T> Vector<size, T>::operator-() const {
Vector<size, T> out{};
for(std::size_t i = 0; i != size; ++i)
out._data[i] = -_data[i];
@ -1257,7 +1257,7 @@ template<std::size_t size, class T> inline Vector<size, T> Vector<size, T>::proj
return line*dot(*this, line);
}
template<std::size_t size, class T> inline T Vector<size, T>::sum() const {
template<std::size_t size, class T> inline constexpr T Vector<size, T>::sum() const {
T out(_data[0]);
for(std::size_t i = 1; i != size; ++i)
@ -1266,7 +1266,7 @@ template<std::size_t size, class T> inline T Vector<size, T>::sum() const {
return out;
}
template<std::size_t size, class T> inline T Vector<size, T>::product() const {
template<std::size_t size, class T> inline constexpr T Vector<size, T>::product() const {
T out(_data[0]);
for(std::size_t i = 1; i != size; ++i)

Loading…
Cancel
Save