sally

#include <iostream>

// If we increase row by 1, the offset will increase by sz (number of elements per row i.e. number of columns)
// If we increase col by 1, the offset will increase by 1
unsigned rowMajorOffset(unsigned row, unsigned col, unsigned sz)
{
    return col + row * sz;
}

// If we increase col by 1, the offset will increase by sz (number of elements per column i.e. number of rows)
// If we increase row by 1, the offset will increase by 1
unsigned columnMajorOffset(unsigned row, unsigned col, unsigned sz)
{
    return row + col * sz;
}

template <typename _ValueT, unsigned _R, unsigned _C, bool _ColumnMajor>
class Matrix {
protected:
	enum { ColumnMajor = _ColumnMajor };
	enum { R = _R };
	enum { C = _C };

	typedef _ValueT ValueT;

	ValueT m_values[C*R];

public:
	const ValueT & at (unsigned r, unsigned c) const
	{
		if (ColumnMajor)
			return m_values[columnMajorOffset(r, c, R)];
		else
			return m_values[rowMajorOffset(r, c, C)];
	}

	ValueT & at (unsigned r, unsigned c)
	{
		if (ColumnMajor)
			return m_values[columnMajorOffset(r, c, R)];
		else
			return m_values[rowMajorOffset(r, c, C)];
	}

	void loadTestPattern ()
	{
		for (unsigned r = 0; r < R; r += 1)
			for (unsigned c = 0; c < C; c += 1)
				at(r, c) = (r+1) * 1000 + (c+1);
	}

	void debug ()
	{
		using namespace std;

		if (ColumnMajor)
			cout << "Column-Major Matrix " << "(" << R << "," << C << ")" << " @ " << this << endl;
		else
			cout << "Row-Major Matrix " << "(" << R << "," << C << ")" << " @ " << this << endl;

		cout << "Memory Offset: ";
		for (unsigned i = 0; i < (R*C); i += 1)
			cout << i << "    ";
		cout << endl;

		cout << "       Values: ";	
		for (unsigned i = 0; i < (R*C); i += 1)
			cout << m_values[i] << " ";
		cout << endl;

		cout << "Standard Mathematical Notation:" << endl;
		cout << "      ";
		for (unsigned c = 0; c < C; c += 1)
			cout << "Col " << c << " ";
		cout << endl;

		for (unsigned r = 0; r < R; r += 1) {
			cout << "Row " << r << " ";
			for (unsigned c = 0; c < C; c += 1)
				cout << at(r, c) << "  ";
			cout << endl;
		}
		cout << endl;
	}

	Matrix<ValueT, R, C, !ColumnMajor> transposeStorage () const
	{
		Matrix<ValueT, R, C, !ColumnMajor> result;

		for (unsigned r = 0; r < R; r += 1)
			for (unsigned c = 0; c < C; c += 1)
				result.at(r, c) = at(r, c);

		return result;
	}

	Matrix<ValueT, C, R, !ColumnMajor> transposeMatrix () const
	{
		Matrix<ValueT, C, R, !ColumnMajor> result;

		memcpy(&result.at(0,0), m_values, sizeof(m_values));

		return result;
	}
};

int main (int argc, char * const argv[]) {
	Matrix<float, 4, 2, false> rowMajorMatrix;
	Matrix<float, 4, 2, true> columnMajorMatrix;

	rowMajorMatrix.loadTestPattern();
	rowMajorMatrix.debug();

	columnMajorMatrix.loadTestPattern();
	columnMajorMatrix.debug();

	rowMajorMatrix = columnMajorMatrix.transposeStorage();
	rowMajorMatrix.debug();

	Matrix<float, 2, 4, false> transposedMatrix = columnMajorMatrix.transposeMatrix();
	transposedMatrix.debug();

	return 0;
}

bob