23#ifndef VCL_MESH_CONTAINERS_DETAIL_CUSTOM_COMPONENTS_VECTOR_MAP_H
24#define VCL_MESH_CONTAINERS_DETAIL_CUSTOM_COMPONENTS_VECTOR_MAP_H
26#include <vclib/mesh/exceptions.h>
28#include <vclib/base.h>
33#include <unordered_map>
36namespace vcl::mesh::detail {
64template<
bool HasCustomComponent>
65class CustomComponentsVectorMap
70class CustomComponentsVectorMap<true>
74 std::unordered_map<std::string, std::vector<std::any>> mMap;
81 mutable std::unordered_map<std::string, bool> mNeedToInitialize;
83 std::unordered_map<std::string, std::type_index> mCompType;
92 mNeedToInitialize.clear();
100 void reserve(uint size)
102 for (
auto& p : mMap) {
103 p.second.reserve(size);
112 void resize(uint size)
114 for (
auto& p : mMap) {
121 if (p.second.size() < size)
122 mNeedToInitialize.at(p.first) =
true;
123 p.second.resize(size);
139 void compact(
const std::vector<uint>& newIndices)
141 for (
auto& p : mMap) {
142 compactVector(p.second, newIndices);
146 void swapCustomComponents(uint i, uint j)
148 for (
auto& p : mMap) {
149 std::swap(p.second[i], p.second[j]);
166 template<
typename CompType>
167 void addNewComponent(
const std::string& name, uint size)
169 std::vector<std::any>& v = mMap[name];
170 v.resize(size, CompType());
171 mNeedToInitialize[name] =
false;
172 mCompType.emplace(name,
typeid(CompType));
180 void deleteComponent(
const std::string& name)
183 mNeedToInitialize.erase(name);
184 mCompType.erase(name);
192 void assertComponentExists(
const std::string& compName)
const
195 assert(mMap.find(compName) != mMap.end());
203 bool componentExists(
const std::string& compName)
const
205 return (mMap.find(compName) != mMap.end());
213 std::vector<std::string> allComponentNames()
const
215 std::vector<std::string> names;
216 names.reserve(mMap.size());
217 for (
const auto& p : mMap)
218 names.push_back(p.first);
231 template<
typename CompType>
232 bool isComponentOfType(
const std::string& compName)
const
234 std::type_index t(
typeid(CompType));
236 return t == mCompType.at(compName);
248 std::type_index componentType(
const std::string& compName)
const
250 return mCompType.at(compName);
261 template<
typename CompType>
262 std::vector<std::string> allComponentNamesOfType()
const
264 std::vector<std::string> names;
265 std::type_index t(
typeid(CompType));
266 for (
const auto& p : mCompType) {
268 names.push_back(p.first);
285 template<
typename CompType>
286 const std::vector<std::any>& componentVector(
287 const std::string& compName)
const
289 checkComponentType<CompType>(compName);
290 std::vector<std::any>& v =
291 const_cast<std::vector<std::any>&
>(mMap.at(compName));
293 if (mNeedToInitialize.at(compName)) {
294 for (std::any& a : v) {
298 mNeedToInitialize.at(compName) =
false;
318 template<
typename CompType>
319 std::vector<std::any>& componentVector(
const std::string& compName)
321 checkComponentType<CompType>(compName);
322 std::vector<std::any>& v = mMap.at(compName);
324 if (mNeedToInitialize.at(compName)) {
325 for (std::any& a : v) {
329 mNeedToInitialize.at(compName) =
false;
334 void importSameCustomComponentFrom(
337 const std::string& compName,
338 const CustomComponentsVectorMap<true>& other)
340 if (other.componentExists(compName) && componentExists(compName)) {
341 if (other.componentType(compName) == componentType(compName)) {
342 mMap.at(compName)[thisPos] = other.mMap.at(compName)[otherPos];
347 template<
typename CompType>
348 void serializeCustomComponentsOfType(std::ostream& os)
const
350 std::vector<std::string> compNames =
351 allComponentNamesOfType<CompType>();
352 vcl::serialize(os, compNames);
353 for (
const auto& name : compNames) {
354 bool b = mNeedToInitialize.at(name);
355 vcl::serialize(os, b);
356 const std::vector<std::any>& v = componentVector<CompType>(name);
361 template<
typename CompType>
362 void deserializeCustomComponentsOfType(std::istream& is)
364 std::vector<std::string> compNames;
365 vcl::deserialize(is, compNames);
366 for (
const auto& name : compNames) {
368 vcl::deserialize(is, b);
369 std::vector<std::any> v;
372 mNeedToInitialize[name] = b;
373 mCompType.emplace(name,
typeid(CompType));
378 template<
typename CompType>
379 void checkComponentType(
const std::string& compName)
const
381 std::type_index t(
typeid(CompType));
382 if (t != mCompType.at(compName)) {
383 throw BadCustomComponentTypeException(
384 "Expected type " + std::string(mCompType.at(compName).name()) +
385 " for " + compName +
", but was " + std::string(t.name()) +
A class representing a box in N-dimensional space.
Definition box.h:46