Blender V5.0
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
10
11#include <sstream>
12
13#include "BLI_cpp_type.hh"
14#include "BLI_index_mask.hh"
15#include "BLI_utildefines.h"
16
18
19template<typename T> inline bool pointer_has_valid_alignment(const void *ptr)
20{
21 return (uintptr_t(ptr) % alignof(T)) == 0;
22}
23
24template<typename T> inline bool pointer_can_point_to_instance(const void *ptr)
25{
26 return ptr != nullptr && pointer_has_valid_alignment<T>(ptr);
27}
28
29template<typename T> void default_construct_cb(void *ptr)
30{
32 new (ptr) T;
33}
34template<typename T> void default_construct_indices_cb(void *ptr, const IndexMask &mask)
35{
37 if constexpr (std::is_trivially_constructible_v<T>) {
38 return;
39 }
40 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (static_cast<T *>(ptr) + i) T; });
41}
42template<typename T> void default_construct_n_cb(void *ptr, const int64_t n)
43{
45}
46
47template<typename T> void value_initialize_cb(void *ptr)
48{
50 new (ptr) T();
51}
52template<typename T> void value_initialize_indices_cb(void *ptr, const IndexMask &mask)
53{
55 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (static_cast<T *>(ptr) + i) T(); });
56}
57template<typename T> void value_initialize_n_cb(void *ptr, const int64_t n)
58{
60}
61
62template<typename T> void destruct_cb(void *ptr)
63{
65 (static_cast<T *>(ptr))->~T();
66}
67template<typename T> void destruct_indices_cb(void *ptr, const IndexMask &mask)
68{
70 if (std::is_trivially_destructible_v<T>) {
71 return;
72 }
73 T *ptr_ = static_cast<T *>(ptr);
74 mask.foreach_index_optimized<int64_t>([&](int64_t i) { ptr_[i].~T(); });
75}
76template<typename T> void destruct_n_cb(void *ptr, const int64_t n)
77{
79}
80
81template<typename T> void copy_assign_cb(const void *src, void *dst)
82{
85 *static_cast<T *>(dst) = *static_cast<const T *>(src);
86}
87template<typename T> void copy_assign_indices_cb(const void *src, void *dst, const IndexMask &mask)
88{
89 BLI_assert(mask.size() == 0 || src != dst);
92 const T *src_ = static_cast<const T *>(src);
93 T *dst_ = static_cast<T *>(dst);
94
95 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = src_[i]; });
96}
97template<typename T> void copy_assign_n_cb(const void *src, void *dst, const int64_t n)
98{
100}
101template<typename T>
102void copy_assign_compressed_cb(const void *src, void *dst, const IndexMask &mask)
103{
104 BLI_assert(mask.size() == 0 || src != dst);
107 const T *src_ = static_cast<const T *>(src);
108 T *dst_ = static_cast<T *>(dst);
109
110 mask.foreach_index_optimized<int64_t>(
111 [&](const int64_t i, const int64_t pos) { dst_[pos] = src_[i]; });
112}
113
114template<typename T> void copy_construct_cb(const void *src, void *dst)
115{
116 BLI_assert(src != dst || std::is_trivially_copy_constructible_v<T>);
119 blender::uninitialized_copy_n(static_cast<const T *>(src), 1, static_cast<T *>(dst));
120}
121template<typename T>
122void copy_construct_indices_cb(const void *src, void *dst, const IndexMask &mask)
123{
124 BLI_assert(mask.size() == 0 || src != dst);
127 const T *src_ = static_cast<const T *>(src);
128 T *dst_ = static_cast<T *>(dst);
129
130 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(src_[i]); });
131}
132template<typename T> void copy_construct_n_cb(const void *src, void *dst, const int64_t n)
133{
135}
136template<typename T>
137void copy_construct_compressed_cb(const void *src, void *dst, const IndexMask &mask)
138{
139 BLI_assert(mask.size() == 0 || src != dst);
142 const T *src_ = static_cast<const T *>(src);
143 T *dst_ = static_cast<T *>(dst);
144
145 mask.foreach_index_optimized<int64_t>(
146 [&](const int64_t i, const int64_t pos) { new (dst_ + pos) T(src_[i]); });
147}
148
149template<typename T> void move_assign_cb(void *src, void *dst)
150{
153 blender::initialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
154}
155template<typename T> void move_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
156{
157 BLI_assert(mask.size() == 0 || src != dst);
160 T *src_ = static_cast<T *>(src);
161 T *dst_ = static_cast<T *>(dst);
162
163 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = std::move(src_[i]); });
164}
165template<typename T> void move_assign_n_cb(void *src, void *dst, const int64_t n)
166{
168}
169
170template<typename T> void move_construct_cb(void *src, void *dst)
171{
172 BLI_assert(src != dst || std::is_trivially_move_constructible_v<T>);
175
176 blender::uninitialized_move_n(static_cast<T *>(src), 1, static_cast<T *>(dst));
177}
178template<typename T> void move_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
179{
180 BLI_assert(mask.size() == 0 || src != dst);
183 T *src_ = static_cast<T *>(src);
184 T *dst_ = static_cast<T *>(dst);
185
186 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(std::move(src_[i])); });
187}
188template<typename T> void move_construct_n_cb(void *src, void *dst, const int64_t n)
189{
191}
192
193template<typename T> void relocate_assign_cb(void *src, void *dst)
194{
195 BLI_assert(src != dst || std::is_trivially_move_constructible_v<T>);
198 T *src_ = static_cast<T *>(src);
199 T *dst_ = static_cast<T *>(dst);
200
201 *dst_ = std::move(*src_);
202 src_->~T();
203}
204template<typename T> void relocate_assign_indices_cb(void *src, void *dst, const IndexMask &mask)
205{
206 BLI_assert(mask.size() == 0 || src != dst);
209 T *src_ = static_cast<T *>(src);
210 T *dst_ = static_cast<T *>(dst);
211
212 mask.foreach_index_optimized<int64_t>([&](int64_t i) {
213 dst_[i] = std::move(src_[i]);
214 src_[i].~T();
215 });
216}
217template<typename T> void relocate_assign_n_cb(void *src, void *dst, const int64_t n)
218{
220}
221
222template<typename T> void relocate_construct_cb(void *src, void *dst)
223{
224 BLI_assert(src != dst || std::is_trivially_move_constructible_v<T>);
227 T *src_ = static_cast<T *>(src);
228 T *dst_ = static_cast<T *>(dst);
229
230 new (dst_) T(std::move(*src_));
231 src_->~T();
232}
233template<typename T>
234void relocate_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
235{
236 BLI_assert(mask.size() == 0 || src != dst);
239 T *src_ = static_cast<T *>(src);
240 T *dst_ = static_cast<T *>(dst);
241
242 mask.foreach_index_optimized<int64_t>([&](int64_t i) {
243 new (dst_ + i) T(std::move(src_[i]));
244 src_[i].~T();
245 });
246}
247template<typename T> void relocate_construct_n_cb(void *src, void *dst, const int64_t n)
248{
250}
251
252template<typename T>
253void fill_assign_indices_cb(const void *value, void *dst, const IndexMask &mask)
254{
255 BLI_assert(mask.size() == 0 || pointer_can_point_to_instance<T>(value));
257 const T &value_ = *static_cast<const T *>(value);
258 T *dst_ = static_cast<T *>(dst);
259
260 mask.foreach_index_optimized<int64_t>([&](int64_t i) { dst_[i] = value_; });
261}
262template<typename T> void fill_assign_n_cb(const void *value, void *dst, const int64_t n)
263{
264 fill_assign_indices_cb<T>(value, dst, IndexMask(n));
265}
266
267template<typename T> void fill_construct_cb(const void *value, void *dst, int64_t n)
268{
269 const T &value_ = *static_cast<const T *>(value);
270 T *dst_ = static_cast<T *>(dst);
271
272 for (int64_t i = 0; i < n; i++) {
273 new (dst_ + i) T(value_);
274 }
275}
276template<typename T>
277void fill_construct_indices_cb(const void *value, void *dst, const IndexMask &mask)
278{
279 const T &value_ = *static_cast<const T *>(value);
280 T *dst_ = static_cast<T *>(dst);
281
282 mask.foreach_index_optimized<int64_t>([&](int64_t i) { new (dst_ + i) T(value_); });
283}
284template<typename T> void fill_construct_n_cb(const void *value, void *dst, const int64_t n)
285{
287}
288
289template<typename T> void print_cb(const void *value, std::stringstream &ss)
290{
291 const T &value_ = *static_cast<const T *>(value);
292 ss << value_;
293}
294
295template<typename T> bool is_equal_cb(const void *a, const void *b)
296{
299 const T &a_ = *static_cast<const T *>(a);
300 const T &b_ = *static_cast<const T *>(b);
301 return a_ == b_;
302}
303
304template<typename T> uint64_t hash_cb(const void *value)
305{
307 const T &value_ = *static_cast<const T *>(value);
308 return get_default_hash(value_);
309}
310
311} // namespace blender::cpp_type_util
312
313namespace blender {
314
315template<typename T, CPPTypeFlags Flags>
318 const StringRef debug_name)
319{
320 using namespace cpp_type_util;
321
322 debug_name_ = debug_name;
323 this->size = int64_t(sizeof(T));
324 this->alignment = int64_t(alignof(T));
325 this->is_trivial = std::is_trivial_v<T>;
326 this->is_trivially_destructible = std::is_trivially_destructible_v<T>;
327 if constexpr (std::is_default_constructible_v<T>) {
328 default_construct_ = default_construct_cb<T>;
329 default_construct_n_ = default_construct_n_cb<T>;
330 default_construct_indices_ = default_construct_indices_cb<T>;
331 value_initialize_ = value_initialize_cb<T>;
332 value_initialize_n_ = value_initialize_n_cb<T>;
333 value_initialize_indices_ = value_initialize_indices_cb<T>;
334 if constexpr (bool(Flags & CPPTypeFlags::IdentityDefaultValue)) {
335 static const T default_value = T::identity();
336 default_value_ = &default_value;
337 }
338 else {
339 static const T default_value = T();
340 default_value_ = &default_value;
341 }
342 }
343 if constexpr (std::is_destructible_v<T>) {
344 destruct_ = destruct_cb<T>;
345 destruct_n_ = destruct_n_cb<T>;
346 destruct_indices_ = destruct_indices_cb<T>;
347 }
348 if constexpr (std::is_copy_assignable_v<T>) {
349 copy_assign_ = copy_assign_cb<T>;
350 copy_assign_n_ = copy_assign_n_cb<T>;
351 copy_assign_indices_ = copy_assign_indices_cb<T>;
352 copy_assign_compressed_ = copy_assign_compressed_cb<T>;
353 }
354 if constexpr (std::is_copy_constructible_v<T>) {
355 if constexpr (std::is_trivially_copy_constructible_v<T>) {
356 copy_construct_ = copy_assign_;
357 copy_construct_n_ = copy_assign_n_;
358 copy_construct_indices_ = copy_assign_indices_;
359 copy_construct_compressed_ = copy_assign_compressed_;
360 }
361 else {
362 copy_construct_ = copy_construct_cb<T>;
363 copy_construct_n_ = copy_construct_n_cb<T>;
364 copy_construct_indices_ = copy_construct_indices_cb<T>;
365 copy_construct_compressed_ = copy_construct_compressed_cb<T>;
366 }
367 }
368 if constexpr (std::is_move_assignable_v<T>) {
369 if constexpr (std::is_trivially_move_assignable_v<T>) {
370 /* This casts away the const from the src pointer. This is fine for trivial types as moving
371 * them does not change the original value. */
372 move_assign_ = reinterpret_cast<decltype(move_assign_)>(copy_assign_);
373 move_assign_n_ = reinterpret_cast<decltype(move_assign_n_)>(copy_assign_n_);
374 move_assign_indices_ = reinterpret_cast<decltype(move_assign_indices_)>(
375 copy_assign_indices_);
376 }
377 else {
378 move_assign_ = move_assign_cb<T>;
379 move_assign_n_ = move_assign_n_cb<T>;
380 move_assign_indices_ = move_assign_indices_cb<T>;
381 }
382 }
383 if constexpr (std::is_move_constructible_v<T>) {
384 if constexpr (std::is_trivially_move_constructible_v<T>) {
385 move_construct_ = move_assign_;
386 move_construct_n_ = move_assign_n_;
387 move_construct_indices_ = move_assign_indices_;
388 }
389 else {
390 move_construct_ = move_construct_cb<T>;
391 move_construct_n_ = move_construct_n_cb<T>;
392 move_construct_indices_ = move_construct_indices_cb<T>;
393 }
394 }
395 if constexpr (std::is_destructible_v<T>) {
396 if constexpr (std::is_trivially_move_assignable_v<T> && std::is_trivially_destructible_v<T>) {
397 relocate_assign_ = move_assign_;
398 relocate_assign_n_ = move_assign_n_;
399 relocate_assign_indices_ = move_assign_indices_;
400
401 relocate_construct_ = move_assign_;
402 relocate_construct_n_ = move_assign_n_;
403 relocate_construct_indices_ = move_assign_indices_;
404 }
405 else {
406 if constexpr (std::is_move_assignable_v<T>) {
407 relocate_assign_ = relocate_assign_cb<T>;
408 relocate_assign_n_ = relocate_assign_n_cb<T>;
409 relocate_assign_indices_ = relocate_assign_indices_cb<T>;
410 }
411 if constexpr (std::is_move_constructible_v<T>) {
412 relocate_construct_ = relocate_construct_cb<T>;
413 relocate_construct_n_ = relocate_construct_n_cb<T>;
414 relocate_construct_indices_ = relocate_construct_indices_cb<T>;
415 }
416 }
417 }
418 if constexpr (std::is_copy_assignable_v<T>) {
419 fill_assign_n_ = fill_assign_n_cb<T>;
420 fill_assign_indices_ = fill_assign_indices_cb<T>;
421 }
422 if constexpr (std::is_copy_constructible_v<T>) {
423 if constexpr (std::is_trivially_constructible_v<T>) {
424 fill_construct_n_ = fill_assign_n_;
425 fill_construct_indices_ = fill_assign_indices_;
426 }
427 else {
428 fill_construct_n_ = fill_construct_n_cb<T>;
429 fill_construct_indices_ = fill_construct_indices_cb<T>;
430 }
431 }
432 if constexpr ((bool)(Flags & CPPTypeFlags::Hashable)) {
433 hash_ = hash_cb<T>;
434 }
435 if constexpr ((bool)(Flags & CPPTypeFlags::Printable)) {
436 print_ = print_cb<T>;
437 }
438 if constexpr ((bool)(Flags & CPPTypeFlags::EqualityComparable)) {
439 is_equal_ = is_equal_cb<T>;
440 }
441
442 alignment_mask_ = uintptr_t(this->alignment) - uintptr_t(1);
443 this->has_special_member_functions = (default_construct_ && copy_construct_ && copy_assign_ &&
444 move_construct_ && move_assign_ && destruct_);
445 this->is_default_constructible = default_construct_ != nullptr;
446 this->is_copy_constructible = copy_construct_ != nullptr;
447 this->is_move_constructible = move_construct_ != nullptr;
448 this->is_destructible = destruct_ != nullptr;
449 this->is_copy_assignable = copy_assign_ != nullptr;
450 this->is_move_assignable = move_assign_ != nullptr;
451}
452
453} // namespace blender
454
456#define BLI_CPP_TYPE_MAKE(TYPE_NAME, FLAGS) \
457 template<> const blender::CPPType &blender::CPPType::get_impl<TYPE_NAME>() \
458 { \
459 static CPPType type{blender::TypeTag<TYPE_NAME>(), \
460 TypeForValue<CPPTypeFlags, FLAGS>(), \
461 STRINGIFY(TYPE_NAME)}; \
462 return type; \
463 }
464
466#define BLI_CPP_TYPE_REGISTER(TYPE_NAME) blender::CPPType::get<TYPE_NAME>()
#define BLI_assert(a)
Definition BLI_assert.h:46
long long int int64_t
unsigned long long int uint64_t
bool has_special_member_functions
const void * default_value() const
CPPType(TypeTag< T >, TypeForValue< CPPTypeFlags, Flags >, StringRef debug_name)
uint pos
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
#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 move_assign_n_cb(void *src, void *dst, const int64_t n)
void copy_assign_n_cb(const void *src, void *dst, const int64_t n)
void value_initialize_cb(void *ptr)
void move_construct_n_cb(void *src, void *dst, const int64_t n)
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)
bool pointer_can_point_to_instance(const void *ptr)
void relocate_construct_n_cb(void *src, void *dst, const int64_t n)
void move_construct_indices_cb(void *src, void *dst, const IndexMask &mask)
void value_initialize_n_cb(void *ptr, const int64_t n)
void fill_assign_n_cb(const void *value, void *dst, const int64_t n)
void destruct_n_cb(void *ptr, const int64_t n)
void fill_construct_n_cb(const void *value, void *dst, const int64_t n)
void relocate_assign_n_cb(void *src, void *dst, const 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)
bool pointer_has_valid_alignment(const void *ptr)
void copy_construct_n_cb(const void *src, void *dst, const int64_t n)
void default_construct_cb(void *ptr)
void move_construct_cb(void *src, void *dst)
void default_construct_n_cb(void *ptr, const int64_t n)
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
void initialized_move_n(T *src, int64_t n, T *dst)
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
void uninitialized_move_n(T *src, int64_t n, T *dst)
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4238