3#include <stratax/core/containers/Buffer.hpp>
4#include <stratax/core/Concepts.hpp>
5#include <stratax/core/containers/Shape.hpp>
6#include <stratax/core/Exceptions.hpp>
7#include <stratax/core/containers/Strides.hpp>
10#include <initializer_list>
15namespace stratax::container {
71 buffer_(core::validation::checked_multiply(
rows,
cols,
"Matrix size overflow"))
83 : shape_(core::validation::require_rank(
shape, 2,
"Shape must be rank 2")),
85 buffer_(core::validation::checked_multiply(
88 "Matrix size overflow"))
102 buffer_(core::validation::checked_multiply(
rows,
cols,
"Matrix size overflow"), value)
115 Matrix(std::initializer_list<std::initializer_list<T>> list)
117 std::size_t
rows = list.size();
118 std::size_t
cols = (
rows == 0) ? 0 : list.begin()->size();
121 for (
const auto& row : list)
123 if (row.size() !=
cols)
132 core::validation::checked_multiply(
rows,
cols,
"Matrix size overflow"));
134 std::size_t index = 0;
136 for (
const auto& row : list)
138 for (
const auto& value : row)
140 buffer_[index++] = value;
175 [[nodiscard]] std::
size_t size() const noexcept
177 return shape_.elements();
185 [[nodiscard]]
bool empty() const noexcept
187 return buffer_.empty();
195 [[nodiscard]] std::size_t
rows() const noexcept
205 [[nodiscard]] std::size_t
cols() const noexcept
235 [[nodiscard]] std::size_t
rank() const noexcept
237 return shape_.rank();
251 core::validation::require_index(row,
rows(),
"Row index out of bounds.");
252 core::validation::require_index(col,
cols(),
"Column index out of bounds.");
253 return buffer_[row *
cols() + col];
267 core::validation::require_index(row,
rows(),
"Row index out of bounds.");
268 core::validation::require_index(col,
cols(),
"Column index out of bounds.");
269 return buffer_[row *
cols() + col];
282 return buffer_[index];
295 return buffer_[index];
307 T&
at(std::ptrdiff_t row, std::ptrdiff_t col)
309 const std::size_t normalized_row =
310 core::validation::normalize_index(row,
rows(),
"Row index out of bounds.");
311 const std::size_t normalized_col =
312 core::validation::normalize_index(col,
cols(),
"Column index out of bounds.");
313 return (*
this)(normalized_row, normalized_col);
325 const T&
at(std::ptrdiff_t row, std::ptrdiff_t col)
const
327 const std::size_t normalized_row =
328 core::validation::normalize_index(row,
rows(),
"Row index out of bounds.");
329 const std::size_t normalized_col =
330 core::validation::normalize_index(col,
cols(),
"Column index out of bounds.");
331 return (*
this)(normalized_row, normalized_col);
347 return buffer_.front();
363 return buffer_.front();
379 return buffer_.back();
395 return buffer_.back();
403 [[nodiscard]] T*
data() noexcept
405 return buffer_.data();
413 [[nodiscard]]
const T*
data() const noexcept
415 return buffer_.data();
425 return buffer_.begin();
435 return buffer_.begin();
445 return buffer_.cbegin();
455 return buffer_.end();
465 return buffer_.end();
475 return buffer_.cend();
485 return buffer_.rbegin();
495 return buffer_.rbegin();
505 return buffer_.crbegin();
515 return buffer_.rend();
525 return buffer_.rend();
535 return buffer_.crend();
557 swap(shape_, other.shape_);
558 swap(strides_, other.strides_);
559 swap(buffer_, other.buffer_);
Shared runtime validation helpers.
Signals an invalid index access.
Signals an invalid or incompatible shape.
const_iterator cend() const noexcept
Returns a const iterator one past the last element.
T * data() noexcept
Returns the raw data pointer.
const T & back() const
Returns the last element as a const reference.
void fill(const T &value)
Fills every element with the same value.
typename core::Buffer< T >::const_reverse_iterator const_reverse_iterator
Const reverse iterator over matrix elements.
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last element.
const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
const T & front() const
Returns the first element as a const reference.
typename core::Buffer< T >::iterator iterator
Mutable iterator over matrix elements.
Matrix()
Creates a default rank-2 empty matrix.
Matrix(std::initializer_list< std::initializer_list< T > > list)
Creates a matrix from a nested initializer list.
T & front()
Returns the first element.
bool empty() const noexcept
Returns whether the matrix contains no elements.
const T & operator()(std::size_t row, std::size_t col) const
Returns an element by row and column with bounds checking.
const T * data() const noexcept
Returns the raw data pointer as a const pointer.
Matrix< U > rebind
Rebinds the matrix container to another element type.
typename core::Buffer< T >::const_iterator const_iterator
Const iterator over matrix elements.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last element.
T & operator[](std::size_t index) noexcept
Returns a flat element without bounds checking.
const stratax::core::Strides & strides() const noexcept
Returns the matrix strides.
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the last element.
T & operator()(std::size_t row, std::size_t col)
Returns an element by row and column with bounds checking.
T & back()
Returns the last element.
Matrix(std::size_t rows, std::size_t cols, const T &value)
Creates a matrix and fills it with a value.
T value_type
Element type stored by the matrix.
std::size_t rank() const noexcept
Returns the matrix rank.
Matrix(const core::Shape &shape)
Creates a matrix from a validated rank-2 shape.
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator before the first element.
void swap(Matrix &other) noexcept
Swaps the contents of two matrices.
const T & operator[](std::size_t index) const noexcept
Returns a flat element without bounds checking.
Matrix(Matrix &&) noexcept=default
Transfers ownership from another matrix.
Matrix(const Matrix &)=default
Creates a copy of another matrix.
const stratax::core::Shape & shape() const noexcept
iterator begin() noexcept
Returns an iterator to the first element.
const_iterator begin() const noexcept
Returns a const iterator to the first element.
std::size_t size() const noexcept
Matrix(std::size_t rows, std::size_t cols)
Creates a rank-2 matrix with the given number of rows and columns.
reverse_iterator rend() noexcept
Returns a reverse iterator before the first element.
const_reverse_iterator rend() const noexcept
Returns a const reverse iterator before the first element.
typename core::Buffer< T >::reverse_iterator reverse_iterator
Mutable reverse iterator over matrix elements.
iterator end() noexcept
Returns an iterator one past the last element.
const T & at(std::ptrdiff_t row, std::ptrdiff_t col) const
Returns an element by row and column.
const_iterator end() const noexcept
Returns a const iterator one past the last element.
T & at(std::ptrdiff_t row, std::ptrdiff_t col)
Returns an element by row and column.
std::size_t rows() const noexcept
std::size_t cols() const noexcept
Owns contiguous dynamically allocated storage.
std::reverse_iterator< iterator > reverse_iterator
Mutable reverse iterator over contiguous buffer elements.
const T * const_iterator
Const iterator over contiguous buffer elements.
T * iterator
Mutable iterator over contiguous buffer elements.
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator over contiguous buffer elements.
Stores a list of dimension lengths for an array shape.
static constexpr allow_zero_t allow_zero
Tag value documenting that zero-valued dimensions are intentional.
Stores strides for a shape in contiguous memory.