diff options
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.h | 194 |
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__ */ |