Function: add method to create shallow copy of virtual array

Creating a shallow copy is sometimes useful to get a unique ptr
for a virtual array when one only has a reference. It shouldn't
be used usually, but sometimes its the fastest way to do correct
ownership handling.
This commit is contained in:
Jacques Lucke 2021-04-29 15:42:32 +02:00
parent 41945454f7
commit 4225a18b35
2 changed files with 59 additions and 3 deletions

View File

@ -34,6 +34,12 @@ namespace blender::fn {
template<typename T> class GVArray_Typed;
template<typename T> class GVMutableArray_Typed;
class GVArray;
class GVMutableArray;
using GVArrayPtr = std::unique_ptr<GVArray>;
using GVMutableArrayPtr = std::unique_ptr<GVMutableArray>;
/* A generically typed version of `VArray<T>`. */
class GVArray {
protected:
@ -143,6 +149,8 @@ class GVArray {
return GVArray_Typed<T>(*this);
}
GVArrayPtr shallow_copy() const;
protected:
virtual void get_impl(const int64_t index, void *r_value) const;
virtual void get_to_uninitialized_impl(const int64_t index, void *r_value) const = 0;
@ -215,9 +223,6 @@ class GVMutableArray : public GVArray {
virtual void *try_get_internal_mutable_varray_impl();
};
using GVArrayPtr = std::unique_ptr<GVArray>;
using GVMutableArrayPtr = std::unique_ptr<GVMutableArray>;
class GVArray_For_GSpan : public GVArray {
protected:
const void *data_ = nullptr;

View File

@ -18,6 +18,37 @@
namespace blender::fn {
/* --------------------------------------------------------------------
* GVArray_For_ShallowCopy.
*/
class GVArray_For_ShallowCopy : public GVArray {
private:
const GVArray &varray_;
public:
GVArray_For_ShallowCopy(const GVArray &varray)
: GVArray(varray.type(), varray.size()), varray_(varray)
{
}
private:
void get_impl(const int64_t index, void *r_value) const override
{
varray_.get(index, r_value);
}
void get_to_uninitialized_impl(const int64_t index, void *r_value) const override
{
varray_.get_to_uninitialized(index, r_value);
}
void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override
{
varray_.materialize_to_uninitialized(mask, dst);
}
};
/* --------------------------------------------------------------------
* GVArray.
*/
@ -73,6 +104,26 @@ const void *GVArray::try_get_internal_varray_impl() const
return nullptr;
}
/**
* Creates a new `std::unique_ptr<GVArray>` based on this `GVArray`.
* The lifetime of the returned virtual array must not be longer than the lifetime of this virtual
* array.
*/
GVArrayPtr GVArray::shallow_copy() const
{
if (this->is_span()) {
return std::make_unique<GVArray_For_GSpan>(this->get_internal_span());
}
if (this->is_single()) {
BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer);
this->get_internal_single(buffer);
std::unique_ptr new_varray = std::make_unique<GVArray_For_SingleValue>(*type_, size_, buffer);
type_->destruct(buffer);
return new_varray;
}
return std::make_unique<GVArray_For_ShallowCopy>(*this);
}
/* --------------------------------------------------------------------
* GVMutableArray.
*/