Strides
Version: v0.2.0
Status: Complete
Header: include/stratax/core/containers/Strides.hpp
Overview
Strides stores row-major stride metadata for a Shape.
It maps logical multi-dimensional indices to flat storage offsets and is used as lightweight layout metadata by Stratax containers.
Responsibilities
The Strides class is responsible for:
- Computing row-major strides from a Shape
- Storing stride values contiguously
- Providing checked and unchecked stride access
- Providing iteration over stride values
- Supporting comparison and swap
The Strides class is not responsible for:
- Owning array element data
- Performing numerical algorithms
- Shape validation beyond stride-index access
- Multidimensional indexing logic itself
Relationships
Strides
│
└── buffer_ : Buffer<std::size_t>
Stored stride values
Depends on:
Used by:
Related classes:
Internal Data
| Member | Description |
| Buffer<std::size_t> buffer_ | Contiguous storage of stride values |
Invariants
The following conditions are always true:
- rank() equals size().
- Empty shape produces empty strides.
- For non-empty row-major shapes, the last stride is 1.
- at(index) validates bounds and throws on invalid access.
- operator== compares both rank and all stride values.
Public Interface
Iterator Aliases
using iterator = Buffer<std::size_t>::const_iterator;
using const_iterator = Buffer<std::size_t>::const_iterator;
using reverse_iterator = Buffer<std::size_t>::const_reverse_iterator;
using const_reverse_iterator = Buffer<std::size_t>::const_reverse_iterator;
Strides intentionally exposes const-backed iterator aliases because stride values are derived metadata.
Constructors
Default Constructor
Constructs an empty stride vector.
Complexity
Throws
Shape Constructor
explicit Strides(const Shape& shape);
Constructs row-major strides for a shape.
Complexity
Throws
Copy Constructor
Strides(const Strides&) = default;
Complexity
Move Constructor
Strides(Strides&&) noexcept = default;
Complexity
Destructor
Complexity
Assignment Operators
Copy Assignment
Strides& operator=(const Strides&) = default;
Complexity
Move Assignment
Strides& operator=(Strides&&) noexcept = default;
Complexity
Methods
size()
[[nodiscard]] std::size_t size() const noexcept;
Returns the number of stored stride values.
Complexity
rank()
[[nodiscard]] std::size_t rank() const noexcept;
Returns the represented dimensional rank.
Complexity
empty()
[[nodiscard]] bool empty() const noexcept;
Returns true if no strides are stored.
Complexity
at()
const std::size_t& at(std::size_t index) const;
Returns a stride value with bounds checking.
Complexity
Throws
front()
const std::size_t& front() const;
Returns first stride.
Preconditions
- Strides must not be empty.
Complexity
back()
const std::size_t& back() const;
Returns last stride.
Preconditions
- Strides must not be empty.
Complexity
data()
[[nodiscard]] const std::size_t* data() const noexcept;
Returns pointer to first stride value.
Complexity
begin()/end()/cbegin()/cend()
[[nodiscard]] iterator begin() noexcept;
[[nodiscard]] const_iterator begin() const noexcept;
[[nodiscard]] const_iterator cbegin() const noexcept;
[[nodiscard]] iterator end() noexcept;
[[nodiscard]] const_iterator end() const noexcept;
[[nodiscard]] const_iterator cend() const noexcept;
Provides iteration over stride values.
Complexity
rbegin()/rend()/crbegin()/crend()
[[nodiscard]] reverse_iterator rbegin() noexcept;
[[nodiscard]] const_reverse_iterator rbegin() const noexcept;
[[nodiscard]] const_reverse_iterator crbegin() const noexcept;
[[nodiscard]] reverse_iterator rend() noexcept;
[[nodiscard]] const_reverse_iterator rend() const noexcept;
[[nodiscard]] const_reverse_iterator crend() const noexcept;
Provides reverse iteration over stride values.
Complexity
swap()
void swap(Strides& other) noexcept;
Exchanges stride storage with another instance.
Complexity
Operators
operator()
const std::size_t& operator()(std::size_t index) const;
Returns stride value without bounds checking.
Complexity
See Also
const std::size_t& at(std::size_t index) const;
operator== / operator!=
[[nodiscard]] bool operator==(const Strides& other) const noexcept;
[[nodiscard]] bool operator!=(const Strides& other) const noexcept;
Compares stride vectors by rank and values.
Complexity
stream operator
std::ostream& operator<<(std::ostream& os, const Strides& stride);
Writes tuple-like stride representation, for example (12, 4, 1) and (1,) for rank-1.
Complexity
Complexity Summary
| Operation | Complexity |
| Default construction | O(1) |
| Shape construction | O(n) |
| Copy construction | O(n) |
| Move construction | O(1) |
| Copy assignment | O(n) |
| Move assignment | O(1) |
| Destruction | O(n) |
| size() / rank() / empty() | O(1) |
| operator() / at() | O(1) |
| front() / back() | O(1) |
| operator== / operator!= | O(n) |
| Iteration | O(n) |
| swap() | O(1) |
Examples
Building Strides From a Shape
Shape shape(2, 3, 4);
Strides strides(shape);
std::cout << strides << '\n';
Accessing Strides
Strides strides(Shape(2, 3, 4));
auto first = strides(0);
auto safe = strides.at(1);
Design Notes
Strides stores only layout metadata and intentionally avoids array value ownership.
By separating shape and stride metadata from value storage, Stratax keeps indexing and layout logic explicit and reusable across Vector, Matrix, and Tensor.
Future Improvements
- Optional column-major stride construction helper
- Utility helpers for broadcast-aware stride derivation
- Additional constexpr-friendly constructors
See Also