[Bf-blender-cvs] [72eb10b467b] functions-experimental-refactor: copy generic data structures to functions2

Jacques Lucke noreply at git.blender.org
Fri Nov 1 20:31:25 CET 2019


Commit: 72eb10b467b85ca119b4367a77d854c1a047ae63
Author: Jacques Lucke
Date:   Fri Nov 1 19:11:53 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rB72eb10b467b85ca119b4367a77d854c1a047ae63

copy generic data structures to functions2

===================================================================

M	source/blender/functions2/CMakeLists.txt
A	source/blender/functions2/FN_generic_array_ref.h
A	source/blender/functions2/FN_generic_vector_array.h
A	source/blender/functions2/FN_generic_virtual_list_list_ref.h
A	source/blender/functions2/FN_generic_virtual_list_ref.h

===================================================================

diff --git a/source/blender/functions2/CMakeLists.txt b/source/blender/functions2/CMakeLists.txt
index 2f07f0a9930..dd8c1fbeaa3 100644
--- a/source/blender/functions2/CMakeLists.txt
+++ b/source/blender/functions2/CMakeLists.txt
@@ -27,6 +27,10 @@ set(SRC
   intern/initialize.cc
 
   FN_cpp_type.h
+  FN_generic_array_ref.h
+  FN_generic_vector_array.h
+  FN_generic_virtual_list_list_ref.h
+  FN_generic_virtual_list_ref.h
   FN_initialize.h
 
   intern/cpp_types.h
diff --git a/source/blender/functions2/FN_generic_array_ref.h b/source/blender/functions2/FN_generic_array_ref.h
new file mode 100644
index 00000000000..8943cd67598
--- /dev/null
+++ b/source/blender/functions2/FN_generic_array_ref.h
@@ -0,0 +1,145 @@
+#ifndef __FN_GENERIC_ARRAY_REF_H__
+#define __FN_GENERIC_ARRAY_REF_H__
+
+#include "FN_cpp_type.h"
+
+#include "BLI_array_ref.h"
+
+namespace FN {
+
+using BLI::ArrayRef;
+using BLI::MutableArrayRef;
+
+class GenericArrayRef {
+ private:
+  const CPPType *m_type;
+  const void *m_buffer;
+  uint m_size;
+
+ public:
+  GenericArrayRef(const CPPType &type) : GenericArrayRef(type, nullptr, 0)
+  {
+  }
+
+  GenericArrayRef(const CPPType &type, const void *buffer, uint size)
+      : m_type(&type), m_buffer(buffer), m_size(size)
+  {
+    BLI_assert(buffer != nullptr || size == 0);
+    BLI_assert(type.pointer_has_valid_alignment(buffer));
+  }
+
+  const CPPType &type() const
+  {
+    return *m_type;
+  }
+
+  uint size() const
+  {
+    return m_size;
+  }
+
+  const void *buffer() const
+  {
+    return m_buffer;
+  }
+
+  const void *operator[](uint index) const
+  {
+    BLI_assert(index < m_size);
+    return POINTER_OFFSET(m_buffer, m_type->size() * index);
+  }
+
+  template<typename T> ArrayRef<T> get_ref() const
+  {
+    BLI_assert(GET_TYPE<T>().is_same_or_generalization(*m_type));
+    return ArrayRef<T>((const T *)m_buffer, m_size);
+  }
+};
+
+class GenericMutableArrayRef {
+ private:
+  const CPPType *m_type;
+  void *m_buffer;
+  uint m_size;
+
+ public:
+  GenericMutableArrayRef(const CPPType &type) : GenericMutableArrayRef(type, nullptr, 0)
+  {
+  }
+
+  GenericMutableArrayRef(const CPPType &type, void *buffer, uint size)
+      : m_type(&type), m_buffer(buffer), m_size(size)
+  {
+    BLI_assert(buffer != nullptr || size == 0);
+    BLI_assert(type.pointer_has_valid_alignment(buffer));
+  }
+
+  template<typename T>
+  GenericMutableArrayRef(ArrayRef<T> array)
+      : GenericMutableArrayRef(GET_TYPE<T>(), (void *)array.begin(), array.size())
+  {
+  }
+
+  operator GenericArrayRef() const
+  {
+    return GenericArrayRef(*m_type, m_buffer, m_size);
+  }
+
+  void destruct_all()
+  {
+    if (m_type->trivially_destructible()) {
+      return;
+    }
+    for (uint i = 0; i < m_size; i++) {
+      m_type->destruct((*this)[i]);
+    }
+  }
+
+  void destruct_indices(ArrayRef<uint> indices)
+  {
+    if (m_type->trivially_destructible()) {
+      return;
+    }
+    for (uint i : indices) {
+      m_type->destruct((*this)[i]);
+    }
+  }
+
+  const CPPType &type() const
+  {
+    return *m_type;
+  }
+
+  void *buffer()
+  {
+    return m_buffer;
+  }
+
+  uint size() const
+  {
+    return m_size;
+  }
+
+  void copy_in__uninitialized(uint index, const void *src)
+  {
+    BLI_assert(index < m_size);
+    void *dst = POINTER_OFFSET(m_buffer, m_type->size() * index);
+    m_type->copy_to_uninitialized(src, dst);
+  }
+
+  void *operator[](uint index)
+  {
+    BLI_assert(index < m_size);
+    return POINTER_OFFSET(m_buffer, m_type->size() * index);
+  }
+
+  template<typename T> MutableArrayRef<T> get_ref()
+  {
+    BLI_assert(GET_TYPE<T>().is_same_or_generalization(*m_type));
+    return MutableArrayRef<T>((T *)m_buffer, m_size);
+  }
+};
+
+}  // namespace FN
+
+#endif /* __FN_GENERIC_ARRAY_REF_H__ */
diff --git a/source/blender/functions2/FN_generic_vector_array.h b/source/blender/functions2/FN_generic_vector_array.h
new file mode 100644
index 00000000000..bb1658f7503
--- /dev/null
+++ b/source/blender/functions2/FN_generic_vector_array.h
@@ -0,0 +1,203 @@
+#ifndef __FN_GENERIC_MULTI_VECTOR_H__
+#define __FN_GENERIC_MULTI_VECTOR_H__
+
+#include "FN_cpp_type.h"
+#include "FN_generic_array_ref.h"
+#include "FN_generic_virtual_list_list_ref.h"
+
+#include "BLI_array_ref.h"
+#include "BLI_index_range.h"
+#include "BLI_monotonic_allocator.h"
+
+namespace FN {
+
+using BLI::ArrayRef;
+using BLI::IndexRange;
+using BLI::MonotonicAllocator;
+using BLI::MutableArrayRef;
+
+class GenericVectorArray : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  BLI::GuardedAllocator m_slices_allocator;
+  MonotonicAllocator<> m_elements_allocator;
+  const CPPType &m_type;
+  void **m_starts;
+  uint *m_lengths;
+  uint *m_capacities;
+  uint m_array_size;
+  uint m_element_size;
+
+ public:
+  GenericVectorArray() = delete;
+
+  GenericVectorArray(const CPPType &type, uint array_size)
+      : m_type(type), m_array_size(array_size), m_element_size(type.size())
+  {
+    uint byte_size__starts = sizeof(void *) * array_size;
+    m_starts = (void **)m_slices_allocator.allocate(byte_size__starts, __func__);
+    memset((void *)m_starts, 0, byte_size__starts);
+
+    uint byte_size__lengths = sizeof(uint) * array_size;
+    m_lengths = (uint *)m_slices_allocator.allocate(byte_size__lengths, __func__);
+    memset((void *)m_lengths, 0, byte_size__lengths);
+
+    uint byte_size__capacities = sizeof(uint) * array_size;
+    m_capacities = (uint *)m_slices_allocator.allocate(byte_size__capacities, __func__);
+    memset((void *)m_capacities, 0, byte_size__capacities);
+  }
+
+  ~GenericVectorArray()
+  {
+    this->destruct_all_elements();
+    m_slices_allocator.deallocate((void *)m_starts);
+    m_slices_allocator.deallocate((void *)m_lengths);
+    m_slices_allocator.deallocate((void *)m_capacities);
+  }
+
+  operator GenericVirtualListListRef() const
+  {
+    return GenericVirtualListListRef::FromFullArrayList(m_type, m_starts, m_lengths, m_array_size);
+  }
+
+  uint size() const
+  {
+    return m_array_size;
+  }
+
+  const CPPType &type() const
+  {
+    return m_type;
+  }
+
+  const void *const *starts() const
+  {
+    return m_starts;
+  }
+
+  const uint *lengths() const
+  {
+    return m_lengths;
+  }
+
+  void append_single__copy(uint index, const void *src)
+  {
+    if (m_lengths[index] == m_capacities[index]) {
+      this->grow_single(index, m_lengths[index] + 1);
+    }
+
+    void *dst = POINTER_OFFSET(m_starts[index], m_element_size * m_lengths[index]);
+    m_type.copy_to_uninitialized(src, dst);
+    m_lengths[index]++;
+  }
+
+  void extend_single__copy(uint index, const GenericVirtualListRef &values)
+  {
+    for (uint i = 0; i < values.size(); i++) {
+      this->append_single__copy(index, values[i]);
+    }
+  }
+
+  GenericMutableArrayRef allocate_single(uint index, uint size)
+  {
+    if (m_lengths[index] + size > m_capacities[index]) {
+      this->grow_single(index, m_lengths[index] + size);
+    }
+    void *allocation_start = POINTER_OFFSET(m_starts[index], m_element_size * m_lengths[index]);
+    m_lengths[index] += size;
+    return GenericMutableArrayRef(m_type, allocation_start, size);
+  }
+
+  GenericArrayRef operator[](uint index) const
+  {
+    BLI_assert(index < m_array_size);
+    return GenericArrayRef(m_type, m_starts[index], m_lengths[index]);
+  }
+
+  template<typename T> class TypedRef {
+   private:
+    const GenericVectorArray *m_data;
+
+   public:
+    TypedRef(const GenericVectorArray &data) : m_data(&data)
+    {
+    }
+
+    ArrayRef<T> operator[](uint index) const
+    {
+      return ArrayRef<T>((const T *)m_data->m_starts[index], m_data->m_lengths[index]);
+    }
+  };
+
+  template<typename T> class MutableTypedRef {
+   private:
+    GenericVectorArray *m_data;
+
+   public:
+    MutableTypedRef(GenericVectorArray &data) : m_data(&data)
+    {
+    }
+
+    operator TypedRef<T>() const
+    {
+      return TypedRef<T>(*m_data);
+    }
+
+    MutableArrayRef<T> operator[](uint index) const
+    {
+      return MutableArrayRef<T>((T *)m_data->m_starts[index], m_data->m_lengths[index]);
+    }
+
+    void append_single(uint index, const T &value)
+    {
+      m_data->append_single__copy(index, (void *)&value);
+    }
+  };
+
+  template<typename T> const TypedRef<T> as_typed_ref() const
+  {
+    BLI_assert(GET_TYPE<T>().is_same_or_generalization(m_type));
+    return TypedRef<T>(*this);
+  }
+
+  template<typename T> MutableTypedRef<T> as_mutable_typed_ref()
+  {
+    BLI_assert(GET_TYPE<T>().is_same_or_generalization(m_type));
+    return MutableTypedRef<T>(*this);
+  }
+
+ private:
+  void grow_single(uint index, uint min_capacity)
+  {
+    BLI_assert(m_capacities[index] < min_capacity);
+    min_capacity = power_of_2_max_u(min_capacity);
+    void *new_buffer = m_elements_allocator.allocate_aligned(m_element_size * min_capacity,
+                                                             m_type.alignment());
+
+    for (uint i = 0; i < m_lengths[index]; i++) {
+      void *src = POINTER_OFFSET(m_starts[index], m_element_size * i);
+      void *dst = POINTER_OFFSET(new_buffer, m_element_size * i);
+      m_type.relocate_to_uninitialized(src, dst);
+    }
+
+    m_starts[index] = new_buffer;
+    m_capacities[index] = min_capacity;
+  }
+
+  void destruct_all_elements()
+  {
+    if (m_type.trivially_destructible()) {
+      return;
+    }
+
+    for (uint index = 0; index < m_array_size; index++) {
+      for (uint i = 0; i < m_lengths[index]; i++) {
+        void *ptr = POINTER_OFFSET(m_starts[index], m_element_size * i);
+        m_type.destruct(ptr);
+      }
+    }
+  }
+};
+
+};  // namespace FN
+
+#endif /* __FN_GENERIC_MULTI_VECTOR_H__ */
diff --git a/source/blender/functions2/FN_generic_virtual_list_list_ref.h b/source/blender/functions2/FN_generic_virtual_list_list_ref.h
new file mode 100644
index 00000000000..9cd90df4cb8
--- /dev/null
+++ b/source/blender/functions2/FN_generic_virtual_list_list_ref.h
@@ -0,0 +1,142 @@
+#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 Generic

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list