[Bf-blender-cvs] [9f83ef2149e] master: BLI: make different pointer types compatible in hash tables
Jacques Lucke
noreply at git.blender.org
Mon Nov 21 12:03:37 CET 2022
Commit: 9f83ef2149e085f847ac5bde353ba9682036cede
Author: Jacques Lucke
Date: Mon Nov 21 12:02:10 2022 +0100
Branches: master
https://developer.blender.org/rB9f83ef2149e085f847ac5bde353ba9682036cede
BLI: make different pointer types compatible in hash tables
For example, this allows doing a lookup using a raw pointer in a
hash table that uses `std::unique_ptr` as key.
===================================================================
M source/blender/blenlib/BLI_hash.hh
M source/blender/blenlib/BLI_hash_tables.hh
M source/blender/blenlib/BLI_map.hh
M source/blender/blenlib/BLI_set.hh
M source/blender/blenlib/BLI_vector_set.hh
M source/blender/blenlib/tests/BLI_set_test.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 693d4a8a71c..c29dc74599a 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -246,18 +246,17 @@ uint64_t get_default_hash_4(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &
return h1 ^ (h2 * 19349669) ^ (h3 * 83492791) ^ (h4 * 3632623);
}
-template<typename T> struct DefaultHash<std::unique_ptr<T>> {
- uint64_t operator()(const std::unique_ptr<T> &value) const
+/** Support hashing different kinds of pointer types. */
+template<typename T> struct PointerHashes {
+ template<typename U> uint64_t operator()(const U &value) const
{
- return get_default_hash(value.get());
+ return get_default_hash(&*value);
}
};
-template<typename T> struct DefaultHash<std::shared_ptr<T>> {
- uint64_t operator()(const std::shared_ptr<T> &value) const
- {
- return get_default_hash(value.get());
- }
+template<typename T> struct DefaultHash<std::unique_ptr<T>> : public PointerHashes<T> {
+};
+template<typename T> struct DefaultHash<std::shared_ptr<T>> : public PointerHashes<T> {
};
template<typename T> struct DefaultHash<std::reference_wrapper<T>> {
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index de65c58d4db..fff2411f94c 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -331,11 +331,26 @@ class HashTableStats {
* requires the parameters to be of type T. Our hash tables support lookups using other types
* without conversion, therefore DefaultEquality needs to be more generic.
*/
-struct DefaultEquality {
+template<typename T> struct DefaultEquality {
template<typename T1, typename T2> bool operator()(const T1 &a, const T2 &b) const
{
return a == b;
}
};
+/**
+ * Support comparing different kinds of raw and smart pointers.
+ */
+struct PointerComparison {
+ template<typename T1, typename T2> bool operator()(const T1 &a, const T2 &b) const
+ {
+ return &*a == &*b;
+ }
+};
+
+template<typename T> struct DefaultEquality<std::unique_ptr<T>> : public PointerComparison {
+};
+template<typename T> struct DefaultEquality<std::shared_ptr<T>> : public PointerComparison {
+};
+
} // namespace blender
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 6d281420c47..fb048102153 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -92,7 +92,7 @@ template<
* The equality operator used to compare keys. By default it will simply compare keys using the
* `==` operator.
*/
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
/**
* This is what will actually be stored in the hash table array. At a minimum a slot has to be
* able to hold a key, a value and information about whether the slot is empty, occupied or
@@ -1263,7 +1263,7 @@ template<typename Key,
sizeof(Value)),
typename ProbingStrategy = DefaultProbingStrategy,
typename Hash = DefaultHash<Key>,
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
typename Slot = typename DefaultMapSlot<Key, Value>::type>
using RawMap =
Map<Key, Value, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index 8fb618edeb6..548195e48f7 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -89,7 +89,7 @@ template<
* The equality operator used to compare keys. By default it will simply compare keys using the
* `==` operator.
*/
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
/**
* This is what will actually be stored in the hash table array. At a minimum a slot has to
* be able to hold a key and information about whether the slot is empty, occupied or removed.
@@ -949,7 +949,7 @@ template<typename Key,
int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
typename ProbingStrategy = DefaultProbingStrategy,
typename Hash = DefaultHash<Key>,
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
typename Slot = typename DefaultSetSlot<Key>::type>
using RawSet = Set<Key, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index d182e1f1678..9805e8a7d59 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -72,7 +72,7 @@ template<
* The equality operator used to compare keys. By default it will simply compare keys using the
* `==` operator.
*/
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
/**
* This is what will actually be stored in the hash table array. At a minimum a slot has to be
* able to hold an array index and information about whether the slot is empty, occupied or
@@ -874,7 +874,7 @@ class VectorSet {
template<typename Key,
typename ProbingStrategy = DefaultProbingStrategy,
typename Hash = DefaultHash<Key>,
- typename IsEqual = DefaultEquality,
+ typename IsEqual = DefaultEquality<Key>,
typename Slot = typename DefaultVectorSetSlot<Key>::type>
using RawVectorSet = VectorSet<Key, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc
index 79439eb9079..8e311eaf2e4 100644
--- a/source/blender/blenlib/tests/BLI_set_test.cc
+++ b/source/blender/blenlib/tests/BLI_set_test.cc
@@ -393,7 +393,7 @@ TEST(set, IntrusiveIntKey)
2,
DefaultProbingStrategy,
DefaultHash<int>,
- DefaultEquality,
+ DefaultEquality<int>,
IntegerSetSlot<int, 100, 200>>
set;
EXPECT_TRUE(set.add(4));
@@ -589,6 +589,17 @@ TEST(set, RemoveIf)
}
}
+TEST(set, RemoveUniquePtrWithRaw)
+{
+ Set<std::unique_ptr<int>> set;
+ std::unique_ptr<int> a = std::make_unique<int>(5);
+ int *a_ptr = a.get();
+ set.add(std::move(a));
+ EXPECT_EQ(set.size(), 1);
+ set.remove_as(a_ptr);
+ EXPECT_TRUE(set.is_empty());
+}
+
/**
* Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
*/
More information about the Bf-blender-cvs
mailing list