Visual Computing Library  devel
Loading...
Searching...
No Matches
reference_container_component.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MESH_COMPONENTS_BASE_REFERENCE_CONTAINER_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASE_REFERENCE_CONTAINER_COMPONENT_H
25
26#include "index_container_component.h"
27#include "pointer_container_component.h"
28
29namespace vcl::comp {
30
32
70template<
71 bool STORE_INDICES,
72 typename DerivedComponent, // CRTP pattern, derived class
73 uint COMP_ID, // component id
74 typename Elem, // element type for which the pointers are stored
75 int N, // container size
76 typename ParentElemType, // parent element type
77 bool VERT, // true if component vertical
78 bool OPT, // true if component vertical and optional
79 bool TTVN> // true if container size tied to vertex number
80class ReferenceContainerComponent :
81 public std::conditional_t<
82 STORE_INDICES,
83 IndexContainerComponent<
84 DerivedComponent,
85 COMP_ID,
86 Elem,
87 N,
88 ParentElemType,
89 VERT,
90 OPT,
91 TTVN>,
92 PointerContainerComponent<
93 DerivedComponent,
94 COMP_ID,
95 Elem,
96 N,
97 ParentElemType,
98 VERT,
99 OPT,
100 TTVN>>
101{
102protected:
103 using Base = std::conditional_t<
104 STORE_INDICES,
105 IndexContainerComponent<
106 DerivedComponent,
107 COMP_ID,
108 Elem,
109 N,
110 ParentElemType,
111 VERT,
112 OPT,
113 TTVN>,
114 PointerContainerComponent<
115 DerivedComponent,
116 COMP_ID,
117 Elem,
118 N,
119 ParentElemType,
120 VERT,
121 OPT,
122 TTVN>>;
123
124 uint size() const { return Base::container().size(); }
125
126 Elem* element(uint i)
127 {
128 if constexpr (STORE_INDICES)
129 return elemFromParent(elementIndex(i));
130 else
131 return Base::container().at(i);
132 }
133
134 const Elem* element(uint i) const
135 {
136 if constexpr (STORE_INDICES)
137 return elemFromParent(elementIndex(i));
138 else
139 return Base::container().at(i);
140 }
141
142 uint elementIndex(uint i) const
143 {
144 if constexpr (STORE_INDICES)
145 return Base::container().at(i);
146 else
147 return indexFromPointer(Base::container().at(i));
148 }
149
150 Elem* elementMod(int i)
151 {
152 if constexpr (STORE_INDICES)
153 return elemFromParent(elementIndexMod(i));
154 else
155 return Base::container().atMod(i);
156 }
157
158 const Elem* elementMod(int i) const
159 {
160 if constexpr (STORE_INDICES)
161 return elemFromParent(elementIndexMod(i));
162 else
163 return Base::container().atMod(i);
164 }
165
166 uint elementIndexMod(int i) const
167 {
168 if constexpr (STORE_INDICES)
169 return Base::container().atMod(i);
170 else
171 return indexFromPointer(elementMod(i));
172 }
173
174 void setElement(uint i, Elem* e)
175 {
176 if constexpr (STORE_INDICES)
177 Base::container().set(i, indexFromPointer(e));
178 else
179 Base::container().set(i, e);
180 }
181
182 void setElement(uint i, uint ei)
183 {
184 if constexpr (STORE_INDICES)
185 Base::container().set(i, ei);
186 else
187 Base::container().set(i, elemFromParent(ei));
188 }
189
190 void setElement(Base::ConstIterator it, Elem* v)
191 {
192 setElement(it - elementBegin(), v);
193 }
194
195 void setElement(Base::ConstIterator it, uint vi)
196 {
197 setElement(it - elementBegin(), vi);
198 }
199
200 void setElement(Base::ConstIndexIterator it, Elem* v)
201 {
202 setElement(it - elementBegin(), v);
203 }
204
205 void setElement(Base::ConstIndexIterator it, uint vi)
206 {
207 setElement(it - elementBegin(), vi);
208 }
209
210 void setElementMod(int i, Elem* e)
211 {
212 if constexpr (STORE_INDICES)
213 Base::container().atMod(i) = indexFromPointer(e);
214 else
215 Base::container().atMod(i) = e;
216 }
217
218 void setElementMod(int i, uint ei)
219 {
220 if constexpr (STORE_INDICES)
221 Base::container().atMod(i) = ei;
222 else
223 Base::container().atMod(i) = elemFromParent(ei);
224 }
225
226 template<Range Rng>
227 void setElements(Rng&& r) requires InputRange<Rng, Elem*>
228 {
229 if constexpr (STORE_INDICES) {
230 auto conv = [&](auto v) {
231 return indexFromPointer(v);
232 };
233
234 Base::container().set(r | std::views::transform(conv));
235 }
236 else {
237 Base::container().set(r);
238 }
239 }
240
241 template<Range Rng>
242 void setElements(Rng&& r) requires InputRange<Rng, uint>
243 {
244 if constexpr (STORE_INDICES) {
245 Base::container().set(r);
246 }
247 else {
248 auto conv = [&](auto i) {
249 return elemFromParent(i);
250 };
251
252 Base::container().set(r | std::views::transform(conv));
253 }
254 }
255
256 bool containsElement(const Elem* e) const
257 {
258 if constexpr (STORE_INDICES)
259 return Base::container().contains(indexFromPointer(e));
260 else
261 return Base::container().contains(e);
262 }
263
264 bool containsElement(uint ei) const
265 {
266 if constexpr (STORE_INDICES)
267 return Base::container().contains(ei);
268 else
269 return Base::container().contains(elemFromParent(ei));
270 }
271
272 uint indexOfElement(const Elem* e) const
273 {
274 if constexpr (STORE_INDICES)
275 return Base::container().indexOf(indexFromPointer(e));
276 else
277 return Base::container().indexOf(e);
278 }
279
280 uint indexOfElement(uint ei) const
281 {
282 if constexpr (STORE_INDICES)
283 return Base::container().indexOf(ei);
284 else
285 return Base::container().indexOf(elemFromParent(ei));
286 }
287
288 Base::Iterator elementBegin()
289 {
290 if constexpr (STORE_INDICES)
291 return typename Base::Iterator(
292 Base::container().begin(), Base::parentElement());
293 else
294 return Base::container().begin();
295 }
296
297 Base::Iterator elementEnd()
298 {
299 if constexpr (STORE_INDICES)
300 return typename Base::Iterator(Base::container().end());
301 else
302 return Base::container().end();
303 }
304
305 Base::ConstIterator elementBegin() const
306 {
307 if constexpr (STORE_INDICES)
308 return typename Base::ConstIterator(
309 Base::container().begin(), Base::parentElement());
310 else
311 return Base::container().begin();
312 }
313
314 Base::ConstIterator elementEnd() const
315 {
316 if constexpr (STORE_INDICES)
317 return typename Base::ConstIterator(Base::container().end());
318 else
319 return Base::container().end();
320 }
321
322 Base::ConstIndexIterator elementIndexBegin() const
323 {
324 if constexpr (STORE_INDICES)
325 return Base::container().begin();
326 else
327 return typename Base::ConstIndexIterator(elementBegin());
328 }
329
330 Base::ConstIndexIterator elementIndexEnd() const
331 {
332 if constexpr (STORE_INDICES)
333 return Base::container().end();
334 else
335 return typename Base::ConstIndexIterator(elementEnd());
336 }
337
338 View<typename Base::Iterator> elements()
339 {
340 return View(elementBegin(), elementEnd());
341 }
342
343 View<typename Base::ConstIterator> elements() const
344 {
345 return View(elementBegin(), elementEnd());
346 }
347
348 View<typename Base::ConstIndexIterator> elementIndices() const
349 {
350 return View(elementIndexBegin(), elementIndexEnd());
351 }
352
353 // ContainerComponent interface functions
354
355 void resize(uint n) requires (N < 0)
356 {
357 if constexpr (STORE_INDICES)
358 Base::container().resize(n, UINT_NULL);
359 else
360 Base::container().resize(n);
361 }
362
363 void pushBack(Elem* e = nullptr) requires (N < 0)
364 {
365 if constexpr (STORE_INDICES)
366 Base::container().pushBack(indexFromPointer(e));
367 else
368 Base::container().pushBack(e);
369 }
370
371 void pushBack(uint ei) requires (N < 0)
372 {
373 if constexpr (STORE_INDICES)
374 Base::container().pushBack(ei);
375 else
376 Base::container().pushBack(elemFromParent(ei));
377 }
378
379 void insert(uint i, Elem* e = nullptr) requires (N < 0)
380 {
381 if constexpr (STORE_INDICES)
382 Base::container().insert(i, indexFromPointer(e));
383 else
384 Base::container().insert(i, e);
385 }
386
387 void insert(uint i, uint ei) requires (N < 0)
388 {
389 if constexpr (STORE_INDICES)
390 Base::container().insert(i, ei);
391 else
392 Base::container().insert(i, elemFromParent(ei));
393 }
394
395 void erase(uint i) requires (N < 0) { Base::container().erase(i); }
396
397 void clear() requires (N < 0) { Base::container().clear(); }
398
399 // Utility functions
400
401 uint indexFromPointer(const Elem* v) const
402 {
403 if (v == nullptr) [[unlikely]]
404 return UINT_NULL;
405 else
406 return v->index();
407 }
408
409 Elem* elemFromParent(uint vi)
410 {
411 if (vi == UINT_NULL) [[unlikely]]
412 return nullptr;
413 else
414 return &Base::parentElement()
415 ->parentMesh()
416 ->template element<Elem::ELEMENT_ID>(vi);
417 }
418
419 const Elem* elemFromParent(uint vi) const
420 {
421 if (vi == UINT_NULL) [[unlikely]]
422 return nullptr;
423 else
424 return &Base::parentElement()
425 ->parentMesh()
426 ->template element<Elem::ELEMENT_ID>(vi);
427 }
428};
429
431
432} // namespace vcl::comp
433
434#endif // VCL_MESH_COMPONENTS_BASE_REFERENCE_CONTAINER_COMPONENT_H
PointT size() const
Computes the size of the box.
Definition box.h:267
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:48