Blender  V3.3
BLI_resource_scope.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
28 #include "BLI_linear_allocator.hh"
29 #include "BLI_utility_mixins.hh"
30 #include "BLI_vector.hh"
31 
32 namespace blender {
33 
35  private:
36  struct ResourceData {
37  void *data;
38  void (*free)(void *data);
39  };
40 
41  LinearAllocator<> allocator_;
42  Vector<ResourceData> resources_;
43 
44  public:
47 
48  template<typename T> T *add(std::unique_ptr<T> resource);
49  template<typename T> T *add(destruct_ptr<T> resource);
50  void add(void *userdata, void (*free)(void *));
51 
52  template<typename T> T &add_value(T &&value);
53  template<typename Func> void add_destruct_call(Func func);
54 
55  template<typename T, typename... Args> T &construct(Args &&...args);
56 
58 };
59 
60 /* -------------------------------------------------------------------- */
68 template<typename T> inline T *ResourceScope::add(std::unique_ptr<T> resource)
69 {
70  T *ptr = resource.release();
71  if (ptr == nullptr) {
72  return nullptr;
73  }
74  this->add(ptr, [](void *data) {
75  T *typed_data = reinterpret_cast<T *>(data);
76  delete typed_data;
77  });
78  return ptr;
79 }
80 
85 template<typename T> inline T *ResourceScope::add(destruct_ptr<T> resource)
86 {
87  T *ptr = resource.release();
88  if (ptr == nullptr) {
89  return nullptr;
90  }
91  /* There is no need to keep track of such types. */
92  if constexpr (std::is_trivially_destructible_v<T>) {
93  return ptr;
94  }
95 
96  this->add(ptr, [](void *data) {
97  T *typed_data = reinterpret_cast<T *>(data);
98  typed_data->~T();
99  });
100  return ptr;
101 }
102 
107 inline void ResourceScope::add(void *userdata, void (*free)(void *))
108 {
109  ResourceData data;
110  data.data = userdata;
111  data.free = free;
112  resources_.append(data);
113 }
114 
119 template<typename T> inline T &ResourceScope::add_value(T &&value)
120 {
121  return this->construct<T>(std::forward<T>(value));
122 }
123 
127 template<typename Func> inline void ResourceScope::add_destruct_call(Func func)
128 {
129  void *buffer = allocator_.allocate(sizeof(Func), alignof(Func));
130  new (buffer) Func(std::move(func));
131  this->add(buffer, [](void *data) { (*(Func *)data)(); });
132 }
133 
137 template<typename T, typename... Args> inline T &ResourceScope::construct(Args &&...args)
138 {
139  destruct_ptr<T> value_ptr = allocator_.construct<T>(std::forward<Args>(args)...);
140  T &value_ref = *value_ptr;
141  this->add(std::move(value_ptr));
142  return value_ref;
143 }
144 
150 {
151  return allocator_;
152 }
153 
156 } // namespace blender
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
destruct_ptr< T > construct(Args &&...args)
void * allocate(const int64_t size, const int64_t alignment)
T & construct(Args &&...args)
void add_destruct_call(Func func)
LinearAllocator & linear_allocator()
T * add(std::unique_ptr< T > resource)
void append(const T &value)
Definition: BLI_vector.hh:433
SyclQueue void void size_t num_bytes void
ccl_global float * buffer
#define T
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
PointerRNA * ptr
Definition: wm_files.c:3480