Browse Source

Fixed matrix multiplication in RectangularMatrix subclasses.

Now all possible cases are properly handled (row vector * column vector,
column vector * row vector, ...). All operators taking arbitrary type as
argument (element-wise multiplication) now have std::enable_if only for
numerical types.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
fb61c22e07
  1. 12
      src/Math/Matrix.h
  2. 17
      src/Math/Vector.h

12
src/Math/Matrix.h

@ -140,16 +140,16 @@ template<size_t s, class T> class Matrix: public RectangularMatrix<s, s, T> {
inline Vector<size, T> operator*(const Vector<size, T>& other) const {
return RectangularMatrix<size, size, T>::operator*(other);
}
#endif
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix<size, T>)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(size, size, Matrix<size, T>)
#endif
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<size_t size, class T, class U> inline Matrix<size, T> operator*(U number, const Matrix<size, T>& matrix) {
template<size_t size, class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Matrix<size, T>>::type operator*(U number, const Matrix<size, T>& matrix) {
return number*RectangularMatrix<size, size, T>(matrix);
}
template<size_t size, class T, class U> inline Matrix<size, T> operator/(U number, const Matrix<size, T>& matrix) {
template<size_t size, class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Matrix<size, T>>::type operator/(U number, const Matrix<size, T>& matrix) {
return number/RectangularMatrix<size, size, T>(matrix);
}
#endif
@ -190,7 +190,7 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
Matrix<size, T>::operator*=(other); \
return *this; \
} \
template<size_t otherCols> inline RectangularMatrix<otherCols, size, T> operator*(const RectangularMatrix<otherCols, size, T>& other) const { \
template<size_t otherCols> inline RectangularMatrix<otherCols, size, T> operator*(const RectangularMatrix<otherCols, size, T>& other) const { \
return Matrix<size, T>::operator*(other); \
} \
inline VectorType<T> operator*(const Vector<size, T>& other) const { \
@ -201,10 +201,10 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
inline Type<T> inverted() const { return Matrix<size, T>::inverted(); }
#define MAGNUM_MATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(Type, size) \
template<class T, class U> inline Type<T> operator*(U number, const Type<T>& matrix) { \
template<class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Type<T>>::type operator*(U number, const Type<T>& matrix) { \
return number*Matrix<size, T>(matrix); \
} \
template<class T, class U> inline Type<T> operator/(U number, const Type<T>& matrix) { \
template<class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Type<T>>::type operator/(U number, const Type<T>& matrix) { \
return number/Matrix<size, T>(matrix); \
}

17
src/Math/Vector.h

@ -247,8 +247,14 @@ template<size_t s, class T> class Vector: public RectangularMatrix<1, s, T> {
return out;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Reimplementation of functions to return correct type */
template<size_t otherCols> inline RectangularMatrix<otherCols, size, T> operator*(const RectangularMatrix<otherCols, 1, T>& other) const {
return RectangularMatrix<1, size, T>::operator*(other);
}
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(1, size, Vector<size, T>)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, size, Vector<size, T>)
#endif
private:
/* Hiding unused things from RectangularMatrix */
@ -259,10 +265,10 @@ template<size_t s, class T> class Vector: public RectangularMatrix<1, s, T> {
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<size_t size, class T, class U> inline Vector<size, T> operator*(U number, const Vector<size, T>& vector) {
template<size_t size, class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Vector<size, T>>::type operator*(U number, const Vector<size, T>& vector) {
return number*RectangularMatrix<1, size, T>(vector);
}
template<size_t size, class T, class U> inline Vector<size, T> operator/(U number, const Vector<size, T>& vector) {
template<size_t size, class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Vector<size, T>>::type operator/(U number, const Vector<size, T>& vector) {
return number/RectangularMatrix<1, size, T>(vector);
}
#endif
@ -297,6 +303,9 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
return *this; \
} \
\
template<size_t otherCols> inline Math::RectangularMatrix<otherCols, size, T> operator*(const Math::RectangularMatrix<otherCols, 1, T>& other) const { \
return Math::Vector<size, T>::operator*(other); \
} \
inline Type<T> operator*(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator*(other); \
} \
@ -316,10 +325,10 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
inline Type<T> normalized() const { return Math::Vector<size, T>::normalized(); }
#define MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Type, size) \
template<class T, class U> inline Type<T> operator*(U number, const Type<T>& vector) { \
template<class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Type<T>>::type operator*(U number, const Type<T>& vector) { \
return number*Math::Vector<size, T>(vector); \
} \
template<class T, class U> inline Type<T> operator/(U number, const Type<T>& vector) { \
template<class T, class U> inline typename std::enable_if<std::is_arithmetic<U>::value, Type<T>>::type operator/(U number, const Type<T>& vector) { \
return number/Math::Vector<size, T>(vector); \
}
#endif

Loading…
Cancel
Save