Move amt's examples into scratchpad for later review.
This commit is contained in:
parent
9c02fb846b
commit
a4a4389281
8 changed files with 1847 additions and 0 deletions
197
scratchpad/amt/matrix.hpp
Normal file
197
scratchpad/amt/matrix.hpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace amt {
|
||||
|
||||
namespace detail {
|
||||
[[nodiscard]] constexpr auto cal_index(
|
||||
std::size_t r,
|
||||
std::size_t c,
|
||||
[[maybe_unused]] std::size_t rs,
|
||||
[[maybe_unused]] std::size_t cs
|
||||
) -> std::size_t {
|
||||
return r * cs + c;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct Matrix {
|
||||
using value_type = T;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = value_type const*;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
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 r;
|
||||
size_type rows;
|
||||
size_type cols;
|
||||
|
||||
constexpr reference operator[](size_type c) noexcept requires (!IsConst) {
|
||||
assert(c < cols && "Out of bound access");
|
||||
auto const index = detail::cal_index(r, c, rows, cols);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type c) const noexcept {
|
||||
assert(c < cols && "Out of bound access");
|
||||
auto const index = detail::cal_index(r, c, rows, cols);
|
||||
return data[index];
|
||||
}
|
||||
};
|
||||
|
||||
constexpr Matrix() noexcept = default;
|
||||
Matrix(Matrix const& other)
|
||||
: Matrix(other.rows(), other.cols())
|
||||
{
|
||||
std::copy(other.begin(), other.end(), begin());
|
||||
}
|
||||
Matrix& operator=(Matrix const& other) {
|
||||
if (this == &other) return *this;
|
||||
auto temp = Matrix(other);
|
||||
swap(temp, *this);
|
||||
return *this;
|
||||
}
|
||||
constexpr Matrix(Matrix && other) noexcept
|
||||
: m_data(other.m_data)
|
||||
, m_row(other.m_row)
|
||||
, m_col(other.m_col)
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
}
|
||||
constexpr Matrix& operator=(Matrix && other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
swap(*this, other);
|
||||
return *this;
|
||||
}
|
||||
~Matrix() {
|
||||
if (m_data) delete[] m_data;
|
||||
}
|
||||
|
||||
|
||||
Matrix(size_type row, size_type col)
|
||||
: m_data(new value_type[row * col])
|
||||
, m_row(row)
|
||||
, m_col(col)
|
||||
{}
|
||||
|
||||
Matrix(size_type row, size_type col, value_type def)
|
||||
: Matrix(row, col)
|
||||
{
|
||||
std::fill(begin(), end(), def);
|
||||
}
|
||||
|
||||
Matrix(std::initializer_list<std::initializer_list<value_type>> li)
|
||||
: m_row(li.size())
|
||||
{
|
||||
for (auto const& row: li) {
|
||||
m_col = std::max(m_col, row.size());
|
||||
}
|
||||
|
||||
auto const size = m_row * m_col;
|
||||
|
||||
if (size == 0) return;
|
||||
|
||||
m_data = new value_type[size];
|
||||
std::fill_n(m_data, size, 0);
|
||||
|
||||
for (auto r = 0ul; auto const& row: li) {
|
||||
for (auto c = 0ul; auto const& col: row) {
|
||||
this->operator()(r, c++) = col;
|
||||
}
|
||||
++r;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
constexpr size_type size() const noexcept { return rows() * cols(); }
|
||||
constexpr size_type rows() const noexcept { return m_row; }
|
||||
constexpr size_type cols() const noexcept { return m_col; }
|
||||
constexpr auto data() noexcept -> pointer { return m_data; }
|
||||
constexpr auto data() const noexcept -> const_pointer { return m_data; }
|
||||
|
||||
constexpr iterator begin() noexcept { return m_data; }
|
||||
constexpr iterator end() noexcept { return m_data + size(); }
|
||||
constexpr const_iterator begin() const noexcept { return m_data; }
|
||||
constexpr const_iterator end() const noexcept { return m_data + size(); }
|
||||
constexpr reverse_iterator rbegin() noexcept { return std::reverse_iterator(end()); }
|
||||
constexpr reverse_iterator rend() noexcept { return std::reverse_iterator(begin()); }
|
||||
constexpr const_reverse_iterator rbegin() const noexcept { return std::reverse_iterator(end()); }
|
||||
constexpr const_reverse_iterator rend() const noexcept { return std::reverse_iterator(begin()); }
|
||||
|
||||
constexpr auto operator()(size_type r, size_type c) noexcept -> reference {
|
||||
auto const index = detail::cal_index(r, c, rows(), cols());
|
||||
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 = detail::cal_index(r, c, rows(), cols());
|
||||
assert(index < size() && "Out of bound access");
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
constexpr auto operator[](size_type r) noexcept -> View<false> {
|
||||
assert(r < rows() && "Out of bound access");
|
||||
return { .data = m_data, .r = r, .rows = m_row, .cols = m_col };
|
||||
}
|
||||
|
||||
constexpr auto operator[](size_type r) const noexcept -> View<true> {
|
||||
assert(r < rows() && "Out of bound access");
|
||||
return { .data = m_data, .r = r, .rows = m_row, .cols = m_col };
|
||||
}
|
||||
|
||||
friend void swap(Matrix& lhs, Matrix& rhs) noexcept {
|
||||
using std::swap;
|
||||
swap(lhs.m_data, rhs.m_data);
|
||||
swap(lhs.m_row, rhs.m_row);
|
||||
swap(lhs.m_col, rhs.m_col);
|
||||
}
|
||||
|
||||
private:
|
||||
pointer m_data{};
|
||||
size_type m_row{};
|
||||
size_type m_col{};
|
||||
};
|
||||
|
||||
} // namespace amt
|
||||
|
||||
#if 0
|
||||
#include <format>
|
||||
namespace std {
|
||||
template <typename T>
|
||||
struct formatter<amt::Matrix<T>> {
|
||||
constexpr auto parse(format_parse_context& ctx) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
auto format(amt::Matrix<T> const& m, auto& ctx) const {
|
||||
std::string s = "[\n";
|
||||
for (auto r = std::size_t{}; r < m.rows(); ++r) {
|
||||
for (auto c = std::size_t{}; c < m.cols(); ++c) {
|
||||
s += std::format("{}, ", m(r, c));
|
||||
}
|
||||
s += '\n';
|
||||
}
|
||||
s += "]";
|
||||
return format_to(ctx.out(), "{}", s);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue