BLI: provide a default hash for enums
This avoids some boilerplate code that was necessary when using enums as keys in maps or sets.
This commit is contained in:
@@ -49,16 +49,6 @@ enum class GeometryOwnershipType {
|
|||||||
ReadOnly = 2,
|
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 {
|
namespace blender::bke {
|
||||||
class ComponentAttributeProviders;
|
class ComponentAttributeProviders;
|
||||||
}
|
}
|
||||||
|
@@ -88,11 +88,18 @@ namespace blender {
|
|||||||
* If there is no other specialization of #DefaultHash for a given type, try to call `hash()` on
|
* 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
|
* 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.
|
* 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 {
|
template<typename T> struct DefaultHash {
|
||||||
uint64_t operator()(const T &value) const
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -565,6 +565,28 @@ TEST(map, AddOrModifyExceptions)
|
|||||||
EXPECT_ANY_THROW({ map.add_or_modify(3, create_fn, modify_fn); });
|
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.
|
* Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user