diff --git a/scratchpad/amitmatrix.hpp b/scratchpad/amitmatrix.hpp index c7e47f9..2a9af08 100644 --- a/scratchpad/amitmatrix.hpp +++ b/scratchpad/amitmatrix.hpp @@ -7,99 +7,100 @@ namespace amt { - template - requires std::is_integral_v - struct Matrix { - using base_type = std::vector; - using value_type = typename base_type::value_type; - using pointer = typename base_type::pointer; - using const_pointer = typename base_type::const_pointer; - using reference = typename base_type::reference; - using const_reference = typename base_type::const_reference; - using iterator = typename base_type::iterator; - using const_iterator = typename base_type::const_iterator; - using size_type = std::size_t; - - template - struct View { - using base_type = std::conditional_t; - base_type data; - size_type size; - - constexpr auto operator[](size_type k) const noexcept { - assert(k < size && "Out of bound access"); - return data[k]; - } - - constexpr auto operator[](size_type k) noexcept requires (!IsConst) { - assert(k < size && "Out of bound access"); - return data[k]; - } - }; - - constexpr Matrix() noexcept = default; - constexpr Matrix(Matrix const&) = default; - constexpr Matrix& operator=(Matrix const&) = default; - constexpr Matrix(Matrix &&) noexcept = default; - constexpr Matrix& operator=(Matrix &&) noexcept = default; - constexpr ~Matrix() = default; - - - Matrix(size_type row, size_type col, value_type def = {}) - : m_data(row * col, def) - , m_row(row) - , m_col(col) - {} - - constexpr bool empty() const noexcept { return m_data.empty(); }; - constexpr bool size() const noexcept { return m_data.size(); }; - constexpr size_type rows() const noexcept { return m_row; }; - constexpr size_type cols() const noexcept { return m_col; }; - - constexpr iterator begin() noexcept { return m_data.begin(); } - constexpr iterator end() noexcept { return m_data.end(); } - constexpr const_iterator begin() const noexcept { return m_data.begin(); } - constexpr const_iterator end() const noexcept { return m_data.end(); } - - constexpr auto operator()(size_type r, size_type c) noexcept -> reference { - auto const index = r * m_col + c; // column-major; - assert(index < size() && "Out of bound access"); - return m_data[index]; - } - - constexpr auto operator()(size_type r, size_type c) const noexcept -> const_reference { - auto const index = r * m_col + c; // column-major; - assert(index < size() && "Out of bound access"); - return m_data[index]; - } - - constexpr auto operator[](size_type r) noexcept -> View { - auto const base = r * m_col; - assert(r < rows() && "Out of bound access"); - return { .data = m_data.data() + base, .size = m_col }; - } - - constexpr auto operator[](size_type r) const noexcept -> View { - auto const base = r * m_col; - assert(r < rows() && "Out of bound access"); - return { .data = m_data.data() + base, .size = m_col }; - } - - friend std::ostream& operator<<(std::ostream& os, Matrix const& m) { - os << "[\n"; - for (auto i = size_type{}; i < m.rows(); ++i) { - for (auto j = size_type{}; j < m.cols(); ++j) { - os << m[i][j] << ", "; - } - os << '\n'; - } - return os << "]"; - } - - private: - base_type m_data; - size_type m_row{}; - size_type m_col{}; - }; + template + requires std::is_integral_v + struct Matrix { + using base_type = std::vector; + using value_type = typename base_type::value_type; + using pointer = typename base_type::pointer; + using const_pointer = typename base_type::const_pointer; + using reference = typename base_type::reference; + using const_reference = typename base_type::const_reference; + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using size_type = std::size_t; + + template + struct View { + using base_type = std::conditional_t; + base_type data; + size_type size; + + constexpr reference operator[](size_type k) noexcept requires (!IsConst) { + assert(k < size && "Out of bound access"); + return data[k]; + } + + constexpr const_reference operator[](size_type k) const noexcept { + assert(k < size && "Out of bound access"); + return data[k]; + } + }; + + + constexpr Matrix() noexcept = default; + constexpr Matrix(Matrix const&) = default; + constexpr Matrix& operator=(Matrix const&) = default; + constexpr Matrix(Matrix &&) noexcept = default; + constexpr Matrix& operator=(Matrix &&) noexcept = default; + constexpr ~Matrix() = default; + + + Matrix(size_type row, size_type col, value_type def = {}) + : m_data(row * col, def) + , m_row(row) + , m_col(col) + {} + + constexpr bool empty() const noexcept { return m_data.empty(); }; + constexpr bool size() const noexcept { return m_data.size(); }; + constexpr size_type rows() const noexcept { return m_row; }; + constexpr size_type cols() const noexcept { return m_col; }; + + constexpr iterator begin() noexcept { return m_data.begin(); } + constexpr iterator end() noexcept { return m_data.end(); } + constexpr const_iterator begin() const noexcept { return m_data.begin(); } + constexpr const_iterator end() const noexcept { return m_data.end(); } + + constexpr auto operator()(size_type r, size_type c) noexcept -> reference { + auto const index = r * m_col + c; // column-major; + assert(index < size() && "Out of bound access"); + return m_data[index]; + } + + constexpr auto operator()(size_type r, size_type c) const noexcept -> const_reference { + auto const index = r * m_col + c; // column-major; + assert(index < size() && "Out of bound access"); + return m_data[index]; + } + + constexpr auto operator[](size_type r) noexcept -> View { + auto const base = r * m_col; + assert(r < rows() && "Out of bound access"); + return { .data = m_data.data() + base, .size = m_col }; + } + + constexpr auto operator[](size_type r) const noexcept -> View { + auto const base = r * m_col; + assert(r < rows() && "Out of bound access"); + return { .data = m_data.data() + base, .size = m_col }; + } + + friend std::ostream& operator<<(std::ostream& os, Matrix const& m) { + os << "[\n"; + for (auto i = size_type{}; i < m.rows(); ++i) { + for (auto j = size_type{}; j < m.cols(); ++j) { + os << m[i][j] << ", "; + } + os << '\n'; + } + return os << "]"; + } + + private: + base_type m_data; + size_type m_row{}; + size_type m_col{}; + }; } // namespace amt diff --git a/tests/matrix2.cpp b/tests/matrix2.cpp new file mode 100644 index 0000000..e3522c9 --- /dev/null +++ b/tests/matrix2.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include "rand.hpp" +#include "scratchpad/amitmatrix.hpp" +#include "worldbuilder.hpp" +#include +#include +#include + +using namespace fmt; +using std::string; + +inline void random_matrix(amt::Matrix &out) { + for(size_t y = 0; y < out.rows(); y++) { + for(size_t x = 0; x < out.cols(); x++) { + out[y][x] = Random::uniform(-10,10); + } + } +} + +TEST_CASE("basic matrix iterator", "[matrix2:basic]") { + size_t width = Random::uniform(5, 11); + size_t height = Random::uniform(3, 13); + + amt::Matrix test{height,width,0}; + random_matrix(test); + + println("FIRST RANDOM"); + std::cout << test << std::endl; + + for(auto cell : test) { + print("{} ", cell); + } + + println("DIRECT ACCESS"); + for(size_t y = 0; y < test.rows(); y++) { + for(size_t x = 0; x < test.cols(); x++) { + print("{} ", test(x, y)); + } + } + + auto filled = test; + std::fill(filled.begin(), filled.end(), 8); + println("SECOND FILLED"); + std::cout << filled << std::endl; + + auto iota_style = filled; + std::iota(iota_style.begin(), iota_style.end(), 0); + println("THIRD IOTA"); + std::cout << iota_style << std::endl; +}