22 for (
const auto& p : m_handles) {
23 const auto& handle = p.second;
24 const auto& attr_ptr = attribute(handle);
25 if (is_active(handle)) {
26 const auto& attr = *m_attributes[handle.index];
27 attr.serialize(p.first, dim, writer);
39 for (
const auto& [name, handle] : m_handles) {
40 ret[
"attr_handle_" + name] = std::hash<AttributeHandle>{}(handle);
48 std::map<std::string, const wmtk::utils::Hashable*> ret;
49 for (
const auto& [name, handle] : m_handles) {
50 const auto& attr = attribute(handle);
51 ret[
"attr_" + name] = &attr;
59 for (
auto& attr_ptr : m_attributes) {
61 attr_ptr->push_scope();
68 for (
auto& attr_ptr : m_attributes) {
70 attr_ptr->pop_scope(apply_updates);
77 for (
auto& attr_ptr : m_attributes) {
79 attr_ptr->rollback_current_scope();
86 for (
const auto& attr_ptr : m_attributes) {
88 auto& stack = attr_ptr->get_local_scope_stack();
90 stack.change_to_next_scope();
98 for (
const auto& attr_ptr : m_attributes) {
100 attr_ptr->get_local_scope_stack().change_to_previous_scope();
105 template <
typename T>
107 const std::string& name,
112 if (!replace && m_handles.find(name) != m_handles.end()) {
114 "Cannot register attribute '{}' because it exists already. Set replace to true if you "
115 "want to overwrite the attribute",
122 if (replace && m_handles.find(name) != m_handles.end()) {
123 auto it = m_handles.find(name);
124 handle.
index = it->second.index;
126 handle.
index = m_attributes.size();
127 m_attributes.emplace_back(
130 m_handles[name] = handle;
136 template <
typename T>
139 for (
const auto& a : m_attributes) {
141 assert(a->reserved_size() >= cap);
145 template <
typename T>
148 return m_handles.at(name);
150 template <
typename T>
153 auto it = m_handles.find(name);
154 return it != m_handles.end() && bool(m_attributes[it->second.index]);
157 template <
typename T>
166 for (
size_t j = 0; j < m_attributes.size(); ++j) {
167 const bool exists = bool(m_attributes[j]);
169 if (exists != o_exists) {
171 }
else if (exists && o_exists && !(*m_attributes[j] == *other.
m_attributes[j])) {
179 template <
typename T>
183 auto& attr_ptr = m_attributes[handle.
index];
184 assert(
bool(attr_ptr));
185 auto& attr = *attr_ptr;
186 attr.set(std::move(val));
189 template <
typename T>
192 auto& attr_ptr = m_attributes[handle.
index];
193 assert(
bool(attr_ptr));
194 return attr_ptr->reserved_size();
197 template <
typename T>
200 return m_reserved_size;
203 template <
typename T>
206 return active_attributes().size();
208 template <
typename T>
211 std::vector<AttributeHandle> handles;
212 handles.reserve(m_attributes.size());
213 for (
size_t j = 0; j < m_attributes.size(); ++j) {
214 if (
bool(m_attributes[j])) {
215 handles.emplace_back(j);
221 template <
typename T>
224 const size_t index = h.
index;
225 assert(index < m_attributes.size());
226 return bool(m_attributes[index]);
229 template <
typename T>
232 m_reserved_size = size;
233 for (
auto& attr_ptr : m_attributes) {
234 if (
bool(attr_ptr)) {
235 attr_ptr->reserve(size);
240 template <
typename T>
243 reserve(m_reserved_size + size);
246 template <
typename T>
249 if (size > m_reserved_size) {
255 template <
typename T>
257 const std::vector<AttributeHandle>& attributes,
258 bool invalidate_handles)
260 if (attributes.empty()) {
263 std::vector<int64_t> remove_indices;
267 std::back_inserter(remove_indices),
269 std::sort(remove_indices.begin(), remove_indices.end());
270 remove_indices.erase(
271 std::unique(remove_indices.begin(), remove_indices.end()),
272 remove_indices.end());
275 for (
const int64_t& i : remove_indices) {
276 m_attributes[i].reset();
280 if (invalidate_handles) {
281 clear_dead_attributes();
286 template <
typename T>
289 m_attributes[attribute.
index].reset();
292 template <
typename T>
295 size_t old_index = 0;
296 size_t new_index = 0;
297 std::vector<int64_t> old_to_new_id(m_attributes.size(), -1);
298 for (old_index = 0; old_index < m_attributes.size(); ++old_index) {
299 if (
bool(m_attributes[old_index])) {
300 old_to_new_id[old_index] = new_index;
301 m_attributes[new_index++] = std::move(m_attributes[old_index]);
304 m_attributes.resize(new_index);
307 for (
auto it = m_handles.begin(); it != m_handles.end(); ) {
308 if (int64_t new_ind = old_to_new_id[it->second.index]; new_ind == -1) {
309 it = m_handles.erase(it);
311 it->second.index = new_ind;
316 template <
typename T>
319 for (
const auto& [key, value] : m_handles) {
320 if (value == handle) {
324 throw std::runtime_error(
"Could not find handle in MeshAttributes");
328 template <
typename T>
331 const std::string old_name = get_name(handle);
333 if (old_name == name) {
337 auto& attr = m_attributes[handle.
index];
339 assert(attr->m_name == old_name);
341 assert(m_handles.count(name) == 0);
344 m_handles[name] = m_handles[old_name];
345 m_handles.erase(old_name);
Internal handle representation used by MeshAttributes.
This class stores data of type T in a vector.
Contains all attributes of type T for a single mesh.
std::map< std::string, std::size_t > child_hashes() const override
size_t attribute_size(const AttributeHandle &handle) const
void clear_dead_attributes()
Clears and compactifies the attribute list. This invalidates all existing handles.
void change_to_child_scope() const
std::vector< std::unique_ptr< Attribute< T > > > m_attributes
void rollback_current_scope()
bool is_active(const AttributeHandle &handle) const
int64_t reserved_size() const
void reserve_more(int64_t size)
void guarantee_at_least(int64_t size)
void change_to_parent_scope() const
std::map< std::string, AttributeHandle > m_handles
std::map< std::string, const wmtk::utils::Hashable * > child_hashables() const override
void remove_attributes(const std::vector< AttributeHandle > &attributes, bool invalidate_handles=true)
Remove all passed in attributes.
bool operator==(const MeshAttributes< T > &other) const
size_t attribute_count() const
AttributeHandle attribute_handle(const std::string &name) const
std::vector< AttributeHandle > active_attributes() const
void remove_attribute(const AttributeHandle &attribute)
Remove a single attribute.
AttributeHandle register_attribute(const std::string &name, int64_t dimension, bool replace=false, T default_value=T(0))
void assert_capacity_valid(int64_t cap) const
void set(const AttributeHandle &handle, std::vector< T > val)
void reserve(const int64_t size)
void pop_scope(bool apply_updates=true)
bool has_attribute(const std::string &name) const
void set_name(const AttributeHandle &handle, const std::string &name)
std::string get_name(const AttributeHandle &handle) const
void serialize(const int dim, MeshWriter &writer) const
std::map< std::string, std::size_t > child_hashes() const override
std::vector< Simplex > make_unique(const Mesh &m, const std::vector< Simplex > &s)
void log_and_throw_error(const std::string &msg)