Blender
V4.5
source
blender
blenlib
tests
BLI_vector_set_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 "
BLI_exception_safety_test_utils.hh
"
6
#include "
BLI_vector_set.hh
"
7
8
#include "testing/testing.h"
9
10
#include "
BLI_strict_flags.h
"
/* IWYU pragma: keep. Keep last. */
11
12
namespace
blender::tests
{
13
14
TEST
(vector_set, DefaultConstructor)
15
{
16
VectorSet<int>
set
;
17
EXPECT_EQ
(set.size(), 0);
18
EXPECT_TRUE(set.is_empty());
19
}
20
21
TEST
(vector_set, InitializerListConstructor_WithoutDuplicates)
22
{
23
VectorSet<int>
set = {1, 4, 5};
24
EXPECT_EQ
(set.size(), 3);
25
EXPECT_EQ
(set[0], 1);
26
EXPECT_EQ
(set[1], 4);
27
EXPECT_EQ
(set[2], 5);
28
VectorSet<int>
set_bigger_than_inline = {1, 4, 5, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19};
29
EXPECT_EQ
(set_bigger_than_inline.
size
(), 14);
30
EXPECT_EQ
(set_bigger_than_inline[0], 1);
31
EXPECT_EQ
(set_bigger_than_inline[1], 4);
32
EXPECT_EQ
(set_bigger_than_inline[2], 5);
33
EXPECT_EQ
(set_bigger_than_inline.
as_span
().last(), 19);
34
}
35
36
TEST
(vector_set, InitializerListConstructor_WithDuplicates)
37
{
38
VectorSet<int>
set = {1, 3, 3, 2, 1, 5};
39
EXPECT_EQ
(set.size(), 4);
40
EXPECT_EQ
(set[0], 1);
41
EXPECT_EQ
(set[1], 3);
42
EXPECT_EQ
(set[2], 2);
43
EXPECT_EQ
(set[3], 5);
44
}
45
46
TEST
(vector_set, Copy)
47
{
48
VectorSet<int>
set1 = {1, 2, 3};
49
VectorSet<int>
set2 = set1;
50
EXPECT_EQ
(set1.
size
(), 3);
51
EXPECT_EQ
(set2.
size
(), 3);
52
EXPECT_EQ
(set1.
index_of
(2), 1);
53
EXPECT_EQ
(set2.
index_of
(2), 1);
54
}
55
56
TEST
(vector_set, CopyAssignment)
57
{
58
VectorSet<int>
set1 = {1, 2, 3};
59
VectorSet<int>
set2 = {};
60
set2 = set1;
61
EXPECT_EQ
(set1.
size
(), 3);
62
EXPECT_EQ
(set2.
size
(), 3);
63
EXPECT_EQ
(set1.
index_of
(2), 1);
64
EXPECT_EQ
(set2.
index_of
(2), 1);
65
}
66
67
TEST
(vector_set, Move)
68
{
69
{
70
VectorSet<int>
set1 = {1, 2, 3};
71
VectorSet<int>
set2 = std::move(set1);
72
EXPECT_EQ
(set1.
size
(), 0);
/* NOLINT: bugprone-use-after-move */
73
EXPECT_EQ
(set2.
size
(), 3);
74
}
75
{
76
VectorSet<int, 24>
set1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
77
VectorSet<int>
set2 = std::move(set1);
78
EXPECT_EQ
(set1.
size
(), 0);
/* NOLINT: bugprone-use-after-move */
79
EXPECT_EQ
(set2.
size
(), 9);
80
}
81
}
82
83
TEST
(vector_set, MoveNonInline)
84
{
85
VectorSet<int>
set1 = {1, 2, 3, 5, 1, 6, 7, 8, 1, 4, 57, 8, 7, 34, 57, 8, 1231};
86
VectorSet<int>
set2 = std::move(set1);
87
EXPECT_EQ
(set1.
size
(), 0);
/* NOLINT: bugprone-use-after-move */
88
EXPECT_EQ
(set2.
size
(), 11);
89
}
90
91
TEST
(vector_set, MoveAssignment)
92
{
93
VectorSet<int>
set1 = {1, 2, 3};
94
VectorSet<int>
set2 = {};
95
set2 = std::move(set1);
96
EXPECT_EQ
(set1.
size
(), 0);
/* NOLINT: bugprone-use-after-move */
97
EXPECT_EQ
(set2.
size
(), 3);
98
}
99
100
TEST
(vector_set, AddNewIncreasesSize)
101
{
102
VectorSet<int>
set
;
103
EXPECT_TRUE(set.is_empty());
104
EXPECT_EQ
(set.size(), 0);
105
set.add(5);
106
EXPECT_FALSE(set.is_empty());
107
EXPECT_EQ
(set.size(), 1);
108
}
109
110
TEST
(vector_set, AddExistingDoesNotIncreaseSize)
111
{
112
VectorSet<int>
set
;
113
EXPECT_EQ
(set.size(), 0);
114
EXPECT_TRUE(set.add(5));
115
EXPECT_EQ
(set.size(), 1);
116
EXPECT_FALSE(set.add(5));
117
EXPECT_EQ
(set.size(), 1);
118
}
119
120
TEST
(vector_set, Index)
121
{
122
VectorSet<int>
set = {3, 6, 4};
123
EXPECT_EQ
(set.index_of(6), 1);
124
EXPECT_EQ
(set.index_of(3), 0);
125
EXPECT_EQ
(set.index_of(4), 2);
126
}
127
128
TEST
(vector_set, IndexTry)
129
{
130
VectorSet<int>
set = {3, 6, 4};
131
EXPECT_EQ
(set.index_of_try(5), -1);
132
EXPECT_EQ
(set.index_of_try(3), 0);
133
EXPECT_EQ
(set.index_of_try(6), 1);
134
EXPECT_EQ
(set.index_of_try(2), -1);
135
}
136
137
TEST
(vector_set, RemoveContained)
138
{
139
VectorSet<int>
set = {4, 5, 6, 7};
140
EXPECT_EQ
(set.size(), 4);
141
set.remove_contained(5);
142
EXPECT_EQ
(set.size(), 3);
143
EXPECT_EQ
(set[0], 4);
144
EXPECT_EQ
(set[1], 7);
145
EXPECT_EQ
(set[2], 6);
146
set.remove_contained(6);
147
EXPECT_EQ
(set.size(), 2);
148
EXPECT_EQ
(set[0], 4);
149
EXPECT_EQ
(set[1], 7);
150
set.remove_contained(4);
151
EXPECT_EQ
(set.size(), 1);
152
EXPECT_EQ
(set[0], 7);
153
set.remove_contained(7);
154
EXPECT_EQ
(set.size(), 0);
155
}
156
157
TEST
(vector_set, RemoveIf)
158
{
159
VectorSet<int64_t>
set
;
160
for
(
const
int64_t
i :
IndexRange
(100)) {
161
set.
add
(i * i);
162
}
163
const
int64_t
removed = set.remove_if([](
const
int64_t
key
) {
return
key
% 2 == 0; });
164
EXPECT_EQ
(set.size() + removed, 100);
165
for
(
const
int64_t
i :
IndexRange
(100)) {
166
EXPECT_EQ
(set.contains(i * i), i % 2 == 1);
167
}
168
}
169
170
TEST
(vector_set, AddMultipleTimes)
171
{
172
VectorSet<int>
set
;
173
for
(
int
i = 0; i < 100; i++) {
174
EXPECT_FALSE(set.contains(i * 13));
175
set.add(i * 12);
176
set.add(i * 13);
177
EXPECT_TRUE(set.contains(i * 13));
178
}
179
}
180
181
TEST
(vector_set, UniquePtrValue)
182
{
183
VectorSet<std::unique_ptr<int>
>
set
;
184
set.
add_new
(std::make_unique<int>());
185
set.add(std::make_unique<int>());
186
set.index_of_try(std::make_unique<int>());
187
std::unique_ptr<int>
value
= set.pop();
188
UNUSED_VARS
(
value
);
189
}
190
191
TEST
(vector_set, Remove)
192
{
193
VectorSet<int>
set
;
194
EXPECT_TRUE(set.add(5));
195
EXPECT_TRUE(set.contains(5));
196
EXPECT_FALSE(set.remove(6));
197
EXPECT_TRUE(set.contains(5));
198
EXPECT_TRUE(set.remove(5));
199
EXPECT_FALSE(set.contains(5));
200
EXPECT_FALSE(set.remove(5));
201
EXPECT_FALSE(set.contains(5));
202
}
203
204
TEST
(vector_set, SpanConstructorExceptions)
205
{
206
std::array<ExceptionThrower, 5>
array
= {1, 2, 3, 4, 5};
207
array
[3].throw_during_copy =
true
;
208
Span<ExceptionThrower>
span =
array
;
209
210
EXPECT_ANY_THROW({
VectorSet<ExceptionThrower>
set
(span); });
211
}
212
213
TEST
(vector_set, CopyConstructorExceptions)
214
{
215
VectorSet<ExceptionThrower>
set = {1, 2, 3, 4, 5};
216
set[3].throw_during_copy =
true
;
217
218
EXPECT_ANY_THROW({
VectorSet<ExceptionThrower>
set_copy(set); });
219
}
220
221
TEST
(vector_set, MoveConstructorExceptions)
222
{
223
VectorSet<ExceptionThrower>
set = {1, 2, 3, 4, 5};
224
set[3].throw_during_copy =
true
;
225
set[3].throw_during_move =
true
;
226
/* Currently never throws on move, because values are separately allocated. */
227
VectorSet<ExceptionThrower>
set_moved(std::move(set));
228
EXPECT_EQ
(set.size(), 0);
/* NOLINT: bugprone-use-after-move */
229
set.add_multiple({4, 5, 6, 7, 8});
230
EXPECT_EQ
(set.size(), 5);
231
}
232
233
TEST
(vector_set, AddNewExceptions)
234
{
235
VectorSet<ExceptionThrower>
set
;
236
ExceptionThrower
value
;
237
value
.throw_during_copy =
true
;
238
EXPECT_ANY_THROW({ set.add_new(
value
); });
239
EXPECT_EQ
(set.size(), 0);
240
EXPECT_ANY_THROW({ set.add_new(
value
); });
241
EXPECT_EQ
(set.size(), 0);
242
}
243
244
TEST
(vector_set, AddExceptions)
245
{
246
VectorSet<ExceptionThrower>
set
;
247
ExceptionThrower
value
;
248
value
.throw_during_copy =
true
;
249
EXPECT_ANY_THROW({ set.add(
value
); });
250
EXPECT_EQ
(set.size(), 0);
251
EXPECT_ANY_THROW({ set.add(
value
); });
252
EXPECT_EQ
(set.size(), 0);
253
}
254
255
TEST
(vector_set, ReserveExceptions)
256
{
257
VectorSet<ExceptionThrower>
set
;
258
set.
add_multiple
({1, 2, 3, 4, 5});
259
set[2].throw_during_move =
true
;
260
EXPECT_ANY_THROW({ set.reserve(100); });
261
}
262
263
TEST
(vector_set, PopExceptions)
264
{
265
VectorSet<ExceptionThrower>
set = {1, 2, 3};
266
set.
as_span
().last().throw_during_move =
true
;
267
EXPECT_EQ
(set.size(), 3);
268
EXPECT_ANY_THROW({ set.pop(); });
/* NOLINT: bugprone-throw-keyword-missing */
269
EXPECT_EQ
(set.size(), 3);
270
set.add(10);
271
EXPECT_EQ
(set.size(), 4);
272
}
273
274
TEST
(vector_set, IndexOfOrAdd)
275
{
276
VectorSet<int>
set
;
277
EXPECT_EQ
(set.index_of_or_add(3), 0);
278
EXPECT_EQ
(set.index_of_or_add(3), 0);
279
EXPECT_EQ
(set.index_of_or_add(2), 1);
280
EXPECT_EQ
(set.index_of_or_add(0), 2);
281
EXPECT_EQ
(set.index_of_or_add(2), 1);
282
EXPECT_EQ
(set.index_of_or_add(3), 0);
283
EXPECT_EQ
(set.index_of_or_add(5), 3);
284
EXPECT_EQ
(set.index_of_or_add(8), 4);
285
EXPECT_EQ
(set.index_of_or_add(5), 3);
286
}
287
288
TEST
(vector_set, Clear)
289
{
290
VectorSet<int>
set = {4, 6, 2, 4};
291
EXPECT_EQ
(set.size(), 3);
292
set.clear();
293
EXPECT_EQ
(set.size(), 0);
294
set.add_multiple({4, 1, 6, 8, 3, 6, 9, 3});
295
EXPECT_EQ
(set.size(), 6);
296
set.clear();
297
EXPECT_EQ
(set.size(), 0);
298
}
299
300
TEST
(vector_set, LookupKey)
301
{
302
VectorSet<std::string>
set
;
303
set.
add
(
"a"
);
304
set.add(
"b"
);
305
set.add(
"c"
);
306
EXPECT_EQ
(set.lookup_key(
"a"
),
"a"
);
307
EXPECT_EQ
(set.lookup_key_as(
"c"
),
"c"
);
308
EXPECT_EQ
(set.lookup_key_ptr_as(
"d"
),
nullptr
);
309
EXPECT_EQ
(set.lookup_key_ptr_as(
"b"
)->size(), 1);
310
EXPECT_EQ
(set.lookup_key_ptr(
"a"
), set.lookup_key_ptr_as(
"a"
));
311
EXPECT_EQ
(set.lookup_key_default(
"d"
,
"default"
),
"default"
);
312
EXPECT_EQ
(set.lookup_key_default(
"c"
,
"default"
),
"c"
);
313
}
314
315
TEST
(vector_set, GrowWhenEmpty)
316
{
317
/* Tests that the internal keys array is freed correctly when growing an empty set. */
318
VectorSet<int>
set
;
319
set.
add
(4);
320
set.remove(4);
321
EXPECT_TRUE(set.is_empty());
322
set.reserve(100);
323
}
324
325
TEST
(vector_set, ExtractVector)
326
{
327
VectorSet<int>
set
;
328
set.
add_multiple
({5, 2, 7, 4, 8, 5, 4, 5});
329
EXPECT_EQ
(set.size(), 5);
330
const
int
*data_ptr = set.data();
331
332
Vector<int>
vec = set.extract_vector();
333
EXPECT_EQ
(vec.
size
(), 5);
334
EXPECT_EQ
(vec.
data
(), data_ptr);
335
EXPECT_TRUE(set.is_empty());
336
}
337
338
TEST
(vector_set, ExtractVectorInline)
339
{
340
VectorSet<int, 32>
set
;
341
set.
add_multiple
({5, 2, 7, 4, 8, 5, 4, 5});
342
EXPECT_EQ
(set.size(), 5);
343
344
Vector<int>
vec = set.extract_vector();
345
EXPECT_EQ
(vec.
size
(), 5);
346
EXPECT_EQ
(vec[2], 7);
347
EXPECT_TRUE(set.is_empty());
348
}
349
350
TEST
(vector_set, ExtractVectorInlineExceptions)
351
{
352
VectorSet<ExceptionThrower, 32>
set
;
353
set.
add_multiple
({5, 2, 7, 4, 8, 5, 4, 5});
354
set[3].throw_during_copy =
true
;
355
set[3].throw_during_move =
true
;
356
EXPECT_EQ
(set.size(), 5);
357
358
EXPECT_ANY_THROW({
Vector<ExceptionThrower>
vec = set.extract_vector(); });
359
EXPECT_EQ
(set.size(), 5);
360
}
361
362
TEST
(vector_set, ExtractVectorEmpty)
363
{
364
VectorSet<int>
set
;
365
Vector<int>
vec = set.extract_vector();
366
EXPECT_TRUE(vec.
is_empty
());
367
}
368
369
TEST
(vector_set,
CustomIDVectorSet
)
370
{
371
struct
ThingWithID {
372
int
a;
373
std::string
b
;
374
int
c;
375
};
376
struct
ThingGetter {
377
StringRef
operator()
(
const
ThingWithID &
value
)
const
378
{
379
return
value
.b;
380
}
381
};
382
CustomIDVectorSet<ThingWithID, ThingGetter>
set
;
383
set.
add_new
(ThingWithID{0,
"test"
, 54});
384
EXPECT_TRUE(set.contains_as(
"test"
));
385
set.add_new(ThingWithID{4333,
"other"
, 2});
386
EXPECT_EQ
(set.size(), 2);
387
set.add(ThingWithID{3333,
"test"
, 27});
388
EXPECT_EQ
(set.size(), 2);
389
390
/* Add more elements than the inline capacity. */
391
CustomIDVectorSet<ThingWithID, ThingGetter>
larger_set;
392
larger_set.
add_new
(ThingWithID{12,
"test"
, 9});
393
EXPECT_EQ
(larger_set.
index_of_as
(
"test"
), 0);
394
larger_set.
add_new
(ThingWithID{123,
"other"
, 8});
395
larger_set.
add
(ThingWithID{1234,
"test"
, 7});
396
larger_set.
add_new
(ThingWithID{12345,
"test_2"
, 6});
397
larger_set.
add_new
(ThingWithID{123456,
"test_4"
, 5});
398
larger_set.
add_new
(ThingWithID{1234567,
"test_5"
, 4});
399
EXPECT_EQ
(larger_set.
index_of_as
(
"test_4"
), 3);
400
larger_set.
add_new
(ThingWithID{12345678,
"test_6"
, 3});
401
EXPECT_TRUE(larger_set.
size
() == 6);
402
}
403
404
TEST
(vector_set, CustomIDVectorSetMove)
405
{
406
407
struct
ThingWithID {
408
int
a;
409
std::string
b
;
410
int
c;
411
};
412
struct
ThingGetter {
413
StringRef
operator()
(
const
std::unique_ptr<ThingWithID> &
value
)
const
414
{
415
return
value
->b;
416
}
417
};
418
CustomIDVectorSet<std::unique_ptr<ThingWithID>
, ThingGetter>
set
;
419
set.
add
(std::make_unique<ThingWithID>(ThingWithID{1,
"hug"
, 2}));
420
set.add(std::make_unique<ThingWithID>(ThingWithID{2,
"a"
, 2}));
421
set.add(std::make_unique<ThingWithID>(ThingWithID{3,
"bug"
, 4}));
422
auto
set_new = std::move(set);
423
EXPECT_EQ
(set.size(), 0);
/* NOLINT: bugprone-use-after-move */
424
EXPECT_EQ
(set_new.size(), 3);
425
}
426
427
namespace
{
428
struct
KeyWithData {
429
int
key
;
430
std::string
data
;
431
432
KeyWithData(
int
key, std::string data) :
key
(
key
),
data
(
data
) {}
433
KeyWithData(
const
StringRef data) :
key
(0),
data
(
data
) {}
434
435
uint64_t
hash
()
const
436
{
437
return
uint64_t
(this->key);
438
}
439
440
friend
bool
operator==
(
const
KeyWithData &a,
const
KeyWithData &
b
)
441
{
442
return
a.key ==
b
.key;
443
}
444
};
445
}
// namespace
446
447
TEST
(vector_set, AddOverwrite)
448
{
449
VectorSet<KeyWithData>
set
;
450
EXPECT_TRUE(set.add_overwrite(KeyWithData{1,
"a"
}));
451
EXPECT_EQ
(set.size(), 1);
452
EXPECT_EQ
(set[0].
data
,
"a"
);
453
EXPECT_FALSE(set.add(KeyWithData{1,
"b"
}));
454
EXPECT_EQ
(set.size(), 1);
455
EXPECT_EQ
(set[0].
data
,
"a"
);
456
EXPECT_EQ
(set.lookup_key(KeyWithData{1,
"_"
}).data,
"a"
);
457
EXPECT_FALSE(set.add_overwrite(KeyWithData{1,
"c"
}));
458
EXPECT_EQ
(set.size(), 1);
459
EXPECT_EQ
(set[0].
data
,
"c"
);
460
EXPECT_EQ
(set.lookup_key(KeyWithData{1,
"_"
}).data,
"c"
);
461
462
const
KeyWithData
key
{2,
"d"
};
463
EXPECT_TRUE(set.add_overwrite(
key
));
464
EXPECT_EQ
(set.size(), 2);
465
EXPECT_EQ
(set[0].
data
,
"c"
);
466
EXPECT_EQ
(set[1].
data
,
"d"
);
467
EXPECT_EQ
(set.lookup_key(
key
).data,
"d"
);
468
}
469
470
TEST
(vector_set, LookupDefault)
471
{
472
VectorSet<KeyWithData>
set
;
473
EXPECT_TRUE(set.add(KeyWithData{1,
"b"
}));
474
EXPECT_TRUE(set.add(KeyWithData{423,
"s"
}));
475
EXPECT_TRUE(set.add(KeyWithData{2,
"t"
}));
476
KeyWithData default_key{1,
"default"
};
477
EXPECT_EQ
(set.lookup_key_default(KeyWithData{1221,
"3"
}, default_key), default_key);
478
KeyWithData other_s{0,
"testing"
};
479
EXPECT_EQ
(set.lookup_key_default(KeyWithData{2398745,
"fffff"
},
StringRef
(
"testing"
)), other_s);
480
EXPECT_EQ
(set.lookup_key_default(KeyWithData{1,
"s"
},
StringRef
(
"testing"
)), set[0]);
481
EXPECT_EQ
(set.lookup_key_default(KeyWithData{2,
"t"
}, {1,
"default"
}), set[2]);
482
}
483
484
}
// namespace blender::tests
BLI_exception_safety_test_utils.hh
EXPECT_EQ
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
key
int key
Definition
BLI_set_test.cc:631
data
std::string data
Definition
BLI_set_test.cc:632
BLI_strict_flags.h
UNUSED_VARS
#define UNUSED_VARS(...)
Definition
BLI_utildefines.h:505
BLI_vector_set.hh
operator()
SIMD_FORCE_INLINE btVector3 operator()(const btVector3 &x) const
Return the transform of the vector.
Definition
btTransform.h:90
array
Definition
cycles/util/array.h:22
blender::IndexRange
Definition
BLI_index_range.hh:50
blender::Span
Definition
BLI_span.hh:74
blender::StringRef
Definition
BLI_string_ref.hh:150
blender::VectorSet
Definition
BLI_vector_set.hh:92
blender::VectorSet::add
bool add(const Key &key)
Definition
BLI_vector_set.hh:338
blender::VectorSet::index_of_as
int64_t index_of_as(const ForwardKey &key) const
Definition
BLI_vector_set.hh:468
blender::VectorSet::add_multiple
void add_multiple(Span< Key > keys)
Definition
BLI_vector_set.hh:381
blender::VectorSet::size
int64_t size() const
Definition
BLI_vector_set.hh:596
blender::VectorSet::index_of
int64_t index_of(const Key &key) const
Definition
BLI_vector_set.hh:464
blender::VectorSet::as_span
Span< Key > as_span() const
Definition
BLI_vector_set.hh:313
blender::VectorSet::add_new
void add_new(const Key &key)
Definition
BLI_vector_set.hh:323
blender::Vector
Definition
BLI_vector.hh:76
blender::Vector::size
int64_t size() const
Definition
BLI_vector.hh:771
blender::Vector::is_empty
bool is_empty() const
Definition
BLI_vector.hh:783
blender::Vector::data
T * data()
Definition
BLI_vector.hh:945
blender::tests::ExceptionThrower
Definition
BLI_exception_safety_test_utils.hh:12
b
b
Definition
compositor_morphological_distance_info.hh:24
set
node_ attributes set("label", ss.str())
blender::tests
Definition
BLF_tests.cc:9
blender::tests::operator==
static bool operator==(const Type1 &a, const Type1 &b)
Definition
BLI_set_test.cc:288
blender::tests::TEST
TEST(blf_load, load)
Definition
BLF_tests.cc:34
hash
#define hash
Definition
noise_c.cc:154
int64_t
__int64 int64_t
Definition
stdint.h:89
uint64_t
unsigned __int64 uint64_t
Definition
stdint.h:90
value
T value
Definition
usd_reader_camera.cc:34
Generated on Fri Apr 3 2026 06:33:18 for Blender by
doxygen
1.11.0