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/functions | |
parent | c655146b87fe20853e52b87991b46732a04d749e (diff) |
BLI: move generic data structures to blenlib
This is a follow up to rB2252bc6a5527cd7360d1ccfe7a2d1bc640a8dfa6.
Diffstat (limited to 'source/blender/functions')
17 files changed, 4 insertions, 2968 deletions
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt index eef5b1e3ea6..f1298a7f5b7 100644 --- a/source/blender/functions/CMakeLists.txt +++ b/source/blender/functions/CMakeLists.txt @@ -13,9 +13,6 @@ set(INC_SYS set(SRC intern/cpp_types.cc intern/field.cc - intern/generic_vector_array.cc - intern/generic_virtual_array.cc - intern/generic_virtual_vector_array.cc intern/multi_function.cc intern/multi_function_builder.cc intern/multi_function_params.cc @@ -26,13 +23,6 @@ set(SRC FN_field.hh FN_field_cpp_type.hh - FN_generic_array.hh - FN_generic_pointer.hh - FN_generic_span.hh - FN_generic_value_map.hh - FN_generic_vector_array.hh - FN_generic_virtual_array.hh - FN_generic_virtual_vector_array.hh FN_multi_function.hh FN_multi_function_builder.hh FN_multi_function_context.hh @@ -71,9 +61,6 @@ blender_add_lib(bf_functions "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WITH_GTESTS) set(TEST_SRC tests/FN_field_test.cc - tests/FN_generic_array_test.cc - tests/FN_generic_span_test.cc - tests/FN_generic_vector_array_test.cc tests/FN_multi_function_procedure_test.cc tests/FN_multi_function_test.cc diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 957b395e633..5a27cda0787 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -33,11 +33,11 @@ */ #include "BLI_function_ref.hh" +#include "BLI_generic_virtual_array.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" #include "BLI_vector_set.hh" -#include "FN_generic_virtual_array.hh" #include "FN_multi_function_builder.hh" namespace blender::fn { diff --git a/source/blender/functions/FN_generic_array.hh b/source/blender/functions/FN_generic_array.hh deleted file mode 100644 index c5388d27585..00000000000 --- a/source/blender/functions/FN_generic_array.hh +++ /dev/null @@ -1,256 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup fn - * - * This is a generic counterpart to #blender::Array, used when the type is not known at runtime. - * - * `GArray` should generally only be used for passing data around in dynamic contexts. - * It does not support a few things that #blender::Array supports: - * - Small object optimization / inline buffer. - * - Exception safety and various more specific constructors. - */ - -#include "BLI_allocator.hh" -#include "BLI_cpp_type.hh" - -#include "FN_generic_span.hh" - -namespace blender::fn { - -template< - /** - * The allocator used by this array. Should rarely be changed, except when you don't want that - * MEM_* functions are used internally. - */ - typename Allocator = GuardedAllocator> -class GArray { - protected: - /** The type of the data in the array, will be null after the array is default constructed, - * but a value should be assigned before any other interaction with the array. */ - const CPPType *type_ = nullptr; - void *data_ = nullptr; - int64_t size_ = 0; - - Allocator allocator_; - - public: - /** - * The default constructor creates an empty array, the only situation in which the type is - * allowed to be null. This default constructor exists so `GArray` can be used in containers, - * but the type should be supplied before doing anything else to the array. - */ - GArray(Allocator allocator = {}) noexcept : allocator_(allocator) - { - } - - GArray(NoExceptConstructor, Allocator allocator = {}) noexcept : GArray(allocator) - { - } - - /** - * Create and allocate a new array, with elements default constructed - * (which does not do anything for trivial types). - */ - GArray(const CPPType &type, int64_t size, Allocator allocator = {}) : GArray(type, allocator) - { - BLI_assert(size >= 0); - size_ = size; - data_ = this->allocate(size_); - type_->default_construct_n(data_, size_); - } - - /** - * Create an empty array with just a type. - */ - GArray(const CPPType &type, Allocator allocator = {}) : GArray(allocator) - { - type_ = &type; - } - - /** - * Take ownership of a buffer with a provided size. The buffer should be - * allocated with the same allocator provided to the constructor. - */ - GArray(const CPPType &type, void *buffer, int64_t size, Allocator allocator = {}) - : GArray(type, allocator) - { - BLI_assert(size >= 0); - BLI_assert(buffer != nullptr || size == 0); - BLI_assert(type_->pointer_has_valid_alignment(buffer)); - - data_ = buffer; - size_ = size; - } - - /** - * Create an array by copying values from a generic span. - */ - GArray(const GSpan span, Allocator allocator = {}) : GArray(span.type(), span.size(), allocator) - { - if (span.data() != nullptr) { - BLI_assert(span.size() != 0); - /* Use copy assign rather than construct since the memory is already initialized. */ - type_->copy_assign_n(span.data(), data_, size_); - } - } - - /** - * Create an array by copying values from another generic array. - */ - GArray(const GArray &other) : GArray(other.as_span(), other.allocator()) - { - } - - /** - * Create an array by taking ownership of another array's data, clearing the data in the other. - */ - GArray(GArray &&other) : GArray(other.type(), other.data(), other.size(), other.allocator()) - { - other.data_ = nullptr; - other.size_ = 0; - } - - ~GArray() - { - if (data_ != nullptr) { - type_->destruct_n(data_, size_); - this->deallocate(data_); - } - } - - GArray &operator=(const GArray &other) - { - return copy_assign_container(*this, other); - } - - GArray &operator=(GArray &&other) - { - return move_assign_container(*this, std::move(other)); - } - - const CPPType &type() const - { - BLI_assert(type_ != nullptr); - return *type_; - } - - bool is_empty() const - { - return size_ == 0; - } - - /** - * Return the number of elements in the array (not the size in bytes). - */ - int64_t size() const - { - return size_; - } - - /** - * Get a pointer to the beginning of the array. - */ - const void *data() const - { - return data_; - } - void *data() - { - return data_; - } - - const void *operator[](int64_t index) const - { - BLI_assert(index < size_); - return POINTER_OFFSET(data_, type_->size() * index); - } - - void *operator[](int64_t index) - { - BLI_assert(index < size_); - return POINTER_OFFSET(data_, type_->size() * index); - } - - operator GSpan() const - { - BLI_assert(type_ != nullptr); - return GSpan(*type_, data_, size_); - } - - operator GMutableSpan() - { - BLI_assert(type_ != nullptr); - return GMutableSpan(*type_, data_, size_); - } - - GSpan as_span() const - { - return *this; - } - - GMutableSpan as_mutable_span() - { - return *this; - } - - /** - * Access the allocator used by this array. - */ - Allocator &allocator() - { - return allocator_; - } - const Allocator &allocator() const - { - return allocator_; - } - - /** - * Destruct values and create a new array of the given size. The values in the new array are - * default constructed. - */ - void reinitialize(const int64_t new_size) - { - BLI_assert(new_size >= 0); - int64_t old_size = size_; - - type_->destruct_n(data_, size_); - size_ = 0; - - if (new_size <= old_size) { - type_->default_construct_n(data_, new_size); - } - else { - void *new_data = this->allocate(new_size); - try { - type_->default_construct_n(new_data, new_size); - } - catch (...) { - this->deallocate(new_data); - throw; - } - this->deallocate(data_); - data_ = new_data; - } - - size_ = new_size; - } - - private: - void *allocate(int64_t size) - { - const int64_t item_size = type_->size(); - const int64_t alignment = type_->alignment(); - return allocator_.allocate(static_cast<size_t>(size) * item_size, alignment, AT); - } - - void deallocate(void *ptr) - { - allocator_.deallocate(ptr); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_pointer.hh b/source/blender/functions/FN_generic_pointer.hh deleted file mode 100644 index 382d882e3f7..00000000000 --- a/source/blender/functions/FN_generic_pointer.hh +++ /dev/null @@ -1,123 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_cpp_type.hh" - -namespace blender::fn { - -/** - * A generic non-const pointer whose type is only known at runtime. - */ -class GMutablePointer { - private: - const CPPType *type_ = nullptr; - void *data_ = nullptr; - - public: - GMutablePointer() = default; - - GMutablePointer(const CPPType *type, void *data = nullptr) : type_(type), data_(data) - { - /* If there is data, there has to be a type. */ - BLI_assert(data_ == nullptr || type_ != nullptr); - } - - GMutablePointer(const CPPType &type, void *data = nullptr) : GMutablePointer(&type, data) - { - } - - template<typename T> GMutablePointer(T *data) : GMutablePointer(&CPPType::get<T>(), data) - { - } - - void *get() const - { - return data_; - } - - const CPPType *type() const - { - return type_; - } - - template<typename T> T *get() const - { - BLI_assert(this->is_type<T>()); - return static_cast<T *>(data_); - } - - template<typename T> bool is_type() const - { - return type_ != nullptr && type_->is<T>(); - } - - template<typename T> T relocate_out() - { - BLI_assert(this->is_type<T>()); - T value; - type_->relocate_assign(data_, &value); - data_ = nullptr; - type_ = nullptr; - return value; - } - - void destruct() - { - BLI_assert(data_ != nullptr); - type_->destruct(data_); - } -}; - -/** - * A generic const pointer whose type is only known at runtime. - */ -class GPointer { - private: - const CPPType *type_ = nullptr; - const void *data_ = nullptr; - - public: - GPointer() = default; - - GPointer(GMutablePointer ptr) : type_(ptr.type()), data_(ptr.get()) - { - } - - GPointer(const CPPType *type, const void *data = nullptr) : type_(type), data_(data) - { - /* If there is data, there has to be a type. */ - BLI_assert(data_ == nullptr || type_ != nullptr); - } - - GPointer(const CPPType &type, const void *data = nullptr) : type_(&type), data_(data) - { - } - - template<typename T> GPointer(T *data) : GPointer(&CPPType::get<T>(), data) - { - } - - const void *get() const - { - return data_; - } - - const CPPType *type() const - { - return type_; - } - - template<typename T> const T *get() const - { - BLI_assert(this->is_type<T>()); - return static_cast<const T *>(data_); - } - - template<typename T> bool is_type() const - { - return type_ != nullptr && type_->is<T>(); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_span.hh b/source/blender/functions/FN_generic_span.hh deleted file mode 100644 index c79cece138f..00000000000 --- a/source/blender/functions/FN_generic_span.hh +++ /dev/null @@ -1,169 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup fn - */ - -#include "BLI_cpp_type.hh" -#include "BLI_span.hh" - -namespace blender::fn { - -/** - * A generic span. It behaves just like a blender::Span<T>, but the type is only known at run-time. - */ -class GSpan { - protected: - const CPPType *type_; - const void *data_; - int64_t size_; - - public: - GSpan(const CPPType &type, const void *buffer, int64_t size) - : type_(&type), data_(buffer), size_(size) - { - BLI_assert(size >= 0); - BLI_assert(buffer != nullptr || size == 0); - BLI_assert(type.pointer_has_valid_alignment(buffer)); - } - - GSpan(const CPPType &type) : GSpan(type, nullptr, 0) - { - } - - template<typename T> - GSpan(Span<T> array) - : GSpan(CPPType::get<T>(), static_cast<const void *>(array.data()), array.size()) - { - } - - const CPPType &type() const - { - return *type_; - } - - bool is_empty() const - { - return size_ == 0; - } - - int64_t size() const - { - return size_; - } - - const void *data() const - { - return data_; - } - - const void *operator[](int64_t index) const - { - BLI_assert(index < size_); - return POINTER_OFFSET(data_, type_->size() * index); - } - - template<typename T> Span<T> typed() const - { - BLI_assert(type_->is<T>()); - return Span<T>(static_cast<const T *>(data_), size_); - } - - GSpan slice(const int64_t start, int64_t size) const - { - BLI_assert(start >= 0); - BLI_assert(size >= 0); - const int64_t new_size = std::max<int64_t>(0, std::min(size, size_ - start)); - return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * start), new_size); - } - - GSpan slice(const IndexRange range) const - { - return this->slice(range.start(), range.size()); - } -}; - -/** - * A generic mutable span. It behaves just like a blender::MutableSpan<T>, but the type is only - * known at run-time. - */ -class GMutableSpan { - protected: - const CPPType *type_; - void *data_; - int64_t size_; - - public: - GMutableSpan(const CPPType &type, void *buffer, int64_t size) - : type_(&type), data_(buffer), size_(size) - { - BLI_assert(size >= 0); - BLI_assert(buffer != nullptr || size == 0); - BLI_assert(type.pointer_has_valid_alignment(buffer)); - } - - GMutableSpan(const CPPType &type) : GMutableSpan(type, nullptr, 0) - { - } - - template<typename T> - GMutableSpan(MutableSpan<T> array) - : GMutableSpan(CPPType::get<T>(), static_cast<void *>(array.begin()), array.size()) - { - } - - operator GSpan() const - { - return GSpan(*type_, data_, size_); - } - - const CPPType &type() const - { - return *type_; - } - - bool is_empty() const - { - return size_ == 0; - } - - int64_t size() const - { - return size_; - } - - void *data() const - { - return data_; - } - - void *operator[](int64_t index) const - { - BLI_assert(index >= 0); - BLI_assert(index < size_); - return POINTER_OFFSET(data_, type_->size() * index); - } - - template<typename T> MutableSpan<T> typed() const - { - BLI_assert(type_->is<T>()); - return MutableSpan<T>(static_cast<T *>(data_), size_); - } - - GMutableSpan slice(const int64_t start, int64_t size) const - { - BLI_assert(start >= 0); - BLI_assert(size >= 0); - const int64_t new_size = std::max<int64_t>(0, std::min(size, size_ - start)); - return GMutableSpan(*type_, POINTER_OFFSET(data_, type_->size() * start), new_size); - } - - GMutableSpan slice(IndexRange range) const - { - return this->slice(range.start(), range.size()); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_value_map.hh b/source/blender/functions/FN_generic_value_map.hh deleted file mode 100644 index 3807ada1c3c..00000000000 --- a/source/blender/functions/FN_generic_value_map.hh +++ /dev/null @@ -1,112 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_linear_allocator.hh" -#include "BLI_map.hh" - -#include "FN_generic_pointer.hh" - -namespace blender::fn { - -/** - * This is a map that stores key-value-pairs. What makes it special is that the type of values does - * not have to be known at compile time. There just has to be a corresponding CPPType. - */ -template<typename Key> class GValueMap { - private: - /* Used to allocate values owned by this container. */ - LinearAllocator<> &allocator_; - Map<Key, GMutablePointer> values_; - - public: - GValueMap(LinearAllocator<> &allocator) : allocator_(allocator) - { - } - - ~GValueMap() - { - /* Destruct all values that are still in the map. */ - for (GMutablePointer value : values_.values()) { - value.destruct(); - } - } - - /* Add a value to the container. The container becomes responsible for destructing the value that - * is passed in. The caller remains responsible for freeing the value after it has been - * destructed. */ - template<typename ForwardKey> void add_new_direct(ForwardKey &&key, GMutablePointer value) - { - values_.add_new_as(std::forward<ForwardKey>(key), value); - } - - /* Add a value to the container that is move constructed from the given value. The caller remains - * responsible for destructing and freeing the given value. */ - template<typename ForwardKey> void add_new_by_move(ForwardKey &&key, GMutablePointer value) - { - const CPPType &type = *value.type(); - void *buffer = allocator_.allocate(type.size(), type.alignment()); - type.move_construct(value.get(), buffer); - values_.add_new_as(std::forward<ForwardKey>(key), GMutablePointer{type, buffer}); - } - - /* Add a value to the container that is copy constructed from the given value. The caller remains - * responsible for destructing and freeing the given value. */ - template<typename ForwardKey> void add_new_by_copy(ForwardKey &&key, GPointer value) - { - const CPPType &type = *value.type(); - void *buffer = allocator_.allocate(type.size(), type.alignment()); - type.copy_construct(value.get(), buffer); - values_.add_new_as(std::forward<ForwardKey>(key), GMutablePointer{type, buffer}); - } - - /* Add a value to the container. */ - template<typename ForwardKey, typename T> void add_new(ForwardKey &&key, T &&value) - { - if constexpr (std::is_rvalue_reference_v<T>) { - this->add_new_by_move(std::forward<ForwardKey>(key), &value); - } - else { - this->add_new_by_copy(std::forward<ForwardKey>(key), &value); - } - } - - /* Remove the value for the given name from the container and remove it. The caller is - * responsible for freeing it. The lifetime of the referenced memory might be bound to lifetime - * of the container. */ - template<typename ForwardKey> GMutablePointer extract(const ForwardKey &key) - { - return values_.pop_as(key); - } - - template<typename ForwardKey> GPointer lookup(const ForwardKey &key) const - { - return values_.lookup_as(key); - } - - /* Remove the value for the given name from the container and remove it. */ - template<typename T, typename ForwardKey> T extract(const ForwardKey &key) - { - GMutablePointer value = values_.pop_as(key); - const CPPType &type = *value.type(); - BLI_assert(type.is<T>()); - T return_value; - type.relocate_assign(value.get(), &return_value); - return return_value; - } - - template<typename T, typename ForwardKey> const T &lookup(const ForwardKey &key) const - { - GMutablePointer value = values_.lookup_as(key); - BLI_assert(value.is_type<T>()); - BLI_assert(value.get() != nullptr); - return *(const T *)value.get(); - } - - template<typename ForwardKey> bool contains(const ForwardKey &key) const - { - return values_.contains_as(key); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_vector_array.hh b/source/blender/functions/FN_generic_vector_array.hh deleted file mode 100644 index d7416a0f5b9..00000000000 --- a/source/blender/functions/FN_generic_vector_array.hh +++ /dev/null @@ -1,148 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup fn - * - * A`GVectorArray` is a container for a fixed amount of dynamically growing vectors with a generic - * data type. Its main use case is to store many small vectors with few separate allocations. Using - * this structure is generally more efficient than allocating each vector separately. - */ - -#include "BLI_array.hh" -#include "BLI_linear_allocator.hh" - -#include "FN_generic_virtual_vector_array.hh" - -namespace blender::fn { - -/* An array of vectors containing elements of a generic type. */ -class GVectorArray : NonCopyable, NonMovable { - private: - struct Item { - void *start = nullptr; - int64_t length = 0; - int64_t capacity = 0; - }; - - /* Use a linear allocator to pack many small vectors together. Currently, memory from reallocated - * vectors is not reused. This can be improved in the future. */ - LinearAllocator<> allocator_; - /* The data type of individual elements. */ - const CPPType &type_; - /* The size of an individual element. This is inlined from `type_.size()` for easier access. */ - const int64_t element_size_; - /* The individual vectors. */ - Array<Item> items_; - - public: - GVectorArray() = delete; - - GVectorArray(const CPPType &type, int64_t array_size); - - ~GVectorArray(); - - int64_t size() const - { - return items_.size(); - } - - bool is_empty() const - { - return items_.is_empty(); - } - - const CPPType &type() const - { - return type_; - } - - void append(int64_t index, const void *value); - - /* Add multiple elements to a single vector. */ - void extend(int64_t index, const GVArray &values); - void extend(int64_t index, GSpan values); - - /* Add multiple elements to multiple vectors. */ - void extend(IndexMask mask, const GVVectorArray &values); - void extend(IndexMask mask, const GVectorArray &values); - - void clear(IndexMask mask); - - GMutableSpan operator[](int64_t index); - GSpan operator[](int64_t index) const; - - private: - void realloc_to_at_least(Item &item, int64_t min_capacity); -}; - -/* A non-owning typed mutable reference to an `GVectorArray`. It simplifies access when the type of - * the data is known at compile time. */ -template<typename T> class GVectorArray_TypedMutableRef { - private: - GVectorArray *vector_array_; - - public: - GVectorArray_TypedMutableRef(GVectorArray &vector_array) : vector_array_(&vector_array) - { - BLI_assert(vector_array_->type().is<T>()); - } - - int64_t size() const - { - return vector_array_->size(); - } - - bool is_empty() const - { - return vector_array_->is_empty(); - } - - void append(const int64_t index, const T &value) - { - vector_array_->append(index, &value); - } - - void extend(const int64_t index, const Span<T> values) - { - vector_array_->extend(index, values); - } - - void extend(const int64_t index, const VArray<T> &values) - { - vector_array_->extend(index, values); - } - - MutableSpan<T> operator[](const int64_t index) - { - return (*vector_array_)[index].typed<T>(); - } -}; - -/* A generic virtual vector array implementation for a `GVectorArray`. */ -class GVVectorArray_For_GVectorArray : public GVVectorArray { - private: - const GVectorArray &vector_array_; - - public: - GVVectorArray_For_GVectorArray(const GVectorArray &vector_array) - : GVVectorArray(vector_array.type(), vector_array.size()), vector_array_(vector_array) - { - } - - protected: - int64_t get_vector_size_impl(const int64_t index) const override - { - return vector_array_[index].size(); - } - - void get_vector_element_impl(const int64_t index, - const int64_t index_in_vector, - void *r_value) const override - { - type_->copy_assign(vector_array_[index][index_in_vector], r_value); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_virtual_array.hh b/source/blender/functions/FN_generic_virtual_array.hh deleted file mode 100644 index ced0c2b9546..00000000000 --- a/source/blender/functions/FN_generic_virtual_array.hh +++ /dev/null @@ -1,878 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup fn - * - * A generic virtual array is the same as a virtual array from blenlib, except for the fact that - * the data type is only known at runtime. - */ - -#include "BLI_timeit.hh" -#include "BLI_virtual_array.hh" - -#include "FN_generic_array.hh" -#include "FN_generic_span.hh" - -namespace blender::fn { - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl and #GVMutableArrayImpl. - * \{ */ - -class GVArray; -class GVArrayImpl; -class GVMutableArray; -class GVMutableArrayImpl; - -/* A generically typed version of #VArrayImpl. */ -class GVArrayImpl { - protected: - const CPPType *type_; - int64_t size_; - - public: - GVArrayImpl(const CPPType &type, int64_t size); - virtual ~GVArrayImpl() = default; - - const CPPType &type() const; - - int64_t size() const; - - virtual void get(int64_t index, void *r_value) const; - virtual void get_to_uninitialized(int64_t index, void *r_value) const = 0; - - virtual bool is_span() const; - virtual GSpan get_internal_span() const; - - virtual bool is_single() const; - virtual void get_internal_single(void *UNUSED(r_value)) const; - - virtual void materialize(const IndexMask mask, void *dst) const; - virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const; - - virtual bool try_assign_VArray(void *varray) const; - virtual bool may_have_ownership() const; -}; - -/* A generic version of #VMutableArrayImpl. */ -class GVMutableArrayImpl : public GVArrayImpl { - public: - GVMutableArrayImpl(const CPPType &type, int64_t size); - - virtual void set_by_copy(int64_t index, const void *value); - virtual void set_by_relocate(int64_t index, void *value); - virtual void set_by_move(int64_t index, void *value) = 0; - - virtual void set_all(const void *src); - - virtual bool try_assign_VMutableArray(void *varray) const; -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArray and #GVMutableArray - * \{ */ - -namespace detail { -struct GVArrayAnyExtraInfo { - const GVArrayImpl *(*get_varray)(const void *buffer) = - [](const void *UNUSED(buffer)) -> const GVArrayImpl * { return nullptr; }; - - template<typename StorageT> static GVArrayAnyExtraInfo get(); -}; -} // namespace detail - -class GVMutableArray; - -/** - * Utility class to reduce code duplication between #GVArray and #GVMutableArray. - * It pretty much follows #VArrayCommon. Don't use this class outside of this header. - */ -class GVArrayCommon { - protected: - /** - * See #VArrayCommon for more information. The inline buffer is a bit larger here, because - * generic virtual array implementations often require a bit more space than typed ones. - */ - using Storage = Any<detail::GVArrayAnyExtraInfo, 40, 8>; - - const GVArrayImpl *impl_ = nullptr; - Storage storage_; - - protected: - GVArrayCommon(); - GVArrayCommon(const GVArrayCommon &other); - GVArrayCommon(GVArrayCommon &&other) noexcept; - GVArrayCommon(const GVArrayImpl *impl); - GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl); - ~GVArrayCommon(); - - template<typename ImplT, typename... Args> void emplace(Args &&...args); - - void copy_from(const GVArrayCommon &other); - void move_from(GVArrayCommon &&other) noexcept; - - const GVArrayImpl *impl_from_storage() const; - - public: - const CPPType &type() const; - operator bool() const; - - int64_t size() const; - bool is_empty() const; - IndexRange index_range() const; - - template<typename T> bool try_assign_VArray(VArray<T> &varray) const; - bool may_have_ownership() const; - - void materialize(void *dst) const; - void materialize(const IndexMask mask, void *dst) const; - - void materialize_to_uninitialized(void *dst) const; - void materialize_to_uninitialized(const IndexMask mask, void *dst) const; - - /** - * Returns true when the virtual array is stored as a span internally. - */ - bool is_span() const; - /** - * Returns the internally used span of the virtual array. This invokes undefined behavior if the - * virtual array is not stored as a span internally. - */ - GSpan get_internal_span() const; - - /** - * Returns true when the virtual array returns the same value for every index. - */ - bool is_single() const; - /** - * Copies the value that is used for every element into `r_value`, which is expected to point to - * initialized memory. This invokes undefined behavior if the virtual array would not return the - * same value for every index. - */ - void get_internal_single(void *r_value) const; - /** - * Same as `get_internal_single`, but `r_value` points to initialized memory. - */ - void get_internal_single_to_uninitialized(void *r_value) const; - - void get(int64_t index, void *r_value) const; - /** - * Returns a copy of the value at the given index. Usually a typed virtual array should - * be used instead, but sometimes this is simpler when only a few indices are needed. - */ - template<typename T> T get(int64_t index) const; - void get_to_uninitialized(int64_t index, void *r_value) const; -}; - -/** Generic version of #VArray. */ -class GVArray : public GVArrayCommon { - private: - friend GVMutableArray; - - public: - GVArray() = default; - - GVArray(const GVArray &other); - GVArray(GVArray &&other) noexcept; - GVArray(const GVArrayImpl *impl); - GVArray(std::shared_ptr<const GVArrayImpl> impl); - - template<typename T> GVArray(const VArray<T> &varray); - template<typename T> VArray<T> typed() const; - - template<typename ImplT, typename... Args> static GVArray For(Args &&...args); - - static GVArray ForSingle(const CPPType &type, int64_t size, const void *value); - static GVArray ForSingleRef(const CPPType &type, int64_t size, const void *value); - static GVArray ForSingleDefault(const CPPType &type, int64_t size); - static GVArray ForSpan(GSpan span); - static GVArray ForGArray(GArray<> array); - static GVArray ForEmpty(const CPPType &type); - - GVArray slice(IndexRange slice) const; - - GVArray &operator=(const GVArray &other); - GVArray &operator=(GVArray &&other) noexcept; - - const GVArrayImpl *get_implementation() const - { - return impl_; - } -}; - -/** Generic version of #VMutableArray. */ -class GVMutableArray : public GVArrayCommon { - public: - GVMutableArray() = default; - GVMutableArray(const GVMutableArray &other); - GVMutableArray(GVMutableArray &&other) noexcept; - GVMutableArray(GVMutableArrayImpl *impl); - GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl); - - template<typename T> GVMutableArray(const VMutableArray<T> &varray); - template<typename T> VMutableArray<T> typed() const; - - template<typename ImplT, typename... Args> static GVMutableArray For(Args &&...args); - - static GVMutableArray ForSpan(GMutableSpan span); - - operator GVArray() const &; - operator GVArray() &&noexcept; - - GVMutableArray &operator=(const GVMutableArray &other); - GVMutableArray &operator=(GVMutableArray &&other) noexcept; - - GMutableSpan get_internal_span() const; - - template<typename T> bool try_assign_VMutableArray(VMutableArray<T> &varray) const; - - void set_by_copy(int64_t index, const void *value); - void set_by_move(int64_t index, void *value); - void set_by_relocate(int64_t index, void *value); - - void fill(const void *value); - /** - * Copy the values from the source buffer to all elements in the virtual array. - */ - void set_all(const void *src); - - GVMutableArrayImpl *get_implementation() const; - - private: - GVMutableArrayImpl *get_impl() const; -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArray_GSpan and #GVMutableArray_GSpan. - * \{ */ - -/* A generic version of VArray_Span. */ -class GVArray_GSpan : public GSpan { - private: - GVArray varray_; - void *owned_data_ = nullptr; - - public: - GVArray_GSpan(GVArray varray); - ~GVArray_GSpan(); -}; - -/* A generic version of VMutableArray_Span. */ -class GVMutableArray_GSpan : public GMutableSpan { - private: - GVMutableArray varray_; - void *owned_data_ = nullptr; - bool save_has_been_called_ = false; - bool show_not_saved_warning_ = true; - - public: - GVMutableArray_GSpan(GVMutableArray varray, bool copy_values_to_span = true); - ~GVMutableArray_GSpan(); - - void save(); - void disable_not_applied_warning(); -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Conversions between generic and typed virtual arrays. - * \{ */ - -/* Used to convert a typed virtual array into a generic one. */ -template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl { - protected: - VArray<T> varray_; - - public: - GVArrayImpl_For_VArray(VArray<T> varray) - : GVArrayImpl(CPPType::get<T>(), varray.size()), varray_(std::move(varray)) - { - } - - protected: - void get(const int64_t index, void *r_value) const override - { - *(T *)r_value = varray_[index]; - } - - void get_to_uninitialized(const int64_t index, void *r_value) const override - { - new (r_value) T(varray_[index]); - } - - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override - { - return GSpan(varray_.get_internal_span()); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); - } - - void materialize(const IndexMask mask, void *dst) const override - { - varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); - } - - void materialize_to_uninitialized(const IndexMask mask, void *dst) const override - { - varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size())); - } - - bool try_assign_VArray(void *varray) const override - { - *(VArray<T> *)varray = varray_; - return true; - } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } -}; - -/* Used to convert any generic virtual array into a typed one. */ -template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> { - protected: - GVArray varray_; - - public: - VArrayImpl_For_GVArray(GVArray varray) : VArrayImpl<T>(varray.size()), varray_(std::move(varray)) - { - BLI_assert(varray_); - BLI_assert(varray_.type().template is<T>()); - } - - protected: - T get(const int64_t index) const override - { - T value; - varray_.get(index, &value); - return value; - } - - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override - { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; - } - - bool try_assign_GVArray(GVArray &varray) const override - { - varray = varray_; - return true; - } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } -}; - -/* Used to convert any typed virtual mutable array into a generic one. */ -template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutableArrayImpl { - protected: - VMutableArray<T> varray_; - - public: - GVMutableArrayImpl_For_VMutableArray(VMutableArray<T> varray) - : GVMutableArrayImpl(CPPType::get<T>(), varray.size()), varray_(std::move(varray)) - { - } - - protected: - void get(const int64_t index, void *r_value) const override - { - *(T *)r_value = varray_[index]; - } - - void get_to_uninitialized(const int64_t index, void *r_value) const override - { - new (r_value) T(varray_[index]); - } - - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override - { - Span<T> span = varray_.get_internal_span(); - return span; - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); - } - - void set_by_copy(const int64_t index, const void *value) override - { - const T &value_ = *(const T *)value; - varray_.set(index, value_); - } - - void set_by_relocate(const int64_t index, void *value) override - { - T &value_ = *(T *)value; - varray_.set(index, std::move(value_)); - value_.~T(); - } - - void set_by_move(const int64_t index, void *value) override - { - T &value_ = *(T *)value; - varray_.set(index, std::move(value_)); - } - - void set_all(const void *src) override - { - varray_.set_all(Span((T *)src, size_)); - } - - void materialize(const IndexMask mask, void *dst) const override - { - varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); - } - - void materialize_to_uninitialized(const IndexMask mask, void *dst) const override - { - varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size())); - } - - bool try_assign_VArray(void *varray) const override - { - *(VArray<T> *)varray = varray_; - return true; - } - - bool try_assign_VMutableArray(void *varray) const override - { - *(VMutableArray<T> *)varray = varray_; - return true; - } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } -}; - -/* Used to convert an generic mutable virtual array into a typed one. */ -template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutableArrayImpl<T> { - protected: - GVMutableArray varray_; - - public: - VMutableArrayImpl_For_GVMutableArray(GVMutableArray varray) - : VMutableArrayImpl<T>(varray.size()), varray_(varray) - { - BLI_assert(varray_); - BLI_assert(varray_.type().template is<T>()); - } - - private: - T get(const int64_t index) const override - { - T value; - varray_.get(index, &value); - return value; - } - - void set(const int64_t index, T value) override - { - varray_.set_by_relocate(index, &value); - } - - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override - { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; - } - - bool try_assign_GVArray(GVArray &varray) const override - { - varray = varray_; - return true; - } - - bool try_assign_GVMutableArray(GVMutableArray &varray) const override - { - varray = varray_; - return true; - } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_GSpan. - * \{ */ - -class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { - protected: - void *data_ = nullptr; - const int64_t element_size_; - - public: - GVArrayImpl_For_GSpan(const GMutableSpan span); - - protected: - GVArrayImpl_For_GSpan(const CPPType &type, int64_t size); - - public: - void get(int64_t index, void *r_value) const override; - void get_to_uninitialized(int64_t index, void *r_value) const override; - - void set_by_copy(int64_t index, const void *value) override; - void set_by_move(int64_t index, void *value) override; - void set_by_relocate(int64_t index, void *value) override; - - bool is_span() const override; - GSpan get_internal_span() const override; -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Inline methods for #GVArrayImpl. - * \{ */ - -inline GVArrayImpl::GVArrayImpl(const CPPType &type, const int64_t size) - : type_(&type), size_(size) -{ - BLI_assert(size_ >= 0); -} - -inline const CPPType &GVArrayImpl::type() const -{ - return *type_; -} - -inline int64_t GVArrayImpl::size() const -{ - return size_; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Inline methods for #GVMutableArrayImpl. - * \{ */ - -inline void GVMutableArray::set_by_copy(const int64_t index, const void *value) -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - this->get_impl()->set_by_copy(index, value); -} - -inline void GVMutableArray::set_by_move(const int64_t index, void *value) -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - this->get_impl()->set_by_move(index, value); -} - -inline void GVMutableArray::set_by_relocate(const int64_t index, void *value) -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - this->get_impl()->set_by_relocate(index, value); -} - -template<typename T> -inline bool GVMutableArray::try_assign_VMutableArray(VMutableArray<T> &varray) const -{ - BLI_assert(impl_->type().is<T>()); - return this->get_impl()->try_assign_VMutableArray(&varray); -} - -inline GVMutableArrayImpl *GVMutableArray::get_impl() const -{ - return (GVMutableArrayImpl *)impl_; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Inline methods for #GVArrayCommon. - * \{ */ - -template<typename ImplT, typename... Args> inline void GVArrayCommon::emplace(Args &&...args) -{ - static_assert(std::is_base_of_v<GVArrayImpl, ImplT>); - if constexpr (std::is_copy_constructible_v<ImplT> && Storage::template is_inline_v<ImplT>) { - impl_ = &storage_.template emplace<ImplT>(std::forward<Args>(args)...); - } - else { - std::shared_ptr<const GVArrayImpl> ptr = std::make_shared<ImplT>(std::forward<Args>(args)...); - impl_ = &*ptr; - storage_ = std::move(ptr); - } -} - -/* Copies the value at the given index into the provided storage. The `r_value` pointer is - * expected to point to initialized memory. */ -inline void GVArrayCommon::get(const int64_t index, void *r_value) const -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - impl_->get(index, r_value); -} - -template<typename T> inline T GVArrayCommon::get(const int64_t index) const -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - BLI_assert(this->type().is<T>()); - T value{}; - impl_->get(index, &value); - return value; -} - -/* Same as `get`, but `r_value` is expected to point to uninitialized memory. */ -inline void GVArrayCommon::get_to_uninitialized(const int64_t index, void *r_value) const -{ - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - impl_->get_to_uninitialized(index, r_value); -} - -template<typename T> inline bool GVArrayCommon::try_assign_VArray(VArray<T> &varray) const -{ - BLI_assert(impl_->type().is<T>()); - return impl_->try_assign_VArray(&varray); -} - -inline const CPPType &GVArrayCommon::type() const -{ - return impl_->type(); -} - -inline GVArrayCommon::operator bool() const -{ - return impl_ != nullptr; -} - -inline int64_t GVArrayCommon::size() const -{ - if (impl_ == nullptr) { - return 0; - } - return impl_->size(); -} - -inline bool GVArrayCommon::is_empty() const -{ - return this->size() == 0; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Inline methods for #GVArray. - * \{ */ - -namespace detail { -template<typename StorageT> inline GVArrayAnyExtraInfo GVArrayAnyExtraInfo::get() -{ - static_assert(std::is_base_of_v<GVArrayImpl, StorageT> || - is_same_any_v<StorageT, const GVArrayImpl *, std::shared_ptr<const GVArrayImpl>>); - - if constexpr (std::is_base_of_v<GVArrayImpl, StorageT>) { - return {[](const void *buffer) { - return static_cast<const GVArrayImpl *>((const StorageT *)buffer); - }}; - } - else if constexpr (std::is_same_v<StorageT, const GVArrayImpl *>) { - return {[](const void *buffer) { return *(const StorageT *)buffer; }}; - } - else if constexpr (std::is_same_v<StorageT, std::shared_ptr<const GVArrayImpl>>) { - return {[](const void *buffer) { return ((const StorageT *)buffer)->get(); }}; - } - else { - BLI_assert_unreachable(); - return {}; - } -} -} // namespace detail - -template<typename ImplT, typename... Args> inline GVArray GVArray::For(Args &&...args) -{ - static_assert(std::is_base_of_v<GVArrayImpl, ImplT>); - GVArray varray; - varray.template emplace<ImplT>(std::forward<Args>(args)...); - return varray; -} - -template<typename T> inline GVArray::GVArray(const VArray<T> &varray) -{ - if (!varray) { - return; - } - if (varray.try_assign_GVArray(*this)) { - return; - } - /* Need to check this before the span/single special cases, because otherwise we might loose - * ownership to the referenced data when #varray goes out of scope. */ - if (varray.may_have_ownership()) { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); - } - else if (varray.is_span()) { - Span<T> data = varray.get_internal_span(); - *this = GVArray::ForSpan(data); - } - else if (varray.is_single()) { - T value = varray.get_internal_single(); - *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), &value); - } - else { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); - } -} - -template<typename T> inline VArray<T> GVArray::typed() const -{ - if (!*this) { - return {}; - } - BLI_assert(impl_->type().is<T>()); - VArray<T> varray; - if (this->try_assign_VArray(varray)) { - return varray; - } - if (this->may_have_ownership()) { - return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); - } - if (this->is_span()) { - const Span<T> span = this->get_internal_span().typed<T>(); - return VArray<T>::ForSpan(span); - } - if (this->is_single()) { - T value; - this->get_internal_single(&value); - return VArray<T>::ForSingle(value, this->size()); - } - return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Inline methods for #GVMutableArray. - * \{ */ - -template<typename ImplT, typename... Args> -inline GVMutableArray GVMutableArray::For(Args &&...args) -{ - static_assert(std::is_base_of_v<GVMutableArrayImpl, ImplT>); - GVMutableArray varray; - varray.emplace<ImplT>(std::forward<Args>(args)...); - return varray; -} - -template<typename T> inline GVMutableArray::GVMutableArray(const VMutableArray<T> &varray) -{ - if (!varray) { - return; - } - if (varray.try_assign_GVMutableArray(*this)) { - return; - } - if (varray.may_have_ownership()) { - *this = GVMutableArray::For<GVMutableArrayImpl_For_VMutableArray<T>>(varray); - } - else if (varray.is_span()) { - MutableSpan<T> data = varray.get_internal_span(); - *this = GVMutableArray::ForSpan(data); - } - else { - *this = GVMutableArray::For<GVMutableArrayImpl_For_VMutableArray<T>>(varray); - } -} - -template<typename T> inline VMutableArray<T> GVMutableArray::typed() const -{ - if (!*this) { - return {}; - } - BLI_assert(this->type().is<T>()); - VMutableArray<T> varray; - if (this->try_assign_VMutableArray(varray)) { - return varray; - } - if (this->may_have_ownership()) { - return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); - } - if (this->is_span()) { - const MutableSpan<T> span = this->get_internal_span().typed<T>(); - return VMutableArray<T>::ForSpan(span); - } - return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); -} - -/** \} */ - -} // namespace blender::fn diff --git a/source/blender/functions/FN_generic_virtual_vector_array.hh b/source/blender/functions/FN_generic_virtual_vector_array.hh deleted file mode 100644 index 1f40366da04..00000000000 --- a/source/blender/functions/FN_generic_virtual_vector_array.hh +++ /dev/null @@ -1,174 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup fn - * - * A generic virtual vector array is essentially the same as a virtual vector array from blenlib, - * but its data type is only known at runtime. - */ - -#include "FN_generic_virtual_array.hh" - -#include "BLI_virtual_vector_array.hh" - -namespace blender::fn { - -/* A generically typed version of `VVectorArray`. */ -class GVVectorArray { - protected: - const CPPType *type_; - int64_t size_; - - public: - GVVectorArray(const CPPType &type, const int64_t size) : type_(&type), size_(size) - { - } - - virtual ~GVVectorArray() = default; - - /* Returns the number of vectors in the vector array. */ - int64_t size() const - { - return size_; - } - - /* Returns true when there is no vector in the vector array. */ - bool is_empty() const - { - return size_ == 0; - } - - const CPPType &type() const - { - return *type_; - } - - /* Returns the size of the vector at the given index. */ - int64_t get_vector_size(const int64_t index) const - { - BLI_assert(index >= 0); - BLI_assert(index < size_); - return this->get_vector_size_impl(index); - } - - /* Copies an element from one of the vectors into `r_value`, which is expected to point to - * initialized memory. */ - void get_vector_element(const int64_t index, const int64_t index_in_vector, void *r_value) const - { - BLI_assert(index >= 0); - BLI_assert(index < size_); - BLI_assert(index_in_vector >= 0); - BLI_assert(index_in_vector < this->get_vector_size(index)); - this->get_vector_element_impl(index, index_in_vector, r_value); - } - - /* Returns true when the same vector is used at every index. */ - bool is_single_vector() const - { - if (size_ == 1) { - return true; - } - return this->is_single_vector_impl(); - } - - protected: - virtual int64_t get_vector_size_impl(int64_t index) const = 0; - - virtual void get_vector_element_impl(int64_t index, - int64_t index_in_vector, - void *r_value) const = 0; - - virtual bool is_single_vector_impl() const - { - return false; - } -}; - -class GVArray_For_GVVectorArrayIndex : public GVArrayImpl { - private: - const GVVectorArray &vector_array_; - const int64_t index_; - - public: - GVArray_For_GVVectorArrayIndex(const GVVectorArray &vector_array, const int64_t index) - : GVArrayImpl(vector_array.type(), vector_array.get_vector_size(index)), - vector_array_(vector_array), - index_(index) - { - } - - protected: - void get(int64_t index_in_vector, void *r_value) const override; - void get_to_uninitialized(int64_t index_in_vector, void *r_value) const override; -}; - -class GVVectorArray_For_SingleGVArray : public GVVectorArray { - private: - GVArray varray_; - - public: - GVVectorArray_For_SingleGVArray(GVArray varray, const int64_t size) - : GVVectorArray(varray.type(), size), varray_(std::move(varray)) - { - } - - protected: - int64_t get_vector_size_impl(int64_t index) const override; - void get_vector_element_impl(int64_t index, - int64_t index_in_vector, - void *r_value) const override; - - bool is_single_vector_impl() const override; -}; - -class GVVectorArray_For_SingleGSpan : public GVVectorArray { - private: - const GSpan span_; - - public: - GVVectorArray_For_SingleGSpan(const GSpan span, const int64_t size) - : GVVectorArray(span.type(), size), span_(span) - { - } - - protected: - int64_t get_vector_size_impl(int64_t UNUSED(index)) const override; - void get_vector_element_impl(int64_t UNUSED(index), - int64_t index_in_vector, - void *r_value) const override; - - bool is_single_vector_impl() const override; -}; - -template<typename T> class VVectorArray_For_GVVectorArray : public VVectorArray<T> { - private: - const GVVectorArray &vector_array_; - - public: - VVectorArray_For_GVVectorArray(const GVVectorArray &vector_array) - : VVectorArray<T>(vector_array.size()), vector_array_(vector_array) - { - } - - protected: - int64_t get_vector_size_impl(const int64_t index) const override - { - return vector_array_.get_vector_size(index); - } - - T get_vector_element_impl(const int64_t index, const int64_t index_in_vector) const override - { - T value; - vector_array_.get_vector_element(index, index_in_vector, &value); - return value; - } - - bool is_single_vector_impl() const override - { - return vector_array_.is_single_vector(); - } -}; - -} // namespace blender::fn diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index edeb1fed27e..015df179ef0 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -154,8 +154,6 @@ inline MFParamsBuilder::MFParamsBuilder(const MultiFunction &fn, const IndexMask } namespace multi_function_types { -using fn::GMutableSpan; -using fn::GSpan; using fn::MFContext; using fn::MFContextBuilder; using fn::MFDataType; diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 38736527771..67f31a61dc4 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -13,11 +13,11 @@ #include <mutex> +#include "BLI_generic_pointer.hh" +#include "BLI_generic_vector_array.hh" +#include "BLI_generic_virtual_vector_array.hh" #include "BLI_resource_scope.hh" -#include "FN_generic_pointer.hh" -#include "FN_generic_vector_array.hh" -#include "FN_generic_virtual_vector_array.hh" #include "FN_multi_function_signature.hh" namespace blender::fn { diff --git a/source/blender/functions/intern/generic_vector_array.cc b/source/blender/functions/intern/generic_vector_array.cc deleted file mode 100644 index b188b31b087..00000000000 --- a/source/blender/functions/intern/generic_vector_array.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "FN_generic_vector_array.hh" -#include "FN_multi_function_params.hh" -#include "FN_multi_function_signature.hh" - -namespace blender::fn { - -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::fn diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc deleted file mode 100644 index 4644323bd1f..00000000000 --- a/source/blender/functions/intern/generic_virtual_array.cc +++ /dev/null @@ -1,724 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "FN_generic_virtual_array.hh" - -namespace blender::fn { - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl - * \{ */ - -void GVArrayImpl::materialize(const IndexMask mask, void *dst) const -{ - for (const int64_t i : mask) { - void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); - this->get(i, elem_dst); - } -} - -void GVArrayImpl::materialize_to_uninitialized(const IndexMask mask, void *dst) const -{ - for (const int64_t i : mask) { - void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); - this->get_to_uninitialized(i, elem_dst); - } -} - -void GVArrayImpl::get(const int64_t index, void *r_value) const -{ - type_->destruct(r_value); - this->get_to_uninitialized(index, r_value); -} - -bool GVArrayImpl::is_span() const -{ - return false; -} - -GSpan GVArrayImpl::get_internal_span() const -{ - BLI_assert(false); - return GSpan(*type_); -} - -bool GVArrayImpl::is_single() const -{ - return false; -} - -void GVArrayImpl::get_internal_single(void *UNUSED(r_value)) const -{ - BLI_assert(false); -} - -bool GVArrayImpl::try_assign_VArray(void *UNUSED(varray)) const -{ - return false; -} - -bool GVArrayImpl::may_have_ownership() const -{ - /* Use true as default to avoid accidentally creating subclasses that have this set to false but - * actually own data. Subclasses should set the to false instead. */ - return true; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVMutableArrayImpl - * \{ */ - -GVMutableArrayImpl::GVMutableArrayImpl(const CPPType &type, const int64_t size) - : GVArrayImpl(type, size) -{ -} - -void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value) -{ - BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); - type_->copy_construct(value, buffer); - this->set_by_move(index, buffer); - type_->destruct(buffer); -} - -void GVMutableArrayImpl::set_by_relocate(const int64_t index, void *value) -{ - this->set_by_move(index, value); - type_->destruct(value); -} - -void GVMutableArrayImpl::set_all(const void *src) -{ - if (this->is_span()) { - const GSpan span = this->get_internal_span(); - type_->copy_assign_n(src, const_cast<void *>(span.data()), size_); - } - else { - for (int64_t i : IndexRange(size_)) { - this->set_by_copy(i, POINTER_OFFSET(src, type_->size() * i)); - } - } -} - -void GVMutableArray::fill(const void *value) -{ - if (this->is_span()) { - const GSpan span = this->get_internal_span(); - this->type().fill_assign_n(value, const_cast<void *>(span.data()), this->size()); - } - else { - for (int64_t i : IndexRange(this->size())) { - this->set_by_copy(i, value); - } - } -} - -bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const -{ - return false; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_GSpan - * \{ */ - -GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GMutableSpan span) - : GVMutableArrayImpl(span.type(), span.size()), - data_(span.data()), - element_size_(span.type().size()) -{ -} - -GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size) - : GVMutableArrayImpl(type, size), element_size_(type.size()) -{ -} - -void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const -{ - type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value); -} - -void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const -{ - type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value); -} - -void GVArrayImpl_For_GSpan::set_by_copy(const int64_t index, const void *value) -{ - type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index)); -} - -void GVArrayImpl_For_GSpan::set_by_move(const int64_t index, void *value) -{ - type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index)); -} - -void GVArrayImpl_For_GSpan::set_by_relocate(const int64_t index, void *value) -{ - type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index)); -} - -bool GVArrayImpl_For_GSpan::is_span() const -{ - return true; -} - -GSpan GVArrayImpl_For_GSpan::get_internal_span() const -{ - return GSpan(*type_, data_, size_); -} - -class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { - public: - using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; - - private: - bool may_have_ownership() const override - { - return false; - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_SingleValueRef - * \{ */ - -/* Generic virtual array where each element has the same value. The value is not owned. */ -class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { - protected: - const void *value_ = nullptr; - - public: - GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value) - : GVArrayImpl(type, size), value_(value) - { - } - - protected: - GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size) - { - } - - void get(const int64_t UNUSED(index), void *r_value) const override - { - type_->copy_assign(value_, r_value); - } - void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override - { - type_->copy_construct(value_, r_value); - } - - bool is_span() const override - { - return size_ == 1; - } - GSpan get_internal_span() const override - { - return GSpan{*type_, value_, 1}; - } - - bool is_single() const override - { - return true; - } - void get_internal_single(void *r_value) const override - { - type_->copy_assign(value_, r_value); - } -}; - -class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { - public: - using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; - - private: - bool may_have_ownership() const override - { - return false; - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_SingleValue - * \{ */ - -/* Same as GVArrayImpl_For_SingleValueRef, but the value is owned. */ -class GVArrayImpl_For_SingleValue : public GVArrayImpl_For_SingleValueRef, - NonCopyable, - NonMovable { - public: - GVArrayImpl_For_SingleValue(const CPPType &type, const int64_t size, const void *value) - : GVArrayImpl_For_SingleValueRef(type, size) - { - value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__); - type.copy_construct(value, (void *)value_); - } - - ~GVArrayImpl_For_SingleValue() override - { - type_->destruct((void *)value_); - MEM_freeN((void *)value_); - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_SmallTrivialSingleValue - * \{ */ - -/** - * Contains an inline buffer that can store a single value of a trivial type. - * This avoids the allocation that would be done by #GVArrayImpl_For_SingleValue. - */ -template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public GVArrayImpl { - private: - AlignedBuffer<BufferSize, 8> buffer_; - - public: - GVArrayImpl_For_SmallTrivialSingleValue(const CPPType &type, - const int64_t size, - const void *value) - : GVArrayImpl(type, size) - { - BLI_assert(type.is_trivial()); - BLI_assert(type.alignment() <= 8); - BLI_assert(type.size() <= BufferSize); - type.copy_construct(value, &buffer_); - } - - private: - void get(const int64_t UNUSED(index), void *r_value) const override - { - this->copy_value_to(r_value); - } - void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override - { - this->copy_value_to(r_value); - } - - bool is_single() const override - { - return true; - } - void get_internal_single(void *r_value) const override - { - this->copy_value_to(r_value); - } - - void copy_value_to(void *dst) const - { - memcpy(dst, &buffer_, type_->size()); - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArray_GSpan - * \{ */ - -GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray)) -{ - size_ = varray_.size(); - if (varray_.is_span()) { - data_ = varray_.get_internal_span().data(); - } - else { - owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__); - varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_); - data_ = owned_data_; - } -} - -GVArray_GSpan::~GVArray_GSpan() -{ - if (owned_data_ != nullptr) { - type_->destruct_n(owned_data_, size_); - MEM_freeN(owned_data_); - } -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVMutableArray_GSpan - * \{ */ - -GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool copy_values_to_span) - : GMutableSpan(varray.type()), varray_(std::move(varray)) -{ - size_ = varray_.size(); - if (varray_.is_span()) { - data_ = varray_.get_internal_span().data(); - } - else { - owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__); - if (copy_values_to_span) { - varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_); - } - else { - type_->default_construct_n(owned_data_, size_); - } - data_ = owned_data_; - } -} - -GVMutableArray_GSpan::~GVMutableArray_GSpan() -{ - if (show_not_saved_warning_) { - if (!save_has_been_called_) { - std::cout << "Warning: Call `apply()` to make sure that changes persist in all cases.\n"; - } - } - if (owned_data_ != nullptr) { - type_->destruct_n(owned_data_, size_); - MEM_freeN(owned_data_); - } -} - -void GVMutableArray_GSpan::save() -{ - save_has_been_called_ = true; - if (data_ != owned_data_) { - return; - } - const int64_t element_size = type_->size(); - for (int64_t i : IndexRange(size_)) { - varray_.set_by_copy(i, POINTER_OFFSET(owned_data_, element_size * i)); - } -} - -void GVMutableArray_GSpan::disable_not_applied_warning() -{ - show_not_saved_warning_ = false; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayImpl_For_SlicedGVArray - * \{ */ - -class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl { - protected: - GVArray varray_; - int64_t offset_; - IndexRange slice_; - - public: - GVArrayImpl_For_SlicedGVArray(GVArray varray, const IndexRange slice) - : GVArrayImpl(varray.type(), slice.size()), - varray_(std::move(varray)), - offset_(slice.start()), - slice_(slice) - { - BLI_assert(slice.one_after_last() <= varray_.size()); - } - - void get(const int64_t index, void *r_value) const override - { - varray_.get(index + offset_, r_value); - } - - void get_to_uninitialized(const int64_t index, void *r_value) const override - { - varray_.get_to_uninitialized(index + offset_, r_value); - } - - bool is_span() const override - { - return varray_.is_span(); - } - GSpan get_internal_span() const override - { - return varray_.get_internal_span().slice(slice_); - } - - bool is_single() const override - { - return varray_.is_single(); - } - void get_internal_single(void *r_value) const override - { - varray_.get_internal_single(r_value); - } -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArrayCommon - * \{ */ - -GVArrayCommon::GVArrayCommon() = default; - -GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_) -{ - impl_ = this->impl_from_storage(); -} - -GVArrayCommon::GVArrayCommon(GVArrayCommon &&other) noexcept : storage_(std::move(other.storage_)) -{ - impl_ = this->impl_from_storage(); - other.storage_.reset(); - other.impl_ = nullptr; -} - -GVArrayCommon::GVArrayCommon(const GVArrayImpl *impl) : impl_(impl) -{ - storage_ = impl_; -} - -GVArrayCommon::GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl) : impl_(impl.get()) -{ - if (impl) { - storage_ = std::move(impl); - } -} - -GVArrayCommon::~GVArrayCommon() = default; - -void GVArrayCommon::materialize(void *dst) const -{ - this->materialize(IndexMask(impl_->size()), dst); -} - -void GVArrayCommon::materialize(const IndexMask mask, void *dst) const -{ - impl_->materialize(mask, dst); -} - -void GVArrayCommon::materialize_to_uninitialized(void *dst) const -{ - this->materialize_to_uninitialized(IndexMask(impl_->size()), dst); -} - -void GVArrayCommon::materialize_to_uninitialized(const IndexMask mask, void *dst) const -{ - BLI_assert(mask.min_array_size() <= impl_->size()); - impl_->materialize_to_uninitialized(mask, dst); -} - -bool GVArrayCommon::may_have_ownership() const -{ - return impl_->may_have_ownership(); -} - -void GVArrayCommon::copy_from(const GVArrayCommon &other) -{ - if (this == &other) { - return; - } - storage_ = other.storage_; - impl_ = this->impl_from_storage(); -} - -void GVArrayCommon::move_from(GVArrayCommon &&other) noexcept -{ - if (this == &other) { - return; - } - storage_ = std::move(other.storage_); - impl_ = this->impl_from_storage(); - other.storage_.reset(); - other.impl_ = nullptr; -} - -bool GVArrayCommon::is_span() const -{ - return impl_->is_span(); -} - -GSpan GVArrayCommon::get_internal_span() const -{ - BLI_assert(this->is_span()); - return impl_->get_internal_span(); -} - -bool GVArrayCommon::is_single() const -{ - return impl_->is_single(); -} - -void GVArrayCommon::get_internal_single(void *r_value) const -{ - BLI_assert(this->is_single()); - impl_->get_internal_single(r_value); -} - -void GVArrayCommon::get_internal_single_to_uninitialized(void *r_value) const -{ - impl_->type().default_construct(r_value); - this->get_internal_single(r_value); -} - -const GVArrayImpl *GVArrayCommon::impl_from_storage() const -{ - return storage_.extra_info().get_varray(storage_.get()); -} - -IndexRange GVArrayCommon::index_range() const -{ - return IndexRange(this->size()); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArray - * \{ */ - -GVArray::GVArray(const GVArray &other) = default; - -GVArray::GVArray(GVArray &&other) noexcept = default; - -GVArray::GVArray(const GVArrayImpl *impl) : GVArrayCommon(impl) -{ -} - -GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::move(impl)) -{ -} - -GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value) -{ - if (type.is_trivial() && type.size() <= 16 && type.alignment() <= 8) { - return GVArray::For<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value); - } - return GVArray::For<GVArrayImpl_For_SingleValue>(type, size, value); -} - -GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value) -{ - return GVArray::For<GVArrayImpl_For_SingleValueRef_final>(type, size, value); -} - -GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size) -{ - return GVArray::ForSingleRef(type, size, type.default_value()); -} - -GVArray GVArray::ForSpan(GSpan span) -{ - /* Use const-cast because the underlying virtual array implementation is shared between const - * and non const data. */ - GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()}; - return GVArray::For<GVArrayImpl_For_GSpan_final>(mutable_span); -} - -class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan { - protected: - GArray<> array_; - - public: - GVArrayImpl_For_GArray(GArray<> array) - : GVArrayImpl_For_GSpan(array.as_mutable_span()), array_(std::move(array)) - { - } -}; - -GVArray GVArray::ForGArray(GArray<> array) -{ - return GVArray::For<GVArrayImpl_For_GArray>(array); -} - -GVArray GVArray::ForEmpty(const CPPType &type) -{ - return GVArray::ForSpan(GSpan(type)); -} - -GVArray GVArray::slice(IndexRange slice) const -{ - return GVArray::For<GVArrayImpl_For_SlicedGVArray>(*this, slice); -} - -GVArray &GVArray::operator=(const GVArray &other) -{ - this->copy_from(other); - return *this; -} - -GVArray &GVArray::operator=(GVArray &&other) noexcept -{ - this->move_from(std::move(other)); - return *this; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVMutableArray - * \{ */ - -GVMutableArray::GVMutableArray(const GVMutableArray &other) = default; -GVMutableArray::GVMutableArray(GVMutableArray &&other) noexcept = default; - -GVMutableArray::GVMutableArray(GVMutableArrayImpl *impl) : GVArrayCommon(impl) -{ -} - -GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl) - : GVArrayCommon(std::move(impl)) -{ -} - -GVMutableArray GVMutableArray::ForSpan(GMutableSpan span) -{ - return GVMutableArray::For<GVArrayImpl_For_GSpan_final>(span); -} - -GVMutableArray::operator GVArray() const & -{ - GVArray varray; - varray.copy_from(*this); - return varray; -} - -GVMutableArray::operator GVArray() &&noexcept -{ - GVArray varray; - varray.move_from(std::move(*this)); - return varray; -} - -GVMutableArray &GVMutableArray::operator=(const GVMutableArray &other) -{ - this->copy_from(other); - return *this; -} - -GVMutableArray &GVMutableArray::operator=(GVMutableArray &&other) noexcept -{ - this->move_from(std::move(other)); - return *this; -} - -GVMutableArrayImpl *GVMutableArray::get_implementation() const -{ - return this->get_impl(); -} - -void GVMutableArray::set_all(const void *src) -{ - this->get_impl()->set_all(src); -} - -GMutableSpan GVMutableArray::get_internal_span() const -{ - BLI_assert(this->is_span()); - const GSpan span = impl_->get_internal_span(); - return GMutableSpan(span.type(), const_cast<void *>(span.data()), span.size()); -} - -/** \} */ - -} // namespace blender::fn diff --git a/source/blender/functions/intern/generic_virtual_vector_array.cc b/source/blender/functions/intern/generic_virtual_vector_array.cc deleted file mode 100644 index 7dc728a4460..00000000000 --- a/source/blender/functions/intern/generic_virtual_vector_array.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "FN_generic_virtual_vector_array.hh" - -namespace blender::fn { - -void GVArray_For_GVVectorArrayIndex::get(const int64_t index_in_vector, void *r_value) const -{ - vector_array_.get_vector_element(index_, index_in_vector, r_value); -} - -void GVArray_For_GVVectorArrayIndex::get_to_uninitialized(const int64_t index_in_vector, - void *r_value) const -{ - type_->default_construct(r_value); - vector_array_.get_vector_element(index_, index_in_vector, r_value); -} - -int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t UNUSED(index)) const -{ - return varray_.size(); -} - -void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t UNUSED(index), - const int64_t index_in_vector, - void *r_value) const -{ - varray_.get(index_in_vector, r_value); -} - -bool GVVectorArray_For_SingleGVArray::is_single_vector_impl() const -{ - return true; -} - -int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t UNUSED(index)) const -{ - return span_.size(); -} - -void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t UNUSED(index), - const int64_t index_in_vector, - void *r_value) const -{ - type_->copy_assign(span_[index_in_vector], r_value); -} - -bool GVVectorArray_For_SingleGSpan::is_single_vector_impl() const -{ - return true; -} - -} // namespace blender::fn diff --git a/source/blender/functions/tests/FN_generic_array_test.cc b/source/blender/functions/tests/FN_generic_array_test.cc deleted file mode 100644 index 5420a809ffc..00000000000 --- a/source/blender/functions/tests/FN_generic_array_test.cc +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include "testing/testing.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_array.hh" - -#include "FN_generic_array.hh" - -namespace blender::fn::tests { - -TEST(generic_array, TypeConstructor) -{ - GArray array(CPPType::get<float>()); - EXPECT_TRUE(array.data() == nullptr); - EXPECT_EQ(array.size(), 0); - EXPECT_EQ(array.as_span().typed<float>().size(), 0); - EXPECT_TRUE(array.is_empty()); -} - -TEST(generic_array, MoveConstructor) -{ - GArray array_a(CPPType::get<int32_t>(), (int64_t)10); - GMutableSpan span_a = array_a.as_mutable_span(); - MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>(); - typed_span_a.fill(42); - - const GArray array_b = std::move(array_a); - Span<int32_t> typed_span_b = array_b.as_span().typed<int32_t>(); - EXPECT_FALSE(array_b.data() == nullptr); - EXPECT_EQ(array_b.size(), 10); - EXPECT_EQ(typed_span_b[4], 42); - - /* Make sure the copy constructor cleaned up the original, but it shouldn't clear the type. */ - EXPECT_TRUE(array_a.data() == nullptr); /* NOLINT: bugprone-use-after-move */ - EXPECT_EQ(array_a.size(), 0); /* NOLINT: bugprone-use-after-move */ - EXPECT_TRUE(array_a.is_empty()); /* NOLINT: bugprone-use-after-move */ - EXPECT_EQ(array_b.type(), array_a.type()); /* NOLINT: bugprone-use-after-move */ -} - -TEST(generic_array, CopyConstructor) -{ - GArray array_a(CPPType::get<int32_t>(), (int64_t)10); - GMutableSpan span_a = array_a.as_mutable_span(); - MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>(); - typed_span_a.fill(42); - - /* From span directly. */ - const GArray array_b = array_a.as_span(); - Span<int32_t> typed_span_b = array_b.as_span().typed<int32_t>(); - EXPECT_FALSE(array_b.data() == nullptr); - EXPECT_EQ(array_b.size(), 10); - EXPECT_EQ(typed_span_b[4], 42); - EXPECT_FALSE(array_a.is_empty()); - - /* From array. */ - const GArray array_c = array_a; - Span<int32_t> typed_span_c = array_c.as_span().typed<int32_t>(); - EXPECT_FALSE(array_c.data() == nullptr); - EXPECT_EQ(array_c.size(), 10); - EXPECT_EQ(typed_span_c[4], 42); - EXPECT_FALSE(array_a.is_empty()); -} - -TEST(generic_array, BufferAndSizeConstructor) -{ - int32_t *values = (int32_t *)MEM_malloc_arrayN(12, sizeof(int32_t), __func__); - void *buffer = (void *)values; - GArray array(CPPType::get<int32_t>(), buffer, 4); - EXPECT_FALSE(array.data() == nullptr); - EXPECT_EQ(array.size(), 4); - EXPECT_FALSE(array.is_empty()); - EXPECT_EQ(array.as_span().typed<int>().size(), 4); - EXPECT_EQ(array[0], &values[0]); - EXPECT_EQ(array[1], &values[1]); - EXPECT_EQ(array[2], &values[2]); - EXPECT_EQ(array[3], &values[3]); -} - -TEST(generic_array, Reinitialize) -{ - GArray array(CPPType::get<int32_t>(), (int64_t)5); - EXPECT_FALSE(array.data() == nullptr); - GMutableSpan span = array.as_mutable_span(); - MutableSpan<int32_t> typed_span = span.typed<int32_t>(); - typed_span.fill(77); - EXPECT_FALSE(typed_span.data() == nullptr); - typed_span[2] = 8; - EXPECT_EQ(array[2], &typed_span[2]); - EXPECT_EQ(typed_span[0], 77); - EXPECT_EQ(typed_span[1], 77); - - array.reinitialize(10); - EXPECT_EQ(array.size(), 10); - span = array.as_mutable_span(); - EXPECT_EQ(span.size(), 10); - - typed_span = span.typed<int32_t>(); - EXPECT_FALSE(typed_span.data() == nullptr); - - array.reinitialize(0); - EXPECT_EQ(array.size(), 0); -} - -TEST(generic_array, InContainer) -{ - blender::Array<GArray<>> arrays; - for (GArray<> &array : arrays) { - array = GArray(CPPType::get<int32_t>(), (int64_t)5); - array.as_mutable_span().typed<int32_t>().fill(55); - } - for (GArray<> &array : arrays) { - EXPECT_EQ(array.as_span().typed<int32_t>()[3], 55); - } -} - -} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_generic_span_test.cc b/source/blender/functions/tests/FN_generic_span_test.cc deleted file mode 100644 index 19b3ceaf44e..00000000000 --- a/source/blender/functions/tests/FN_generic_span_test.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include "testing/testing.h" - -#include "FN_generic_span.hh" - -namespace blender::fn::tests { - -TEST(generic_span, TypeConstructor) -{ - GSpan span(CPPType::get<float>()); - EXPECT_EQ(span.size(), 0); - EXPECT_EQ(span.typed<float>().size(), 0); - EXPECT_TRUE(span.is_empty()); -} - -TEST(generic_span, BufferAndSizeConstructor) -{ - int values[4] = {6, 7, 3, 2}; - void *buffer = (void *)values; - GSpan span(CPPType::get<int32_t>(), buffer, 4); - EXPECT_EQ(span.size(), 4); - EXPECT_FALSE(span.is_empty()); - EXPECT_EQ(span.typed<int>().size(), 4); - EXPECT_EQ(span[0], &values[0]); - EXPECT_EQ(span[1], &values[1]); - EXPECT_EQ(span[2], &values[2]); - EXPECT_EQ(span[3], &values[3]); -} - -TEST(generic_mutable_span, TypeConstructor) -{ - GMutableSpan span(CPPType::get<int32_t>()); - EXPECT_EQ(span.size(), 0); - EXPECT_TRUE(span.is_empty()); -} - -TEST(generic_mutable_span, BufferAndSizeConstructor) -{ - int values[4] = {4, 7, 3, 5}; - void *buffer = (void *)values; - GMutableSpan span(CPPType::get<int32_t>(), buffer, 4); - EXPECT_EQ(span.size(), 4); - EXPECT_FALSE(span.is_empty()); - EXPECT_EQ(span.typed<int>().size(), 4); - EXPECT_EQ(values[2], 3); - *(int *)span[2] = 10; - EXPECT_EQ(values[2], 10); - span.typed<int>()[2] = 20; - EXPECT_EQ(values[2], 20); -} - -} // namespace blender::fn::tests diff --git a/source/blender/functions/tests/FN_generic_vector_array_test.cc b/source/blender/functions/tests/FN_generic_vector_array_test.cc deleted file mode 100644 index 6a83e6094b4..00000000000 --- a/source/blender/functions/tests/FN_generic_vector_array_test.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include "testing/testing.h" - -#include "FN_generic_vector_array.hh" - -namespace blender::fn::tests { - -TEST(generic_vector_array, Construct) -{ - GVectorArray vector_array{CPPType::get<int>(), 4}; - EXPECT_EQ(vector_array.size(), 4); - EXPECT_FALSE(vector_array.is_empty()); -} - -TEST(generic_vector_array, Append) -{ - GVectorArray vector_array{CPPType::get<int>(), 3}; - int value1 = 2; - vector_array.append(1, &value1); - vector_array.append(1, &value1); - int value2 = 3; - vector_array.append(0, &value2); - vector_array.append(1, &value2); - - EXPECT_EQ(vector_array[0].size(), 1); - EXPECT_EQ(vector_array[1].size(), 3); - EXPECT_EQ(vector_array[2].size(), 0); -} - -TEST(generic_vector_array, Extend) -{ - GVectorArray vector_array{CPPType::get<int>(), 3}; - vector_array.extend(0, Span<int>({1, 4, 6, 4})); - vector_array.extend(1, Span<int>()); - vector_array.extend(0, Span<int>({10, 20, 30})); - - EXPECT_EQ(vector_array[0].size(), 7); - EXPECT_EQ(vector_array[1].size(), 0); - EXPECT_EQ(vector_array[2].size(), 0); -} - -} // namespace blender::fn::tests |