Blender V4.3
BLI_cpp_type_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "BLI_cpp_type.hh"
9
10namespace blender::tests {
11
12static const int default_constructed_value = 1;
13static const int copy_constructed_value = 2;
14static const int move_constructed_value = 3;
15static const int copy_constructed_from_value = 4;
16static const int move_constructed_from_value = 5;
17static const int copy_assigned_value = 6;
18static const int copy_assigned_from_value = 7;
19static const int move_assigned_value = 8;
20static const int move_assigned_from_value = 9;
21static const int destructed_value = 10;
22
23struct TestType {
24 mutable volatile int value;
25
27 {
29 }
30
32 {
33 value = destructed_value;
34 }
35
36 TestType(const TestType &other)
37 {
39 other.value = copy_constructed_from_value;
40 }
41
42 TestType(TestType &&other) noexcept
43 {
45 other.value = move_constructed_from_value;
46 }
47
49 {
50 value = copy_assigned_value;
52 return *this;
53 }
54
55 TestType &operator=(TestType &&other) noexcept
56 {
57 value = move_assigned_value;
59 return *this;
60 }
61
62 friend std::ostream &operator<<(std::ostream &stream, const TestType &value)
63 {
64 stream << value.value;
65 return stream;
66 }
67
68 friend bool operator==(const TestType & /*a*/, const TestType & /*b*/)
69 {
70 return false;
71 }
72
73 uint64_t hash() const
74 {
75 return 0;
76 }
77};
78
79} // namespace blender::tests
80
82
83namespace blender::tests {
84
86
87TEST(cpp_type, Size)
88{
90}
91
92TEST(cpp_type, Alignment)
93{
95}
96
97TEST(cpp_type, Is)
98{
99 EXPECT_TRUE(CPPType_TestType.is<TestType>());
100 EXPECT_FALSE(CPPType_TestType.is<int>());
101}
102
103TEST(cpp_type, DefaultConstruction)
104{
105 int buffer[10] = {0};
106 CPPType_TestType.default_construct((void *)buffer);
108 EXPECT_EQ(buffer[1], 0);
109 CPPType_TestType.default_construct_n((void *)buffer, 3);
113 EXPECT_EQ(buffer[3], 0);
114 IndexMaskMemory memory;
116 IndexMask::from_indices<int>({2, 5, 7}, memory));
118 EXPECT_EQ(buffer[4], 0);
120 EXPECT_EQ(buffer[6], 0);
122 EXPECT_EQ(buffer[8], 0);
123}
124
125TEST(cpp_type, DefaultConstructTrivial)
126{
127 int value = 5;
129 EXPECT_EQ(value, 5);
130}
131
132TEST(cpp_type, ValueInitialize)
133{
134 int buffer[10] = {0};
135 CPPType_TestType.value_initialize((void *)buffer);
137 EXPECT_EQ(buffer[1], 0);
138 CPPType_TestType.value_initialize_n((void *)buffer, 3);
142 EXPECT_EQ(buffer[3], 0);
143 IndexMaskMemory memory;
145 IndexMask::from_indices<int>({2, 5, 7}, memory));
147 EXPECT_EQ(buffer[4], 0);
149 EXPECT_EQ(buffer[6], 0);
151 EXPECT_EQ(buffer[8], 0);
152}
153
154TEST(cpp_type, ValueInitializeTrivial)
155{
156 int value = 5;
158 EXPECT_EQ(value, 0);
159}
160
161TEST(cpp_type, Destruct)
162{
163 int buffer[10] = {0};
164 CPPType_TestType.destruct((void *)buffer);
165 EXPECT_EQ(buffer[0], destructed_value);
166 EXPECT_EQ(buffer[1], 0);
167 CPPType_TestType.destruct_n((void *)buffer, 3);
168 EXPECT_EQ(buffer[0], destructed_value);
169 EXPECT_EQ(buffer[1], destructed_value);
170 EXPECT_EQ(buffer[2], destructed_value);
171 EXPECT_EQ(buffer[3], 0);
172 IndexMaskMemory memory;
173 CPPType_TestType.destruct_indices((void *)buffer,
174 IndexMask::from_indices<int>({2, 5, 7}, memory));
175 EXPECT_EQ(buffer[2], destructed_value);
176 EXPECT_EQ(buffer[4], 0);
177 EXPECT_EQ(buffer[5], destructed_value);
178 EXPECT_EQ(buffer[6], 0);
179 EXPECT_EQ(buffer[7], destructed_value);
180 EXPECT_EQ(buffer[8], 0);
181}
182
183TEST(cpp_type, CopyToUninitialized)
184{
185 int buffer1[10] = {0};
186 int buffer2[10] = {0};
187 CPPType_TestType.copy_construct((void *)buffer1, (void *)buffer2);
190 CPPType_TestType.copy_construct_n((void *)buffer1, (void *)buffer2, 3);
197 EXPECT_EQ(buffer1[3], 0);
198 EXPECT_EQ(buffer2[3], 0);
199 IndexMaskMemory memory;
201 (void *)buffer1, (void *)buffer2, IndexMask::from_indices<int>({2, 5, 7}, memory));
204 EXPECT_EQ(buffer1[4], 0);
205 EXPECT_EQ(buffer2[4], 0);
208 EXPECT_EQ(buffer1[6], 0);
209 EXPECT_EQ(buffer2[6], 0);
212 EXPECT_EQ(buffer1[8], 0);
213 EXPECT_EQ(buffer2[8], 0);
214}
215
216TEST(cpp_type, CopyToInitialized)
217{
218 int buffer1[10] = {0};
219 int buffer2[10] = {0};
220 CPPType_TestType.copy_assign((void *)buffer1, (void *)buffer2);
222 EXPECT_EQ(buffer2[0], copy_assigned_value);
223 CPPType_TestType.copy_assign_n((void *)buffer1, (void *)buffer2, 3);
225 EXPECT_EQ(buffer2[0], copy_assigned_value);
227 EXPECT_EQ(buffer2[1], copy_assigned_value);
229 EXPECT_EQ(buffer2[2], copy_assigned_value);
230 EXPECT_EQ(buffer1[3], 0);
231 EXPECT_EQ(buffer2[3], 0);
232 IndexMaskMemory memory;
234 (void *)buffer1, (void *)buffer2, IndexMask::from_indices<int>({2, 5, 7}, memory));
236 EXPECT_EQ(buffer2[2], copy_assigned_value);
237 EXPECT_EQ(buffer1[4], 0);
238 EXPECT_EQ(buffer2[4], 0);
240 EXPECT_EQ(buffer2[5], copy_assigned_value);
241 EXPECT_EQ(buffer1[6], 0);
242 EXPECT_EQ(buffer2[6], 0);
244 EXPECT_EQ(buffer2[7], copy_assigned_value);
245 EXPECT_EQ(buffer1[8], 0);
246 EXPECT_EQ(buffer2[8], 0);
247}
248
249TEST(cpp_type, RelocateToUninitialized)
250{
251 int buffer1[10] = {0};
252 int buffer2[10] = {0};
253 CPPType_TestType.relocate_construct((void *)buffer1, (void *)buffer2);
254 EXPECT_EQ(buffer1[0], destructed_value);
256 CPPType_TestType.relocate_construct_n((void *)buffer1, (void *)buffer2, 3);
257 EXPECT_EQ(buffer1[0], destructed_value);
259 EXPECT_EQ(buffer1[1], destructed_value);
261 EXPECT_EQ(buffer1[2], destructed_value);
263 EXPECT_EQ(buffer1[3], 0);
264 EXPECT_EQ(buffer2[3], 0);
265 IndexMaskMemory memory;
267 (void *)buffer1, (void *)buffer2, IndexMask::from_indices<int>({2, 5, 7}, memory));
268 EXPECT_EQ(buffer1[2], destructed_value);
270 EXPECT_EQ(buffer1[4], 0);
271 EXPECT_EQ(buffer2[4], 0);
272 EXPECT_EQ(buffer1[5], destructed_value);
274 EXPECT_EQ(buffer1[6], 0);
275 EXPECT_EQ(buffer2[6], 0);
276 EXPECT_EQ(buffer1[7], destructed_value);
278 EXPECT_EQ(buffer1[8], 0);
279 EXPECT_EQ(buffer2[8], 0);
280}
281
282TEST(cpp_type, RelocateToInitialized)
283{
284 int buffer1[10] = {0};
285 int buffer2[10] = {0};
286 CPPType_TestType.relocate_assign((void *)buffer1, (void *)buffer2);
287 EXPECT_EQ(buffer1[0], destructed_value);
288 EXPECT_EQ(buffer2[0], move_assigned_value);
289 CPPType_TestType.relocate_assign_n((void *)buffer1, (void *)buffer2, 3);
290 EXPECT_EQ(buffer1[0], destructed_value);
291 EXPECT_EQ(buffer2[0], move_assigned_value);
292 EXPECT_EQ(buffer1[1], destructed_value);
293 EXPECT_EQ(buffer2[1], move_assigned_value);
294 EXPECT_EQ(buffer1[2], destructed_value);
295 EXPECT_EQ(buffer2[2], move_assigned_value);
296 EXPECT_EQ(buffer1[3], 0);
297 EXPECT_EQ(buffer2[3], 0);
298 IndexMaskMemory memory;
300 (void *)buffer1, (void *)buffer2, IndexMask::from_indices<int>({2, 5, 7}, memory));
301 EXPECT_EQ(buffer1[2], destructed_value);
302 EXPECT_EQ(buffer2[2], move_assigned_value);
303 EXPECT_EQ(buffer1[4], 0);
304 EXPECT_EQ(buffer2[4], 0);
305 EXPECT_EQ(buffer1[5], destructed_value);
306 EXPECT_EQ(buffer2[5], move_assigned_value);
307 EXPECT_EQ(buffer1[6], 0);
308 EXPECT_EQ(buffer2[6], 0);
309 EXPECT_EQ(buffer1[7], destructed_value);
310 EXPECT_EQ(buffer2[7], move_assigned_value);
311 EXPECT_EQ(buffer1[8], 0);
312 EXPECT_EQ(buffer2[8], 0);
313}
314
315TEST(cpp_type, FillInitialized)
316{
317 int buffer1 = 0;
318 int buffer2[10] = {0};
319 CPPType_TestType.fill_assign_n((void *)&buffer1, (void *)buffer2, 3);
321 EXPECT_EQ(buffer2[0], copy_assigned_value);
322 EXPECT_EQ(buffer2[1], copy_assigned_value);
323 EXPECT_EQ(buffer2[2], copy_assigned_value);
324 EXPECT_EQ(buffer2[3], 0);
325
326 buffer1 = 0;
327 IndexMaskMemory memory;
329 (void *)&buffer1, (void *)buffer2, IndexMask::from_indices<int>({1, 6, 8}, memory));
331 EXPECT_EQ(buffer2[0], copy_assigned_value);
332 EXPECT_EQ(buffer2[1], copy_assigned_value);
333 EXPECT_EQ(buffer2[2], copy_assigned_value);
334 EXPECT_EQ(buffer2[3], 0);
335 EXPECT_EQ(buffer2[4], 0);
336 EXPECT_EQ(buffer2[5], 0);
337 EXPECT_EQ(buffer2[6], copy_assigned_value);
338 EXPECT_EQ(buffer2[7], 0);
339 EXPECT_EQ(buffer2[8], copy_assigned_value);
340 EXPECT_EQ(buffer2[9], 0);
341}
342
343TEST(cpp_type, FillUninitialized)
344{
345 int buffer1 = 0;
346 int buffer2[10] = {0};
347 CPPType_TestType.fill_construct_n((void *)&buffer1, (void *)buffer2, 3);
352 EXPECT_EQ(buffer2[3], 0);
353
354 buffer1 = 0;
355 IndexMaskMemory memory;
357 (void *)&buffer1, (void *)buffer2, IndexMask::from_indices<int>({1, 6, 8}, memory));
362 EXPECT_EQ(buffer2[3], 0);
363 EXPECT_EQ(buffer2[4], 0);
364 EXPECT_EQ(buffer2[5], 0);
366 EXPECT_EQ(buffer2[7], 0);
368 EXPECT_EQ(buffer2[9], 0);
369}
370
371TEST(cpp_type, DebugPrint)
372{
373 int value = 42;
374 std::stringstream ss;
375 CPPType::get<int32_t>().print((void *)&value, ss);
376 std::string text = ss.str();
377 EXPECT_EQ(text, "42");
378}
379
380TEST(cpp_type, ToStaticType)
381{
383 bool found_unsupported_type = false;
384 auto fn = [&](auto type_tag) {
385 using T = typename decltype(type_tag)::type;
386 if constexpr (!std::is_same_v<T, void>) {
387 types.append(&CPPType::get<T>());
388 }
389 else {
390 found_unsupported_type = true;
391 }
392 };
394 CPPType::get<float>().to_static_type_tag<int, float, std::string>(fn);
395 EXPECT_FALSE(found_unsupported_type);
397 EXPECT_TRUE(found_unsupported_type);
398
399 EXPECT_EQ(types.size(), 2);
401 EXPECT_EQ(types[1], &CPPType::get<float>());
402}
403
404TEST(cpp_type, CopyAssignCompressed)
405{
406 std::array<std::string, 5> array = {"a", "b", "c", "d", "e"};
407 std::array<std::string, 3> array_compressed;
408 IndexMaskMemory memory;
410 &array, &array_compressed, IndexMask::from_indices<int>({0, 2, 3}, memory));
411 EXPECT_EQ(array_compressed[0], "a");
412 EXPECT_EQ(array_compressed[1], "c");
413 EXPECT_EQ(array_compressed[2], "d");
414}
415
416} // namespace blender::tests
#define BLI_CPP_TYPE_MAKE(TYPE_NAME, FLAGS)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void copy_construct_n(const void *src, void *dst, int64_t n) const
void value_initialize_indices(void *ptr, const IndexMask &mask) const
void default_construct_n(void *ptr, int64_t n) const
void destruct_n(void *ptr, int64_t n) const
void copy_assign_indices(const void *src, void *dst, const IndexMask &mask) const
void fill_assign_n(const void *value, void *dst, int64_t n) const
void fill_construct_indices(const void *value, void *dst, const IndexMask &mask) const
void relocate_assign_n(void *src, void *dst, int64_t n) const
void copy_construct_indices(const void *src, void *dst, const IndexMask &mask) const
void fill_assign_indices(const void *value, void *dst, const IndexMask &mask) const
void fill_construct_n(const void *value, void *dst, int64_t n) const
void relocate_construct(void *src, void *dst) const
static const CPPType & get()
void relocate_assign_indices(void *src, void *dst, const IndexMask &mask) const
bool is() const
void copy_assign_n(const void *src, void *dst, int64_t n) const
void value_initialize_n(void *ptr, int64_t n) const
void destruct_indices(void *ptr, const IndexMask &mask) const
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
int64_t size() const
int64_t alignment() const
void default_construct_indices(void *ptr, const IndexMask &mask) const
void copy_assign(const void *src, void *dst) const
void to_static_type_tag(const Fn &fn) const
void print(const void *value, std::stringstream &ss) const
void relocate_construct_n(void *src, void *dst, int64_t n) const
void relocate_assign(void *src, void *dst) const
void default_construct(void *ptr) const
void relocate_construct_indices(void *src, void *dst, const IndexMask &mask) const
void copy_assign_compressed(const void *src, void *dst, const IndexMask &mask) const
void value_initialize(void *ptr) const
void append(const T &value)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static char ** types
Definition makesdna.cc:71
static const CPPType & CPPType_TestType
static const int move_assigned_from_value
static const int move_constructed_from_value
static const int move_constructed_value
static const int copy_assigned_from_value
static const int copy_constructed_from_value
static const int move_assigned_value
TEST(any, DefaultConstructor)
static const int destructed_value
static const int default_constructed_value
static const int copy_assigned_value
static const int copy_constructed_value
unsigned __int64 uint64_t
Definition stdint.h:90
friend std::ostream & operator<<(std::ostream &stream, const TestType &value)
TestType & operator=(const TestType &other)
friend bool operator==(const TestType &, const TestType &)
TestType & operator=(TestType &&other) noexcept
TestType(TestType &&other) noexcept
TestType(const TestType &other)