Stratax 0.2.0
Loading...
Searching...
No Matches
Strides.hpp
1#pragma once
2
3#include "Buffer.hpp"
4#include "Shape.hpp"
5#include "../Exceptions.hpp"
7
8#include <cstddef>
9#include <stdexcept>
10#include <utility>
11#include <ostream>
12
13namespace stratax::core {
14
23{
24private:
25 Buffer<std::size_t> buffer_;
26
27public:
30
33
36
39
43 Strides() noexcept = default;
44
55 explicit Strides(const Shape& shape)
56 : buffer_(shape.rank())
57 {
58 if (shape.empty()) {
59 return;
60 }
61
62 buffer_[shape.rank() - 1] = 1;
63
64 for (std::size_t i = shape.rank() - 1; i > 0; --i) {
65 buffer_[i - 1] = validation::checked_multiply(
66 buffer_[i],
67 shape(i),
68 "Strides overflow for shape");
69 }
70 }
71
73 Strides(const Strides&) = default;
74
76 Strides(Strides&&) noexcept = default;
77
79 Strides& operator=(const Strides&) = default;
80
82 Strides& operator=(Strides&&) noexcept = default;
83
87 ~Strides() = default;
88
94 [[nodiscard]] std::size_t size() const noexcept
95 {
96 return buffer_.size();
97 }
98
104 [[nodiscard]] bool empty() const noexcept
105 {
106 return buffer_.empty();
107 }
108
114 [[nodiscard]] std::size_t rank() const noexcept
115 {
116 return buffer_.size();
117 }
118
127 const std::size_t& operator()(std::size_t index) const
128 {
129 return buffer_[index];
130 }
131
141 const std::size_t& at(std::size_t index) const
142 {
143 validation::require_index(index, rank(), "Strides index out of bounds");
144 return buffer_[index];
145 }
146
152 const std::size_t& front() const
153 {
154 return buffer_.front();
155 }
156
162 const std::size_t& back() const
163 {
164 return buffer_.back();
165 }
166
172 [[nodiscard]] const std::size_t* data() const noexcept
173 {
174 return buffer_.data();
175 }
176
182 [[nodiscard]] iterator begin() noexcept
183 {
184 return buffer_.begin();
185 }
186
192 [[nodiscard]] const_iterator begin() const noexcept
193 {
194 return buffer_.begin();
195 }
196
202 [[nodiscard]] const_iterator cbegin() const noexcept
203 {
204 return buffer_.cbegin();
205 }
206
212 [[nodiscard]] iterator end() noexcept
213 {
214 return buffer_.end();
215 }
216
222 [[nodiscard]] const_iterator end() const noexcept
223 {
224 return buffer_.end();
225 }
226
232 [[nodiscard]] const_iterator cend() const noexcept
233 {
234 return buffer_.cend();
235 }
236
242 [[nodiscard]] reverse_iterator rbegin() noexcept
243 {
244 return buffer_.rbegin();
245 }
246
252 [[nodiscard]] const_reverse_iterator rbegin() const noexcept
253 {
254 return buffer_.rbegin();
255 }
256
262 [[nodiscard]] const_reverse_iterator crbegin() const noexcept
263 {
264 return buffer_.crbegin();
265 }
266
272 [[nodiscard]] reverse_iterator rend() noexcept
273 {
274 return buffer_.rend();
275 }
276
282 [[nodiscard]] const_reverse_iterator rend() const noexcept
283 {
284 return buffer_.rend();
285 }
286
292 [[nodiscard]] const_reverse_iterator crend() const noexcept
293 {
294 return buffer_.crend();
295 }
296
302 void swap(Strides& other) noexcept
303 {
304 buffer_.swap(other.buffer_);
305 }
306
314 [[nodiscard]] bool operator==(const Strides& other) const noexcept
315 {
316 if (rank() != other.rank()) {
317 return false;
318 }
319
320 for (std::size_t i = 0; i < rank(); ++i) {
321 if (buffer_[i] != other.buffer_[i]) {
322 return false;
323 }
324 }
325
326 return true;
327 }
328
336 [[nodiscard]] bool operator!=(const Strides& other) const noexcept
337 {
338 return !(*this == other);
339 }
340};
341
350inline std::ostream& operator<<(std::ostream& os, const Strides& stride)
351{
352 os << "(";
353
354 bool first = true;
355 for (std::size_t dim : stride)
356 {
357 if (!first)
358 os << ", ";
359
360 os << dim;
361 first = false;
362 }
363
364 if (stride.rank() == 1)
365 {
366 os << ",";
367 }
368
369 os << ")";
370
371 return os;
372}
373
374}
375
Shared runtime validation helpers.
Owns contiguous dynamically allocated storage.
Definition Buffer.hpp:38
const T * const_iterator
Const iterator over contiguous buffer elements.
Definition Buffer.hpp:50
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator over contiguous buffer elements.
Definition Buffer.hpp:56
Stores a list of dimension lengths for an array shape.
Definition Shape.hpp:22
const_iterator begin() const noexcept
Returns a const iterator to the first stride value.
Definition Strides.hpp:192
const_iterator cbegin() const noexcept
Returns a const iterator to the first stride value.
Definition Strides.hpp:202
bool operator!=(const Strides &other) const noexcept
Returns whether two stride vectors differ.
Definition Strides.hpp:336
bool operator==(const Strides &other) const noexcept
Compares two stride vectors for equality.
Definition Strides.hpp:314
Buffer< std::size_t >::const_iterator iterator
Iterator over immutable stride values.
Definition Strides.hpp:29
const std::size_t & at(std::size_t index) const
Returns a stride value with bounds checking.
Definition Strides.hpp:141
Buffer< std::size_t >::const_iterator const_iterator
Const iterator over stride values.
Definition Strides.hpp:32
Buffer< std::size_t >::const_reverse_iterator reverse_iterator
Reverse iterator over immutable stride values.
Definition Strides.hpp:35
Strides(const Strides &)=default
Copies stride metadata.
bool empty() const noexcept
Returns whether the stride vector is empty.
Definition Strides.hpp:104
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the last stride value.
Definition Strides.hpp:252
const std::size_t & operator()(std::size_t index) const
Returns a stride value without bounds checking.
Definition Strides.hpp:127
std::size_t rank() const noexcept
Returns the number of dimensions represented by the strides.
Definition Strides.hpp:114
const_iterator end() const noexcept
Returns a const iterator one past the last stride value.
Definition Strides.hpp:222
Buffer< std::size_t >::const_reverse_iterator const_reverse_iterator
Const reverse iterator over stride values.
Definition Strides.hpp:38
const_iterator cend() const noexcept
Returns a const iterator one past the last stride value.
Definition Strides.hpp:232
const std::size_t * data() const noexcept
Returns the raw stride data pointer.
Definition Strides.hpp:172
reverse_iterator rend() noexcept
Returns a reverse iterator before the first stride value.
Definition Strides.hpp:272
const std::size_t & back() const
Returns the last stride value.
Definition Strides.hpp:162
iterator end() noexcept
Returns an iterator one past the last stride value.
Definition Strides.hpp:212
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last stride value.
Definition Strides.hpp:242
std::size_t size() const noexcept
Returns the number of stored stride values.
Definition Strides.hpp:94
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last stride value.
Definition Strides.hpp:262
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator before the first stride value.
Definition Strides.hpp:292
const std::size_t & front() const
Returns the first stride value.
Definition Strides.hpp:152
iterator begin() noexcept
Returns an iterator to the first stride value.
Definition Strides.hpp:182
Strides(Strides &&) noexcept=default
Moves stride metadata.
void swap(Strides &other) noexcept
Swaps the stored strides with another instance.
Definition Strides.hpp:302
const_reverse_iterator rend() const noexcept
Returns a const reverse iterator before the first stride value.
Definition Strides.hpp:282
Strides() noexcept=default
Creates an empty stride vector.