[Bf-blender-cvs] [474b2889339] master: BLI: add Map.pop_default method

Jacques Lucke noreply at git.blender.org
Wed Jun 10 19:03:25 CEST 2020


Commit: 474b2889339e24e602a7498c30ed07e2c47e6982
Author: Jacques Lucke
Date:   Wed Jun 10 19:02:28 2020 +0200
Branches: master
https://developer.blender.org/rB474b2889339e24e602a7498c30ed07e2c47e6982

BLI: add Map.pop_default method

There is a nice use case for this in depsgraph code.

Also I added some previously missing calls to std::move.

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

M	source/blender/blenlib/BLI_map.hh
M	tests/gtests/blenlib/BLI_map_test.cc

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

diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 13f1a967d65..9737367ebca 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -405,6 +405,28 @@ class Map {
     return this->pop_try__impl(key, m_hash(key));
   }
 
+  /**
+   * Get the value that corresponds to the given key and remove it from the map. If the key is not
+   * in the map, return the given default value instead.
+   */
+  Value pop_default(const Key &key, const Value &default_value)
+  {
+    return this->pop_default_as(key, default_value);
+  }
+  Value pop_default(const Key &key, Value &&default_value)
+  {
+    return this->pop_default_as(key, std::move(default_value));
+  }
+
+  /**
+   * Same as `pop_default`, but accepts other key types that are supported by the hash function.
+   */
+  template<typename ForwardKey, typename ForwardValue>
+  Value pop_default_as(const ForwardKey &key, ForwardValue &&default_value)
+  {
+    return this->pop_default__impl(key, std::forward<ForwardValue>(default_value), m_hash(key));
+  }
+
   /**
    * This method can be used to implement more complex custom behavior without having to do
    * multiple lookups
@@ -1039,7 +1061,7 @@ class Map {
 
     MAP_SLOT_PROBING_BEGIN (hash, slot) {
       if (slot.contains(key, m_is_equal, hash)) {
-        Value value = *slot.value();
+        Value value = std::move(*slot.value());
         slot.remove();
         return value;
       }
@@ -1051,7 +1073,7 @@ class Map {
   {
     MAP_SLOT_PROBING_BEGIN (hash, slot) {
       if (slot.contains(key, m_is_equal, hash)) {
-        Optional<Value> value = *slot.value();
+        Optional<Value> value = std::move(*slot.value());
         slot.remove();
         m_removed_slots++;
         return value;
@@ -1063,6 +1085,23 @@ class Map {
     MAP_SLOT_PROBING_END();
   }
 
+  template<typename ForwardKey, typename ForwardValue>
+  Value pop_default__impl(const ForwardKey &key, ForwardValue &&default_value, uint32_t hash)
+  {
+    MAP_SLOT_PROBING_BEGIN (hash, slot) {
+      if (slot.contains(key, m_is_equal, hash)) {
+        Value value = std::move(*slot.value());
+        slot.remove();
+        m_removed_slots++;
+        return value;
+      }
+      if (slot.is_empty()) {
+        return std::forward<ForwardValue>(default_value);
+      }
+    }
+    MAP_SLOT_PROBING_END();
+  }
+
   template<typename ForwardKey, typename CreateValueF, typename ModifyValueF>
   auto add_or_modify__impl(ForwardKey &&key,
                            const CreateValueF &create_value,
diff --git a/tests/gtests/blenlib/BLI_map_test.cc b/tests/gtests/blenlib/BLI_map_test.cc
index aa064e2f427..b14ba40ed7c 100644
--- a/tests/gtests/blenlib/BLI_map_test.cc
+++ b/tests/gtests/blenlib/BLI_map_test.cc
@@ -99,6 +99,25 @@ TEST(map, PopTry)
   EXPECT_EQ(map.size(), 0);
 }
 
+TEST(map, PopDefault)
+{
+  Map<int, int> map;
+  map.add(1, 4);
+  map.add(2, 7);
+  map.add(3, 8);
+  EXPECT_EQ(map.size(), 3);
+  EXPECT_EQ(map.pop_default(4, 10), 10);
+  EXPECT_EQ(map.size(), 3);
+  EXPECT_EQ(map.pop_default(1, 10), 4);
+  EXPECT_EQ(map.size(), 2);
+  EXPECT_EQ(map.pop_default(2, 20), 7);
+  EXPECT_EQ(map.size(), 1);
+  EXPECT_EQ(map.pop_default(2, 20), 20);
+  EXPECT_EQ(map.size(), 1);
+  EXPECT_EQ(map.pop_default(3, 0), 8);
+  EXPECT_EQ(map.size(), 0);
+}
+
 TEST(map, PopItemMany)
 {
   Map<int, int> map;
@@ -373,6 +392,7 @@ TEST(map, UniquePtrValue)
   map.add(6, std::unique_ptr<int>(new int()));
   map.add_overwrite(7, std::unique_ptr<int>(new int()));
   map.lookup_or_add(8, std::unique_ptr<int>(new int()));
+  map.pop_default(9, std::unique_ptr<int>(new int()));
 
   EXPECT_EQ(map.lookup(1).get(), value1_ptr);
   EXPECT_EQ(map.lookup_ptr(100), nullptr);



More information about the Bf-blender-cvs mailing list