Blender V4.3
BLI_cpp_type_make.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
11#include "BLI_cpp_type.hh"
12#include "BLI_utildefines.h"
13#include <sstream>
14
16
17template<typename T> void default_construct_cb(void *ptr)
18{
19 new (ptr) T;
20}
21template<typename T> void default_construct_indices_cb(void *ptr, const IndexMask &mask)
22{
23 if constexpr (std::is_trivially_constructible_v<T>) {
24 return;
25 }
26 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (static_cast<T *>(ptr) + i) T; });
27}
28
29template<typename T> void value_initialize_cb(void *ptr)
30{
31 new (ptr) T();
32}
33
34template<typename T> void value_initialize_indices_cb(void *ptr, const IndexMask &mask)
35{
36 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (static_cast<T *>(ptr) + i) T(); });
37}
38
39template<typename T> void destruct_cb(void *ptr)
40{
41 (static_cast<T *>(ptr))->~T();
42}
43template<typename T> void destruct_indices_cb(void *ptr, const IndexMask &mask)
44{
45 if (std::is_trivially_destructible_v<T>) {
46 return;
47 }
48 T *ptr_ = static_cast<T *>(ptr);
49 mask.foreach_index_optimized<int64_t>([&](int64_t i) { ptr_[i].~T(); });
50}
51
52template<typename T> void copy_assign_cb(const void *src, void *dst)
53{
54 *static_cast<T *>(dst) = *static_cast<const T *>(src);
55}
56template<typename T> void copy_assign_indices_cb(const void *src, void *dst, const IndexMask &mask)
57{
58 const T *src_ = static_cast<const T *>(src);
59 T *dst_ = static_cast<T *>(dst);
60
61 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = src_[i]; });
62}
63template<typename T>
64void copy_assign_compressed_cb(const void *src, void *dst, const IndexMask &mask)
65{
66 const T *src_ = static_cast<const T *>(src);
67 T *dst_ = static_cast<T *>(dst);
68
69 mask.foreach_index_optimized<int64_t>(
70 [&](const int64_t i, const int64_t pos) { dst_[pos] = src_[i]; });
71}
72
73template<typename T> void copy_construct_cb(const void *src, void *dst)
74{
75 blender::uninitialized_copy_n(static_cast<const T *>(src), 1, static_cast<T *>(dst));
76}
77template<typename T>
78void copy_construct_indices_cb(const void *src, void *dst, const IndexMask &mask)
79{
80 const T *src_ = static_cast<const T *>(src);
81 T *dst_ = static_cast<T *>(dst);
82
83 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(src_[i]); });
84}
85template<typename T>
86void copy_construct_compressed_cb(const void *src, void *dst, const IndexMask &mask)
87{
88 const T *src_ = static_cast<const T *>(src);
89 T *dst_ = static_cast<T *>(dst);
90
91 mask.foreach_index_optimized<int64_t>(
92 [&](const int64_t i, const int64_t pos) { new (dst_ + pos) T(src_[i]); });
93}
94
95template<typename T> void move_assign_cb(void *src, void *dst)
96{
97 blender::initialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
98}
99template<typename T> void move_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
100{
101 T *src_ = static_cast<T *>(src);
102 T *dst_ = static_cast<T *>(dst);
103
104 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = std::move(src_[i]); });
105}
106
107template<typename T> void move_construct_cb(void *src, void *dst)
108{
109 blender::uninitialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
110}
111template<typename T> void move_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
112{
113 T *src_ = static_cast<T *>(src);
114 T *dst_ = static_cast<T *>(dst);
115
116 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(std::move(src_[i])); });
117}
118
119template<typename T> void relocate_assign_cb(void *src, void *dst)
120{
121 T *src_ = static_cast<T *>(src);
122 T *dst_ = static_cast<T *>(dst);
123
124 *dst_ = std::move(*src_);
125 src_->~T();
126}
127template<typename T> void relocate_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
128{
129 T *src_ = static_cast<T *>(src);
130 T *dst_ = static_cast<T *>(dst);
131
132 mask.foreach_index_optimized<int64_t>([&](int64_t i) {
133 dst_[i] = std::move(src_[i]);
134 src_[i].~T();
135 });
136}
137
138template<typename T> void relocate_construct_cb(void *src, void *dst)
139{
140 T *src_ = static_cast<T *>(src);
141 T *dst_ = static_cast<T *>(dst);
142
143 new (dst_) T(std::move(*src_));
144 src_->~T();
145}
146template<typename T>
147void relocate_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
148{
149 T *src_ = static_cast<T *>(src);
150 T *dst_ = static_cast<T *>(dst);
151
152 mask.foreach_index_optimized<int64_t>([&](int64_t i) {
153 new (dst_ + i) T(std::move(src_[i]));
154 src_[i].~T();
155 });
156}
157
158template<typename T> void fill_assign_cb(const void *value, void *dst, int64_t n)
159{
160 const T &value_ = *static_cast<const T *>(value);
161 T *dst_ = static_cast<T *>(dst);
162
163 for (int64_t i = 0; i < n; i++) {
164 dst_[i] = value_;
165 }
166}
167template<typename T>
168void fill_assign_indices_cb(const void *value, void *dst, const IndexMask &mask)
169{
170 const T &value_ = *static_cast<const T *>(value);
171 T *dst_ = static_cast<T *>(dst);
172
173 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = value_; });
174}
175
176template<typename T> void fill_construct_cb(const void *value, void *dst, int64_t n)
177{
178 const T &value_ = *static_cast<const T *>(value);
179 T *dst_ = static_cast<T *>(dst);
180
181 for (int64_t i = 0; i < n; i++) {
182 new (dst_ + i) T(value_);
183 }
184}
185template<typename T>
186void fill_construct_indices_cb(const void *value, void *dst, const IndexMask &mask)
187{
188 const T &value_ = *static_cast<const T *>(value);
189 T *dst_ = static_cast<T *>(dst);
190
191 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(value_); });
192}
193
194template<typename T> void print_cb(const void *value, std::stringstream &ss)
195{
196 const T &value_ = *static_cast<const T *>(value);
197 ss << value_;
198}
199
200template<typename T> bool is_equal_cb(const void *a, const void *b)
201{
202 const T &a_ = *static_cast<const T *>(a);
203 const T &b_ = *static_cast<const T *>(b);
204 return a_ == b_;
205}
206
207template<typename T> uint64_t hash_cb(const void *value)
208{
209 const T &value_ = *static_cast<const T *>(value);
210 return get_default_hash(value_);
211}
212
213} // namespace blender::cpp_type_util
214
215namespace blender {
216
217template<typename T, CPPTypeFlags Flags>
220 const StringRef debug_name)
221{
222 using namespace cpp_type_util;
223
224 debug_name_ = debug_name;
225 size_ = int64_t(sizeof(T));
226 alignment_ = int64_t(alignof(T));
227 is_trivial_ = std::is_trivial_v<T>;
228 is_trivially_destructible_ = std::is_trivially_destructible_v<T>;
229 if constexpr (std::is_default_constructible_v<T>) {
230 default_construct_ = default_construct_cb<T>;
231 default_construct_indices_ = default_construct_indices_cb<T>;
232 value_initialize_ = value_initialize_cb<T>;
233 value_initialize_indices_ = value_initialize_indices_cb<T>;
234 if constexpr (bool(Flags & CPPTypeFlags::IdentityDefaultValue)) {
235 static const T default_value = T::identity();
236 default_value_ = &default_value;
237 }
238 else {
239 static const T default_value = T();
240 default_value_ = &default_value;
241 }
242 }
243 if constexpr (std::is_destructible_v<T>) {
244 destruct_ = destruct_cb<T>;
245 destruct_indices_ = destruct_indices_cb<T>;
246 }
247 if constexpr (std::is_copy_assignable_v<T>) {
248 copy_assign_ = copy_assign_cb<T>;
249 copy_assign_indices_ = copy_assign_indices_cb<T>;
250 copy_assign_compressed_ = copy_assign_compressed_cb<T>;
251 }
252 if constexpr (std::is_copy_constructible_v<T>) {
253 if constexpr (std::is_trivially_copy_constructible_v<T>) {
254 copy_construct_ = copy_assign_;
255 copy_construct_indices_ = copy_assign_indices_;
256 copy_construct_compressed_ = copy_assign_compressed_;
257 }
258 else {
259 copy_construct_ = copy_construct_cb<T>;
260 copy_construct_indices_ = copy_construct_indices_cb<T>;
261 copy_construct_compressed_ = copy_construct_compressed_cb<T>;
262 }
263 }
264 if constexpr (std::is_move_assignable_v<T>) {
265 if constexpr (std::is_trivially_move_assignable_v<T>) {
266 /* This casts away the const from the src pointer. This is fine for trivial types as moving
267 * them does not change the original value. */
268 move_assign_ = reinterpret_cast<decltype(move_assign_)>(copy_assign_);
269 move_assign_indices_ = reinterpret_cast<decltype(move_assign_indices_)>(
270 copy_assign_indices_);
271 }
272 else {
273 move_assign_ = move_assign_cb<T>;
274 move_assign_indices_ = move_assign_indices_cb<T>;
275 }
276 }
277 if constexpr (std::is_move_constructible_v<T>) {
278 if constexpr (std::is_trivially_move_constructible_v<T>) {
279 move_construct_ = move_assign_;
280 move_construct_indices_ = move_assign_indices_;
281 }
282 else {
283 move_construct_ = move_construct_cb<T>;
284 move_construct_indices_ = move_construct_indices_cb<T>;
285 }
286 }
287 if constexpr (std::is_destructible_v<T>) {
288 if constexpr (std::is_trivially_move_assignable_v<T> && std::is_trivially_destructible_v<T>) {
289 relocate_assign_ = move_assign_;
290 relocate_assign_indices_ = move_assign_indices_;
291
292 relocate_construct_ = move_assign_;
293 relocate_construct_indices_ = move_assign_indices_;
294 }
295 else {
296 if constexpr (std::is_move_assignable_v<T>) {
297 relocate_assign_ = relocate_assign_cb<T>;
298 relocate_assign_indices_ = relocate_assign_indices_cb<T>;
299 }
300 if constexpr (std::is_move_constructible_v<T>) {
301 relocate_construct_ = relocate_construct_cb<T>;
302 relocate_construct_indices_ = relocate_construct_indices_cb<T>;
303 }
304 }
305 }
306 if constexpr (std::is_copy_assignable_v<T>) {
307 fill_assign_indices_ = fill_assign_indices_cb<T>;
308 }
309 if constexpr (std::is_copy_constructible_v<T>) {
310 if constexpr (std::is_trivially_constructible_v<T>) {
311 fill_construct_indices_ = fill_assign_indices_;
312 }
313 else {
314 fill_construct_indices_ = fill_construct_indices_cb<T>;
315 }
316 }
317 if constexpr ((bool)(Flags & CPPTypeFlags::Hashable)) {
318 hash_ = hash_cb<T>;
319 }
320 if constexpr ((bool)(Flags & CPPTypeFlags::Printable)) {
321 print_ = print_cb<T>;
322 }
323 if constexpr ((bool)(Flags & CPPTypeFlags::EqualityComparable)) {
324 is_equal_ = is_equal_cb<T>;
325 }
326
327 alignment_mask_ = uintptr_t(alignment_) - uintptr_t(1);
328 has_special_member_functions_ = (default_construct_ && copy_construct_ && copy_assign_ &&
329 move_construct_ && move_assign_ && destruct_);
330}
331
332} // namespace blender
333
335#define BLI_CPP_TYPE_MAKE(TYPE_NAME, FLAGS) \
336 template<> const blender::CPPType &blender::CPPType::get_impl<TYPE_NAME>() \
337 { \
338 static CPPType type{blender::TypeTag<TYPE_NAME>(), \
339 TypeForValue<CPPTypeFlags, FLAGS>(), \
340 STRINGIFY(TYPE_NAME)}; \
341 return type; \
342 }
343
345#define BLI_CPP_TYPE_REGISTER(TYPE_NAME) blender::CPPType::get<TYPE_NAME>()
const void * default_value() const
CPPType(TypeTag< T >, TypeForValue< CPPTypeFlags, Flags >, StringRef debug_name)
local_group_size(16, 16) .push_constant(Type b
#define T
void fill_assign_indices_cb(const void *value, void *dst, const IndexMask &mask)
void move_assign_cb(void *src, void *dst)
void destruct_indices_cb(void *ptr, const IndexMask &mask)
void fill_construct_indices_cb(const void *value, void *dst, const IndexMask &mask)
void value_initialize_indices_cb(void *ptr, const IndexMask &mask)
void copy_construct_compressed_cb(const void *src, void *dst, const IndexMask &mask)
void relocate_construct_cb(void *src, void *dst)
void default_construct_indices_cb(void *ptr, const IndexMask &mask)
void copy_assign_indices_cb(const void *src, void *dst, const IndexMask &mask)
void value_initialize_cb(void *ptr)
void relocate_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
void copy_construct_cb(const void *src, void *dst)
void print_cb(const void *value, std::stringstream &ss)
void relocate_assign_cb(void *src, void *dst)
void move_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
void fill_assign_cb(const void *value, void *dst, int64_t n)
bool is_equal_cb(const void *a, const void *b)
void copy_construct_indices_cb(const void *src, void *dst, const IndexMask &mask)
void move_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
void copy_assign_cb(const void *src, void *dst)
void relocate_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
void copy_assign_compressed_cb(const void *src, void *dst, const IndexMask &mask)
void fill_construct_cb(const void *value, void *dst, int64_t n)
uint64_t hash_cb(const void *value)
void default_construct_cb(void *ptr)
void move_construct_cb(void *src, void *dst)
void initialized_move_n(T *src, int64_t n, T *dst)
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
void uninitialized_move_n(T *src, int64_t n, T *dst)
_W64 unsigned int uintptr_t
Definition stdint.h:119
__int64 int64_t
Definition stdint.h:89
unsigned __int64 uint64_t
Definition stdint.h:90
PointerRNA * ptr
Definition wm_files.cc:4126