diff options
author | Jacques Lucke <jacques@blender.org> | 2022-03-19 10:26:29 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-03-19 10:26:29 +0300 |
commit | 3e16f3b3ef4b8f385b30fe4a1e00860620f610ee (patch) | |
tree | cea8e2a3ea8a8a7dbce98263d166b4782d83721b /source/blender/blenlib/intern/generic_vector_array.cc | |
parent | c655146b87fe20853e52b87991b46732a04d749e (diff) |
BLI: move generic data structures to blenlib
This is a follow up to rB2252bc6a5527cd7360d1ccfe7a2d1bc640a8dfa6.
Diffstat (limited to 'source/blender/blenlib/intern/generic_vector_array.cc')
-rw-r--r-- | source/blender/blenlib/intern/generic_vector_array.cc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/generic_vector_array.cc b/source/blender/blenlib/intern/generic_vector_array.cc new file mode 100644 index 00000000000..b32236bfada --- /dev/null +++ b/source/blender/blenlib/intern/generic_vector_array.cc @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_generic_vector_array.hh" + +namespace blender { + +GVectorArray::GVectorArray(const CPPType &type, const int64_t array_size) + : type_(type), element_size_(type.size()), items_(array_size) +{ +} + +GVectorArray::~GVectorArray() +{ + if (type_.is_trivially_destructible()) { + return; + } + for (Item &item : items_) { + type_.destruct_n(item.start, item.length); + } +} + +void GVectorArray::append(const int64_t index, const void *value) +{ + Item &item = items_[index]; + if (item.length == item.capacity) { + this->realloc_to_at_least(item, item.capacity + 1); + } + + void *dst = POINTER_OFFSET(item.start, element_size_ * item.length); + type_.copy_construct(value, dst); + item.length++; +} + +void GVectorArray::extend(const int64_t index, const GVArray &values) +{ + BLI_assert(values.type() == type_); + for (const int i : IndexRange(values.size())) { + BUFFER_FOR_CPP_TYPE_VALUE(type_, buffer); + values.get(i, buffer); + this->append(index, buffer); + type_.destruct(buffer); + } +} + +void GVectorArray::extend(const int64_t index, const GSpan values) +{ + this->extend(index, GVArray::ForSpan(values)); +} + +void GVectorArray::extend(IndexMask mask, const GVVectorArray &values) +{ + for (const int i : mask) { + GVArray_For_GVVectorArrayIndex array{values, i}; + this->extend(i, GVArray(&array)); + } +} + +void GVectorArray::extend(IndexMask mask, const GVectorArray &values) +{ + GVVectorArray_For_GVectorArray virtual_values{values}; + this->extend(mask, virtual_values); +} + +void GVectorArray::clear(IndexMask mask) +{ + for (const int64_t i : mask) { + Item &item = items_[i]; + type_.destruct_n(item.start, item.length); + item.length = 0; + } +} + +GMutableSpan GVectorArray::operator[](const int64_t index) +{ + Item &item = items_[index]; + return GMutableSpan{type_, item.start, item.length}; +} + +GSpan GVectorArray::operator[](const int64_t index) const +{ + const Item &item = items_[index]; + return GSpan{type_, item.start, item.length}; +} + +void GVectorArray::realloc_to_at_least(Item &item, int64_t min_capacity) +{ + const int64_t new_capacity = std::max(min_capacity, item.length * 2); + + void *new_buffer = allocator_.allocate(element_size_ * new_capacity, type_.alignment()); + type_.relocate_assign_n(item.start, new_buffer, item.length); + + item.start = new_buffer; + item.capacity = new_capacity; +} + +} // namespace blender |