#pragma once #include "matrix.hpp" template <typename Element> Matrix<Element>::Matrix(const Bounds &bounds) noexcept : _matrix(new Element *[bounds.get_height()]), _row_cnt(bounds.get_height()), _column_cnt(bounds.get_width()) { for (gsl::owner<Element **> row = _matrix; row != _matrix + _row_cnt; row++) { *row = static_cast<gsl::owner<Element *>>(new Element[bounds.get_width()]); } }; template <typename Element> Matrix<Element>::Matrix(const Matrix &matrix) noexcept : _matrix(new Element *[matrix._row_cnt]), _row_cnt(matrix._row_cnt), _column_cnt(matrix._column_cnt) { _copy_matrix_from(matrix); } template <typename Element> Matrix<Element>::Matrix(Matrix &&matrix) noexcept : _matrix(matrix._matrix), _row_cnt(matrix._row_cnt), _column_cnt(matrix._column_cnt) { matrix._matrix = nullptr; } template <typename Element> Matrix<Element>::~Matrix() noexcept { _delete_matrix(); } template <typename Element> void Matrix<Element>::fill(Element element) noexcept { for (auto row : *this) { for (auto &col : row) { col = element; } } } template <typename Element> auto Matrix<Element>::get(const Vector2 &pos) const noexcept -> Element { auto x = static_cast<std::size_t>(pos.get_x()); auto y = static_cast<std::size_t>(pos.get_y()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) return _matrix[y][x]; } template <typename Element> void Matrix<Element>::set(const Vector2 &pos, Element element) noexcept { auto x = static_cast<std::size_t>(pos.get_x()); auto y = static_cast<std::size_t>(pos.get_y()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) _matrix[y][x] = element; } template <typename Element> auto Matrix<Element>::get_row_cnt() const noexcept -> uint32_t { return _row_cnt; } template <typename Element> auto Matrix<Element>::get_column_cnt() const noexcept -> uint32_t { return _column_cnt; } template <typename Element> auto Matrix<Element>::begin() const noexcept -> MatrixIterator<Element> { return MatrixIterator(_matrix, _column_cnt); } template <typename Element> auto Matrix<Element>::end() const noexcept -> MatrixIterator<Element> { return MatrixIterator(_matrix + _row_cnt, _column_cnt); } template <typename Element> auto Matrix<Element>::operator=(const Matrix &rhs) noexcept -> Matrix<Element> & { if (&rhs != this) { _delete_matrix(); // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) _matrix = nullptr; _matrix = new Element *[rhs._row_cnt]; _copy_matrix_from(rhs); } return *this; } template <typename Element> auto Matrix<Element>::operator=(Matrix &&rhs) noexcept -> Matrix<Element> & { if (&rhs != this) { _delete_matrix(); // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) _matrix = rhs._matrix; rhs._matrix = nullptr; } return *this; } template <typename Element> void Matrix<Element>::_delete_matrix() noexcept { for (gsl::owner<Element **> row = _matrix; row != _matrix + _row_cnt; row++) { delete[](*row); } delete[] _matrix; } template <typename Element> void Matrix<Element>::_copy_matrix_from(const Matrix &source) noexcept { // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) gsl::owner<Element **> source_row = source._matrix; for (gsl::owner<Element **> row = _matrix; row != _matrix + _row_cnt; row++, source_row++) { *row = static_cast<gsl::owner<Element *>>(new Element[_column_cnt]); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) auto *end = *source_row + _column_cnt; std::copy(*source_row, end, *row); } }