Visual Computing Library  devel
Loading...
Searching...
No Matches
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_CONTAINER_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASE_CONTAINER_COMPONENT_H
25
26#include "component.h"
27
28#include <vclib/space/core.h>
29
30namespace vcl::comp {
31
32namespace detail {
33
34// small alias to differentiate between components having only a container or
35// components having a container and an additional data type:
36// - if AD is void, no additional data and the component will have only a Vector
37// - if AD is not void, there is additional data, and the component will have
38// a tuple containing a Vector and the additional data
39template<
40 typename DC,
41 uint CT,
42 typename T,
43 int N,
44 typename AD,
45 typename El,
46 bool v,
47 bool o,
48 bool TT,
49 typename... PT>
50using ContCompBase = std::conditional_t<
51 std::is_same_v<AD, void>,
52 Component<DC, CT, Vector<T, N>, El, v, o, PT...>,
53 Component<DC, CT, std::tuple<Vector<T, N>, AD>, El, v, o, PT...>>;
54
55} // namespace detail
56
58
109template<
110 typename DerivedComponent, // CRTP pattern, derived class
111 uint COMP_ID, // component id
112 typename T, // data stored in container
113 int N, // container size
114 typename AdditionalData, // additional data outside container
115 typename ParentElemType, // parent element type
116 bool VERT, // true if component vertical
117 bool OPT, // true if component vertical and optional
118 bool TTVN, // true if container size tied to vertex number
119 typename... PointedTypes> // types of pointers stored by the component
120class ContainerComponent :
121 public detail::ContCompBase<
122 DerivedComponent,
123 COMP_ID,
124 T,
125 N,
126 AdditionalData,
127 ParentElemType,
128 VERT,
129 OPT,
130 TTVN,
131 PointedTypes...>
132{
133 static constexpr bool HAS_ADDITIONAL_DATA =
134 !std::is_same_v<AdditionalData, void>;
135
136 using Base = detail::ContCompBase<
137 DerivedComponent,
138 COMP_ID,
139 T,
140 N,
141 AdditionalData,
142 ParentElemType,
143 VERT,
144 OPT,
145 TTVN,
146 PointedTypes...>;
147
148public:
159 static const bool TIED_TO_VERTEX_NUMBER = TTVN;
160
161 static const int SIZE = N;
162
163protected:
164 /* Iterator Types declaration */
165
166 using Iterator = Vector<T, N>::Iterator;
167 using ConstIterator = Vector<T, N>::ConstIterator;
168
169 /* Constructor */
170
171 /*
172 * Create a container of T objects.
173 * If this Container is a static array, all its element will be initialized
174 * to T(). If this Container is a dynamic vector, it will be an empty
175 * container.
176 */
177 ContainerComponent()
178 {
179 if constexpr (!Base::IS_VERTICAL) {
180 if constexpr (N >= 0) {
181 Base::data().fill(T());
182 }
183 }
184 }
185
186 /*
187 * Create a container of Objects.
188 * If this Container is a static array, all its element will be initialized
189 * to T(). If this Container is a dynamic vector, it will be an empty
190 * container.
191 */
192 void init()
193 {
194 if constexpr (N >= 0) {
195 // I'll use the array, N is >= 0.
196 // There will be a static number of objects.
197 container().fill(T());
198 }
199 else {
200 // I'll use the vector, because N is < 0.
201 // There will be a dynamic number of objects.
202 container().clear();
203 }
204 }
205
206 Vector<T, N>& container()
207 {
208 if constexpr (HAS_ADDITIONAL_DATA) {
209 return std::get<0>(Base::data());
210 }
211 else {
212 return Base::data();
213 }
214 }
215
216 const Vector<T, N>& container() const
217 {
218 if constexpr (HAS_ADDITIONAL_DATA) {
219 return std::get<0>(Base::data());
220 }
221 else {
222 return Base::data();
223 }
224 }
225
226 template<typename AdDt = AdditionalData>
227 AdDt& additionalData() requires (HAS_ADDITIONAL_DATA)
228 {
229 return std::get<1>(Base::data());
230 }
231
232 template<typename AdDt = AdditionalData>
233 const AdDt& additionalData() const requires (HAS_ADDITIONAL_DATA)
234 {
235 return std::get<1>(Base::data());
236 }
237};
238
240
241} // namespace vcl::comp
242
243#endif // VCL_MESH_COMPONENTS_BASE_CONTAINER_COMPONENT_H