Blender V4.3
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
31#include "BLI_utility_mixins.hh"
32#include "BLI_vector.hh"
33
34namespace blender {
35
37 private:
38 struct ResourceData {
39 void *data;
40 void (*free)(void *data);
41 };
42
43 LinearAllocator<> allocator_;
44 Vector<ResourceData> resources_;
45
46 public:
49
50 template<typename T> T *add(std::unique_ptr<T> resource);
51 template<typename T> T *add(destruct_ptr<T> resource);
52 void add(void *userdata, void (*free)(void *));
53
54 template<typename T> T &add_value(T &&value);
55 template<typename Func> void add_destruct_call(Func func);
56
57 template<typename T, typename... Args> T &construct(Args &&...args);
58
60};
61
62/* -------------------------------------------------------------------- */
70template<typename T> inline T *ResourceScope::add(std::unique_ptr<T> resource)
71{
72 T *ptr = resource.release();
73 if (ptr == nullptr) {
74 return nullptr;
75 }
76 this->add(ptr, [](void *data) {
77 T *typed_data = reinterpret_cast<T *>(data);
78 delete typed_data;
79 });
80 return ptr;
81}
82
87template<typename T> inline T *ResourceScope::add(destruct_ptr<T> resource)
88{
89 T *ptr = resource.release();
90 if (ptr == nullptr) {
91 return nullptr;
92 }
93 /* There is no need to keep track of such types. */
94 if constexpr (std::is_trivially_destructible_v<T>) {
95 return ptr;
96 }
97
98 this->add(ptr, [](void *data) {
99 T *typed_data = reinterpret_cast<T *>(data);
100 typed_data->~T();
101 });
102 return ptr;
103}
104
109inline void ResourceScope::add(void *userdata, void (*free)(void *))
110{
111 ResourceData data;
112 data.data = userdata;
113 data.free = free;
114 resources_.append(data);
115}
116
121template<typename T> inline T &ResourceScope::add_value(T &&value)
122{
123 return this->construct<T>(std::forward<T>(value));
124}
125
129template<typename Func> inline void ResourceScope::add_destruct_call(Func func)
130{
131 void *buffer = allocator_.allocate(sizeof(Func), alignof(Func));
132 new (buffer) Func(std::move(func));
133 this->add(buffer, [](void *data) { (*static_cast<Func *>(data))(); });
134}
135
139template<typename T, typename... Args> inline T &ResourceScope::construct(Args &&...args)
140{
141 destruct_ptr<T> value_ptr = allocator_.construct<T>(std::forward<Args>(args)...);
142 T &value_ref = *value_ptr;
143 this->add(std::move(value_ptr));
144 return value_ref;
145}
146
152{
153 return allocator_;
154}
155
158} // namespace blender
void BLI_kdtree_nd_ free(KDTree *tree)
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)
#define T
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
PointerRNA * ptr
Definition wm_files.cc:4126