[Bf-blender-cvs] [d8d6f2a521a] functions: smallmap: lookup or insert using callback
Jacques Lucke
noreply at git.blender.org
Mon May 20 11:20:01 CEST 2019
Commit: d8d6f2a521a3da974658f3aa9ccac5bce5fa97b5
Author: Jacques Lucke
Date: Mon May 20 10:55:15 2019 +0200
Branches: functions
https://developer.blender.org/rBd8d6f2a521a3da974658f3aa9ccac5bce5fa97b5
smallmap: lookup or insert using callback
===================================================================
M source/blender/blenlib/BLI_small_map.hpp
M tests/gtests/blenlib/BLI_small_map_test.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_small_map.hpp b/source/blender/blenlib/BLI_small_map.hpp
index 6a10250f406..cfe275376f3 100644
--- a/source/blender/blenlib/BLI_small_map.hpp
+++ b/source/blender/blenlib/BLI_small_map.hpp
@@ -121,6 +121,17 @@ template<typename K, typename V, uint N = 4> class SmallMap {
return this->lookup_ptr(key);
}
+ template<typename... Args>
+ V &lookup_ref_or_insert_func(const K &key, V (*create_value)(Args... args), Args &&... args)
+ {
+ V *value = this->lookup_ptr(key);
+ if (value != NULL) {
+ return *value;
+ }
+ this->add_new(key, create_value(std::forward<Args>(args)...));
+ return this->lookup_ref(key);
+ }
+
uint size() const
{
return m_entries.size();
diff --git a/tests/gtests/blenlib/BLI_small_map_test.cc b/tests/gtests/blenlib/BLI_small_map_test.cc
index fdc3c826b75..f11ac8260ca 100644
--- a/tests/gtests/blenlib/BLI_small_map_test.cc
+++ b/tests/gtests/blenlib/BLI_small_map_test.cc
@@ -164,3 +164,64 @@ TEST(small_map, ItemIterator)
EXPECT_TRUE(values.contains(9.0f));
EXPECT_TRUE(values.contains(0.0f));
}
+
+float return_42()
+{
+ return 42.0f;
+}
+
+TEST(small_map, LookupOrInsertFunc_NoArgs)
+{
+ IntFloatMap map;
+ EXPECT_EQ(map.lookup_ref_or_insert_func(0, return_42), 42.0f);
+ EXPECT_EQ(map.lookup(0), 42);
+}
+
+float return_identity(float a)
+{
+ return a;
+}
+
+TEST(small_map, LookupOrInsertFunc_SingleArg)
+{
+ IntFloatMap map;
+ EXPECT_EQ(map.lookup_ref_or_insert_func(1, return_identity, 5.0f), 5.0f);
+ EXPECT_EQ(map.lookup(1), 5.0f);
+}
+
+float add_func(float a, float b)
+{
+ return a + b;
+}
+
+TEST(small_map, LookupOrInsertFunc_TwoArgs)
+{
+ IntFloatMap map;
+ EXPECT_EQ(map.lookup_ref_or_insert_func(2, add_func, 4.0f, 6.0f), 10.0f);
+ EXPECT_EQ(map.lookup(2), 10.0f);
+}
+
+TEST(small_map, LookupOrInsertFunc_NoReinsert)
+{
+ IntFloatMap map;
+ EXPECT_EQ(map.lookup_ref_or_insert_func(2, return_identity, 4.0f), 4.0f);
+ EXPECT_EQ(map.lookup_ref_or_insert_func(2, return_identity, 6.0f), 4.0f);
+ EXPECT_EQ(map.lookup_ref_or_insert_func(2, return_identity, 8.0f), 4.0f);
+ EXPECT_EQ(map.size(), 1);
+}
+
+float inc_value_and_return_42(int *ptr)
+{
+ *ptr += 1;
+ return 42.0f;
+}
+
+TEST(small_map, LookupOrInsertFunc_FuncCalledOnce)
+{
+ int counter = 0;
+ IntFloatMap map;
+ EXPECT_EQ(map.lookup_ref_or_insert_func(0, inc_value_and_return_42, &counter), 42.0f);
+ EXPECT_EQ(counter, 1);
+ EXPECT_EQ(map.lookup_ref_or_insert_func(0, inc_value_and_return_42, &counter), 42.0f);
+ EXPECT_EQ(counter, 1);
+}
More information about the Bf-blender-cvs
mailing list