Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/FN_generic_virtual_list_list_ref.h')
-rw-r--r--source/blender/functions/FN_generic_virtual_list_list_ref.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/source/blender/functions/FN_generic_virtual_list_list_ref.h b/source/blender/functions/FN_generic_virtual_list_list_ref.h
new file mode 100644
index 00000000000..e09df56eba1
--- /dev/null
+++ b/source/blender/functions/FN_generic_virtual_list_list_ref.h
@@ -0,0 +1,194 @@
+#ifndef __FN_GENERIC_VIRTUAL_LIST_LIST_REF_H__
+#define __FN_GENERIC_VIRTUAL_LIST_LIST_REF_H__
+
+#include "BLI_virtual_list_list_ref.h"
+
+#include "FN_generic_virtual_list_ref.h"
+
+namespace FN {
+
+using BLI::VirtualListListRef;
+
+class GenericVirtualListListRef {
+ private:
+ enum Category {
+ SingleArray,
+ FullArrayList,
+ };
+
+ const CPPType *m_type;
+ uint m_virtual_list_size;
+ Category m_category;
+
+ union {
+ struct {
+ const void *data;
+ uint real_array_size;
+ } single_array;
+ struct {
+ const void *const *starts;
+ const uint *real_array_sizes;
+ } full_array_list;
+ } m_data;
+
+ GenericVirtualListListRef() = default;
+
+ public:
+ static GenericVirtualListListRef FromSingleArray(const CPPType &type,
+ const void *buffer,
+ uint real_array_size,
+ uint virtual_list_size)
+ {
+ GenericVirtualListListRef list;
+ list.m_type = &type;
+ list.m_virtual_list_size = virtual_list_size;
+ list.m_category = Category::SingleArray;
+ list.m_data.single_array.data = buffer;
+ list.m_data.single_array.real_array_size = real_array_size;
+ return list;
+ }
+
+ static GenericVirtualListListRef FromFullArrayList(const CPPType &type,
+ const void *const *starts,
+ const uint *real_array_sizes,
+ uint list_size)
+ {
+ GenericVirtualListListRef list;
+ list.m_type = &type;
+ list.m_virtual_list_size = list_size;
+ list.m_category = Category::FullArrayList;
+ list.m_data.full_array_list.starts = starts;
+ list.m_data.full_array_list.real_array_sizes = real_array_sizes;
+ return list;
+ }
+
+ static GenericVirtualListListRef FromFullArrayList(const CPPType &type,
+ ArrayRef<const void *> starts,
+ ArrayRef<uint> array_sizes)
+ {
+ BLI::assert_same_size(starts, array_sizes);
+ return GenericVirtualListListRef::FromFullArrayList(
+ type, starts.begin(), array_sizes.begin(), starts.size());
+ }
+
+ uint size() const
+ {
+ return m_virtual_list_size;
+ }
+
+ uint sublist_size(uint index) const
+ {
+ BLI_assert(index < m_virtual_list_size);
+ switch (m_category) {
+ case Category::SingleArray:
+ return m_data.single_array.real_array_size;
+ case Category::FullArrayList:
+ return m_data.full_array_list.real_array_sizes[index];
+ }
+ BLI_assert(false);
+ return 0;
+ }
+
+ const CPPType &type() const
+ {
+ return *m_type;
+ }
+
+ bool is_single_list() const
+ {
+ switch (m_category) {
+ case Category::SingleArray:
+ return true;
+ case Category::FullArrayList:
+ return m_virtual_list_size == 1;
+ }
+ BLI_assert(false);
+ return false;
+ }
+
+ GenericVirtualListRef operator[](uint index) const
+ {
+ BLI_assert(index < m_virtual_list_size);
+
+ switch (m_category) {
+ case Category::SingleArray:
+ return GenericVirtualListRef::FromFullArray(
+ *m_type, m_data.single_array.data, m_data.single_array.real_array_size);
+ case Category::FullArrayList:
+ return GenericVirtualListRef::FromFullArray(
+ *m_type,
+ m_data.full_array_list.starts[index],
+ m_data.full_array_list.real_array_sizes[index]);
+ }
+
+ BLI_assert(false);
+ return GenericVirtualListRef{*m_type};
+ }
+
+ template<typename T> VirtualListListRef<T> as_typed_ref() const
+ {
+ BLI_assert(CPP_TYPE<T>() == *m_type);
+
+ switch (m_category) {
+ case Category::SingleArray:
+ return VirtualListListRef<T>::FromSingleArray(
+ ArrayRef<T>((const T *)m_data.single_array.data, m_data.single_array.real_array_size),
+ m_virtual_list_size);
+ case Category::FullArrayList:
+ return VirtualListListRef<T>::FromListOfStartPointers(
+ ArrayRef<const T *>((const T **)m_data.full_array_list.starts, m_virtual_list_size),
+ ArrayRef<uint>(m_data.full_array_list.real_array_sizes, m_virtual_list_size));
+ }
+
+ BLI_assert(false);
+ return {};
+ }
+
+ GenericVirtualListRef repeated_sublist(uint index, uint new_virtual_size) const
+ {
+ BLI_assert(index < m_virtual_list_size);
+
+ switch (m_category) {
+ case Category::SingleArray:
+ return GenericVirtualListRef::FromRepeatedArray(*m_type,
+ m_data.single_array.data,
+ m_data.single_array.real_array_size,
+ new_virtual_size);
+ case Category::FullArrayList:
+ return GenericVirtualListRef::FromRepeatedArray(
+ *m_type,
+ m_data.full_array_list.starts[index],
+ m_data.full_array_list.real_array_sizes[index],
+ new_virtual_size);
+ }
+
+ BLI_assert(false);
+ return {*m_type};
+ }
+
+ GenericVirtualListListRef extended_single_list(uint new_virtual_size) const
+ {
+ BLI_assert(this->is_single_list());
+
+ switch (m_category) {
+ case Category::SingleArray:
+ return GenericVirtualListListRef::FromSingleArray(*m_type,
+ m_data.single_array.data,
+ m_data.single_array.real_array_size,
+ new_virtual_size);
+ case Category::FullArrayList:
+ return GenericVirtualListListRef::FromSingleArray(
+ *m_type,
+ m_data.full_array_list.starts[0],
+ m_data.full_array_list.real_array_sizes[0],
+ new_virtual_size);
+ }
+
+ BLI_assert(false);
+ return {};
+ }
+};
+
+} // namespace FN
+
+#endif /* __FN_GENERIC_VIRTUAL_LIST_LIST_REF_H__ */