diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_cpp_type.hh | 20 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_cpp_type_make.hh | 24 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_generic_virtual_array.hh | 7 | ||||
-rw-r--r-- | source/blender/blenlib/intern/generic_virtual_array.cc | 27 |
4 files changed, 78 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh index 9453eb89a2e..c8824813a21 100644 --- a/source/blender/blenlib/BLI_cpp_type.hh +++ b/source/blender/blenlib/BLI_cpp_type.hh @@ -118,9 +118,11 @@ class CPPType : NonCopyable, NonMovable { void (*copy_assign_)(const void *src, void *dst) = nullptr; void (*copy_assign_indices_)(const void *src, void *dst, IndexMask mask) = nullptr; + void (*copy_assign_compressed_)(const void *src, void *dst, IndexMask mask) = nullptr; void (*copy_construct_)(const void *src, void *dst) = nullptr; void (*copy_construct_indices_)(const void *src, void *dst, IndexMask mask) = nullptr; + void (*copy_construct_compressed_)(const void *src, void *dst, IndexMask mask) = nullptr; void (*move_assign_)(void *src, void *dst) = nullptr; void (*move_assign_indices_)(void *src, void *dst, IndexMask mask) = nullptr; @@ -408,6 +410,15 @@ class CPPType : NonCopyable, NonMovable { copy_assign_indices_(src, dst, mask); } + void copy_assign_compressed(const void *src, void *dst, IndexMask mask) const + { + BLI_assert(mask.size() == 0 || src != dst); + BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); + BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); + + copy_assign_compressed_(src, dst, mask); + } + /** * Copy an instance of this type from src to dst. * @@ -439,6 +450,15 @@ class CPPType : NonCopyable, NonMovable { copy_construct_indices_(src, dst, mask); } + void copy_construct_compressed(const void *src, void *dst, IndexMask mask) const + { + BLI_assert(mask.size() == 0 || src != dst); + BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); + BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); + + copy_construct_compressed_(src, dst, mask); + } + /** * Move an instance of this type from src to dst. * diff --git a/source/blender/blenlib/BLI_cpp_type_make.hh b/source/blender/blenlib/BLI_cpp_type_make.hh index 2612348075b..b0dbbff7ca8 100644 --- a/source/blender/blenlib/BLI_cpp_type_make.hh +++ b/source/blender/blenlib/BLI_cpp_type_make.hh @@ -51,6 +51,17 @@ template<typename T> void copy_assign_indices_cb(const void *src, void *dst, Ind mask.foreach_index([&](int64_t i) { dst_[i] = src_[i]; }); } +template<typename T> void copy_assign_compressed_cb(const void *src, void *dst, IndexMask mask) +{ + const T *src_ = static_cast<const T *>(src); + T *dst_ = static_cast<T *>(dst); + + mask.to_best_mask_type([&](auto best_mask) { + for (const int64_t i : IndexRange(best_mask.size())) { + dst_[i] = src_[best_mask[i]]; + } + }); +} template<typename T> void copy_construct_cb(const void *src, void *dst) { @@ -63,6 +74,17 @@ template<typename T> void copy_construct_indices_cb(const void *src, void *dst, mask.foreach_index([&](int64_t i) { new (dst_ + i) T(src_[i]); }); } +template<typename T> void copy_construct_compressed_cb(const void *src, void *dst, IndexMask mask) +{ + const T *src_ = static_cast<const T *>(src); + T *dst_ = static_cast<T *>(dst); + + mask.to_best_mask_type([&](auto best_mask) { + for (const int64_t i : IndexRange(best_mask.size())) { + new (dst_ + i) T(src_[best_mask[i]]); + } + }); +} template<typename T> void move_assign_cb(void *src, void *dst) { @@ -208,10 +230,12 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name) if constexpr (std::is_copy_assignable_v<T>) { copy_assign_ = copy_assign_cb<T>; copy_assign_indices_ = copy_assign_indices_cb<T>; + copy_assign_compressed_ = copy_assign_compressed_cb<T>; } if constexpr (std::is_copy_constructible_v<T>) { copy_construct_ = copy_construct_cb<T>; copy_construct_indices_ = copy_construct_indices_cb<T>; + copy_construct_compressed_ = copy_construct_compressed_cb<T>; } if constexpr (std::is_move_assignable_v<T>) { move_assign_ = move_assign_cb<T>; diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index 3b9ae33c9f1..cb1a984c8ce 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -51,6 +51,9 @@ class GVArrayImpl { virtual void materialize(const IndexMask mask, void *dst) const; virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const; + virtual void materialize_compressed(IndexMask mask, void *dst) const; + virtual void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const; + virtual bool try_assign_VArray(void *varray) const; virtual bool may_have_ownership() const; }; @@ -593,6 +596,10 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { virtual void materialize(const IndexMask mask, void *dst) const override; virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const override; + + virtual void materialize_compressed(const IndexMask mask, void *dst) const override; + virtual void materialize_compressed_to_uninitialized(const IndexMask mask, + void *dst) const override; }; /** \} */ diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc index 7a2b45ff857..3764367b6b7 100644 --- a/source/blender/blenlib/intern/generic_virtual_array.cc +++ b/source/blender/blenlib/intern/generic_virtual_array.cc @@ -24,6 +24,22 @@ void GVArrayImpl::materialize_to_uninitialized(const IndexMask mask, void *dst) } } +void GVArrayImpl::materialize_compressed(IndexMask mask, void *dst) const +{ + for (const int64_t i : mask.index_range()) { + void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); + this->get(mask[i], elem_dst); + } +} + +void GVArrayImpl::materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const +{ + for (const int64_t i : mask.index_range()) { + void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); + this->get_to_uninitialized(mask[i], elem_dst); + } +} + void GVArrayImpl::get(const int64_t index, void *r_value) const { type_->destruct(r_value); @@ -182,6 +198,17 @@ void GVArrayImpl_For_GSpan::materialize_to_uninitialized(const IndexMask mask, v type_->copy_construct_indices(data_, dst, mask); } +void GVArrayImpl_For_GSpan::materialize_compressed(const IndexMask mask, void *dst) const +{ + type_->copy_assign_compressed(data_, dst, mask); +} + +void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexMask mask, + void *dst) const +{ + type_->copy_construct_compressed(data_, dst, mask); +} + class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { public: using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; |