10#include <initializer_list>
69 : shape_(
core::validation::require_rank(
shape, 2,
"Shape must be rank 2")),
71 buffer_(
core::validation::checked_multiply(
74 "Matrix size overflow"))
101 Matrix(std::initializer_list<std::initializer_list<T>> list)
103 std::size_t
rows = list.size();
104 std::size_t
cols = (
rows == 0) ? 0 : list.begin()->size();
107 for (
const auto& row : list)
109 if (row.size() !=
cols)
120 std::size_t index = 0;
122 for (
const auto& row : list)
124 for (
const auto& value : row)
126 buffer_[index++] = value;
161 [[nodiscard]] std::
size_t size() const noexcept
163 return shape_.elements();
171 [[nodiscard]]
bool empty() const noexcept
173 return buffer_.empty();
181 [[nodiscard]] std::size_t
rows() const noexcept
191 [[nodiscard]] std::size_t
cols() const noexcept
221 [[nodiscard]] std::size_t
rank() const noexcept
223 return shape_.rank();
239 return buffer_[row *
cols() + col];
255 return buffer_[row *
cols() + col];
268 return buffer_[index];
281 return buffer_[index];
293 T&
at(std::size_t row, std::size_t col)
295 return (*
this)(row, col);
307 const T&
at(std::size_t row, std::size_t col)
const
309 return (*
this)(row, col);
325 return buffer_.front();
341 return buffer_.front();
357 return buffer_.back();
373 return buffer_.back();
381 [[nodiscard]] T*
data() noexcept
383 return buffer_.data();
391 [[nodiscard]]
const T*
data() const noexcept
393 return buffer_.data();
403 return buffer_.begin();
411 [[nodiscard]]
const T*
begin() const noexcept
413 return buffer_.begin();
421 [[nodiscard]]
const T*
cbegin() const noexcept
423 return buffer_.cbegin();
431 [[nodiscard]] T*
end() noexcept
433 return buffer_.end();
441 [[nodiscard]]
const T*
end() const noexcept
443 return buffer_.end();
451 [[nodiscard]]
const T*
cend() const noexcept
453 return buffer_.cend();
461 [[nodiscard]] std::reverse_iterator<T*>
rbegin() noexcept
463 return buffer_.rbegin();
471 [[nodiscard]] std::reverse_iterator<const T*>
rbegin() const noexcept
473 return buffer_.rbegin();
481 [[nodiscard]] std::reverse_iterator<const T*>
crbegin() const noexcept
483 return buffer_.crbegin();
491 [[nodiscard]] std::reverse_iterator<T*>
rend() noexcept
493 return buffer_.rend();
501 [[nodiscard]] std::reverse_iterator<const T*>
rend() const noexcept
503 return buffer_.rend();
511 [[nodiscard]] std::reverse_iterator<const T*>
crend() const noexcept
513 return buffer_.crend();
535 swap(shape_, other.shape_);
536 swap(strides_, other.strides_);
537 swap(buffer_, other.buffer_);
Shared runtime validation helpers.
Signals an invalid index access.
Base class for Stratax-specific runtime errors.
std::reverse_iterator< const T * > crend() const noexcept
Returns a const reverse iterator before the first element.
const T * begin() const noexcept
Returns a const iterator to the first element.
std::reverse_iterator< T * > rend() noexcept
Returns a reverse iterator before the first 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.
const T & front() const
Returns the first element as a const reference.
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.
std::reverse_iterator< const T * > crbegin() const noexcept
Returns a const reverse iterator to the last element.
T & front()
Returns the first element.
const T & at(std::size_t row, std::size_t col) const
Returns an element by row and column.
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.
std::reverse_iterator< const T * > rbegin() const noexcept
Returns a const reverse iterator to the last element.
const T * cend() const noexcept
Returns a const iterator one past 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.
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.
T * end() noexcept
Returns an iterator one past the last element.
Matrix(std::size_t rows, std::size_t cols, const T &value)
Creates a matrix and fills it with a value.
std::size_t rank() const noexcept
Returns the matrix rank.
const T * cbegin() const noexcept
Returns a const iterator to the first element.
Matrix(const core::Shape &shape)
Creates a matrix from a validated rank-2 shape.
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
std::size_t size() const noexcept
std::reverse_iterator< T * > rbegin() noexcept
Returns a reverse iterator to the last element.
const T * end() const noexcept
Returns a const iterator one past the last element.
T * begin() noexcept
Returns an iterator to the first element.
Matrix(std::size_t rows, std::size_t cols)
Creates a rank-2 matrix with the given number of rows and columns.
std::reverse_iterator< const T * > rend() const noexcept
Returns a const reverse iterator before the first element.
T & at(std::size_t row, std::size_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.
Stores a list of dimension lengths for an array shape.
static constexpr allow_zero_t allow_zero
Stores strides for a shape in contiguous memory.
Matches all scalar types supported by Stratax numeric containers.
std::size_t checked_multiply(std::size_t lhs, std::size_t rhs, const char *message)
Multiplies two sizes while checking for overflow.
void require_index(std::size_t index, std::size_t size, const char *message)
Requires an index to be less than a size.