src/matrix.h

changeset 17
a5111f4e6412
parent 11
771168ee2c76
child 21
0133e565e072
--- a/src/matrix.h	Fri Nov 08 19:05:07 2019 +0200
+++ b/src/matrix.h	Fri Dec 13 15:55:56 2019 +0200
@@ -1,10 +1,30 @@
 #pragma once
 #include <QGenericMatrix>
+#include <type_traits>
+
+template<int Rows, int Columns, typename T = double>
+struct MatrixIterator;
+
+template<int Rows, int Columns>
+struct MatrixIndex
+{
+	int row;
+	int column;
+};
 
 template<int Rows, int Columns, typename T = double>
 struct Matrix
 {
+	using Iterator = MatrixIterator<Rows, Columns, T>;
 	T values[Rows][Columns];
+	Iterator begin()
+	{
+		return {*this, {0, 0}};
+	}
+	Iterator end()
+	{
+		return {*this, {Rows, 0}};
+	}
 	T& operator()(int row, int column)
 	{
 		return this->values[row][column];
@@ -13,9 +33,78 @@
 	{
 		return this->values[row][column];
 	}
+	T& operator[](const MatrixIndex<Rows, Columns>& index)
+	{
+		return (*this)(index.row, index.column);
+	}
+	T operator[](const MatrixIndex<Rows, Columns>& index) const
+	{
+		return (*this)(index.row, index.column);
+	}
 };
 
 template<int Rows, int Columns, typename T>
+struct MatrixIterator
+{
+	struct Value
+	{
+		const MatrixIndex<Rows, Columns> index;
+		decltype(std::declval<Matrix<Rows, Columns, T>>()(0, 0)) value;
+	};
+	Matrix<Rows, Columns, T>& matrix;
+	MatrixIndex<Rows, Columns> index;
+};
+
+template<int Rows, int Columns>
+auto& operator++(MatrixIndex<Rows, Columns>& index)
+{
+	index.column += 1;
+	if (index.column >= Columns)
+	{
+		index.row += 1;
+		index.column -= Columns;
+	}
+	return index;
+}
+
+template<int Rows, int Columns>
+bool operator==(
+	const MatrixIndex<Rows, Columns>& one,
+	const MatrixIndex<Rows, Columns>& other)
+{
+	return one.row == other.row and one.column == other.column;
+}
+template<int Rows, int Columns, typename T>
+auto& operator++(MatrixIterator<Rows, Columns, T>& iterator)
+{
+	++iterator.index;
+	return iterator;
+}
+
+template<int Rows, int Columns, typename T>
+bool operator==(
+	const MatrixIterator<Rows, Columns, T>& one,
+	const MatrixIterator<Rows, Columns, T>& other)
+{
+	return &one.matrix == &other.matrix and one.index == other.index;
+}
+
+template<int Rows, int Columns, typename T>
+bool operator!=(
+	const MatrixIterator<Rows, Columns, T>& one,
+	const MatrixIterator<Rows, Columns, T>& other)
+{
+	return not (one == other);
+}
+
+template<int Rows, int Columns, typename T>
+auto operator*(MatrixIterator<Rows, Columns, T>& iterator)
+	-> typename MatrixIterator<Rows, Columns, T>::Value
+{
+	return {iterator.index, iterator.matrix[iterator.index]};
+}
+
+template<int Rows, int Columns, typename T>
 QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix)
 {
 	return {matrix.values};
@@ -25,12 +114,9 @@
 Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix)
 {
 	Matrix<Rows, Columns, T> result;
-	for (int row = 0; row < Rows; row += 1)
+	for (auto& cell : result)
 	{
-		for (int column = 0; column < Columns; column += 1)
-		{
-			result(row, column) = matrix(row, column);
-		}
+		matrix(cell.index.row, cell.index.column) = result[cell.index];
 	}
 	return result;
 }
@@ -43,14 +129,22 @@
 template<int Rows, int Columns, typename T>
 QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix)
 {
-	return stream << matrixToQGenericMatrix(matrix);
+	for (auto& cell : matrix)
+	{
+		stream << cell.value;
+	}
+	return stream;
 }
 
 template<int Rows, int Columns, typename T>
 QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix)
 {
-	QGenericMatrix<Rows, Columns, T> qmatrix;
-	stream >> qmatrix;
-	matrix = matrixFromQGenericMatrix(matrix);
+	for (auto& cell : matrix)
+	{
+		stream >> cell.value;
+	}
 	return stream;
 }
+
+static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
+static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};

mercurial