Visual Computing Library  devel
Loading...
Searching...
No Matches
vertical_components_vector_tuple.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_CONTAINERS_DETAIL_VERTICAL_COMPONENTS_VECTOR_TUPLE_H
24#define VCL_MESH_CONTAINERS_DETAIL_VERTICAL_COMPONENTS_VECTOR_TUPLE_H
25
26#include <vclib/mesh/components/concepts/component.h>
27
28#include <vclib/base.h>
29
30#include <array>
31#include <tuple>
32#include <vector>
33
34namespace vcl::mesh::detail {
35
36template<typename... Comp>
37class VerticalComponentsVectorTuple
38{
39 using ComponentTypes = std::tuple<Comp...>;
40
41 static constexpr uint COMP_NUMBER =
42 std::tuple_size_v<std::tuple<std::vector<Comp>...>>;
43
44 std::tuple<std::vector<typename Comp::DataValueType>...> mVecTuple;
45
46 std::array<bool, COMP_NUMBER> mVecEnabled;
47 std::size_t mSize = 0;
48
49public:
50 VerticalComponentsVectorTuple()
51 {
52 (setComponentEnabled<Comp, !comp::IsOptionalComponent<Comp>>(), ...);
53 }
54
55 static constexpr uint componentsNumber() { return COMP_NUMBER; }
56
57 template<typename C>
58 constexpr bool hasComponent() const
59 {
60 return indexOfType<C>() != UINT_NULL;
61 }
62
63 template<typename C>
64 constexpr std::vector<typename C::DataValueType>& vector()
65 {
66 constexpr uint ind = indexOfType<C>();
67 return std::get<ind>(mVecTuple);
68 }
69
70 template<typename C>
71 constexpr const std::vector<typename C::DataValueType>& vector() const
72 {
73 constexpr uint ind = indexOfType<C>();
74 return std::get<ind>(mVecTuple);
75 }
76
77 std::size_t size() const { return mSize; }
78
79 void resize(std::size_t size)
80 {
81 if constexpr (componentsNumber() > 0) {
82 vectorResize<componentsNumber() - 1>(size);
83 }
84 mSize = size;
85 }
86
87 void reserve(std::size_t size)
88 {
89 if constexpr (componentsNumber() > 0) {
90 vectorReserve<componentsNumber() - 1>(size);
91 }
92 }
93
94 void compact(const std::vector<uint>& newIndices)
95 {
96 if constexpr (componentsNumber() > 0) {
97 vectorCompact<componentsNumber() - 1>(newIndices);
98 }
99 }
100
101 void clear()
102 {
103 auto function = [](auto&... args) {
104 ((args.clear()), ...);
105 };
106
107 std::apply(function, mVecTuple);
108 mSize = 0;
109 }
110
111 void enableAllOptionalComponents()
112 {
113 (setComponentEnabledIfOptional<Comp, true>(), ...);
114 }
115
116 void disableAllOptionalComponents()
117 {
118 (setComponentEnabledIfOptional<Comp, false>(), ...);
119 }
120
121 void swapComponents(uint i, uint j) { (swapComponent<Comp>(i, j), ...); }
122
123 template<typename C>
124 bool isComponentEnabled() const
125 {
126 constexpr uint ind = indexOfType<C>();
127 return mVecEnabled[ind];
128 }
129
130 template<uint COMP_ID>
131 bool isComponentEnabled() const
132 {
133 using C = comp::ComponentOfType<COMP_ID, Comp...>;
134 return isComponentEnabled<C>();
135 }
136
137 template<typename C>
138 void enableComponent()
139 {
140 constexpr uint ind = indexOfType<C>();
141 mVecEnabled[ind] = true;
142 vector<C>().resize(mSize);
143 }
144
145 template<uint COMP_ID>
146 void enableComponent()
147 {
148 using C = comp::ComponentOfType<COMP_ID, Comp...>;
149 enableComponent<C>();
150 }
151
152 template<typename C>
153 void disableComponent()
154 {
155 constexpr uint ind = indexOfType<C>();
156 mVecEnabled[ind] = false;
157 vector<C>().clear();
158 }
159
160 template<uint COMP_ID>
161 void disableComponent()
162 {
163 using C = comp::ComponentOfType<COMP_ID, Comp...>;
164 disableComponent<C>();
165 }
166
167 template<typename C>
168 void swapComponent(uint i, uint j)
169 {
170 constexpr uint ind = indexOfType<C>();
171 if (mVecEnabled[ind]) {
172 auto& vec = std::get<ind>(mVecTuple);
173 std::swap(vec[i], vec[j]);
174 }
175 }
176
177private:
178 template<typename C>
179 static constexpr uint indexOfType()
180 {
181 return IndexInTypes<C, Comp...>::value;
182 }
183
184 template<std::size_t N>
185 void vectorResize(std::size_t size)
186 {
187 if (mVecEnabled[N]) {
188 std::get<N>(mVecTuple).resize(size);
189 }
190 if constexpr (N != 0)
191 vectorResize<N - 1>(size);
192 }
193
194 template<std::size_t N>
195 void vectorReserve(std::size_t size)
196 {
197 if (mVecEnabled[N]) {
198 std::get<N>(mVecTuple).reserve(size);
199 }
200 if constexpr (N != 0)
201 vectorReserve<N - 1>(size);
202 }
203
204 template<std::size_t N>
205 void vectorCompact(const std::vector<uint>& newIndices)
206 {
207 if (mVecEnabled[N]) {
208 compactVector(std::get<N>(mVecTuple), newIndices);
209 }
210 if constexpr (N != 0)
211 vectorCompact<N - 1>(newIndices);
212 }
213
214 template<typename C, bool E>
215 void setComponentEnabled()
216 {
217 if constexpr (E) {
218 enableComponent<C>();
219 }
220 else {
221 disableComponent<C>();
222 }
223 }
224
225 template<typename C, bool E>
226 void setComponentEnabledIfOptional()
227 {
228 if constexpr (comp::IsOptionalComponent<C>) {
229 setComponentEnabled<C, E>();
230 }
231 }
232};
233
234/*
235 * Crucial specialization - allows to catch components that are passed with a
236 * TypeWrapper
237 */
238template<typename... Comp>
239class VerticalComponentsVectorTuple<TypeWrapper<Comp...>> :
240 public VerticalComponentsVectorTuple<Comp...>
241{
242};
243
244} // namespace vcl::mesh::detail
245
246#endif // VCL_MESH_CONTAINERS_DETAIL_VERTICAL_COMPONENTS_VECTOR_TUPLE_H
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
FirstTypeT< typename detail::ComponentOfTypePred< COMP_ID, Components... >::type > ComponentOfType
Given the ID of a Component and a list of Component types (or a TypeWrapper), this alias sets its typ...
Definition base.h:186