Commits

Jeff Hardy committed 8383d9a

Add in-place operators to Matrix, and restructure code to use them as the primary operators.

Comments (0)

Files changed (3)

Matrix/Matrix/Matrix.h

 #pragma once
 
 #include <cmath>
+#include <utility>
 
 namespace Math
 {
     template<class T, int Rows, int Cols>
-    struct __declspec(align(16)) Matrix
+    struct Matrix;
+
+    namespace Matrix_detail
+    {
+        template<class T, int Rows, int Cols>
+        Matrix<T, Rows, Cols>& iadd(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);
+
+        template<class T, int Rows, int Cols>
+        Matrix<T, Rows, Cols>& isub(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);
+
+        template<class T, int Rows, int Cols>
+        Matrix<T, Rows, Cols>& imul_s(Matrix<T, Rows, Cols> &m, T s);
+
+        template<class T, int Rows, int Cols>
+        Matrix<T, Rows, Cols>& idiv_s(Matrix<T, Rows, Cols> &m, T s);
+
+        template<class T, int Rows, int Cols>
+        Matrix<T, Rows, Cols>& imul(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);
+    }
+
+#define MATRIX_IOPS(Rows, Cols)                                                                                 \
+    Matrix<T, Rows, Cols>& operator+=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::iadd(*this, m); } \
+    Matrix<T, Rows, Cols>& operator-=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::isub(*this, m); } \
+    Matrix<T, Rows, Cols>& operator*=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::imul(*this, m); } \
+    Matrix<T, Rows, Cols>& operator*=(T s) { return Matrix_detail::imul_s(*this, s); }                          \
+    Matrix<T, Rows, Cols>& operator/=(T s) { return Matrix_detail::idiv_s(*this, s); }
+
+    template<class T, int Rows, int Cols>
+    struct Matrix
     {
         T operator()(int row, int col) const
         {
             return raw_data[row][col];
         }
 
+        MATRIX_IOPS(Rows, Cols)
+
         T raw_data[Rows][Cols];
     };
 
     template<class T, int Rows>
-    struct __declspec(align(16)) Matrix<T, Rows, 1>
+    struct Matrix<T, Rows, 1>
     {
         T operator()(int row, int /*col*/) const
         {
             return raw_data[index];
         }
 
+        MATRIX_IOPS(Rows, 1)
+
         T raw_data[Rows];
     };
 
     template<class T>
-    struct __declspec(align(16)) Matrix<T, 3, 1>
+    struct Matrix<T, 3, 1>
     {
         T operator()(int row, int /*col*/) const
         {
             }
         }
 
+        MATRIX_IOPS(3, 1)
+
         T x, y, z;
     };
 
     template<class T>
-    struct __declspec(align(16)) Matrix<T, 4, 1>
+    struct Matrix<T, 4, 1>
     {
         T operator()(int row, int /*col*/) const
         {
             }
         }
 
+        MATRIX_IOPS(4, 1)
+
         T x, y, z, w;
     };
 
     template<class T, int Cols>
-    struct __declspec(align(16)) Matrix<T, 1, Cols>
+    struct Matrix<T, 1, Cols>
     {
         T operator()(int /*row*/, int col) const
         {
             return raw_data[index];
         }
 
+        MATRIX_IOPS(1, Cols)
+
         T raw_data[Cols];
     };
 
     template<class T>
-    struct __declspec(align(16)) Matrix<T, 1, 3>
+    struct Matrix<T, 1, 3>
     {
         T operator()(int /*row*/, int col) const
         {
             }
         }
 
+        MATRIX_IOPS(1, 3)
+
         T x, y, z;
     };
 
     template<class T>
-    struct __declspec(align(16)) Matrix<T, 1, 4>
+    struct Matrix<T, 1, 4>
     {
         T operator()(int /*row*/, int col) const
         {
             }
         }
 
+        MATRIX_IOPS(1, 4)
+
         T x, y, z, w;
     };
 
     template<class T>
