Blender V4.3
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" /* Keep last. */
18
19namespace blender {
20namespace tests {
21
22TEST(set, DefaultConstructor)
23{
25 EXPECT_EQ(set.size(), 0);
26 EXPECT_TRUE(set.is_empty());
27}
28
29TEST(set, ContainsNotExistant)
30{
32 EXPECT_FALSE(set.contains(3));
33}
34
35TEST(set, ContainsExistant)
36{
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{
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{
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{
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;
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 {
282};
283
284struct Type2 {
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{
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{
337 set.add(Type1{5});
338 EXPECT_TRUE(set.contains_as(Type2{5}));
339 set.remove_contained_as(Type2{5});
340 EXPECT_FALSE(set.contains_as(Type2{5}));
341}
342
343TEST(set, RemoveAs)
344{
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 {
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{
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{
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{
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{
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{
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{
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
632#if 0
633template<typename SetT>
634BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
635{
636 RNG *rng = BLI_rng_new(0);
637 Vector<int> values;
638 for (int i = 0; i < amount; i++) {
639 values.append(BLI_rng_get_int(rng) * factor);
640 }
641 BLI_rng_free(rng);
642
643 SetT set;
644 // set.reserve(amount);
645 {
646 SCOPED_TIMER(name + " Add");
647 for (int value : values) {
648 set.add(value);
649 }
650 }
651 int count = 0;
652 {
653 SCOPED_TIMER(name + " Contains");
654 for (int value : values) {
655 count += set.contains(value);
656 }
657 }
658 {
659 SCOPED_TIMER(name + " Remove");
660 for (int value : values) {
661 count += set.remove(value);
662 }
663 }
664
665 /* Print the value for simple error checking and to avoid some compiler optimizations. */
666 std::cout << "Count: " << count << "\n";
667}
668
673template<typename Key> class StdUnorderedSetWrapper {
674 private:
675 using SetType = std::unordered_set<Key, blender::DefaultHash<Key>>;
676 SetType set_;
677
678 public:
679 int64_t size() const
680 {
681 return int64_t(set_.size());
682 }
683
684 bool is_empty() const
685 {
686 return set_.empty();
687 }
688
689 void reserve(int64_t n)
690 {
691 set_.reserve(size_t(n));
692 }
693
694 void add_new(const Key &key)
695 {
696 set_.insert(key);
697 }
698 void add_new(Key &&key)
699 {
700 set_.insert(std::move(key));
701 }
702
703 bool add(const Key &key)
704 {
705 return set_.insert(key).second;
706 }
707 bool add(Key &&key)
708 {
709 return set_.insert(std::move(key)).second;
710 }
711
712 void add_multiple(Span<Key> keys)
713 {
714 for (const Key &key : keys) {
715 set_.insert(key);
716 }
717 }
718
719 bool contains(const Key &key) const
720 {
721 return set_.find(key) != set_.end();
722 }
723
724 bool remove(const Key &key)
725 {
726 return bool(set_.erase(key));
727 }
728
729 void remove_contained(const Key &key)
730 {
731 return set_.erase(key);
732 }
733
734 void clear()
735 {
736 set_.clear();
737 }
738
739 typename SetType::iterator begin() const
740 {
741 return set_.begin();
742 }
743
744 typename SetType::iterator end() const
745 {
746 return set_.end();
747 }
748};
749
750TEST(set, Benchmark)
751{
752 for (int i = 0; i < 3; i++) {
753 benchmark_random_ints<Set<int>>("blender::Set ", 100000, 1);
754 benchmark_random_ints<StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1);
755 }
756 std::cout << "\n";
757 for (int i = 0; i < 3; i++) {
758 uint32_t factor = (3 << 10);
759 benchmark_random_ints<Set<int>>("blender::Set ", 100000, int(factor));
760 benchmark_random_ints<StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, int(factor));
761 }
762}
763
820#endif /* Benchmark */
821
822} // namespace tests
823} // 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:78
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:58
unsigned int uint
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:61
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void add_multiple_new(Span< Key > keys)
Definition BLI_set.hh:279
const Key & lookup_key(const Key &key) const
Definition BLI_set.hh:304
int64_t size() const
Definition BLI_set.hh:564
bool contains(const Key &key) const
Definition BLI_set.hh:291
bool add(const Key &key)
Definition BLI_set.hh:248
void add_multiple(Span< Key > keys)
Definition BLI_set.hh:268
int64_t size() const
bool contains(const T &value) const
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
node_ attributes set("label", ss.str())
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
int count
#define N
static void clear(Message &msg)
Definition msgfmt.cc:218
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
Definition msgfmt.cc:227
static bool operator==(const Type1 &a, const Type1 &b)
TEST(any, DefaultConstructor)
PythonProbingStrategy<> DefaultProbingStrategy
unsigned int uint32_t
Definition stdint.h:80
__int64 int64_t
Definition stdint.h:89
signed int int32_t
Definition stdint.h:77
unsigned __int64 uint64_t
Definition stdint.h:90
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)