Amit's 1d->2d matrix that I can base a rewrite of mine on.
This commit is contained in:
parent
80ef052e15
commit
079734941c
2 changed files with 134 additions and 81 deletions
|
@ -7,99 +7,100 @@
|
|||
|
||||
namespace amt {
|
||||
|
||||
template <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
struct Matrix {
|
||||
using base_type = std::vector<T>;
|
||||
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 <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
struct Matrix {
|
||||
using base_type = std::vector<T>;
|
||||
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 <bool IsConst>
|
||||
struct View {
|
||||
using base_type = std::conditional_t<IsConst, const_pointer, pointer>;
|
||||
base_type data;
|
||||
size_type size;
|
||||
template <bool IsConst>
|
||||
struct View {
|
||||
using base_type = std::conditional_t<IsConst, const_pointer, pointer>;
|
||||
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 reference operator[](size_type k) noexcept requires (!IsConst) {
|
||||
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;
|
||||
constexpr const_reference operator[](size_type k) const noexcept {
|
||||
assert(k < size && "Out of bound access");
|
||||
return data[k];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Matrix(size_type row, size_type col, value_type def = {})
|
||||
: m_data(row * col, def)
|
||||
, m_row(row)
|
||||
, m_col(col)
|
||||
{}
|
||||
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;
|
||||
|
||||
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(); }
|
||||
Matrix(size_type row, size_type col, value_type def = {})
|
||||
: m_data(row * col, def)
|
||||
, m_row(row)
|
||||
, m_col(col)
|
||||
{}
|
||||
|
||||
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 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 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 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) noexcept -> View<false> {
|
||||
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, 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) const noexcept -> View<true> {
|
||||
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, 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];
|
||||
}
|
||||
|
||||
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 << "]";
|
||||
}
|
||||
constexpr auto operator[](size_type r) noexcept -> View<false> {
|
||||
auto const base = r * m_col;
|
||||
assert(r < rows() && "Out of bound access");
|
||||
return { .data = m_data.data() + base, .size = m_col };
|
||||
}
|
||||
|
||||
private:
|
||||
base_type m_data;
|
||||
size_type m_row{};
|
||||
size_type m_col{};
|
||||
};
|
||||
constexpr auto operator[](size_type r) const noexcept -> View<true> {
|
||||
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
|
||||
|
|
52
tests/matrix2.cpp
Normal file
52
tests/matrix2.cpp
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue