|
|
|
@ -48,13 +48,13 @@ namespace Magnum { namespace Math { |
|
|
|
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isNan(T value) { |
|
|
|
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isNan(T value) { |
|
|
|
return std::isnan(UnderlyingTypeOf<T>(value)); |
|
|
|
return std::isnan(UnderlyingTypeOf<T>(value)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Keeping the same parameter names as in Functions.h so the note about
|
|
|
|
template<class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type min(T a, T b) { |
|
|
|
NaN propagation works here too */ |
|
|
|
return b < a ? b : a; |
|
|
|
template<class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type min(T value, T min) { |
|
|
|
|
|
|
|
return min < value ? min : value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
template<class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type max(T value, T max) { |
|
|
|
template<class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type max(T a, T b) { |
|
|
|
return value < max ? max : value; |
|
|
|
return a < b ? b : a; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
@ -237,7 +237,11 @@ template<std::size_t size, class T> class Vector { |
|
|
|
T& operator[](std::size_t pos) { return _data[pos]; } |
|
|
|
T& operator[](std::size_t pos) { return _data[pos]; } |
|
|
|
constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */ |
|
|
|
constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */ |
|
|
|
|
|
|
|
|
|
|
|
/** @brief Equality comparison */ |
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Equality comparison |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @see @ref Math::equal() |
|
|
|
|
|
|
|
*/ |
|
|
|
bool operator==(const Vector<size, T>& other) const { |
|
|
|
bool operator==(const Vector<size, T>& other) const { |
|
|
|
for(std::size_t i = 0; i != size; ++i) |
|
|
|
for(std::size_t i = 0; i != size; ++i) |
|
|
|
if(!TypeTraits<T>::equals(_data[i], other._data[i])) return false; |
|
|
|
if(!TypeTraits<T>::equals(_data[i], other._data[i])) return false; |
|
|
|
@ -245,7 +249,11 @@ template<std::size_t size, class T> class Vector { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** @brief Non-equality comparison */ |
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Non-equality comparison |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @see @ref Math::notEqual() |
|
|
|
|
|
|
|
*/ |
|
|
|
bool operator!=(const Vector<size, T>& other) const { |
|
|
|
bool operator!=(const Vector<size, T>& other) const { |
|
|
|
return !operator==(other); |
|
|
|
return !operator==(other); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -640,6 +648,11 @@ template<std::size_t size, class T> class Vector { |
|
|
|
template<std::size_t, class> friend class Matrix; |
|
|
|
template<std::size_t, class> friend class Matrix; |
|
|
|
template<std::size_t, class> friend struct Implementation::MatrixDeterminant; |
|
|
|
template<std::size_t, class> friend struct Implementation::MatrixDeterminant; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* So the out-of-class comparators can access data directly to avoid
|
|
|
|
|
|
|
|
function call overhead */ |
|
|
|
|
|
|
|
template<std::size_t size_, class T_> friend BoolVector<size_> equal(const Vector<size_, T_>&, const Vector<size_, T_>&); |
|
|
|
|
|
|
|
template<std::size_t size_, class T_> friend BoolVector<size_> notEqual(const Vector<size_, T_>&, const Vector<size_, T_>&); |
|
|
|
|
|
|
|
|
|
|
|
/* Implementation for Vector<size, T>::Vector(const Vector<size, U>&) */ |
|
|
|
/* Implementation for Vector<size, T>::Vector(const Vector<size, U>&) */ |
|
|
|
template<class U, std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, const Vector<size, U>& vector) noexcept: _data{T(vector._data[sequence])...} {} |
|
|
|
template<class U, std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, const Vector<size, U>& vector) noexcept: _data{T(vector._data[sequence])...} {} |
|
|
|
|
|
|
|
|
|
|
|
@ -655,6 +668,36 @@ template<std::size_t size, class T> class Vector { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @relatesalso Vector
|
|
|
|
|
|
|
|
@brief Component-wise equality comparison |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Unlike @ref Vector::operator==() returns a @ref BoolVector instead of a single |
|
|
|
|
|
|
|
value. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
template<std::size_t size, class T> inline BoolVector<size> equal(const Vector<size, T>& a, const Vector<size, T>& b) { |
|
|
|
|
|
|
|
BoolVector<size> out; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(std::size_t i = 0; i != size; ++i) |
|
|
|
|
|
|
|
out.set(i, TypeTraits<T>::equals(a._data[i], b._data[i])); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @relatesalso Vector
|
|
|
|
|
|
|
|
@brief Component-wise non-equality comparison |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Unlike @ref Vector::operator!=() returns a @ref BoolVector instead of a single |
|
|
|
|
|
|
|
value. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
template<std::size_t size, class T> inline BoolVector<size> notEqual(const Vector<size, T>& a, const Vector<size, T>& b) { |
|
|
|
|
|
|
|
BoolVector<size> out; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(std::size_t i = 0; i != size; ++i) |
|
|
|
|
|
|
|
out.set(i, !TypeTraits<T>::equals(a._data[i], b._data[i])); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** @relates Vector
|
|
|
|
/** @relates Vector
|
|
|
|
@brief Multiply a scalar with a vector |
|
|
|
@brief Multiply a scalar with a vector |
|
|
|
|
|
|
|
|
|
|
|
|