|
Stratax 0.3.1
|
Version: v0.2.0
Status: Complete
Header: include/stratax/containers/Tensor.hpp
stratax::container::Tensor<T> is an arbitrary-rank owning array for types that satisfy the Numeric concept. It derives from core::ArrayBase<T> and stores elements contiguously using canonical row-major strides.
The default tensor is empty with shape {0} and rank one. Constructing from an explicit Shape{} instead creates an empty rank-zero tensor.
Tensor<T> is responsible for:
ArrayBase<T>swapTensor<T> does not directly implement broadcasting, reshaping, slicing, or high-level numerical algorithms.
For every normally constructed tensor:
size() == shape().elements()rank() == shape().rank() == strides().rank()strides() describes the canonical row-major layout of shape()Shapes of any rank are accepted, including rank zero and shapes containing zero dimensions. Element-count and stride multiplication are checked during construction.
A moved-from tensor remains destructible and assignable, but its previous contents and layout must not be relied upon.
Tensor<T> republishes the complete container alias set from core::ArrayBase<T>:
Constructs an empty rank-one tensor with shape {0}.
Complexity: O(1).
Constructs shape.elements() value-initialized elements. For arithmetic types, value initialization produces zero.
Complexity: O(shape.elements() + shape.rank()).
Throws:
Exceptions::DimensionError if the element count or a stride overflowsstd::bad_alloc if allocation failsvalue_type constructionConstructs shape.elements() copies of value.
Complexity: O(shape.elements() + shape.rank()).
It has the same overflow and allocation failure conditions as the shape constructor and may propagate exceptions from the value_type copy constructor.
The compiler-generated special members use ArrayBase<T> semantics:
Copying duplicates element storage and metadata. Moving transfers their ownership. Copy operations are O(n), while move construction is O(1).
The supplied components are converted to size_type and combined with the row-major strides.
Preconditions:
rank() components are suppliedNo rank or bounds validation is performed. Violating these preconditions can produce an invalid offset or undefined behavior.
Complexity: O(rank()).
This overload has the same preconditions and unchecked behavior as the variadic overload. indices.size() must equal rank().
Complexity: O(rank()).
Exactly one component per tensor dimension must be supplied. Each signed component is normalized independently, and negative values count backward from the end of the corresponding dimension.
Complexity: O(rank()).
Throws Exceptions::IndexError with:
"Tensor multi-index rank must match tensor rank." for a rank mismatch"Tensor multi-index component is out of bounds." for an invalid componentThe vector overload performs the same rank validation, negative-index normalization, bounds checking, and error reporting as the variadic overload.
Complexity: O(rank()).
Tensor explicitly retains the one-argument checked ArrayBase<T>::at overloads:
operator[] is unchecked flat access. The one-argument at(index) checks a flat index in [-size(), size()) and supports negative values. It throws Exceptions::IndexError when the flat index is invalid.
The inherited interface also provides:
size(), empty(), rank(), shape(), and strides()data(), front(), and back()fill()front() and back() throw Exceptions::IndexError when the tensor is empty.
Metadata queries, iterator acquisition, and individual flat element access are O(1). Traversal and fill() are O(size()).
Both overloads exchange the buffer, shape, and strides in O(1). The non-member overload supports argument-dependent lookup:
Tensors of different ranks and shapes may be swapped.
| Operation | Complexity |
|---|---|
| Default construction | O(1) |
| Shape or shape-and-fill construction | O(elements + rank) |
| Copy construction or assignment | O(n) |
| Move construction | O(1) |
| Metadata query | O(1) |
| Flat element access | O(1) |
| Variadic or vector multidimensional access | O(rank) |
| Iterator acquisition | O(1) |
| Complete traversal | O(n) |
fill() | O(n) |
swap() | O(1) |
Keeping ownership and flat container behavior in ArrayBase<T> gives Vector, Matrix, and Tensor consistent storage and iterator semantics. Tensor<T> adds general row-major multi-index conversion for arbitrary ranks.
Unchecked access deliberately avoids validation for performance-sensitive code. Use at(...) when indices are external, signed, or otherwise untrusted.