Blender V5.0
BLI_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 <set>
6#include <unordered_set>
7
8#include "testing/testing.h"
9
11#include "BLI_ghash.h"
12#include "BLI_rand.h"
13#include "BLI_set.hh"
14#include "BLI_timeit.hh"
15#include "BLI_vector.hh"
16
17#include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
18
19namespace blender {
20namespace tests {
21
22TEST(set, DefaultConstructor)
23{
24 Set<int> set;
25 EXPECT_EQ(set.size(), 0);
26 EXPECT_TRUE(set.is_empty());
27}
28
29TEST(set, ContainsNotExistant)
30{
31 Set<int> set;
32 EXPECT_FALSE(set.contains(3));
33}
34
35TEST(set, ContainsExistant)
36{
37 Set<int> set;
38 EXPECT_FALSE(set.contains(5));
39 EXPECT_TRUE(set.is_empty());
40 set.add(5);
41 EXPECT_TRUE(set.contains(5));
42 EXPECT_FALSE(set.is_empty());
43}
44
45TEST(set, AddMany)
46{
47 Set<int> set;
48 for (int i = 0; i < 100; i++) {
49 set.add(i);
50 }
51
52 for (int i = 50; i < 100; i++) {
53 EXPECT_TRUE(set.contains(i));
54 }
55 for (int i = 100; i < 150; i++) {
56 EXPECT_FALSE(set.contains(i));
57 }
58}
59
60TEST(set, InitializerListConstructor)
61{
62 Set<int> set = {4, 5, 6};
63 EXPECT_EQ(set.size(), 3);
64 EXPECT_TRUE(set.contains(4));
65 EXPECT_TRUE(set.contains(5));
66 EXPECT_TRUE(set.contains(6));
67 EXPECT_FALSE(set.contains(2));
68 EXPECT_FALSE(set.contains(3));
69}
70
71TEST(set, CopyConstructor)
72{
73 Set<int> set = {3};
74 EXPECT_TRUE(set.contains(3));
75 EXPECT_FALSE(set.contains(4));
76
77 Set<int> set2(set);
78 set2.add(4);
79 EXPECT_TRUE(set2.contains(3));
80 EXPECT_TRUE(set2.contains(4));
81
82 EXPECT_FALSE(set.contains(4));
83}
84
85TEST(set, MoveConstructor)
86{
87 Set<int> set = {1, 2, 3};
88 EXPECT_EQ(set.size(), 3);
89 Set<int> set2(std::move(set));
90 EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
91 EXPECT_EQ(set2.size(), 3);
92}
93
94TEST(set, CopyAssignment)
95{
96 Set<int> set = {3};
97 EXPECT_TRUE(set.contains(3));
98 EXPECT_FALSE(set.contains(4));
99
100 Set<int> set2;
101 set2 = set;
102 set2.add(4);
103 EXPECT_TRUE(set2.contains(3));
104 EXPECT_TRUE(set2.contains(4));
105
106 EXPECT_FALSE(set.contains(4));
107}
108
109TEST(set, MoveAssignment)
110{
111 Set<int> set = {1, 2, 3};
112 EXPECT_EQ(set.size(), 3);
113 Set<int> set2;
114 set2 = std::move(set);
115 EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
116 EXPECT_EQ(set2.size(), 3);
117}
118
119TEST(set, RemoveContained)
120{
121 Set<int> set = {3, 4, 5};
122 EXPECT_TRUE(set.contains(3));
123 EXPECT_TRUE(set.contains(4));
124 EXPECT_TRUE(set.contains(5));
125 set.remove_contained(4);
126 EXPECT_TRUE(set.contains(3));
127 EXPECT_FALSE(set.contains(4));
128 EXPECT_TRUE(set.contains(5));
129 set.remove_contained(3);
130 EXPECT_FALSE(set.contains(3));
131 EXPECT_FALSE(set.contains(4));
132 EXPECT_TRUE(set.contains(5));
133 set.remove_contained(5);
134 EXPECT_FALSE(set.contains(3));
135 EXPECT_FALSE(set.contains(4));
136 EXPECT_FALSE(set.contains(5));
137}
138
139TEST(set, RemoveContainedMany)
140{
141 Set<int> set;
142 for (int i = 0; i < 1000; i++) {
143 set.add(i);
144 }
145 for (int i = 100; i < 1000; i++) {
146 set.remove_contained(i);
147 }
148 for (int i = 900; i < 1000; i++) {
149 set.add(i);
150 }
151
152 for (int i = 0; i < 1000; i++) {
153 if (i < 100 || i >= 900) {
154 EXPECT_TRUE(set.contains(i));
155 }
156 else {
157 EXPECT_FALSE(set.contains(i));
158 }
159 }
160}
161
162TEST(set, Intersects)
163{
164 Set<int> a = {3, 4, 5, 6};
165 Set<int> b = {1, 2, 5};
166 EXPECT_TRUE(Set<int>::Intersects(a, b));
167 EXPECT_FALSE(Set<int>::Disjoint(a, b));
168}
169
170TEST(set, Disjoint)
171{
172 Set<int> a = {5, 6, 7, 8};
173 Set<int> b = {2, 3, 4, 9};
174 EXPECT_FALSE(Set<int>::Intersects(a, b));
175 EXPECT_TRUE(Set<int>::Disjoint(a, b));
176}
177
178TEST(set, AddMultiple)
179{
180 Set<int> a;
181 a.add_multiple({5, 7});
182 EXPECT_TRUE(a.contains(5));
183 EXPECT_TRUE(a.contains(7));
184 EXPECT_FALSE(a.contains(4));
185 a.add_multiple({2, 4, 7});
186 EXPECT_TRUE(a.contains(4));
187 EXPECT_TRUE(a.contains(2));
188 EXPECT_EQ(a.size(), 4);
189}
190
191TEST(set, AddMultipleNew)
192{
193 Set<int> a;
194 a.add_multiple_new({5, 6});
195 EXPECT_TRUE(a.contains(5));
196 EXPECT_TRUE(a.contains(6));
197}
198
199TEST(set, Iterator)
200{
201 Set<int> set = {1, 3, 2, 5, 4};
203 for (int value : set) {
204 vec.append(value);
205 }
206 EXPECT_EQ(vec.size(), 5);
207 EXPECT_TRUE(vec.contains(1));
208 EXPECT_TRUE(vec.contains(3));
209 EXPECT_TRUE(vec.contains(2));
210 EXPECT_TRUE(vec.contains(5));
211 EXPECT_TRUE(vec.contains(4));
212}
213
214TEST(set, OftenAddRemoveContained)
215{
216 Set<int> set;
217 for (int i = 0; i < 100; i++) {
218 set.add(42);
219 EXPECT_EQ(set.size(), 1);
220 set.remove_contained(42);
221 EXPECT_EQ(set.size(), 0);
222 }
223}
224
225TEST(set, UniquePtrValues)
226{
228 set.add_new(std::make_unique<int>());
229 auto value1 = std::make_unique<int>();
230 set.add_new(std::move(value1));
231 set.add(std::make_unique<int>());
232
233 EXPECT_EQ(set.size(), 3);
234}
235
236TEST(set, Clear)
237{
238 Set<int> set = {3, 4, 6, 7};
239 EXPECT_EQ(set.size(), 4);
240 set.clear();
241 EXPECT_EQ(set.size(), 0);
242}
243
244TEST(set, StringSet)
245{
247 set.add("hello");
248 set.add("world");
249 EXPECT_EQ(set.size(), 2);
250 EXPECT_TRUE(set.contains("hello"));
251 EXPECT_TRUE(set.contains("world"));
252 EXPECT_FALSE(set.contains("world2"));
253}
254
255TEST(set, PointerSet)
256{
257 int a, b, c;
258 Set<int *> set;
259 set.add(&a);
260 set.add(&b);
261 EXPECT_EQ(set.size(), 2);
262 EXPECT_TRUE(set.contains(&a));
263 EXPECT_TRUE(set.contains(&b));
264 EXPECT_FALSE(set.contains(&c));
265}
266
267TEST(set, Remove)
268{
269 Set<int> set = {1, 2, 3, 4, 5, 6};
270 EXPECT_EQ(set.size(), 6);
271 EXPECT_TRUE(set.remove(2));
272 EXPECT_EQ(set.size(), 5);
273 EXPECT_FALSE(set.contains(2));
274 EXPECT_FALSE(set.remove(2));
275 EXPECT_EQ(set.size(), 5);
276 EXPECT_TRUE(set.remove(5));
277 EXPECT_EQ(set.size(), 4);
278}
279
280struct Type1 {
281 uint32_t value;
282};
283
284struct Type2 {
285 uint32_t value;
286};
287
288static bool operator==(const Type1 &a, const Type1 &b)
289{
290 return a.value == b.value;
291}
292static bool operator==(const Type2 &a, const Type1 &b)
293{
294 return a.value == b.value;
295}
296
297} // namespace tests
298
299/* This has to be defined in ::blender namespace. */
300template<> struct DefaultHash<tests::Type1> {
301 uint32_t operator()(const tests::Type1 &value) const
302 {
303 return value.value;
304 }
305
306 uint32_t operator()(const tests::Type2 &value) const
307 {
308 return value.value;
309 }
310};
311
312namespace tests {
313
314TEST(set, ContainsAs)
315{
316 Set<Type1> set;
317 set.add(Type1{5});
318 EXPECT_TRUE(set.contains_as(Type1{5}));
319 EXPECT_TRUE(set.contains_as(Type2{5}));
320 EXPECT_FALSE(set.contains_as(Type1{6}));
321 EXPECT_FALSE(set.contains_as(Type2{6}));
322}
323
324TEST(set, ContainsAsString)
325{
327 set.add("test");
328 EXPECT_TRUE(set.contains_as("test"));
329 EXPECT_TRUE(set.contains_as(StringRef("test")));
330 EXPECT_FALSE(set.contains_as("string"));
331 EXPECT_FALSE(set.contains_as(StringRef("string")));
332}
333
334TEST(set, RemoveContainedAs)
335{
336 Set<Type1> set;
337 set.add(Type1{5});
338 EXPECT_TRUE(set.contains_as(Type2{5}));
340 EXPECT_FALSE(set.contains_as(Type2{5}));
341}
342
343TEST(set, RemoveAs)
344{
345 Set<Type1> set;
346 set.add(Type1{5});
347 EXPECT_TRUE(set.contains_as(Type2{5}));
348 set.remove_as(Type2{6});
349 EXPECT_TRUE(set.contains_as(Type2{5}));
350 set.remove_as(Type2{5});
351 EXPECT_FALSE(set.contains_as(Type2{5}));
352 set.remove_as(Type2{5});
353 EXPECT_FALSE(set.contains_as(Type2{5}));
354}
355
356TEST(set, AddAs)
357{
359 EXPECT_TRUE(set.add_as("test"));
360 EXPECT_TRUE(set.add_as(StringRef("qwe")));
361 EXPECT_FALSE(set.add_as(StringRef("test")));
362 EXPECT_FALSE(set.add_as("qwe"));
363}
364
365template<uint N> struct EqualityIntModN {
366 bool operator()(uint a, uint b) const
367 {
368 return (a % N) == (b % N);
369 }
370};
371
372template<uint N> struct HashIntModN {
374 {
375 return value % N;
376 }
377};
378
379TEST(set, CustomizeHashAndEquality)
380{
382 set.add(4);
383 EXPECT_TRUE(set.contains(4));
384 EXPECT_TRUE(set.contains(14));
385 EXPECT_TRUE(set.contains(104));
386 EXPECT_FALSE(set.contains(5));
387 set.add(55);
388 EXPECT_TRUE(set.contains(5));
389 EXPECT_TRUE(set.contains(14));
390 set.remove(1004);
391 EXPECT_FALSE(set.contains(14));
392}
393
394TEST(set, IntrusiveIntKey)
395{
396 Set<int,
397 2,
402 set;
403 EXPECT_TRUE(set.add(4));
404 EXPECT_TRUE(set.add(3));
405 EXPECT_TRUE(set.add(11));
406 EXPECT_TRUE(set.add(8));
407 EXPECT_FALSE(set.add(3));
408 EXPECT_FALSE(set.add(4));
409 EXPECT_TRUE(set.remove(4));
410 EXPECT_FALSE(set.remove(7));
411 EXPECT_TRUE(set.add(4));
412 EXPECT_TRUE(set.remove(4));
413}
414
415struct MyKeyType {
416 uint32_t key;
418
420 {
421 return key;
422 }
423
424 friend bool operator==(const MyKeyType &a, const MyKeyType &b)
425 {
426 return a.key == b.key;
427 }
428};
429
430TEST(set, LookupKey)
431{
432 Set<MyKeyType> set;
433 set.add({1, 10});
434 set.add({2, 20});
435 EXPECT_EQ(set.lookup_key({1, 30}).attached_data, 10);
436 EXPECT_EQ(set.lookup_key({2, 0}).attached_data, 20);
437}
438
439TEST(set, LookupKeyDefault)
440{
441 Set<MyKeyType> set;
442 set.add({1, 10});
443 set.add({2, 20});
444
445 MyKeyType fallback{5, 50};
446 EXPECT_EQ(set.lookup_key_default({1, 66}, fallback).attached_data, 10);
447 EXPECT_EQ(set.lookup_key_default({4, 40}, fallback).attached_data, 50);
448}
449
450TEST(set, LookupKeyPtr)
451{
452 Set<MyKeyType> set;
453 set.add({1, 10});
454 set.add({2, 20});
455 EXPECT_EQ(set.lookup_key_ptr({1, 50})->attached_data, 10);
456 EXPECT_EQ(set.lookup_key_ptr({2, 50})->attached_data, 20);
457 EXPECT_EQ(set.lookup_key_ptr({3, 50}), nullptr);
458}
459
460TEST(set, LookupKeyOrAdd)
461{
462 Set<MyKeyType> set;
463 set.lookup_key_or_add({1, 10});
464 set.lookup_key_or_add({2, 20});
465 EXPECT_EQ(set.size(), 2);
466 EXPECT_EQ(set.lookup_key_or_add({2, 40}).attached_data, 20);
467 EXPECT_EQ(set.size(), 2);
468 EXPECT_EQ(set.lookup_key_or_add({3, 40}).attached_data, 40);
469 EXPECT_EQ(set.size(), 3);
470 EXPECT_EQ(set.lookup_key_or_add({3, 60}).attached_data, 40);
471 EXPECT_EQ(set.size(), 3);
472}
473
474TEST(set, StringViewKeys)
475{
477 set.add("hello");
478 set.add("world");
479 EXPECT_FALSE(set.contains("worlds"));
480 EXPECT_TRUE(set.contains("world"));
481 EXPECT_TRUE(set.contains("hello"));
482}
483
484TEST(set, SpanConstructorExceptions)
485{
486 std::array<ExceptionThrower, 5> array = {1, 2, 3, 4, 5};
487 array[3].throw_during_copy = true;
489
490 EXPECT_ANY_THROW({ Set<ExceptionThrower> set(span); });
491}
492
493TEST(set, CopyConstructorExceptions)
494{
495 Set<ExceptionThrower> set = {1, 2, 3, 4, 5};
496 set.lookup_key(3).throw_during_copy = true;
497 EXPECT_ANY_THROW({ Set<ExceptionThrower> set_copy(set); });
498}
499
500TEST(set, MoveConstructorExceptions)
501{
502 using SetType = Set<ExceptionThrower, 4>;
503 SetType set = {1, 2, 3};
504 set.lookup_key(2).throw_during_move = true;
505 EXPECT_ANY_THROW({ SetType set_moved(std::move(set)); });
506 EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
507 set.add_multiple({3, 6, 7});
508 EXPECT_EQ(set.size(), 3);
509}
510
511TEST(set, AddNewExceptions)
512{
514 ExceptionThrower value;
515 value.throw_during_copy = true;
516 EXPECT_ANY_THROW({ set.add_new(value); });
517 EXPECT_EQ(set.size(), 0);
518 EXPECT_ANY_THROW({ set.add_new(value); });
519 EXPECT_EQ(set.size(), 0);
520}
521
522TEST(set, AddExceptions)
523{
525 ExceptionThrower value;
526 value.throw_during_copy = true;
527 EXPECT_ANY_THROW({ set.add(value); });
528 EXPECT_EQ(set.size(), 0);
529 EXPECT_ANY_THROW({ set.add(value); });
530 EXPECT_EQ(set.size(), 0);
531}
532
533TEST(set, ForwardIterator)
534{
535 Set<int> set = {5, 2, 6, 4, 1};
536 Set<int>::iterator iter1 = set.begin();
537 int value1 = *iter1;
538 Set<int>::iterator iter2 = iter1++;
539 EXPECT_EQ(*iter2, value1);
540 EXPECT_EQ(*(++iter2), *iter1);
541 /* Interesting find: On GCC & MSVC this will succeed, as the 2nd argument is evaluated before the
542 * 1st. On Apple Clang it's the other way around, and the test fails. */
543 // EXPECT_EQ(*iter1, *(++iter1));
544 Set<int>::iterator iter3 = ++iter1;
545 /* Check that #iter1 itself changed. */
546 EXPECT_EQ(*iter3, *iter1);
547}
548
549TEST(set, GenericAlgorithms)
550{
551 Set<int> set = {1, 20, 30, 40};
552 EXPECT_FALSE(std::any_of(set.begin(), set.end(), [](int v) { return v == 5; }));
553 EXPECT_TRUE(std::any_of(set.begin(), set.end(), [](int v) { return v == 30; }));
554 EXPECT_EQ(std::count(set.begin(), set.end(), 20), 1);
555}
556
557TEST(set, RemoveDuringIteration)
558{
559 Set<int> set;
560 set.add(6);
561 set.add(5);
562 set.add(2);
563 set.add(3);
564
565 EXPECT_EQ(set.size(), 4);
566
567 using Iter = Set<int>::Iterator;
568 Iter begin = set.begin();
569 Iter end = set.end();
570 for (Iter iter = begin; iter != end; ++iter) {
571 int item = *iter;
572 if (item == 2) {
573 set.remove(iter);
574 }
575 }
576
577 EXPECT_EQ(set.size(), 3);
578 EXPECT_TRUE(set.contains(5));
579 EXPECT_TRUE(set.contains(6));
580 EXPECT_TRUE(set.contains(3));
581}
582
583TEST(set, RemoveIf)
584{
585 Set<int64_t> set;
586 for (const int64_t i : IndexRange(100)) {
587 set.add(i * i);
588 }
589 const int64_t removed = set.remove_if([](const int64_t key) { return key > 100; });
590 EXPECT_EQ(set.size() + removed, 100);
591 for (const int64_t i : IndexRange(100)) {
592 EXPECT_EQ(set.contains(i * i), i <= 10);
593 }
594}
595
596TEST(set, RemoveUniquePtrWithRaw)
597{
599 std::unique_ptr<int> a = std::make_unique<int>(5);
600 int *a_ptr = a.get();
601 set.add(std::move(a));
602 EXPECT_EQ(set.size(), 1);
603 set.remove_as(a_ptr);
604 EXPECT_TRUE(set.is_empty());
605}
606
607TEST(set, Equality)
608{
609 const Set<int> a = {1, 2, 3, 4, 5};
610 const Set<int> b = {5, 2, 3, 1, 4};
611 const Set<int> c = {1, 2, 3};
612 const Set<int> d = {1, 2, 3, 4, 5, 6};
613 const Set<int> e = {};
614 const Set<int> f = {10, 11, 12, 13, 14};
615
616 EXPECT_EQ(a, a);
617 EXPECT_EQ(a, b);
618 EXPECT_EQ(b, a);
619 EXPECT_NE(a, c);
620 EXPECT_NE(a, d);
621 EXPECT_NE(a, e);
622 EXPECT_NE(a, f);
623 EXPECT_NE(c, a);
624 EXPECT_NE(d, a);
625 EXPECT_NE(e, a);
626 EXPECT_NE(f, a);
627}
628
629namespace {
630struct KeyWithData {
631 int key;
632 std::string data;
633
634 uint64_t hash() const
635 {
636 return uint64_t(this->key);
637 }
638
639 friend bool operator==(const KeyWithData &a, const KeyWithData &b)
640 {
641 return a.key == b.key;
642 }
643};
644} // namespace
645
646TEST(set, AddOverwrite)
647{
649 EXPECT_TRUE(set.add_overwrite(KeyWithData{1, "a"}));
650 EXPECT_EQ(set.size(), 1);
651 EXPECT_FALSE(set.add(KeyWithData{1, "b"}));
652 EXPECT_EQ(set.size(), 1);
653 EXPECT_EQ(set.lookup_key(KeyWithData{1, "_"}).data, "a");
654 EXPECT_FALSE(set.add_overwrite(KeyWithData{1, "c"}));
655 EXPECT_EQ(set.size(), 1);
656 EXPECT_EQ(set.lookup_key(KeyWithData{1, "_"}).data, "c");
657
658 const KeyWithData key{2, "d"};
659 EXPECT_TRUE(set.add_overwrite(key));
660 EXPECT_EQ(set.size(), 2);
661 EXPECT_EQ(set.lookup_key(key).data, "d");
662}
663
667#if 0
668template<typename SetT>
669BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
670{
671 RNG *rng = BLI_rng_new(0);
672 Vector<int> values;
673 for (int i = 0; i < amount; i++) {
674 values.append(BLI_rng_get_int(rng) * factor);
675 }
676 BLI_rng_free(rng);
677
678 SetT set;
679 // set.reserve(amount);
680 {
681 SCOPED_TIMER(name + " Add");
682 for (int value : values) {
683 set.add(value);
684 }
685 }
686 int count = 0;
687 {
688 SCOPED_TIMER(name + " Contains");
689 for (int value : values) {
690 count += set.contains(value);
691 }
692 }
693 {
694 SCOPED_TIMER(name + " Remove");
695 for (int value : values) {
696 count += set.remove(value);
697 }
698 }
699
700 /* Print the value for simple error checking and to avoid some compiler optimizations. */
701 std::cout << "Count: " << count << "\n";
702}
703
708template<typename Key> class StdUnorderedSetWrapper {
709 private:
710 using SetType = std::unordered_set<Key, blender::DefaultHash<Key>>;
711 SetType set_;
712
713 public:
714 int64_t size() const
715 {
716 return int64_t(set_.size());
717 }
718
719 bool is_empty() const
720 {
721 return set_.empty();
722 }
723
724 void reserve(int64_t n)
725 {
726 set_.reserve(size_t(n));
727 }
728
729 void add_new(const Key &key)
730 {
731 set_.insert(key);
732 }
733 void add_new(Key &&key)
734 {
735 set_.insert(std::move(key));
736 }
737
738 bool add(const Key &key)
739 {
740 return set_.insert(key).second;
741 }
742 bool add(Key &&key)
743 {
744 return set_.insert(std::move(key)).second;
745 }
746
747 void add_multiple(Span<Key> keys)
748 {
749 for (const Key &key : keys) {
750 set_.insert(key);
751 }
752 }
753
754 bool contains(const Key &key) const
755 {
756 return set_.find(key) != set_.end();
757 }
758
759 bool remove(const Key &key)
760 {
761 return bool(set_.erase(key));
762 }
763
764 void remove_contained(const Key &key)
765 {
766 return set_.erase(key);
767 }
768
769 void clear()
770 {
771 set_.clear();
772 }
773
774 typename SetType::iterator begin() const
775 {
776 return set_.begin();
777 }
778
779 typename SetType::iterator end() const
780 {
781 return set_.end();
782 }
783};
784
785TEST(set, Benchmark)
786{
787 for (int i = 0; i < 3; i++) {
788 benchmark_random_ints<Set<int>>("blender::Set ", 100000, 1);
789 benchmark_random_ints<StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1);
790 }
791 std::cout << "\n";
792 for (int i = 0; i < 3; i++) {
793 uint32_t factor = (3 << 10);
794 benchmark_random_ints<Set<int>>("blender::Set ", 100000, int(factor));
795 benchmark_random_ints<StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, int(factor));
796 }
797}
798
854
855#endif /* Benchmark */
856
857} // namespace tests
858} // namespace blender
#define BLI_NOINLINE
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
Random number functions.
void int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition rand.cc:73
struct RNG * BLI_rng_new(unsigned int seed)
Definition rand.cc:39
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition rand.cc:53
unsigned int uint
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:70
struct Key Key
iter begin(iter)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
long long int int64_t
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
const Key & lookup_key_default(const Key &key, const Key &default_value) const
Definition BLI_set.hh:336
bool remove_as(const ForwardKey &key)
Definition BLI_set.hh:389
Iterator begin() const
Definition BLI_set.hh:480
const Key & lookup_key_or_add(const Key &key)
Definition BLI_set.hh:367
void add_multiple_new(Span< Key > keys)
Definition BLI_set.hh:298
const Key & lookup_key(const Key &key) const
Definition BLI_set.hh:323
Iterator iterator
Definition BLI_set.hh:114
static bool Disjoint(const Set &a, const Set &b)
Definition BLI_set.hh:665
int64_t size() const
Definition BLI_set.hh:587
bool add_as(ForwardKey &&key)
Definition BLI_set.hh:256
bool contains_as(const ForwardKey &key) const
Definition BLI_set.hh:314
Iterator end() const
Definition BLI_set.hh:490
void remove_contained(const Key &key)
Definition BLI_set.hh:397
bool contains(const Key &key) const
Definition BLI_set.hh:310
static bool Intersects(const Set &a, const Set &b)
Definition BLI_set.hh:647
bool add(const Key &key)
Definition BLI_set.hh:248
bool is_empty() const
Definition BLI_set.hh:595
void add_multiple(Span< Key > keys)
Definition BLI_set.hh:287
void add_new(const Key &key)
Definition BLI_set.hh:233
bool add_overwrite(const Key &key)
Definition BLI_set.hh:267
int64_t remove_if(Predicate &&predicate)
Definition BLI_set.hh:515
void clear()
Definition BLI_set.hh:551
void remove_contained_as(const ForwardKey &key)
Definition BLI_set.hh:401
const Key * lookup_key_ptr(const Key &key) const
Definition BLI_set.hh:354
bool remove(const Key &key)
Definition BLI_set.hh:385
int64_t size() const
bool contains(const T &value) const
void append(const T &value)
int count
#define N
static void clear(Message &msg)
Definition msgfmt.cc:213
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
Definition msgfmt.cc:222
bool contains(const VArray< bool > &varray, const IndexMask &indices_to_check, bool value)
bool remove(void *owner, const StringRef name)
static bool operator==(const Type1 &a, const Type1 &b)
TEST(blf_load, load)
Definition BLF_tests.cc:34
IntrusiveSetSlot< Int, TemplatedKeyInfo< Int, EmptyValue, RemovedValue > > IntegerSetSlot
PythonProbingStrategy<> DefaultProbingStrategy
#define hash
Definition noise_c.cc:154
const char * name
Definition rand.cc:33
uint32_t operator()(const tests::Type1 &value) const
uint32_t operator()(const tests::Type2 &value) const
bool operator()(uint a, uint b) const
uint64_t operator()(uint value) const
friend bool operator==(const MyKeyType &a, const MyKeyType &b)
i
Definition text_draw.cc:230