Amit's 1d->2d matrix that I can base a rewrite of mine on.

main
Zed A. Shaw 1 week ago
parent 80ef052e15
commit 079734941c
  1. 189
      scratchpad/amitmatrix.hpp
  2. 52
      tests/matrix2.cpp

@ -7,99 +7,100 @@
namespace amt { namespace amt {
template <typename T> template <typename T>
requires std::is_integral_v<T> requires std::is_integral_v<T>
struct Matrix { struct Matrix {
using base_type = std::vector<T>; using base_type = std::vector<T>;
using value_type = typename base_type::value_type; using value_type = typename base_type::value_type;
using pointer = typename base_type::pointer; using pointer = typename base_type::pointer;
using const_pointer = typename base_type::const_pointer; using const_pointer = typename base_type::const_pointer;
using reference = typename base_type::reference; using reference = typename base_type::reference;
using const_reference = typename base_type::const_reference; using const_reference = typename base_type::const_reference;
using iterator = typename base_type::iterator; using iterator = typename base_type::iterator;
using const_iterator = typename base_type::const_iterator; using const_iterator = typename base_type::const_iterator;
using size_type = std::size_t; using size_type = std::size_t;
template <bool IsConst> template <bool IsConst>
struct View { struct View {
using base_type = std::conditional_t<IsConst, const_pointer, pointer>; using base_type = std::conditional_t<IsConst, const_pointer, pointer>;
base_type data; base_type data;
size_type size; size_type size;
constexpr auto operator[](size_type k) const noexcept { constexpr reference operator[](size_type k) noexcept requires (!IsConst) {
assert(k < size && "Out of bound access"); assert(k < size && "Out of bound access");
return data[k]; return data[k];
} }
constexpr auto operator[](size_type k) noexcept requires (!IsConst) { constexpr const_reference operator[](size_type k) const noexcept {
assert(k < size && "Out of bound access"); assert(k < size && "Out of bound access");
return data[k]; return data[k];
} }
}; };
constexpr Matrix() noexcept = default;
constexpr Matrix(Matrix const&) = default; constexpr Matrix() noexcept = default;
constexpr Matrix& operator=(Matrix const&) = default; constexpr Matrix(Matrix const&) = default;
constexpr Matrix(Matrix &&) noexcept = default; constexpr Matrix& operator=(Matrix const&) = default;
constexpr Matrix& operator=(Matrix &&) noexcept = default; constexpr Matrix(Matrix &&) noexcept = default;
constexpr ~Matrix() = 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) Matrix(size_type row, size_type col, value_type def = {})
, m_row(row) : m_data(row * col, def)
, m_col(col) , 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 bool empty() const noexcept { return m_data.empty(); };
constexpr size_type rows() const noexcept { return m_row; }; constexpr bool size() const noexcept { return m_data.size(); };
constexpr size_type cols() const noexcept { return m_col; }; 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 iterator begin() noexcept { return m_data.begin(); }
constexpr const_iterator begin() const noexcept { return m_data.begin(); } constexpr iterator end() noexcept { return m_data.end(); }
constexpr const_iterator end() const 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; constexpr auto operator()(size_type r, size_type c) noexcept -> reference {
assert(index < size() && "Out of bound access"); auto const index = r * m_col + c; // column-major;
return m_data[index]; 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; constexpr auto operator()(size_type r, size_type c) const noexcept -> const_reference {
assert(index < size() && "Out of bound access"); auto const index = r * m_col + c; // column-major;
return m_data[index]; assert(index < size() && "Out of bound access");
} return m_data[index];
}
constexpr auto operator[](size_type r) noexcept -> View<false> {
auto const base = r * m_col; constexpr auto operator[](size_type r) noexcept -> View<false> {
assert(r < rows() && "Out of bound access"); auto const base = r * m_col;
return { .data = m_data.data() + base, .size = 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<true> {
auto const base = r * m_col; constexpr auto operator[](size_type r) const noexcept -> View<true> {
assert(r < rows() && "Out of bound access"); auto const base = r * m_col;
return { .data = m_data.data() + base, .size = 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"; friend std::ostream& operator<<(std::ostream& os, Matrix const& m) {
for (auto i = size_type{}; i < m.rows(); ++i) { os << "[\n";
for (auto j = size_type{}; j < m.cols(); ++j) { for (auto i = size_type{}; i < m.rows(); ++i) {
os << m[i][j] << ", "; for (auto j = size_type{}; j < m.cols(); ++j) {
} os << m[i][j] << ", ";
os << '\n'; }
} os << '\n';
return os << "]"; }
} return os << "]";
}
private:
base_type m_data; private:
size_type m_row{}; base_type m_data;
size_type m_col{}; size_type m_row{};
}; size_type m_col{};
};
} // namespace amt } // namespace amt

@ -0,0 +1,52 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "rand.hpp"
#include "scratchpad/amitmatrix.hpp"
#include "worldbuilder.hpp"
#include <iostream>
#include <numeric>
#include <algorithm>
using namespace fmt;
using std::string;
inline void random_matrix(amt::Matrix<int> &out) {
for(size_t y = 0; y < out.rows(); y++) {
for(size_t x = 0; x < out.cols(); x++) {
out[y][x] = Random::uniform<int>(-10,10);
}
}
}
TEST_CASE("basic matrix iterator", "[matrix2:basic]") {
size_t width = Random::uniform<size_t>(5, 11);
size_t height = Random::uniform<size_t>(3, 13);
amt::Matrix<int> 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;
}
Loading…
Cancel
Save