Blender V5.0
BLI_resource_scope.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
10
12#include "BLI_utility_mixins.hh"
13#include "BLI_vector.hh"
14
15namespace blender {
16
38 private:
39 struct ResourceData {
40 void *data;
41 void (*free)(void *data);
42 };
43
44 LinearAllocator<> allocator_;
45 Vector<ResourceData> resources_;
46
47 public:
50
55 template<typename T> T *add(std::unique_ptr<T> resource);
56
61 template<typename T> T *add(destruct_ptr<T> resource);
62
67 void add(void *userdata, void (*free)(void *));
68
73 template<typename T> T &add_value(T &&value);
74
78 template<typename Func> void add_destruct_call(Func func);
79
83 template<typename T, typename... Args> T &construct(Args &&...args);
84
89 void *allocate_owned(const CPPType &type);
90
96};
97
98/* -------------------------------------------------------------------- */
101
102template<typename T> inline T *ResourceScope::add(std::unique_ptr<T> resource)
103{
104 T *ptr = resource.release();
105 if (ptr == nullptr) {
106 return nullptr;
107 }
108 this->add(ptr, [](void *data) {
109 T *typed_data = reinterpret_cast<T *>(data);
110 delete typed_data;
111 });
112 return ptr;
113}
114
115template<typename T> inline T *ResourceScope::add(destruct_ptr<T> resource)
116{
117 T *ptr = resource.release();
118 if (ptr == nullptr) {
119 return nullptr;
120 }
121 /* There is no need to keep track of such types. */
122 if constexpr (std::is_trivially_destructible_v<T>) {
123 return ptr;
124 }
125
126 this->add(ptr, [](void *data) {
127 T *typed_data = reinterpret_cast<T *>(data);
128 typed_data->~T();
129 });
130 return ptr;
131}
132
133inline void ResourceScope::add(void *userdata, void (*free)(void *))
134{
135 ResourceData data;
136 data.data = userdata;
137 data.free = free;
138 resources_.append(data);
139}
140
141template<typename T> inline T &ResourceScope::add_value(T &&value)
142{
143 return this->construct<T>(std::forward<T>(value));
144}
145
146template<typename Func> inline void ResourceScope::add_destruct_call(Func func)
147{
148 void *buffer = allocator_.allocate(sizeof(Func), alignof(Func));
149 new (buffer) Func(std::move(func));
150 this->add(buffer, [](void *data) { (*static_cast<Func *>(data))(); });
151}
152
153template<typename T, typename... Args> inline T &ResourceScope::construct(Args &&...args)
154{
155 destruct_ptr<T> value_ptr = allocator_.construct<T>(std::forward<Args>(args)...);
156 T &value_ref = *value_ptr;
157 this->add(std::move(value_ptr));
158 return value_ref;
159}
160
161inline void *ResourceScope::allocate_owned(const CPPType &type)
162{
163 void *buffer = allocator_.allocate(type);
164 if (!type.is_trivially_destructible) {
165 this->add_destruct_call([&type, buffer]() { type.destruct(buffer); });
166 }
167 return buffer;
168}
169
171{
172 return allocator_;
173}
174
176
177} // namespace blender
void BLI_kdtree_nd_ free(KDTree *tree)
BMesh const char void * data
void destruct(void *ptr) const
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
T & construct(Args &&...args)
void add_destruct_call(Func func)
void * allocate_owned(const CPPType &type)
LinearAllocator & allocator()
T * add(std::unique_ptr< T > resource)
#define resource
#define T
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
PointerRNA * ptr
Definition wm_files.cc:4238