WARPXM v1.10.0
Loading...
Searching...
No Matches
multi_iterator.h
Go to the documentation of this file.
1#ifndef WXM_MULTI_ITERATOR_H
2#define WXM_MULTI_ITERATOR_H
3
4#include "meta.h"
5
6#include <array>
7#include <type_traits>
8
9namespace wxm
10{
16template<size_t max_dims> class multi_iterator
17{
18 std::array<size_t, max_dims> idcs;
19
20 std::array<size_t, max_dims> shape_;
21
22 size_t ndims_;
23
27 size_t idx = 0;
28
29 size_t size_;
30
31public:
36 template<class... Idcs,
37 class = typename std::enable_if<
39 multi_iterator(Idcs... lengths)
40 : idcs{0}, shape_{static_cast<size_t>(lengths)...}, ndims_(sizeof...(Idcs))
41 {
42 static_assert(
43 sizeof...(Idcs) < max_dims,
44 "Number of dimensions for the multi-iterator cannot exceed max_dims");
45 size_ = 1;
46 for (size_t i = 0; i < ndims_; ++i)
47 {
48 size_ *= shape_[i];
49 }
50 }
51
57 template<class C> multi_iterator(const C& cont) : idcs{0}
58 {
59 ndims_ = cont.size();
60 std::copy(cont.begin(), cont.end(), shape_.begin());
61 size_ = 1;
62 for (size_t i = 0; i < ndims_; ++i)
63 {
64 size_ *= shape_[i];
65 }
66 }
67
72 const std::array<size_t, max_dims>& indices() const
73 {
74 return idcs;
75 }
76
80 size_t index() const
81 {
82 return idx;
83 }
84
88 size_t size() const
89 {
90 return size_;
91 }
92
96 size_t ndims() const
97 {
98 return ndims_;
99 }
100
105 const std::array<size_t, max_dims>& shape() const
106 {
107 return shape_;
108 }
109
114 {
115 ++idx;
116 ++idcs[ndims_ - 1];
117 for (size_t i = ndims_ - 1; i > 0; --i)
118 {
119 if (idcs[i] >= shape_[i])
120 {
121 idcs[i] = 0;
122 ++idcs[i - 1];
123 continue;
124 }
125 break;
126 }
127 return *this;
128 }
129
134 {
135 idx += val;
136 idcs[ndims_ - 1] += val;
137 bool no_carry = false;
138 for (size_t i = ndims_ - 1; i > 0 && !no_carry; --i)
139 {
140 no_carry = true;
141 while (idcs[i] >= shape_[i])
142 {
143 idcs[i] -= shape_[i];
144 ++idcs[i - 1];
145 no_carry = false;
146 }
147 }
148 return *this;
149 }
150
155 {
156 ++idcs[dim];
157
158 size_t val = 1;
159 for (size_t i = dim + 1; i < ndims_; ++i)
160 {
161 val *= shape_[i];
162 }
163 idx += val;
164
165 for (size_t i = dim; i > 0; --i)
166 {
167 if (idcs[i] >= shape_[i])
168 {
169 idcs[i] = 0;
170 ++idcs[i - 1];
171 continue;
172 }
173 break;
174 }
175 return *this;
176 }
177
181 multi_iterator& advance(size_t dim, size_t val)
182 {
183 idcs[dim] += val;
184
185 for (size_t i = dim + 1; i < ndims_; ++i)
186 {
187 val *= shape_[i];
188 }
189 idx += val;
190
191 bool no_carry = false;
192 for (size_t i = dim; i > 0 && !no_carry; --i)
193 {
194 no_carry = true;
195 while (idcs[i] >= shape_[i])
196 {
197 idcs[i] -= shape_[i];
198 ++idcs[i - 1];
199 no_carry = false;
200 }
201 }
202 return *this;
203 }
204};
205} // namespace wxm
206
207#endif
A multi-dimensional iterator Stores the index in each dimension, as well as a global flattened index.
Definition: multi_iterator.h:17
multi_iterator & advance(size_t dim)
Increment the multi iterator in the given dimension.
Definition: multi_iterator.h:154
multi_iterator & operator+=(size_t val)
Increment the multi iterator by val.
Definition: multi_iterator.h:133
multi_iterator & advance(size_t dim, size_t val)
Increment the multi iterator by val in the given dimension.
Definition: multi_iterator.h:181
const std::array< size_t, max_dims > & shape() const
Gets the multi-dimensional indices.
Definition: multi_iterator.h:105
multi_iterator(Idcs... lengths)
Construct a multi-iterator from a list of lengths.
Definition: multi_iterator.h:39
size_t ndims() const
number of dimensions
Definition: multi_iterator.h:96
multi_iterator & operator++()
Increment the multi iterator.
Definition: multi_iterator.h:113
multi_iterator(const C &cont)
Construct a multi-iterator from a container which contains the lengths.
Definition: multi_iterator.h:57
size_t size() const
Total number of elements.
Definition: multi_iterator.h:88
size_t index() const
Returns the flattened global index.
Definition: multi_iterator.h:80
const std::array< size_t, max_dims > & indices() const
Gets the multi-dimensional indices.
Definition: multi_iterator.h:72
Base namespace for everything not included in the global namespace.
Definition: field_source.h:8
Determines if all predicated values are true or not.
Definition: meta.h:20