diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index 8c8580f90..a6a26ef9f 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -263,6 +263,43 @@ template class Matrix { }; #ifndef DOXYGEN_GENERATING_OUTPUT +#define MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Type, VectorType, size) \ + inline constexpr static Type& from(T* data) { \ + return *reinterpret_cast*>(data); \ + } \ + inline constexpr static const Type& from(const T* data) { \ + return *reinterpret_cast*>(data); \ + } \ + template inline constexpr static Type from(const Vector& first, const U&... next) { \ + return Matrix::from(first, next...); \ + } \ + \ + inline Type& operator=(const Type& other) { \ + Matrix::operator=(other); \ + return *this; \ + } \ + \ + inline VectorType& operator[](size_t col) { \ + return VectorType::from(Matrix::data()+col*size); \ + } \ + inline constexpr const VectorType& operator[](size_t col) const { \ + return VectorType::from(Matrix::data()+col*size); \ + } \ + \ + inline Type operator*(const Matrix& other) const { \ + return Matrix::operator*(other); \ + } \ + inline Type& operator*=(const Matrix& other) { \ + Matrix::operator*=(other); \ + return *this; \ + } \ + inline VectorType operator*(const Vector& other) const { \ + return Matrix::operator*(other); \ + } \ + \ + inline Type transposed() const { return Matrix::transposed(); } \ + inline Type inverted() const { return Matrix::inverted(); } + namespace Implementation { template class MatrixDeterminant { diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index b7f0d91d5..e82da033d 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -27,21 +27,6 @@ namespace Magnum { namespace Math { /** @brief 3x3 matrix */ template class Matrix3: public Matrix<3, T> { public: - /** @copydoc Matrix::from(T*) */ - inline constexpr static Matrix3& from(T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Matrix::from(const T*) */ - inline constexpr static const Matrix3& from(const T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Matrix::from(const Vector&, const U&...) */ - template inline constexpr static Matrix3 from(const Vector<3, T>& first, const U&... next) { - return Matrix<3, T>::from(first, next...); - } - /** @copydoc Matrix::Matrix(ZeroType) */ inline constexpr explicit Matrix3(typename Matrix<3, T>::ZeroType): Matrix<3, T>(Matrix<3, T>::Zero) {} @@ -66,35 +51,7 @@ template class Matrix3: public Matrix<3, T> { /** @copydoc Matrix::Matrix(const Matrix&) */ inline constexpr Matrix3(const Matrix<3, T>& other): Matrix<3, T>(other) {} - /** @copydoc Matrix::operator=() */ - inline Matrix3& operator=(const Matrix3& other) { - Matrix<3, T>::operator=(other); - return *this; - } - - /** @copydoc Matrix::operator[](size_t) */ - inline Vector3& operator[](size_t col) { return Vector3::from(Matrix<3, T>::data()+col*3); } - - /** @copydoc Matrix::operator[](size_t) const */ - inline constexpr const Vector3& operator[](size_t col) const { return Vector3::from(Matrix<3, T>::data()+col*3); } - - /** @copydoc Matrix::operator*(const Matrix&) const */ - inline Matrix3 operator*(const Matrix<3, T>& other) const { return Matrix<3, T>::operator*(other); } - - /** @copydoc Matrix::operator*=() */ - inline Matrix3& operator*=(const Matrix<3, T>& other) { - Matrix<3, T>::operator*=(other); - return *this; - } - - /** @copydoc Matrix::operator*(const Vector&) const */ - inline Vector3 operator*(const Vector<3, T>& other) const { return Matrix<3, T>::operator*(other); } - - /** @copydoc Matrix::transposed() */ - inline Matrix3 transposed() const { return Matrix<3, T>::transposed(); } - - /** @copydoc Matrix::inverted() */ - inline Matrix3 inverted() const { return Matrix<3, T>::inverted(); } + MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix3, Vector3, 3) }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 43224a6ef..ee29378a2 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -32,21 +32,6 @@ namespace Magnum { namespace Math { */ template class Matrix4: public Matrix<4, T> { public: - /** @copydoc Matrix::from(T*) */ - inline constexpr static Matrix4& from(T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Matrix::from(const T*) */ - inline constexpr static const Matrix4& from(const T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Matrix::from(const Vector&, const U&...) */ - template inline constexpr static Matrix4 from(const Vector<4, T>& first, const U&... next) { - return Matrix<4, T>::from(first, next...); - } - /** * @brief Translation matrix * @param vec Translation vector @@ -134,39 +119,9 @@ template class Matrix4: public Matrix<4, T> { /** @copydoc Matrix::Matrix(const Matrix&) */ inline constexpr Matrix4(const Matrix<4, T>& other): Matrix<4, T>(other) {} - /** @copydoc Matrix::operator=() */ - inline Matrix4& operator=(const Matrix4& other) { - Matrix<4, T>::operator=(other); - return *this; - } - - /** @copydoc Matrix::operator[](size_t) */ - inline Vector4& operator[](size_t col) { return Vector4::from(Matrix<4, T>::data()+col*4); } - - /** @copydoc Matrix::operator[](size_t) const */ - inline constexpr const Vector4& operator[](size_t col) const { return Vector4::from(Matrix<4, T>::data()+col*4); } - - /** @copydoc Matrix::operator*(const Matrix&) const */ - inline Matrix4 operator*(const Matrix<4, T>& other) const { return Matrix<4, T>::operator*(other); } - - /** @copydoc Matrix::operator*=() */ - inline Matrix4& operator*=(const Matrix<4, T>& other) { - Matrix<4, T>::operator*=(other); - return *this; - } - - /** @copydoc Matrix::operator*(const Vector&) const */ - inline Vector4 operator*(const Vector<4, T>& other) const { return Matrix<4, T>::operator*(other); } - - /** @copydoc Matrix::transposed() */ - inline Matrix4 transposed() const { return Matrix<4, T>::transposed(); } - /** @copydoc Matrix::ij() */ inline Matrix3 ij(size_t skipRow, size_t skipCol) const { return Matrix<4, T>::ij(skipRow, skipCol); } - /** @copydoc Matrix::inverted() */ - inline Matrix4 inverted() const { return Matrix<4, T>::inverted(); } - /** @brief Rotation and scaling part of the matrix */ inline Matrix3 rotationScaling() const { return Matrix3::from( @@ -182,6 +137,8 @@ template class Matrix4: public Matrix<4, T> { (*this)[1].xyz().normalized(), (*this)[2].xyz().normalized()); } + + MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix4, Vector4, 4) }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 85b36a021..4440c3b29 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -258,6 +258,52 @@ template class Vector { }; #ifndef DOXYGEN_GENERATING_OUTPUT +#define MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Type, size) \ + inline constexpr static Type& from(T* data) { \ + return *reinterpret_cast*>(data); \ + } \ + inline constexpr static const Type& from(const T* data) { \ + return *reinterpret_cast*>(data); \ + } \ + \ + inline Type& operator=(const Type& other) { \ + Vector::operator=(other); \ + return *this; \ + } \ + \ + inline Type operator*(T number) const { \ + return Vector::operator*(number); \ + } \ + inline Type& operator*=(T number) { \ + Vector::operator*=(number); \ + return *this; \ + } \ + inline Type operator/(T number) const { \ + return Vector::operator/(number); \ + } \ + inline Type& operator/=(T number) { \ + Vector::operator/=(number); \ + return *this; \ + } \ + \ + inline Type operator+(const Vector& other) const { \ + return Vector::operator+(other); \ + } \ + inline Type& operator+=(const Vector& other) { \ + Vector::operator+=(other); \ + return *this; \ + } \ + inline Type operator-(const Vector& other) const { \ + return Vector::operator-(other); \ + } \ + inline Type& operator-=(const Vector& other) { \ + Vector::operator-=(other); \ + return *this; \ + } \ + \ + inline Type operator-() const { return Vector::operator-(); } \ + inline Type normalized() const { return Vector::normalized(); } + template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector& value) { debug << "Vector("; debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false); diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index 6fe5687e3..95844297f 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -26,20 +26,10 @@ namespace Magnum { namespace Math { /** @brief Two-component vector */ template class Vector2: public Vector<2, T> { public: - /** @copydoc Vector::from(T*) */ - inline constexpr static Vector2& from(T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Vector::from(const T*) */ - inline constexpr static const Vector2& from(const T* data) { - return *reinterpret_cast*>(data); - } - /** @copydoc Vector::Vector(T) */ inline constexpr explicit Vector2(T value = T()): Vector<2, T>(value, value) {} - /** @copydoc Vector::Vector(const Vector&) */ + /** @copydoc Vector::Vector(const Vector&) */ inline constexpr Vector2(const Vector<2, T>& other): Vector<2, T>(other) {} /** @@ -55,53 +45,7 @@ template class Vector2: public Vector<2, T> { inline void setX(T value) { (*this)[0] = value; } /**< @brief Set X component */ inline void setY(T value) { (*this)[1] = value; } /**< @brief Set Y component */ - /** @copydoc Vector::operator=() */ - inline Vector2& operator=(const Vector2& other) { - Vector<2, T>::operator=(other); - return *this; - } - - /** @copydoc Vector::operator*(T) const */ - inline Vector2 operator*(T number) const { return Vector<2, T>::operator*(number); } - - /** @copydoc Vector::operator*=() */ - inline Vector2& operator*=(T number) { - Vector<2, T>::operator*=(number); - return *this; - } - - /** @copydoc Vector::operator/() */ - inline Vector2 operator/(T number) const { return Vector<2, T>::operator/(number); } - - /** @copydoc Vector::operator/=() */ - inline Vector2& operator/=(T number) { - Vector<2, T>::operator/=(number); - return *this; - } - - /** @copydoc Vector::operator+() */ - inline Vector2 operator+(const Vector<2, T>& other) const { return Vector<2, T>::operator+(other); } - - /** @copydoc Vector::operator+=() */ - inline Vector2& operator+=(const Vector<2, T>& other) { - Vector<2, T>::operator+=(other); - return *this; - } - - /** @copydoc Vector::operator-(const Vector&) const */ - inline Vector2 operator-(const Vector<2, T>& other) const { return Vector<2, T>::operator-(other); } - - /** @copydoc Vector::operator-=() */ - inline Vector2& operator-=(const Vector<2, T>& other) { - Vector<2, T>::operator-=(other); - return *this; - } - - /** @copydoc Vector::operator-() */ - inline Vector2 operator-() const { return Vector<2, T>::operator-(); } - - /** @copydoc Vector::normalized() */ - inline Vector2 normalized() const { return Vector<2, T>::normalized(); } + MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector2, 2) }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index 6689fa7d9..a9068c032 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -26,16 +26,6 @@ namespace Magnum { namespace Math { /** @brief Three-component vector */ template class Vector3: public Vector<3, T> { public: - /** @copydoc Vector::from(T*) */ - inline constexpr static Vector3& from(T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Vector::from(const T*) */ - inline constexpr static const Vector3& from(const T* data) { - return *reinterpret_cast*>(data); - } - /** @brief %Vector in direction of X axis */ inline constexpr static Vector3 xAxis(T length = T(1)) { return Vector3(length, T(), T()); } @@ -62,7 +52,7 @@ template class Vector3: public Vector<3, T> { /** @copydoc Vector::Vector(T) */ inline constexpr explicit Vector3(T value = T()): Vector<3, T>(value, value, value) {} - /** @copydoc Vector::Vector(const Vector&) */ + /** @copydoc Vector::Vector(const Vector&) */ inline constexpr Vector3(const Vector<3, T>& other): Vector<3, T>(other) {} /** @@ -96,53 +86,7 @@ template class Vector3: public Vector<3, T> { inline void setG(T value) { setY(value); } /**< @brief Set G component */ inline void setB(T value) { setZ(value); } /**< @brief Set B component */ - /** @copydoc Vector::operator=() */ - inline Vector3& operator=(const Vector3& other) { - Vector<3, T>::operator=(other); - return *this; - } - - /** @copydoc Vector::operator*(T) const */ - inline Vector3 operator*(T number) const { return Vector<3, T>::operator*(number); } - - /** @copydoc Vector::operator*=() */ - inline Vector3& operator*=(T number) { - Vector<3, T>::operator*=(number); - return *this; - } - - /** @copydoc Vector::operator/() */ - inline Vector3 operator/(T number) const { return Vector<3, T>::operator/(number); } - - /** @copydoc Vector::operator/=() */ - inline Vector3& operator/=(T number) { - Vector<3, T>::operator/=(number); - return *this; - } - - /** @copydoc Vector::operator+() */ - inline Vector3 operator+(const Vector<3, T>& other) const { return Vector<3, T>::operator+(other); } - - /** @copydoc Vector::operator+=() */ - inline Vector3& operator+=(const Vector<3, T>& other) { - Vector<3, T>::operator+=(other); - return *this; - } - - /** @copydoc Vector::operator-(const Vector&) const */ - inline Vector3 operator-(const Vector<3, T>& other) const { return Vector<3, T>::operator-(other); } - - /** @copydoc Vector::operator-=() */ - inline Vector3& operator-=(const Vector<3, T>& other) { - Vector<3, T>::operator-=(other); - return *this; - } - - /** @copydoc Vector::operator-() */ - inline Vector3 operator-() const { return Vector<3, T>::operator-(); } - - /** @copydoc Vector::normalized() */ - inline Vector3 normalized() const { return Vector<3, T>::normalized(); } + MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector3, 3) }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index 0f2fb852a..d41ecc01c 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -26,16 +26,6 @@ namespace Magnum { namespace Math { /** @brief Four-component vector */ template class Vector4: public Vector<4, T> { public: - /** @copydoc Vector::from(T*) */ - inline constexpr static Vector4& from(T* data) { - return *reinterpret_cast*>(data); - } - - /** @copydoc Vector::from(const T*) */ - inline constexpr static const Vector4& from(const T* data) { - return *reinterpret_cast*>(data); - } - /** * @copydoc Vector::Vector * @@ -46,7 +36,7 @@ template class Vector4: public Vector<4, T> { /** @copydoc Vector::Vector(T) */ inline constexpr explicit Vector4(T value): Vector<4, T>(value, value, value, value) {} - /** @copydoc Vector::Vector(const Vector&) */ + /** @copydoc Vector::Vector(const Vector&) */ inline constexpr Vector4(const Vector<4, T>& other): Vector<4, T>(other) {} /** @@ -97,53 +87,7 @@ template class Vector4: public Vector<4, T> { */ inline constexpr Vector3 rgb() const { return xyz(); } - /** @copydoc Vector::operator=() */ - inline Vector4& operator=(const Vector4& other) { - Vector<4, T>::operator=(other); - return *this; - } - - /** @copydoc Vector::operator*(T) const */ - inline Vector4 operator*(T number) const { return Vector<4, T>::operator*(number); } - - /** @copydoc Vector::operator*=() */ - inline Vector4& operator*=(T number) { - Vector<4, T>::operator*=(number); - return *this; - } - - /** @copydoc Vector::operator/() */ - inline Vector4 operator/(T number) const { return Vector<4, T>::operator/(number); } - - /** @copydoc Vector::operator/=() */ - inline Vector4& operator/=(T number) { - Vector<4, T>::operator/=(number); - return *this; - } - - /** @copydoc Vector::operator+() */ - inline Vector4 operator+(const Vector<4, T>& other) const { return Vector<4, T>::operator+(other); } - - /** @copydoc Vector::operator+=() */ - inline Vector4& operator+=(const Vector<4, T>& other) { - Vector<4, T>::operator+=(other); - return *this; - } - - /** @copydoc Vector::operator-(const Vector&) const */ - inline Vector4 operator-(const Vector<4, T>& other) const { return Vector<4, T>::operator-(other); } - - /** @copydoc Vector::operator-=() */ - inline Vector4& operator-=(const Vector<4, T>& other) { - Vector<4, T>::operator-=(other); - return *this; - } - - /** @copydoc Vector::operator-() */ - inline Vector4 operator-() const { return Vector<4, T>::operator-(); } - - /** @copydoc Vector::normalized() */ - inline Vector4 normalized() const { return Vector<4, T>::normalized(); } + MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector4, 4) }; #ifndef DOXYGEN_GENERATING_OUTPUT