Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-05-13 15:14:14 +0300
committerJacques Lucke <jacques@blender.org>2021-05-13 15:14:14 +0300
commitb90fec5d46624d40f35764de629a0e28e7478101 (patch)
tree6ab1049a09b0ef87679a28b271a94d5583ac7d57 /source/blender/blenlib/BLI_hash.hh
parent23a788b8bd3f54b38755e3615a65837785ebedd5 (diff)
BLI: simplify supporting heterogeneous lookup for new types
Heterogeneous lookup is useful when constructing a key in a map/set is relatively expensive (e.g. `std::string`). When doing lookups in the map/set, one usually does not want to construct the type to avoid overhead. Instead, heterogeneous lookup allows for using a different type (such as `StringRef`) as key. This change makes it easier to implement heterogeneous lookup for custom types. Before, one had to specialize `blender::DefaultHash`. Now, one just has to implement a `static uint64_t hash_as(value)` on the type itself. One still has to provide the equality operator in addition to the hash function of course.
Diffstat (limited to 'source/blender/blenlib/BLI_hash.hh')
-rw-r--r--source/blender/blenlib/BLI_hash.hh22
1 files changed, 19 insertions, 3 deletions
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 4022c2baa1f..fbed321534c 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -85,9 +85,12 @@
namespace blender {
/**
- * If there is no other specialization of #DefaultHash for a given type, try to call `hash()` on
- * the value. If there is no such method, this will result in a compiler error. Usually that means
- * that you have to implement a hash function using one of three strategies listed above.
+ * If there is no other specialization of #DefaultHash for a given type, look for a hash function
+ * on the type itself. Implementing a `hash()` method on a type is often significantly easier than
+ * specializing #DefaultHash.
+ *
+ * To support heterogeneous lookup, a type can also implement a static `hash_as(const OtherType &)`
+ * function.
*
* In the case of an enum type, the default hash is just to cast the enum value to an integer.
*/
@@ -95,12 +98,25 @@ template<typename T> struct DefaultHash {
uint64_t operator()(const T &value) const
{
if constexpr (std::is_enum_v<T>) {
+ /* For enums use the value as hash directly. */
return (uint64_t)value;
}
else {
+ /* Try to call the `hash()` function on the value. */
+ /* If this results in a compiler error, no hash function for the type has been found. */
return value.hash();
}
}
+
+ template<typename U> uint64_t operator()(const U &value) const
+ {
+ /* Try calling the static `T::hash_as(value)` function with the given value. The returned hash
+ * should be "compatible" with `T::hash()`. Usually that means that if `value` is converted to
+ * `T` its hash does not change. */
+ /* If this results in a compiler error, no hash function for the heterogeneous lookup has been
+ * found. */
+ return T::hash_as(value);
+ }
};
/**