This is an automated email from the ASF dual-hosted git repository.

alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new d30dbd2  [gutil] EmplaceOrDie() to return reference
d30dbd2 is described below

commit d30dbd205fb7c59444a6adcdd670eefd048fb8b0
Author: Alexey Serbin <[email protected]>
AuthorDate: Fri Feb 5 21:34:16 2021 -0800

    [gutil] EmplaceOrDie() to return reference
    
    I found it's useful for EmplaceOrDie() to return a reference
    to the object that is constructed in-place in the container.
    
    To implement this change, I needed to use std::enable_if()
    dance because EmplaceOrDie() is already used in Kudu codebase
    for not only dictionary, but for set containers as well:
    that's so in src/kudu/ranger/ranger_client.cc at least.
    
    Change-Id: Ife1e07b7454078d3392555866fd32b89fac28af7
    Reviewed-on: http://gerrit.cloudera.org:8080/17034
    Tested-by: Alexey Serbin <[email protected]>
    Reviewed-by: Andrew Wong <[email protected]>
---
 src/kudu/gutil/map-util.h      | 32 ++++++++++++++++++++++++++------
 src/kudu/util/map-util-test.cc | 27 +++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/src/kudu/gutil/map-util.h b/src/kudu/gutil/map-util.h
index 985b91c..dc089b8 100644
--- a/src/kudu/gutil/map-util.h
+++ b/src/kudu/gutil/map-util.h
@@ -62,8 +62,7 @@
 #ifndef UTIL_GTL_MAP_UTIL_H_
 #define UTIL_GTL_MAP_UTIL_H_
 
-#include <stddef.h>
-
+#include <cstddef>
 #include <tuple>
 #include <utility>
 #include <vector>
@@ -463,11 +462,32 @@ bool EmplaceOrUpdate(Collection* const collection,
   return false;
 }
 
+// EmplaceOrDie() returns reference to the mapped object for map-like 
containers
+// or constant reference to the element itself for set-like containers given
+// the key and parameters to construct the mapped object in-place (the latter
+// is only for map-like containers).
+// Dancing with std::enable_if() is necessary to make it work for set-like
+// containers as well.
 template <class Collection, class... Args>
-void EmplaceOrDie(Collection* const collection,
-                  Args&&... args) {
-  CHECK(EmplaceIfNotPresent(collection, std::forward<Args>(args)...))
-      << "duplicate value";
+typename std::enable_if<
+    std::is_same<typename Collection::key_type,
+                 typename Collection::value_type>::value,
+    const typename Collection::value_type&>::type
+EmplaceOrDie(Collection* const collection, Args&&... args) {
+  auto res = collection->emplace(std::forward<Args>(args)...);
+  CHECK(res.second) << "duplicate value";
+  return *res.first;
+}
+
+template <class Collection, class... Args>
+typename std::enable_if<
+    !std::is_same<typename Collection::key_type,
+                  typename Collection::value_type>::value,
+    typename Collection::mapped_type&>::type
+EmplaceOrDie(Collection* const collection, Args&&... args) {
+  auto res = collection->emplace(std::forward<Args>(args)...);
+  CHECK(res.second) << "duplicate value";
+  return res.first->second;
 }
 
 //
diff --git a/src/kudu/util/map-util-test.cc b/src/kudu/util/map-util-test.cc
index 51b428e..65718ab 100644
--- a/src/kudu/util/map-util-test.cc
+++ b/src/kudu/util/map-util-test.cc
@@ -21,6 +21,7 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -33,6 +34,7 @@
 template <class X> struct GoodFastHash;
 
 using std::map;
+using std::set;
 using std::string;
 using std::shared_ptr;
 using std::unique_ptr;
@@ -218,4 +220,29 @@ TEST(LookupOrEmplaceTest, UniquePtrMap) {
   }
 }
 
+TEST(EmplaceOrDieTest, MapLikeContainer) {
+  constexpr int key = 0;
+  const string ref_value_0 = "turbo";
+  const string ref_value_1 = "giga";
+  map<int, string> int_to_string;
+
+  {
+    auto& mapped = EmplaceOrDie(&int_to_string, key, "turbo");
+    ASSERT_EQ(ref_value_0, mapped);
+    mapped = "giga";
+  }
+  {
+    const auto& mapped = FindOrDie(int_to_string, key);
+    ASSERT_EQ(ref_value_1, mapped);
+  }
+}
+
+TEST(EmplaceOrDieTest, SetLikeContainer) {
+  const string ref_str = "turbo";
+  set<string> strings;
+
+  auto& value = EmplaceOrDie(&strings, "turbo");
+  ASSERT_EQ(ref_str, value);
+}
+
 } // namespace kudu

Reply via email to