Visual Computing Library
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_BASES_REFERENCE_CONTAINER_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASES_REFERENCE_CONTAINER_COMPONENT_H
25
26#include "index_container_component.h"
27#include "pointer_container_component.h"
28
29namespace vcl::comp {
30
68template<
69 bool STORE_INDICES,
70 typename DerivedComponent, // CRTP pattern, derived class
71 uint COMP_ID, // component id
72 typename Elem, // element type for which the pointers are stored
73 int N, // container size
74 typename ParentElemType, // parent element type
75 bool VERT, // true if component vertical
76 bool OPT, // true if component vertical and optional
77 bool TTVN> // true if container size tied to vertex number
79 public std::conditional_t<
80 STORE_INDICES,
81 IndexContainerComponent<
82 DerivedComponent,
83 COMP_ID,
84 Elem,
85 N,
86 ParentElemType,
87 VERT,
88 OPT,
89 TTVN>,
90 PointerContainerComponent<
91 DerivedComponent,
92 COMP_ID,
93 Elem,
94 N,
95 ParentElemType,
96 VERT,
97 OPT,
98 TTVN>>
99{
100protected:
101 using Base = std::conditional_t<
105 COMP_ID,
106 Elem,
107 N,
109 VERT,
110 OPT,
111 TTVN>,
114 COMP_ID,
115 Elem,
116 N,
118 VERT,
119 OPT,
120 TTVN>>;
121
122 uint size() const { return Base::container().size(); }
123
124 Elem* element(uint i)
125 {
126 if constexpr (STORE_INDICES)
127 return elemFromParent(elementIndex(i));
128 else
129 return Base::container().at(i);
130 }
131
132 const Elem* element(uint i) const
133 {
134 if constexpr (STORE_INDICES)
135 return elemFromParent(elementIndex(i));
136 else
137 return Base::container().at(i);
138 }
139
140 uint elementIndex(uint i) const
141 {
142 if constexpr (STORE_INDICES)
143 return Base::container().at(i);
144 else
145 return indexFromPointer(Base::container().at(i));
146 }
147
148 Elem* elementMod(int i)
149 {
150 if constexpr (STORE_INDICES)
151 return elemFromParent(elementIndexMod(i));
152 else
153 return Base::container().atMod(i);
154 }
155
156 const Elem* elementMod(int i) const
157 {
158 if constexpr (STORE_INDICES)
159 return elemFromParent(elementIndexMod(i));
160 else
161 return Base::container().atMod(i);
162 }
163
164 uint elementIndexMod(int i) const
165 {
166 if constexpr (STORE_INDICES)
167 return Base::container().atMod(i);
168 else
169 return indexFromPointer(elementMod(i));
170 }
171
172 void setElement(uint i, Elem* e)
173 {
174 if constexpr (STORE_INDICES)
175 Base::container().set(i, indexFromPointer(e));
176 else
177 Base::container().set(i, e);
178 }
179
180 void setElement(uint i, uint ei)
181 {
182 if constexpr (STORE_INDICES)
183 Base::container().set(i, ei);
184 else
185 Base::container().set(i, elemFromParent(ei));
186 }
187
188 void setElement(Base::ConstIterator it, Elem* v)
189 {
190 setElement(it - elementBegin(), v);
191 }
192
193 void setElement(Base::ConstIterator it, uint vi)
194 {
195 setElement(it - elementBegin(), vi);
196 }
197
198 void setElement(Base::ConstIndexIterator it, Elem* v)
199 {
200 setElement(it - elementBegin(), v);
201 }
202
203 void setElement(Base::ConstIndexIterator it, uint vi)
204 {
205 setElement(it - elementBegin(), vi);
206 }
207
208 void setElementMod(int i, Elem* e)
209 {
210 if constexpr (STORE_INDICES)
211 Base::container().atMod(i) = indexFromPointer(e);
212 else
213 Base::container().atMod(i) = e;
214 }
215
216 void setElementMod(int i, uint ei)
217 {
218 if constexpr (STORE_INDICES)
219 Base::container().atMod(i) = ei;
220 else
221 Base::container().atMod(i) = elemFromParent(ei);
222 }
223
224 template<Range Rng>
225 void setElements(Rng&& r) requires InputRange<Rng, Elem*>
226 {
227 if constexpr (STORE_INDICES) {
228 auto conv = [&](auto v) {
229 return indexFromPointer(v);
230 };
231
232 Base::container().set(r | std::views::transform(conv));
233 }
234 else {
235 Base::container().set(r);
236 }
237 }
238
239 template<Range Rng>
240 void setElements(Rng&& r) requires InputRange<Rng, uint>
241 {
242 if constexpr (STORE_INDICES) {
243 Base::container().set(r);
244 }
245 else {
246 auto conv = [&](auto i) {
247 return elemFromParent(i);
248 };
249
250 Base::container().set(r | std::views::transform(conv));
251 }
252 }
253
254 bool containsElement(const Elem* e) const
255 {
256 if constexpr (STORE_INDICES)
257 return Base::container().contains(indexFromPointer(e));
258 else
259 return Base::container().contains(e);
260 }
261
262 bool containsElement(uint ei) const
263 {
264 if constexpr (STORE_INDICES)
265 return Base::container().contains(ei);
266 else
267 return Base::container().contains(elemFromParent(ei));
268 }
269
270 uint indexOfElement(const Elem* e) const
271 {
272 if constexpr (STORE_INDICES)
273 return Base::container().indexOf(indexFromPointer(e));
274 else
275 return Base::container().indexOf(e);
276 }
277
278 uint indexOfElement(uint ei) const
279 {
280 if constexpr (STORE_INDICES)
281 return Base::container().indexOf(ei);
282 else
283 return Base::container().indexOf(elemFromParent(ei));
284 }
285
286 Base::Iterator elementBegin()
287 {
288 if constexpr (STORE_INDICES)
289 return typename Base::Iterator(
290 Base::container().begin(), Base::parentElement());
291 else
292 return Base::container().begin();
293 }
294
295 Base::Iterator elementEnd()
296 {
297 if constexpr (STORE_INDICES)
298 return typename Base::Iterator(Base::container().end());
299 else
300 return Base::container().end();
301 }
302
303 Base::ConstIterator elementBegin() const
304 {
305 if constexpr (STORE_INDICES)
306 return typename Base::ConstIterator(
307 Base::container().begin(), Base::parentElement());
308 else
309 return Base::container().begin();
310 }
311
312 Base::ConstIterator elementEnd() const
313 {
314 if constexpr (STORE_INDICES)
315 return typename Base::ConstIterator(Base::container().end());
316 else
317 return Base::container().end();
318 }
319
320 Base::ConstIndexIterator elementIndexBegin() const
321 {
322 if constexpr (STORE_INDICES)
323 return Base::container().begin();
324 else
325 return typename Base::ConstIndexIterator(elementBegin());
326 }
327
328 Base::ConstIndexIterator elementIndexEnd() const
329 {
330 if constexpr (STORE_INDICES)
331 return Base::container().end();
332 else
333 return typename Base::ConstIndexIterator(elementEnd());
334 }
335
337 {
338 return View(elementBegin(), elementEnd());
339 }
340
342 {
343 return View(elementBegin(), elementEnd());
344 }
345
346 View<typename Base::ConstIndexIterator> elementIndices() const
347 {
348 return View(elementIndexBegin(), elementIndexEnd());
349 }
350
351 // ContainerComponent interface functions
352
353 void resize(uint n) requires (N < 0)
354 {
355 if constexpr (STORE_INDICES)
356 Base::container().resize(n, UINT_NULL);
357 else
358 Base::container().resize(n);
359 }
360
361 void pushBack(Elem* e = nullptr) requires (N < 0)
362 {
363 if constexpr (STORE_INDICES)
364 Base::container().pushBack(indexFromPointer(e));
365 else
366 Base::container().pushBack(e);
367 }
368
369 void pushBack(uint ei) requires (N < 0)
370 {
371 if constexpr (STORE_INDICES)
372 Base::container().pushBack(ei);
373 else
374 Base::container().pushBack(elemFromParent(ei));
375 }
376
377 void insert(uint i, Elem* e = nullptr) requires (N < 0)
378 {
379 if constexpr (STORE_INDICES)
380 Base::container().insert(i, indexFromPointer(e));
381 else
382 Base::container().insert(i, e);
383 }
384
385 void insert(uint i, uint ei) requires (N < 0)
386 {
387 if constexpr (STORE_INDICES)
388 Base::container().insert(i, ei);
389 else
390 Base::container().insert(i, elemFromParent(ei));
391 }
392
393 void erase(uint i) requires (N < 0) { Base::container().erase(i); }
394
395 void clear() requires (N < 0) { Base::container().clear(); }
396
397 // Utility functions
398
399 uint indexFromPointer(const Elem* v) const
400 {
401 if (v == nullptr) [[unlikely]]
402 return UINT_NULL;
403 else
404 return v->index();
405 }
406
407 Elem* elemFromParent(uint vi)
408 {
409 if (vi == UINT_NULL) [[unlikely]]
410 return nullptr;
411 else
412 return &Base::parentElement()
413 ->parentMesh()
414 ->template element<Elem::ELEMENT_ID>(vi);
415 }
416
417 const Elem* elemFromParent(uint vi) const
418 {
419 if (vi == UINT_NULL) [[unlikely]]
420 return nullptr;
421 else
422 return &Base::parentElement()
423 ->parentMesh()
424 ->template element<Elem::ELEMENT_ID>(vi);
425 }
426};
427
428} // namespace vcl::comp
429
430#endif // VCL_MESH_COMPONENTS_BASES_REFERENCE_CONTAINER_COMPONENT_H
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
The View class is a simple class that stores and exposes two iterators begin and end.
Definition view.h:67
The IndexContainerComponent is the base class for all the components of VCLib that store a container ...
Definition index_container_component.h:95
The PointerContainerComponent is the base class for all the components of VCLib that store a containe...
Definition pointer_container_component.h:95
The ReferenceContainerComponent is a class that inherits from the IndexContainerComponent or PointerC...
Definition reference_container_component.h:99
Utility concept that is evaluated true the Range R is an Input Range and has a value_type that is con...
Definition range.h:89
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