diff options
author | Jacques Lucke <jacques@blender.org> | 2021-03-17 13:37:46 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-03-17 13:37:46 +0300 |
commit | ac60e6474569a69ffa4b9c28f9ae79ef674c5408 (patch) | |
tree | 8c721e4f9cb58ea03b3b17fe0063f8ba1cdec112 /source/blender/blenlib | |
parent | e00a47ffd611b0ab06dba2a4933ab15871d576e6 (diff) |
BLI: provide a default hash for enums
This avoids some boilerplate code that was necessary when using enums
as keys in maps or sets.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_hash.hh | 9 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_map_test.cc | 22 |
2 files changed, 30 insertions, 1 deletions
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. */ |