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.
pull/279/head
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 { inline Vector<size, T> operator*(const Vector<size, T>& other) const {
return RectangularMatrix<size, size, T>::operator*(other); return RectangularMatrix<size, size, T>::operator*(other);
} }
#endif
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix<size, T>) MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix<size, T>)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(size, size, Matrix<size, T>) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(size, size, Matrix<size, T>)
#endif
}; };
#ifndef DOXYGEN_GENERATING_OUTPUT #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); 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); return number/RectangularMatrix<size, size, T>(matrix);
} }
#endif #endif
@ -190,7 +190,7 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
Matrix<size, T>::operator*=(other); \ Matrix<size, T>::operator*=(other); \
return *this; \ 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); \ return Matrix<size, T>::operator*(other); \
} \ } \
inline VectorType<T> operator*(const Vector<size, T>& other) const { \ 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(); } inline Type<T> inverted() const { return Matrix<size, T>::inverted(); }
#define MAGNUM_MATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(Type, size) \ #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); \ 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); \ 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; 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_IMPLEMENTATION(1, size, Vector<size, T>)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, size, Vector<size, T>) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, size, Vector<size, T>)
#endif
private: private:
/* Hiding unused things from RectangularMatrix */ /* 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 #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); 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); return number/RectangularMatrix<1, size, T>(vector);
} }
#endif #endif
@ -297,6 +303,9 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
return *this; \ 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 { \ inline Type<T> operator*(const Math::Vector<size, T>& other) const { \
return Math::Vector<size, T>::operator*(other); \ 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(); } inline Type<T> normalized() const { return Math::Vector<size, T>::normalized(); }
#define MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Type, size) \ #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); \ 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); \ return number/Math::Vector<size, T>(vector); \
} }
#endif #endif

Loading…
Cancel
Save