Tatooine
dynamic_multidim_size.h
Go to the documentation of this file.
1#ifndef TATOOINE_DYNAMIC_MULTIDIM_SIZE_H
2#define TATOOINE_DYNAMIC_MULTIDIM_SIZE_H
3//==============================================================================
4#include <tatooine/concepts.h>
5#include <tatooine/for_loop.h>
11#include <tatooine/utility.h>
12//==============================================================================
13namespace tatooine {
14//==============================================================================
15template <typename IndexOrder>
17 public:
19 using index_order_type = IndexOrder;
20
21 private:
22 //----------------------------------------------------------------------------
23 // members
24 //----------------------------------------------------------------------------
25 std::vector<std::size_t> m_size = {};
26
27 //----------------------------------------------------------------------------
28 // ctors
29 //----------------------------------------------------------------------------
30 public:
32 //----------------------------------------------------------------------------
34 dynamic_multidim_size(dynamic_multidim_size&& other) noexcept = default;
35 //----------------------------------------------------------------------------
37 -> dynamic_multidim_size& = default;
38 auto operator =(dynamic_multidim_size&& other) noexcept
39 -> dynamic_multidim_size& = default;
40 //----------------------------------------------------------------------------
42 //----------------------------------------------------------------------------
43 template <typename OtherIndexing>
46 : m_size{other.size()} {}
47
48 template <typename OtherIndexing>
50 : m_size{std::move(other.m_size)} {}
51
52 template <typename OtherIndexing>
55 m_size = other.m_size;
56 return *this;
57 }
58 template <typename OtherIndexing>
61 m_size = std::move(other.m_size);
62 return *this;
63 }
64 //----------------------------------------------------------------------------
65 explicit dynamic_multidim_size(integral auto const... size)
66 : m_size{static_cast<std::size_t>(size)...} {}
67 //----------------------------------------------------------------------------
68 explicit dynamic_multidim_size(std::vector<std::size_t>&& size)
69 : m_size(std::move(size)) {}
70 //----------------------------------------------------------------------------
72 : m_size(begin(size), end(size)) {}
73 //----------------------------------------------------------------------------
74 // comparisons
75 //----------------------------------------------------------------------------
76 template <typename OtherIndexing>
78 if (num_dimensions() != other.num_dimensions()) {
79 return false;
80 }
81 for (std::size_t i = 0; i < num_dimensions(); ++i) {
82 if (m_size[i] != other.size(i)) {
83 return false;
84 }
85 }
86 return true;
87 }
88 //----------------------------------------------------------------------------
89 template <typename OtherIndexing>
91 if (num_dimensions() == other.num_dimensions()) {
92 return false;
93 }
94 for (std::size_t i = 0; i < num_dimensions(); ++i) {
95 if (m_size[i] == other.size(i)) {
96 return false;
97 }
98 }
99 return true;
100 }
101
102 //----------------------------------------------------------------------------
103 // methods
104 //----------------------------------------------------------------------------
105 auto num_dimensions() const { return m_size.size(); }
106 //----------------------------------------------------------------------------
107 [[nodiscard]] auto size() const -> auto const& { return m_size; }
109 auto size(std::size_t const i) const { return m_size[i]; }
110 //----------------------------------------------------------------------------
111 auto num_components() const {
112 return std::accumulate(begin(m_size), end(m_size), std::size_t(1),
113 std::multiplies<std::size_t>{});
114 }
115 //----------------------------------------------------------------------------
116 auto resize(integral auto const... size) -> void {
117 m_size = {static_cast<std::size_t>(size)...};
118 }
119 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120 auto resize(integral_range auto const& size) -> void {
121 m_size = std::vector<std::size_t>(begin(size), end(size));
122 }
123 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
124 auto resize(std::vector<std::size_t>&& size) -> void {
125 m_size = std::move(size);
126 }
127 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
128 auto resize(std::vector<std::size_t> const& size) -> void { m_size = size; }
129 //----------------------------------------------------------------------------
130 auto constexpr in_range(integral auto const... indices) const {
131 if (sizeof...(indices) != num_dimensions()) {
132 return false;
133 }
134 return in_range(std::array{static_cast<std::size_t>(indices)...});
135 }
136 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
137 auto constexpr in_range(integral_range auto const& indices) const {
138 if (indices.size() != num_dimensions()) {
139 return false;
140 }
141 for (std::size_t i = 0; i < indices.size(); ++i) {
142 if (indices[i] >= size(i)) {
143 return false;
144 }
145 }
146 return true;
147 }
148 //----------------------------------------------------------------------------
149 auto constexpr plain_index(integral auto const... indices) const {
150 assert(sizeof...(indices) == num_dimensions());
151 assert(in_range(indices...));
152 return IndexOrder::plain_index(m_size, indices...);
153 }
154 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
155 auto constexpr plain_index(integral_range auto const& indices) const {
156 assert(indices.size() == num_dimensions());
157 assert(in_range(indices));
158 return IndexOrder::plain_index(m_size, indices);
159 }
160 //----------------------------------------------------------------------------
161 auto constexpr multi_index(std::size_t const gi) const {
162 return IndexOrder::multi_index(m_size, gi);
163 }
164 //============================================================================
166 //--------------------------------------------------------------------------
167 this_type const* m_multidim_size = nullptr;
168 std::vector<std::size_t> m_status = {};
169 //--------------------------------------------------------------------------
170 indices_iterator(this_type const& c, std::vector<std::size_t> status)
171 : m_multidim_size{&c}, m_status{std::move(status)} {}
172 //--------------------------------------------------------------------------
173 indices_iterator(indices_iterator const& other) = default;
174 indices_iterator(indices_iterator&& other) noexcept = default;
175 //--------------------------------------------------------------------------
176 auto operator =(indices_iterator const& other)
177 -> indices_iterator& = default;
178 auto operator =(indices_iterator&& other) noexcept
179 -> indices_iterator& = default;
180 //--------------------------------------------------------------------------
181 ~indices_iterator() = default;
182 //--------------------------------------------------------------------------
183 auto operator++() {
184 ++m_status.front();
185 auto size_it = m_multidim_size->size().begin();
186 auto status_it = m_status.begin();
187 for (; size_it != prev(m_multidim_size->size().end());
188 ++status_it, ++size_it) {
189 if (*size_it <= *status_it) {
190 *status_it = 0;
191 ++(*next(status_it));
192 }
193 }
194 }
195 //--------------------------------------------------------------------------
196 auto operator==(indices_iterator const& other) const {
197 if (m_multidim_size != other.m_multidim_size) {
198 return false;
199 }
200 for (std::size_t i = 0; i < m_multidim_size->num_dimensions(); ++i) {
201 if (m_status[i] != other.m_status[i]) {
202 return false;
203 }
204 }
205 return true;
206 }
207 //--------------------------------------------------------------------------
208 auto operator!=(indices_iterator const& other) const {
209 return !operator==(other);
210 }
211 //--------------------------------------------------------------------------
212 auto operator*() const -> auto const& { return m_status; }
213 };
214 //----------------------------------------------------------------------------
215 auto begin_indices() const {
216 return indices_iterator{*this,
217 std::vector<std::size_t>(num_dimensions(), 0)};
218 }
219 //----------------------------------------------------------------------------
220 auto end_indices() const {
221 auto v = std::vector<std::size_t>(num_dimensions(), 0);
222 v.back() = size().back();
223 return indices_iterator{*this, std::move(v)};
224 }
225 //------------------------------------------------------------------------------
226 struct index_range {
227 private:
229
230 public:
231 explicit index_range(this_type const* multidim_size)
232 : m_multidim_size{multidim_size} {}
233 auto begin() const { return m_multidim_size->begin_indices(); }
234 auto end() const { return m_multidim_size->end_indices(); }
235 };
236 auto indices() const { return index_range{this}; }
237};
238//==============================================================================
239// deduction guides
240//==============================================================================
242template <typename IndexOrder>
245template <typename IndexOrder>
248template <typename... Resolution>
250//==============================================================================
251} // namespace tatooine
252//==============================================================================
253#endif
Definition: dynamic_multidim_size.h:16
dynamic_multidim_size(dynamic_multidim_size< OtherIndexing > const &other)
Definition: dynamic_multidim_size.h:44
dynamic_multidim_size(dynamic_multidim_size< OtherIndexing > &&other)
Definition: dynamic_multidim_size.h:49
dynamic_multidim_size(dynamic_multidim_size const &other)=default
dynamic_multidim_size(integral_range auto const &size)
Definition: dynamic_multidim_size.h:71
auto constexpr plain_index(integral auto const ... indices) const
Definition: dynamic_multidim_size.h:149
auto constexpr in_range(integral auto const ... indices) const
Definition: dynamic_multidim_size.h:130
auto size(std::size_t const i) const
Definition: dynamic_multidim_size.h:109
auto begin_indices() const
Definition: dynamic_multidim_size.h:215
dynamic_multidim_size(std::vector< std::size_t > &&size)
Definition: dynamic_multidim_size.h:68
IndexOrder index_order_type
Definition: dynamic_multidim_size.h:19
auto constexpr multi_index(std::size_t const gi) const
Definition: dynamic_multidim_size.h:161
std::vector< std::size_t > m_size
Definition: dynamic_multidim_size.h:25
dynamic_multidim_size(dynamic_multidim_size &&other) noexcept=default
auto operator=(dynamic_multidim_size< OtherIndexing > const &other) -> dynamic_multidim_size &
Definition: dynamic_multidim_size.h:53
auto indices() const
Definition: dynamic_multidim_size.h:236
auto operator!=(dynamic_multidim_size< OtherIndexing > const &other) const
Definition: dynamic_multidim_size.h:90
auto resize(integral_range auto const &size) -> void
Definition: dynamic_multidim_size.h:120
auto size() const -> auto const &
Definition: dynamic_multidim_size.h:107
auto operator=(dynamic_multidim_size< OtherIndexing > &&other) -> dynamic_multidim_size &
Definition: dynamic_multidim_size.h:59
auto constexpr plain_index(integral_range auto const &indices) const
Definition: dynamic_multidim_size.h:155
auto num_dimensions() const
Definition: dynamic_multidim_size.h:105
auto operator==(dynamic_multidim_size< OtherIndexing > const &other) const
Definition: dynamic_multidim_size.h:77
auto resize(std::vector< std::size_t > const &size) -> void
Definition: dynamic_multidim_size.h:128
auto resize(integral auto const ... size) -> void
Definition: dynamic_multidim_size.h:116
auto constexpr in_range(integral_range auto const &indices) const
Definition: dynamic_multidim_size.h:137
auto num_components() const
Definition: dynamic_multidim_size.h:111
dynamic_multidim_size(integral auto const ... size)
Definition: dynamic_multidim_size.h:65
auto end_indices() const
Definition: dynamic_multidim_size.h:220
auto resize(std::vector< std::size_t > &&size) -> void
Definition: dynamic_multidim_size.h:124
auto operator=(dynamic_multidim_size const &other) -> dynamic_multidim_size &=default
Definition: concepts.h:91
Definition: concepts.h:21
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto next(Iter iter)
Definition: iterator_facade.h:325
auto prev(Iter iter)
Definition: iterator_facade.h:343
Definition: dynamic_multidim_size.h:226
index_range(this_type const *multidim_size)
Definition: dynamic_multidim_size.h:231
this_type const * m_multidim_size
Definition: dynamic_multidim_size.h:228
auto begin() const
Definition: dynamic_multidim_size.h:233
auto end() const
Definition: dynamic_multidim_size.h:234
Definition: dynamic_multidim_size.h:165
indices_iterator(indices_iterator const &other)=default
std::vector< std::size_t > m_status
Definition: dynamic_multidim_size.h:168
auto operator==(indices_iterator const &other) const
Definition: dynamic_multidim_size.h:196
this_type const * m_multidim_size
Definition: dynamic_multidim_size.h:167
indices_iterator(indices_iterator &&other) noexcept=default
indices_iterator(this_type const &c, std::vector< std::size_t > status)
Definition: dynamic_multidim_size.h:170
auto operator!=(indices_iterator const &other) const
Definition: dynamic_multidim_size.h:208
auto operator=(indices_iterator const &other) -> indices_iterator &=default
auto operator++()
Definition: dynamic_multidim_size.h:183
auto operator*() const -> auto const &
Definition: dynamic_multidim_size.h:212
Definition: index_order.h:17