[Bf-blender-cvs] [ac60e647456] master: BLI: provide a default hash for enums

Jacques Lucke noreply at git.blender.org
Wed Mar 17 11:37:57 CET 2021


Commit: ac60e6474569a69ffa4b9c28f9ae79ef674c5408
Author: Jacques Lucke
Date:   Wed Mar 17 11:37:46 2021 +0100
Branches: master
https://developer.blender.org/rBac60e6474569a69ffa4b9c28f9ae79ef674c5408

BLI: provide a default hash for enums

This avoids some boilerplate code that was necessary when using enums
as keys in maps or sets.

===================================================================

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenlib/BLI_hash.hh
M	source/blender/blenlib/tests/BLI_map_test.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 632fff07575..8cc37a3e711 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -49,16 +49,6 @@ enum class GeometryOwnershipType {
   ReadOnly = 2,
 };
 
-/* Make it possible to use the component type as key in hash tables. */
-namespace blender {
-template<> struct DefaultHash<GeometryComponentType> {
-  uint64_t operator()(const GeometryComponentType &value) const
-  {
-    return (uint64_t)value;
-  }
-};
-}  // namespace blender
-
 namespace blender::bke {
 class ComponentAttributeProviders;
 }
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 2e3212cc83b..39695b110b1 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -88,11 +88,18 @@ 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.
+ *
+ * In the case of an enum type, the default hash is just to cast the enum value to an integer.
  */
 template<typename T> struct DefaultHash {
   uint64_t operator()(const T &value) const
   {
-    return value.hash();
+    if constexpr (std::is_enum_v<T>) {
+      return (uint64_t)value;
+    }
+    else {
+      return value.hash();
+    }
   }
 };
 
diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc
index 323ced87d9e..70c1887a527 100644
--- a/source/blender/blenlib/tests/BLI_map_test.cc
+++ b/source/blender/blenlib/tests/BLI_map_test.cc
@@ -565,6 +565,28 @@ TEST(map, AddOrModifyExceptions)
   EXPECT_ANY_THROW({ map.add_or_modify(3, create_fn, modify_fn); });
 }
 
+namespace {
+enum class TestEnum {
+  A = 0,
+  B = 1,
+  C = 2,
+  D = 1,
+};
+}
+
+TEST(map, EnumKey)
+{
+  Map<TestEnum, int> map;
+  map.add(TestEnum::A, 4);
+  map.add(TestEnum::B, 6);
+  EXPECT_EQ(map.lookup(TestEnum::A), 4);
+  EXPECT_EQ(map.lookup(TestEnum::B), 6);
+  EXPECT_EQ(map.lookup(TestEnum::D), 6);
+  EXPECT_FALSE(map.contains(TestEnum::C));
+  map.lookup(TestEnum::D) = 10;
+  EXPECT_EQ(map.lookup(TestEnum::B), 10);
+}
+
 /**
  * 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