Stratax 0.3.1
Loading...
Searching...
No Matches
Shape.hpp
1#pragma once
2
3#include <algorithm>
4#include <cstddef>
5#include <initializer_list>
6#include <ostream>
7#include <vector>
8#include <limits>
9
10#include <stratax/core/Buffer.hpp>
11#include <stratax/exceptions/Exceptions.hpp>
12#include <stratax/indexing/Normalize.hpp>
13
14namespace stratax::core {
15
32class Shape
33{
34private:
36
37public:
39 using value_type = std::size_t;
41 using size_type = std::size_t;
43 using difference_type = std::ptrdiff_t;
50
55 Shape() noexcept = default;
56
64 Shape(std::initializer_list<value_type> dims)
65 : dims_(dims)
66 {}
67
75 Shape(const std::vector<value_type>& dims)
76 : dims_(dims.size())
77 {
78 std::copy(dims.begin(), dims.end(), dims_.begin());
79 }
80
91 [[nodiscard]] size_type elements() const
92 {
93 if (empty())
94 {
95 return 0;
96 }
97 size_type prod = 1;
98 for (value_type dim : dims_)
99 {
100 if (dim == 0)
101 {
102 return 0;
103 }
104
105 if (prod > std::numeric_limits<size_type>::max() / dim)
106 {
108 "Shape element count exceeds the maximum representable size.");
109 }
110
111 prod *= dim;
112 }
113
114 return prod;
115 }
116
122 [[nodiscard]] size_type rank() const noexcept
123 {
124 return dims_.size();
125 }
126
139 [[nodiscard]] Shape strides() const
140 {
141 if (empty())
142 {
143 return {};
144 }
145
146 std::vector<value_type> stride_values(rank());
147 stride_values[rank() - 1] = 1;
148
149 for (size_type i = rank() - 1; i > 0; --i)
150 {
151 if (dims_[i] != 0 &&
152 stride_values[i] > std::numeric_limits<value_type>::max() / dims_[i])
153 {
155 "Stride value exceeds the maximum representable size.");
156 }
157
158 stride_values[i - 1] = stride_values[i] * dims_[i];
159 }
160
161 return Shape(stride_values);
162 }
163
171 [[nodiscard]] const_reference operator[](size_type index) const noexcept
172 {
173 return dims_[index];
174 }
175
187 [[nodiscard]] const_reference at(difference_type index) const
188 {
189 return dims_[stratax::indexing::normalize_index(index, rank())];
190 }
191
197 [[nodiscard]] bool empty() const noexcept
198 {
199 return dims_.empty();
200 }
201
208 [[nodiscard]] bool operator==(const Shape& other) const noexcept
209 {
210 if (rank() != other.rank())
211 {
212 return false;
213 }
214 for (size_type i = 0; i < rank(); ++i)
215 {
216 if (dims_[i] != other.dims_[i])
217 {
218 return false;
219 }
220 }
221 return true;
222 }
223
225 const_iterator begin() const noexcept
226 {
227 return dims_.begin();
228 }
229
230 const_iterator end() const noexcept
231 {
232 return dims_.end();
233 }
234
235 const_iterator cbegin() const noexcept
236 {
237 return dims_.cbegin();
238 }
239
240 const_iterator cend() const noexcept
241 {
242 return dims_.cend();
243 }
244
246 {
247 return dims_.rbegin();
248 }
249
251 {
252 return dims_.crbegin();
253 }
254
256 {
257 return dims_.rend();
258 }
259
261 {
262 return dims_.crend();
263 }
264
270 void swap(Shape& other) noexcept
271 {
272 dims_.swap(other.dims_);
273 }
274
275};
276
288inline std::ostream& operator<<(std::ostream& os, const Shape& shape)
289{
290 os << "(";
291
292 bool first = true;
293 for (Shape::value_type dim : shape)
294 {
295 if (!first)
296 os << ", ";
297
298 os << dim;
299 first = false;
300 }
301
302 if (shape.rank() == 1)
303 {
304 os << ",";
305 }
306
307 os << ")";
308
309 return os;
310}
311
312}
Fixed-size owner of aligned, contiguous element storage.
Definition Buffer.hpp:51
const_pointer const_iterator
Read-only contiguous random-access iterator type.
Definition Buffer.hpp:74
std::reverse_iterator< const_iterator > const_reverse_iterator
Read-only iterator that traverses elements in reverse order.
Definition Buffer.hpp:78
Shape(const std::vector< value_type > &dims)
Constructs a shape by copying a vector of dimensions.
Definition Shape.hpp:75
size_type elements() const
Computes the total number of elements described by the shape.
Definition Shape.hpp:91
std::size_t size_type
Unsigned type used for ranks and dimension indices.
Definition Shape.hpp:41
size_type rank() const noexcept
Returns the number of dimensions.
Definition Shape.hpp:122
const_reference at(difference_type index) const
Returns a dimension using checked, Python-style indexing.
Definition Shape.hpp:187
const_iterator cend() const noexcept
Returns a const iterator past the final dimension.
Definition Shape.hpp:240
bool empty() const noexcept
Reports whether the shape has rank zero.
Definition Shape.hpp:197
const value_type & const_reference
Read-only reference to a dimension.
Definition Shape.hpp:45
bool operator==(const Shape &other) const noexcept
Compares two shapes dimension by dimension.
Definition Shape.hpp:208
void swap(Shape &other) noexcept
Exchanges dimension storage with another shape.
Definition Shape.hpp:270
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the final dimension.
Definition Shape.hpp:250
const_iterator begin() const noexcept
Returns a const iterator to the first dimension.
Definition Shape.hpp:225
Shape strides() const
Computes canonical row-major strides for this shape.
Definition Shape.hpp:139
const_iterator end() const noexcept
Returns a const iterator past the final dimension.
Definition Shape.hpp:230
Shape() noexcept=default
Constructs an empty, rank-zero shape.
const_reference operator[](size_type index) const noexcept
Returns a dimension without bounds checking.
Definition Shape.hpp:171
Buffer< value_type >::const_reverse_iterator const_reverse_iterator
Read-only iterator over dimensions in reverse order.
Definition Shape.hpp:49
const_reverse_iterator crend() const noexcept
Returns the past-the-end const reverse iterator.
Definition Shape.hpp:260
std::size_t value_type
Type used to represent each dimension.
Definition Shape.hpp:39
const_iterator cbegin() const noexcept
Returns a const iterator to the first dimension.
Definition Shape.hpp:235
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the final dimension.
Definition Shape.hpp:245
Buffer< value_type >::const_iterator const_iterator
Read-only contiguous iterator over dimensions.
Definition Shape.hpp:47
const_reverse_iterator rend() const noexcept
Returns the past-the-end reverse iterator.
Definition Shape.hpp:255
std::ptrdiff_t difference_type
Signed type used for checked indices and iterator distances.
Definition Shape.hpp:43