6#include "../Concepts.hpp"
7#include "../Exceptions.hpp"
12namespace stratax::core {
26 void validate_dimensions()
const
28 for (std::size_t dim : dims_)
30 validation::nonnegative_shape_dimension(
32 "Shape dimensions cannot be negative.");
72 requires (sizeof...(Dims) > 0)
74 : dims_{
static_cast<std::size_t
>(dims)...}
76 validate_dimensions();
101 validate_dimensions();
122 : dims_(std::move(dims))
124 validate_dimensions();
132 Shape(
const std::vector<std::size_t>& dims)
135 for (std::size_t i = 0; i < dims.size(); ++i)
163 std::size_t prod = 1;
164 for (std::size_t dim : dims_)
166 prod = validation::checked_multiply(prod, dim,
"Shape elements overflow");
176 [[nodiscard]] std::size_t
rank()
const
192 validation::require_index(index,
rank(),
"Shape dimension index out of bounds");
209 return dims_[validation::normalize_index(index,
rank(),
"Shape dimension index out of bounds")];
217 [[nodiscard]]
bool empty() const noexcept
219 return dims_.empty();
231 if (
rank() != other.rank())
235 for (std::size_t i = 0; i <
rank(); ++i)
237 if (dims_[i] != other.dims_[i])
254 return !(*
this == other);
264 return dims_.begin();
284 return dims_.begin();
304 return dims_.cbegin();
324 return dims_.rbegin();
334 return dims_.rbegin();
344 return dims_.crbegin();
374 return dims_.crend();
384 dims_.swap(other.dims_);
397inline std::ostream& operator<<(std::ostream& os,
const Shape& shape)
402 for (std::size_t dim : shape)
411 if (shape.rank() == 1)
Shared runtime validation helpers.
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.
~Shape()=default
Destroys the shape.
Shape(const std::vector< std::size_t > &dims)
Creates a shape by copying dimension lengths from a standard vector.
std::size_t elements() const
Returns the total number of elements described by the shape.
const std::size_t & operator[](std::ptrdiff_t index) const
Returns the length of a specific dimension using signed indexing.
Buffer< std::size_t >::const_iterator const_iterator
Const iterator over dimension lengths.
bool operator!=(const Shape &other) const noexcept
Returns whether two shapes differ in rank or dimension values.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last stored dimension.
Buffer< std::size_t >::reverse_iterator reverse_iterator
Mutable reverse iterator over dimension lengths.
reverse_iterator rend() noexcept
Returns a reverse iterator before the first stored dimension.
Buffer< std::size_t >::iterator iterator
Mutable iterator over dimension lengths.
const_iterator cend() const noexcept
Returns a const iterator one past the last stored dimension.
const std::size_t & operator()(std::size_t index) const
Returns the length of a specific dimension.
bool empty() const noexcept
Returns whether the shape has no dimensions.
bool operator==(const Shape &other) const noexcept
Compares two shapes for exact rank and dimension equality.
void swap(Shape &other) noexcept
Swaps the stored dimensions with another shape.
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last stored dimension.
const_iterator begin() const noexcept
Returns a const iterator to the first stored dimension.
const_iterator end() const noexcept
Returns a const iterator one past the last stored dimension.
Shape() noexcept=default
Creates an empty shape.
std::size_t rank() const
Returns the number of stored dimensions.
iterator end() noexcept
Returns an iterator one past the last stored dimension.
Shape(const Buffer< std::size_t > &dims)
Creates a shape by copying dimension lengths from a buffer.
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator before the first stored dimension.
static constexpr allow_zero_t allow_zero
Tag value documenting that zero-valued dimensions are intentional.
Buffer< std::size_t >::const_reverse_iterator const_reverse_iterator
Const reverse iterator over dimension lengths.
const_iterator cbegin() const noexcept
Returns a const iterator to the first stored dimension.
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the last stored dimension.
Shape(Buffer< std::size_t > &&dims)
Creates a shape by taking ownership of dimension lengths from a buffer.
const_reverse_iterator rend() const noexcept
Returns a const reverse iterator before the first stored dimension.
Shape(std::initializer_list< std::size_t > list, allow_zero_t allow_zero)
Creates a shape from dimension lengths using the explicit zero-dimension tag.
iterator begin() noexcept
Returns an iterator to the first stored dimension.
Shape(const Buffer< std::size_t > &dims, allow_zero_t allow_zero)
Creates a shape by copying dimension lengths using the explicit zero-dimension tag.
Matches signed and unsigned integral types, excluding character-like types.
Tag type documenting that zero-valued dimensions are intentional.