BLI: add Map.lookup_try method

This adds a new `Map.lookup_try` method that returns a `std::optional<Value>`
for a given key. If the key is not in the map, `std::nullopt` is returned. If it
is in the map, then a copy of the value is returned. Note that the copy is
necessary because `std::optional` can't contain reference types.

This method helps a lot in #132219 to reduce boilerplate.

Pull Request: https://projects.blender.org/blender/blender/pulls/132278
This commit is contained in:
Jacques Lucke
2024-12-23 17:03:32 +01:00
parent 80f5b3ad21
commit d2485239f8
2 changed files with 25 additions and 0 deletions

View File

@@ -523,6 +523,21 @@ class Map {
return const_cast<Value *>(const_cast<const Map *>(this)->lookup_ptr_as(key));
}
/**
* Returns a copy of the value that corresponds to the given key, or std::nullopt if the key is
* not in the map. In some cases, one may not want a copy but an actual reference to the value.
* In that case it's better to use #lookup_ptr instead.
*/
std::optional<Value> lookup_try(const Key &key) const
{
return this->lookup_try_as(key);
}
template<typename ForwardKey> std::optional<Value> lookup_try_as(const ForwardKey &key) const
{
const Slot *slot = this->lookup_slot_ptr(key, hash_(key));
return (slot != nullptr) ? std::optional<Value>(*slot->value()) : std::nullopt;
}
/**
* Returns a reference to the value that corresponds to the given key. This invokes undefined
* behavior when the key is not in the map.

View File

@@ -394,6 +394,16 @@ TEST(map, LookupOrAdd)
EXPECT_EQ(map.lookup(6), 14);
}
TEST(map, LookupTry)
{
Map<int, int> map;
map.add(1, 10);
map.add(2, 20);
EXPECT_EQ(map.lookup_try(1), 10);
EXPECT_EQ(map.lookup_try(2), 20);
EXPECT_EQ(map.lookup_try(3), std::nullopt);
}
TEST(map, MoveConstructorSmall)
{
Map<int, float> map1;