#pragma once #include <gsl/pointers> template <typename Element> class MatrixRowIterator { public: using ColumnPtr = gsl::owner<Element *>; explicit MatrixRowIterator(ColumnPtr column_ptr) noexcept; auto operator++() noexcept -> MatrixRowIterator &; auto operator++(int) noexcept -> MatrixRowIterator; auto operator*() const noexcept -> Element &; auto operator==(const MatrixRowIterator &rhs) const noexcept -> bool; auto operator!=(const MatrixRowIterator &rhs) const noexcept -> bool; private: ColumnPtr _column_ptr; }; template <typename Element> class MatrixRow { public: using RowPtr = gsl::owner<Element *>; explicit MatrixRow(RowPtr row_ptr, const uint32_t &column_cnt) noexcept; [[nodiscard]] auto begin() const noexcept -> MatrixRowIterator<Element>; [[nodiscard]] auto end() const noexcept -> MatrixRowIterator<Element>; private: RowPtr _row_ptr; const uint32_t &_column_cnt; }; template <typename Element> class MatrixIterator { public: using RowPtr = gsl::owner<Element **>; explicit MatrixIterator(RowPtr row_ptr, const uint32_t &column_cnt) noexcept; auto operator++() noexcept -> MatrixIterator &; auto operator++(int) noexcept -> MatrixIterator; auto operator*() const noexcept -> MatrixRow<Element>; auto operator==(const MatrixIterator &rhs) const noexcept -> bool; auto operator!=(const MatrixIterator &rhs) const noexcept -> bool; private: RowPtr _row_ptr; const uint32_t &_column_cnt; }; #include "matrix_iterator_impl.hpp"