13#include <initializer_list>
61 buffer_(shape_.elements())
75 buffer_(shape_.elements(), value)
114 [[nodiscard]] std::
size_t size() const noexcept
116 return buffer_.size();
124 [[nodiscard]]
bool empty() const noexcept
126 return buffer_.empty();
134 [[nodiscard]] std::size_t
rank() const noexcept
136 return shape_.rank();
169 return buffer_[index];
182 return buffer_[index];
195 return buffer_[index];
208 return buffer_[index];
225 template<
typename... Rest>
226 T&
operator()(std::size_t first, std::size_t second, Rest... rest)
228 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
231 static_cast<std::size_t
>(rest)...
234 return buffer_[
offset(shape_, strides_, indices)];
248 template<
typename... Rest>
249 const T&
operator()(std::size_t first, std::size_t second, Rest... rest)
const
251 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
254 static_cast<std::size_t
>(rest)...
257 return buffer_[
offset(shape_, strides_, indices)];
268 T&
at(std::size_t index)
271 return buffer_[index];
282 const T&
at(std::size_t index)
const
285 return buffer_[index];
299 template<
typename... Rest>
300 T&
at(std::size_t first, std::size_t second, Rest... rest)
302 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
305 static_cast<std::size_t
>(rest)...
310 return buffer_[
offset(shape_, strides_, indices)];
333 template<
typename... Rest>
334 const T&
at(std::size_t first, std::size_t second, Rest... rest)
const
336 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
339 static_cast<std::size_t
>(rest)...
344 return buffer_[
offset(shape_, strides_, indices)];
364 return buffer_.front();
375 return buffer_.front();
386 return buffer_.back();
397 return buffer_.back();
405 [[nodiscard]] T*
data() noexcept
407 return buffer_.data();
415 [[nodiscard]]
const T*
data() const noexcept
417 return buffer_.data();
427 return buffer_.begin();
435 [[nodiscard]]
auto begin() const noexcept
437 return buffer_.begin();
445 [[nodiscard]]
auto cbegin() const noexcept
447 return buffer_.cbegin();
455 [[nodiscard]]
auto end() noexcept
457 return buffer_.end();
465 [[nodiscard]]
auto end() const noexcept
467 return buffer_.end();
475 [[nodiscard]]
auto cend() const noexcept
477 return buffer_.cend();
487 return buffer_.rbegin();
495 [[nodiscard]]
auto rbegin() const noexcept
497 return buffer_.rbegin();
507 return buffer_.crbegin();
515 [[nodiscard]]
auto rend() noexcept
517 return buffer_.rend();
525 [[nodiscard]]
auto rend() const noexcept
527 return buffer_.rend();
535 [[nodiscard]]
auto crend() const noexcept
537 return buffer_.crend();
557 shape_.swap(other.shape_);
558 strides_.swap(other.strides_);
559 buffer_.swap(other.buffer_);
std::size_t offset(const stratax::core::Shape &shape, const stratax::core::Strides &strides, const IndexContainer &index)
Computes a flat storage offset from a shape, strides, and index container.
Shared runtime validation helpers.
Signals an invalid dimension count or dimension arithmetic failure.
Signals an invalid index access.
void fill(const T &value)
Fills every element with the same value.
void swap(Tensor &other) noexcept
Swaps the contents of two tensors.
T & operator()(std::size_t first, std::size_t second, Rest... rest)
Returns an element by multidimensional index with bounds checking.
auto end() const noexcept
Returns a const iterator one past the last element.
auto begin() noexcept
Returns an iterator to the first element.
Tensor(const Tensor &)=default
Creates a copy of another tensor.
const core::Shape & shape() const noexcept
T * data() noexcept
Returns the raw data pointer.
const T & front() const
Returns the first element as a const reference.
const T & operator[](std::size_t index) const noexcept
Returns a flat element without bounds checking.
Tensor(const core::Shape &shape, const T &value)
Creates a tensor from a shape and fills it with a value.
std::size_t rank() const noexcept
Returns the tensor rank.
bool empty() const noexcept
Returns whether the tensor contains no elements.
const T & at(std::size_t first, std::size_t second, Rest... rest) const
Returns an element by multi-index with bounds checking.
std::size_t size() const noexcept
auto end() noexcept
Returns an iterator one past the last element.
auto rend() const noexcept
Returns a const reverse iterator before the first element.
T & front()
Returns the first element.
auto rend() noexcept
Returns a reverse iterator before the first element.
const core::Strides & strides() const noexcept
Returns the tensor strides.
auto cbegin() const noexcept
Returns a const iterator to the first element.
auto rbegin() noexcept
Returns a reverse iterator to the last element.
auto crbegin() const noexcept
Returns a const reverse iterator to the last element.
Tensor() noexcept=default
Creates an empty tensor with rank 0.
auto rbegin() const noexcept
Returns a const reverse iterator to the last element.
const T & at(std::size_t index) const
Returns an element by rank-1 flat index with bounds checking.
T & at(std::size_t index)
Returns an element by rank-1 flat index with bounds checking.
T & operator[](std::size_t index) noexcept
Returns a flat element without bounds checking.
const T * data() const noexcept
Returns the raw data pointer as a const pointer.
auto 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.
T & back()
Returns the last element.
auto crend() const noexcept
Returns a const reverse iterator before the first element.
const T & operator()(std::size_t index) const noexcept
Returns a flat element without bounds checking.
T & at(std::size_t first, std::size_t second, Rest... rest)
Returns an element by multi-index with bounds checking.
Tensor(Tensor &&) noexcept=default
Transfers ownership from another tensor.
const T & operator()(std::size_t first, std::size_t second, Rest... rest) const
Returns an element by multidimensional index with bounds checking.
auto begin() const noexcept
Returns a const iterator to the first element.
const T & back() const
Returns the last element as a const reference.
Owns contiguous dynamically allocated storage.
Stores a list of dimension lengths for an array shape.
Stores strides for a shape in contiguous memory.
void require_index(std::size_t index, std::size_t size, const char *message)
Requires an index to be less than a size.