-    struct __declspec(align(16)) Matrix<T, 1, 1>
+    struct Matrix<T, 1, 1>
     {
         T operator()(int row, int col) const
         {
             return value;
         }
 
+        MATRIX_IOPS(1, 1)
+
         T value;
     };
 
     namespace Matrix_detail
     {
         template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> add(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
+        Matrix<T, Rows, Cols>& iadd(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
         {
-            Matrix<T, Rows, Cols> result;
-
             for(int i = 0; i < Rows; ++i)
                 for(int j = 0; j < Cols; ++j)
-                    result(i, j) = l(i, j) + r(i, j);
+                    l(i, j) += r(i, j);
 
-            return result;
+            return l;
         }
 
         template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> scalar_multiply(const Matrix<T, Rows, Cols> &m, T s)
+        Matrix<T, Rows, Cols>& isub(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
         {
-            Matrix<T, Rows, Cols> result;
-            
             for(int i = 0; i < Rows; ++i)
                 for(int j = 0; j < Cols; ++j)
-                    result(i, j) = m(i, j) * s;
+                    l(i, j) -= r(i, j);
 
-            return result;
+            return l;
         }
 
         template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> scalar_divide(const Matrix<T, Rows, Cols> &m, T s)
+        Matrix<T, Rows, Cols>& imul_s(Matrix<T, Rows, Cols> &m, T s)
         {
-            Matrix<T, Rows, Cols> result;
-            
             for(int i = 0; i < Rows; ++i)
                 for(int j = 0; j < Cols; ++j)
-                    result(i, j) = m(i, j) / s;
-
-            return result;
+                    m(i, j) *= s;
+            
+            return m;
         }
 
         template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> negate(const Matrix<T, Rows, Cols> &m)
+        Matrix<T, Rows, Cols>& idiv_s(Matrix<T, Rows, Cols> &m, T s)
         {
-            return m * -1;
+            for(int i = 0; i < Rows; ++i)
+                for(int j = 0; j < Cols; ++j)
+                    m(i, j) /= s;
+
+            return m;
         }
 
         template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> subtract(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
+        Matrix<T, Rows, Cols>& imul(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
         {
-            return l + negate(r);
+            using namespace std;
+
+            Matrix<T, Rows, Cols> result = {};
+
+            for(int i = 0; i < Rows; i++) 
+               for(int j = 0; j < Cols; j++)
+                   for(int k = 0; k < Cols; k++) 
+                       result(i, j) += l(i, k) * r(k, j);
+            
+            swap(result, l);
+            return l;
+        }
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Cols, Rows> transpose(const Matrix<T, Rows, Cols> &m)
+    {
+        Matrix<T, Cols, Rows> result;
+
+        for(int i = 0; i < Rows; ++i)
+            for(int j = 0; j < Cols; ++j)
+                result(j, i) = m(i, j);
+
+        return result;
+    }
+
+    template<class T, int Rows>
+    T inner_product(const Matrix<T, Rows, 1> &l, const Matrix<T, Rows, 1> &r)
+    {
+        T result = 0;
+
+        for(int i = 0; i < Rows; ++i)
+            result += l(i) * r(i);
+
+        return result;
+    }
+
+    template<class T, int Cols>
+    T inner_product(const Matrix<T, 1, Cols> &l, const Matrix<T, 1, Cols> &r)
+    {
+        T result = 0;
+
+        for(int j = 0; j < Cols; ++j)
+            result += l(j) * r(j);
+
+        return result;
+    }
+
+    template<class T, int Rows, int Cols>
+    T magnitude(const Matrix<T, Rows, Cols> &m)
+    {
+        return std::sqrt(inner_product(m, m));
+    }
+
+    template<int Rows, int Cols>
+    int magnitude(const Matrix<int, Rows, Cols> &m)
+    {
+        return (int)std::sqrt((double)inner_product(m, m));
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> normalize(const Matrix<T, Rows, Cols> &m)
+    {
+        return m / magnitude(m);
+    }
+
+    template<class T>
+    Matrix<T, 3, 1> cross_product(const Matrix<T, 3, 1> &l, const Matrix<T, 3, 1> &r)
+    {
+        Matrix<T, 3, 1> result = {
+            l(1) * r(2) - l(2) * r(1),
+            l(2) * r(0) - l(0) * r(2),
+            l(0) * r(1) - l(1) * r(0)
+        };
+        return result;
+    }
+
+    template<class T>
+    Matrix<T, 1, 3> cross_product(const Matrix<T, 1, 3> &l, const Matrix<T, 1, 3> &r)
+    {
+        Matrix<T, 1, 3> result = {
+            l(1) * r(2) - l(2) * r(1),
+            l(2) * r(0) - l(0) * r(2),
+            l(0) * r(1) - l(1) * r(0)
+        };
+        return result;
+    }
+
+    template<class T>
+    T determinant(const Matrix<T, 2, 2> &m)
+    {
+        return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);
+    }
+    
+    template<class T, int N>
+    Matrix<T, N - 1, N - 1> minor_matrix(const Matrix<T, N, N> &m, int i, int j)
+    {
+        Matrix<T, N - 1, N - 1> result;
+
+        for(int a = 0, b = 0; a < N; ++a)
+        {
+            if(a != i)
+            {
+                for(int c = 0, d = 0; c < N; ++c)
+                {
+                    if(c != j)
+                    {
+                        result(b, d) = m(a, c);
+                        ++d;
+                    }
+                }
+                ++b;
+            }
         }
 
-        template<class T, int RowsL, int ColsL, int ColsR>
-        Matrix<T, RowsL, ColsR> multiply(const Matrix<T, RowsL, ColsL> &l, const Matrix<T, ColsL, ColsR> &r)
-        {
-            Matrix<T, RowsL, ColsR> result = {};
+        return result;
+    }
 
-            for(int i = 0; i < RowsL; i++) 
-               for(int j = 0; j < ColsR; j++)
-                   for(int k = 0; k < ColsL; k++) 
-                       result(i, j) +=  l(i, k) * r(k, j);
+    template<class T, int N>
+    T cofactor(const Matrix<T, N, N> &m, int row, int col)
+    {
+        return determinant(minor_matrix(m, row, col)) * (T)std::pow((T)-1, row + col);
+    }
 
-            return result;
-        }
+    template<int N>
+    int cofactor(const Matrix<int, N, N> &m, int row, int col)
+    {
+        return determinant(minor_matrix(m, row, col)) * (int)std::pow(-1.0, row + col);
+    }
 
-        template<class T, int Rows, int Cols>
-        Matrix<T, Cols, Rows> transpose(const Matrix<T, Rows, Cols> &m)
-        {
-            Matrix<T, Cols, Rows> result;
+    template<class T, int N>
+    Matrix<T, N, N> cofactor_matrix(const Matrix<T, N, N> &m)
+    {
+        Matrix<T, N, N> result;
 
-            for(int i = 0; i < Rows; ++i)
-                for(int j = 0; j < Cols; ++j)
-                    result(j, i) = m(i, j);
+        for(int i = 0; i < N; ++i)
+            for(int j = 0; j < N; ++j)
+                result(i, j) = cofactor(m, i, j);
 
-            return result;
-        }
+        return result;
+    }
 
-        template<class T, int Rows, int Cols>
-        bool equals(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)
-        {
-            for(int i = 0; i < Rows; ++i)
+    template<class T, int N>
+    Matrix<T, N, N> adjoint(const Matrix<T, N, N> &m)
+    {
+        return transpose(cofactor_matrix(m));
+    }
+
+    template<class T, int N>
+    T determinant(const Matrix<T, N, N> &m)
+    {
+        T result = 0;
+
+        // Laplace expansion of first row
+        for(int i = 0; i < N; ++i)
+            result += m(i, 0) * cofactor(m, i, 0);
+
+        return result;
+    }
+
+    template<class T>
+    Matrix<T, 2, 2> inverse(const Matrix<T, 2, 2> &m)
+    {
+        Matrix<T, 2, 2> result = {m(1, 1), -m(0, 1), -m(1, 0), m(0, 0)};
+        return result / determinant(m);
+    }
+
+    template<class T, int N>
+    Matrix<T, N, N> inverse(const Matrix<T, N, N> &m)
+    {
+        return adjoint(m) / determinant(m);
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator+(Matrix<T, Rows, Cols> m)
+    {
+        return m;
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator-(Matrix<T, Rows, Cols> m)
+    {
+        return m *= -1;
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator~(const Matrix<T, Rows, Cols> &m)
+    {
+        return inverse(m);
+    }
+
+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
+    Matrix<T, RowsL, ColsL> operator+(Matrix<T, RowsL, ColsL> l, const Matrix<U, RowsR, ColsR> &r)
+    {
+        return l += r;
+    }
+
+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
+    Matrix<T, RowsL, ColsL> operator-(Matrix<T, RowsL, ColsL> l, const Matrix<U, RowsR, ColsR> &r)
+    {
+        return l -= r;
+    }
+
+    template<class T, class U, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator*(Matrix<T, Rows, Cols> l, const Matrix<U, Rows, Cols> &r)
+    {
+        return l *= r;
+    }
+
+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
+    Matrix<T, RowsL, ColsR> operator*(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
+    {
+        Matrix<T, RowsL, ColsR> result = {};
+
+        for(int i = 0; i < RowsL; i++) 
+           for(int j = 0; j < ColsR; j++)
+               for(int k = 0; k < ColsL; k++) 
+                   result(i, j) += l(i, k) * r(k, j);
+
+        return result;
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator*(Matrix<T, Rows, Cols> m, T s)
+    {
+        return m *= s;
+    }
+
+    template<class T, int Rows, int Cols>
+    Matrix<T, Rows, Cols> operator/(Matrix<T, Rows, Cols> m, T s)
+    {
+        return m /= s;
+    }
+
+    template<class T, class U, int Rows>
+    T operator*(const Matrix<T, Rows, 1> &l, const Matrix<U, Rows, 1> &r)
+    {
+        return inner_product(l, r);
+    }
+
+    template<class T, class U, int Cols>
+    T operator*(const Matrix<T, 1, Cols> &l, const Matrix<U, 1, Cols> &r)
+    {
+        return inner_product(l, r);
+    }
+
+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
+    Matrix<T, RowsL, ColsL> operator^(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
+    {
+        return cross_product(l, r);
+    }
+
+    template<class T, class U, int Rows, int Cols>
+    bool operator==(const Matrix<T, Rows, Cols> &l, const Matrix<U, Rows, Cols> &r)
+    {
+        for(int i = 0; i < Rows; ++i)
                 for(int j = 0; j < Cols; ++j)
                     if(l(i, j) != r(i, j))
                         return false;
 
             return true;
-        }
-
-        template<class T, int Rows>
-        T inner_product(const Matrix<T, Rows, 1> &l, const Matrix<T, Rows, 1> &r)
-        {
-            T result = 0;
-
-            for(int i = 0; i < Rows; ++i)
-                result += l(i) * r(i);
-
-            return result;
-        }
-
-        template<class T, int Cols>
-        T inner_product(const Matrix<T, 1, Cols> &l, const Matrix<T, 1, Cols> &r)
-        {
-            T result = 0;
-
-            for(int j = 0; j < Cols; ++j)
-                result += l(j) * r(j);
-
-            return result;
-        }
-
-        template<class T, int Rows, int Cols>
-        T magnitude(const Matrix<T, Rows, Cols> &m)
-        {
-            return std::sqrt(inner_product(m, m));
-        }
-
-        template<int Rows, int Cols>
-        int magnitude(const Matrix<int, Rows, Cols> &m)
-        {
-            return (int)std::sqrt((double)inner_product(m, m));
-        }
-
-        template<class T, int Rows, int Cols>
-        Matrix<T, Rows, Cols> normalize(const Matrix<T, Rows, Cols> &m)
-        {
-            return m / magnitude(m);
-        }
-
-        template<class T>
-        Matrix<T, 3, 1> cross_product(const Matrix<T, 3, 1> &l, const Matrix<T, 3, 1> &r)
-        {
-            Matrix<T, 3, 1> result = {
-                l(1) * r(2) - l(2) * r(1),
-                l(2) * r(0) - l(0) * r(2),
-                l(0) * r(1) - l(1) * r(0)
-            };
-            return result;
-        }
-
-        template<class T>
-        Matrix<T, 1, 3> cross_product(const Matrix<T, 1, 3> &l, const Matrix<T, 1, 3> &r)
-        {
-            Matrix<T, 1, 3> result = {
-                l(1) * r(2) - l(2) * r(1),
-                l(2) * r(0) - l(0) * r(2),
-                l(0) * r(1) - l(1) * r(0)
-            };
-            return result;
-        }
-
-        template<class T>
-        T determinant(const Matrix<T, 2, 2> &m)
-        {
-            return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);
-        }
-        
-        template<class T, int N>
-        Matrix<T, N - 1, N - 1> minor_matrix(const Matrix<T, N, N> &m, int i, int j)
-        {
-            Matrix<T, N - 1, N - 1> result;
-
-            for(int a = 0, b = 0; a < N; ++a)
-            {
-                if(a != i)
-                {
-                    for(int c = 0, d = 0; c < N; ++c)
-                    {
-                        if(c != j)
-                        {
-                            result(b, d) = m(a, c);
-                            ++d;
-                        }
-                    }
-                    ++b;
-                }
-            }
-
-            return result;
-        }
-
-        template<class T, int N>
-        T cofactor(const Matrix<T, N, N> &m, int row, int col)
-        {
-            return determinant(minor_matrix(m, row, col)) * (T)std::pow((T)-1, row + col);
-        }
-
-        template<int N>
-        int cofactor(const Matrix<int, N, N> &m, int row, int col)
-        {
-            return determinant(minor_matrix(m, row, col)) * (int)std::pow(-1.0, row + col);
-        }
-
-        template<class T, int N>
-        Matrix<T, N, N> cofactor_matrix(const Matrix<T, N, N> &m)
-        {
-            Matrix<T, N, N> result;
-
-            for(int i = 0; i < N; ++i)
-                for(int j = 0; j < N; ++j)
-                    result(i, j) = cofactor(m, i, j);
-
-            return result;
-        }
-
-        template<class T, int N>
-        Matrix<T, N, N> adjoint(const Matrix<T, N, N> &m)
-        {
-            return transpose(cofactor_matrix(m));
-        }
-
-        template<class T, int N>
-        T determinant(const Matrix<T, N, N> &m)
-        {
-            T result = 0;
-
-            // Laplace expansion of first row
-            for(int i = 0; i < N; ++i)
-                result += m(i, 0) * cofactor(m, i, 0);
-
-            return result;
-        }
-
-        template<class T>
-        Matrix<T, 2, 2> inverse(const Matrix<T, 2, 2> &m)
-        {
-            Matrix<T, 2, 2> result = {m(1, 1), -m(0, 1), -m(1, 0), m(0, 0)};
-            return result / determinant(m);
-        }
-
-        template<class T, int N>
-        Matrix<T, N, N> inverse(const Matrix<T, N, N> &m)
-        {
-            return adjoint(m) / determinant(m);
-        }
     }
-
-    template<class T, int Rows, int Cols>
-    Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m)
-    {
-        return m;
-    }
-
-    template<class T, int Rows, int Cols>
-    Matrix<T, Rows, Cols> operator-(const Matrix<T, Rows, Cols> &m)
-    {
-        return Matrix_detail::negate(m);
-    }
-
-    template<class T, int Rows, int Cols>
-    Matrix<T, Rows, Cols> operator~(const Matrix<T, Rows, Cols> &m)
-    {
-        return Matrix_detail::inverse(m);
-    }
-
-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
-    Matrix<T, RowsL, ColsL> operator+(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
-    {
-        return Matrix_detail::add(l, r);
-    }
-
-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
-    Matrix<T, RowsL, ColsL> operator-(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
-    {
-        return Matrix_detail::subtract(l, r);
-    }
-
-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
-    Matrix<T, RowsL, ColsR> operator*(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
-    {
-        return Matrix_detail::multiply(l, r);
-    }
-
-    template<class T, int Rows, int Cols>
-    Matrix<T, Rows, Cols> operator*(const Matrix<T, Rows, Cols> &m, T s)
-    {
-        return Matrix_detail::scalar_multiply(m, s);
-    }
-
-    template<class T, int Rows, int Cols>
-    Matrix<T, Rows, Cols> operator/(const Matrix<T, Rows, Cols> &m, T s)
-    {
-        return Matrix_detail::scalar_divide(m, s);
-    }
-
-    template<class T, class U, int RowsL, int RowsR>
-    T operator*(const Matrix<T, RowsL, 1> &l, const Matrix<U, RowsR, 1> &r)
-    {
-        return Matrix_detail::inner_product(l, r);
-    }
-
-    template<class T, class U, int ColsL, int ColsR>
-    T operator*(const Matrix<T, 1, ColsL> &l, const Matrix<U, 1, ColsR> &r)
-    {
-        return Matrix_detail::inner_product(l, r);
-    }
-
-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
-    Matrix<T, RowsL, ColsL> operator^(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
-    {
-        return Matrix_detail::cross_product(l, r);
-    }
-
-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>
-    bool operator==(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)
-    {
-        return Matrix_detail::equals(l, r);
-    }
-
-    using Matrix_detail::magnitude;
-    using Matrix_detail::determinant;
-    using Matrix_detail::transpose;
-    using Matrix_detail::normalize;
 }

Matrix/Matrix/Matrix.vcproj

 			<File
 				RelativePath=".\Matrix.cpp"
 				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						GeneratePreprocessedFile="0"
+					/>
+				</FileConfiguration>
 			</File>
 		</Filter>
 		<Filter

Matrix/MatrixTests/MatrixTests.cpp

 
 BOOST_AUTO_TEST_CASE( test_add )
 {
-    Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();
+    const Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();
 
     Matrix<int, 3, 3> a = {0, 1, 2, 
                            3, 4, 5, 
     BOOST_CHECK_EQUAL(b + a, expected);
 }
 
+BOOST_AUTO_TEST_CASE( test_iadd )
+{
+    const Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();
+
+    Matrix<int, 3, 3> a = {0, 1, 2, 
+                           3, 4, 5, 
+                           6, 7, 8};
+
+    const Matrix<int, 3, 3> a0 = a;
+
+    a += zero;
+    BOOST_CHECK_EQUAL(a, a0);
+    
+    Matrix<int, 3, 3> b = {9, 8, 7, 
+                           6, 5, 4, 
+                           3, 2, 1};
+    const Matrix<int, 3, 3> b0 = b;
+    
+    Matrix<int, 3, 3> expected = {9, 9, 9, 
+                                  9, 9, 9, 
+                                  9, 9, 9};
+
+    b += a;
+    BOOST_CHECK_EQUAL(b, expected);
+    
+    b = b0;
+    a += b;
+    BOOST_CHECK_EQUAL(a, expected);
+}
+
 BOOST_AUTO_TEST_CASE( test_multiply )
 {
-    Matrix<int, 3, 3> I = identity_matrix<int, 3>();
+    const Matrix<int, 3, 3> I = identity_matrix<int, 3>();
     
     Matrix<int, 3, 3> a = {0, 1, 2, 
                            3, 4, 5, 
                                   -6,  3, -0,
                                    2, -1,  3};
 
-    BOOST_CHECK_EQUAL(Matrix_detail::cofactor_matrix(m), expected);
+    BOOST_CHECK_EQUAL(cofactor_matrix(m), expected);
 }
 
 BOOST_AUTO_TEST_CASE( test_adjoint )
                                    4,  3, -1,
                                   -3, -0,  3};
 
-    BOOST_CHECK_EQUAL(Matrix_detail::adjoint(m), expected);
+    BOOST_CHECK_EQUAL(adjoint(m), expected);
 }
 
 BOOST_AUTO_TEST_CASE( test_inverse )