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>
8#include <stratax/core/containers/Strides.hpp>
9#include <stratax/core/ops/Indexing.hpp>
13#include <initializer_list>
18namespace stratax::container {
76 buffer_(shape_.elements())
90 buffer_(shape_.elements(), value)
129 [[nodiscard]] std::
size_t size() const noexcept
131 return buffer_.size();
139 [[nodiscard]]
bool empty() const noexcept
141 return buffer_.empty();
149 [[nodiscard]] std::size_t
rank() const noexcept
151 return shape_.rank();
184 return buffer_[index];
197 return buffer_[index];
210 return buffer_[index];
223 return buffer_[index];
240 template<
typename... Rest>
241 T&
operator()(std::size_t first, std::size_t second, Rest... rest)
243 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
246 static_cast<std::size_t
>(rest)...
249 return buffer_[offset(shape_, strides_, indices)];
263 template<
typename... Rest>
264 const T&
operator()(std::size_t first, std::size_t second, Rest... rest)
const
266 std::array<std::size_t,
sizeof...(Rest) + 2> indices{
269 static_cast<std::size_t
>(rest)...
272 return buffer_[offset(shape_, strides_, indices)];
286 return buffer_[offset(shape_, strides_, indices)];
298 const T&
operator()(
const std::vector<std::size_t>& indices)
const
300 return buffer_[offset(shape_, strides_, indices)];
311 T&
at(std::ptrdiff_t index)
313 const std::size_t normalized =
314 core::validation::normalize_index(index,
size(),
"Tensor flat index out of bounds.");
315 return buffer_[normalized];
326 const T&
at(std::ptrdiff_t index)
const
328 const std::size_t normalized =
329 core::validation::normalize_index(index,
size(),
"Tensor flat index out of bounds.");
330 return buffer_[normalized];
344 template<
typename... Rest>
345 requires ((std::is_integral_v<Rest>) && ...)
346 T&
at(std::ptrdiff_t first, std::ptrdiff_t second, Rest... rest)
348 std::array<std::ptrdiff_t,
sizeof...(Rest) + 2> raw_indices{
351 static_cast<std::ptrdiff_t
>(rest)...
354 std::array<std::size_t,
sizeof...(Rest) + 2> indices{};
355 if (indices.size() !=
rank())
360 for (std::size_t i = 0; i < indices.size(); ++i)
362 indices[i] = core::validation::normalize_index(
365 "Tensor multi-index component is out of bounds.");
370 return buffer_[offset(shape_, strides_, indices)];
393 template<
typename... Rest>
394 requires ((std::is_integral_v<Rest>) && ...)
395 const T&
at(std::ptrdiff_t first, std::ptrdiff_t second, Rest... rest)
const
397 std::array<std::ptrdiff_t,
sizeof...(Rest) + 2> raw_indices{
400 static_cast<std::ptrdiff_t
>(rest)...
403 std::array<std::size_t,
sizeof...(Rest) + 2> indices{};
404 if (indices.size() !=
rank())
409 for (std::size_t i = 0; i < indices.size(); ++i)
411 indices[i] = core::validation::normalize_index(
414 "Tensor multi-index component is out of bounds.");
419 return buffer_[offset(shape_, strides_, indices)];
439 return buffer_.front();
450 return buffer_.front();
461 return buffer_.back();
472 return buffer_.back();
480 [[nodiscard]] T*
data() noexcept
482 return buffer_.data();
490 [[nodiscard]]
const T*
data() const noexcept
492 return buffer_.data();
502 return buffer_.begin();
512 return buffer_.begin();
522 return buffer_.cbegin();
532 return buffer_.end();
542 return buffer_.end();
552 return buffer_.cend();
562 return buffer_.rbegin();
572 return buffer_.rbegin();
582 return buffer_.crbegin();
592 return buffer_.rend();
602 return buffer_.rend();
612 return buffer_.crend();
632 shape_.swap(other.shape_);
633 strides_.swap(other.strides_);
634 buffer_.swap(other.buffer_);
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.
T & operator()(const std::vector< std::size_t > &indices)
Returns an element by multidimensional index from a vector with bounds checking.
void swap(Tensor &other) noexcept
Swaps the contents of two tensors.
typename core::Buffer< T >::const_reverse_iterator const_reverse_iterator
Const reverse iterator over tensor elements.
T & operator()(std::size_t first, std::size_t second, Rest... rest)
Returns an element by multidimensional index with bounds checking.
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last element.
Tensor(const Tensor &)=default
Creates a copy of another tensor.
const_iterator end() const noexcept
Returns a const iterator one past the last element.
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.
std::size_t size() const noexcept
const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
T & front()
Returns the first element.
typename core::Buffer< T >::reverse_iterator reverse_iterator
Mutable reverse iterator over tensor elements.
const_reverse_iterator rend() const noexcept
Returns a const reverse iterator before the first element.
const core::Strides & strides() const noexcept
Returns the tensor strides.
const_iterator begin() const noexcept
Returns a const iterator to the first element.
iterator begin() noexcept
Returns an iterator to the first element.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last element.
Tensor() noexcept=default
Creates an empty tensor with rank 0.
iterator end() noexcept
Returns an iterator one past the last element.
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.
const T & operator()(const std::vector< std::size_t > &indices) const
Returns an element by multidimensional index from a vector with bounds checking.
T & operator()(std::size_t index) noexcept
Returns a flat element without bounds checking.
Tensor< U > rebind
Rebinds the tensor container to another element type.
typename core::Buffer< T >::const_iterator const_iterator
Const iterator over tensor elements.
typename core::Buffer< T >::iterator iterator
Mutable iterator over tensor elements.
T & at(std::ptrdiff_t index)
Returns an element by rank-1 flat index with bounds checking.
const T & at(std::ptrdiff_t index) const
Returns an element by rank-1 flat index with bounds checking.
T & back()
Returns the last element.
const T & at(std::ptrdiff_t first, std::ptrdiff_t second, Rest... rest) const
Returns an element by multi-index with bounds checking.
T value_type
Element type stored by the tensor.
const T & operator()(std::size_t index) const noexcept
Returns a flat element without bounds checking.
reverse_iterator rend() noexcept
Returns a reverse iterator before the first element.
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator before the first element.
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.
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the last element.
const_iterator cend() const noexcept
Returns a const iterator one past the last element.
const T & back() const
Returns the last element as a const reference.
T & at(std::ptrdiff_t first, std::ptrdiff_t second, Rest... rest)
Returns an element by multi-index with bounds checking.
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.
Stores strides for a shape in contiguous memory.