Problem A
The Matrix
In this assignment you will implement a matrix class. You may need to refresh your knowledge on basic matrix arithmetics. The matrix should be implemented with a onedimensional array (m_vec) which means you need to use some simple arithmetic to access a matrix index (i, j). If the number of rows is only one, the matrix will essentially behave like a vector. Random access to an element should be on average constant O(1). The first element (0, 0) is at m_vec[0].
You shall upload a single file named Matrix.h
Requirements
Constructors and assignment operators

It should be possible to construct the matrix with a single number. The matrix created should be a square matrix with initial elements set to the default element of the type.
Matrix<int> m(3); m [ 0 0 0 0 0 0 0 0 0 ]

It should be possible to defaultconstruct the container, which should be semantically equivalent to Matrix<T>(0).

It should be possible to construct a matrix with two parameters specifying the rows and columns of the matrix.

You should implement a copyconstructor and a destructor. Note modifying a copied matrix should not change the contents of the copiedfrom matrix.

It should not be possible to instantiate the class template unless the specified element type is both moveConstructible and moveAssignable. Use static_assert with an appropriate error message, to moveAssignable. Use static_assert with an appropriate error message, to make sure that this is the case.

Appropriate constructors should be explicit. If someone, without intending to, types m = 3 there should be a compile error.

You should implement a copyassignment operator, and although assigning a matrix to itself might seem silly, make sure it is handled correctly.

Implement a moveconstructor and a moveassignment operator taking another matrix potentially of a different size. Move constructors can reduce the number of copies in a C++program.

Implement a constructor taking std::initializer_list. This constructor can only construct square matrices. If the number of elements is not an even square root std::out_of_range should be thrown. The first elements defines the first row and then the next rows in sequence.
Accessors

Implement rows() and cols() which returns number of rows and columns respectively.

Implement the function operator to access/modify elements. Make a const version as well.
Matrix<int> m(3); m(1, 1) = 3; const Matrix<int> & mref = m; std::cout << mref(1, 1);
Operators
For both scalar and matrix operations:

Implement * +  which should be chainable.

Implement *= += = as non chainable.
Writing and reading from stdin and stdout in human friendly (readable) format.

Implement operator<< and operator>> and make them compatible. If you write to a file, you should be able to read the matrix from the same file. The exact format is up to you but do make it humanreadable (use a line break after each row).
Methods/functions

Implement reset() method which sets all elements to the default value of the type. Default constructor T() can be assumed.

Implement the function identity(unsigned int) which returns a square identity matrix where all elements but the diagonal are set to 0 and the diagonal values to 1. This function does only have to work with numeric types such as int or double.

Implement insert_row which inserts a row of zeroes before a given row number.

Implement append_row which inserts a row of zeroes after a given row number.

Implement remove_row which erases the entire row at a given row number.

Implement insert_column which inserts a column of zeroes before a given column number.

Implement append_column which inserts a column of zeroes after a given column number.

Implement remove_column which erases the entire column at a given column number.
Iterators, do typedef T* as iterator

Implement begin() which returns the pointer to the first element of the matrix.

Implement end() which returns the pointer to the element after the last element.
When being typedef, these will essentially work as random access iterators and can be used by library.