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 1a998fe [gutil] update map-util to benefit from C++17
1a998fe is described below
commit 1a998fe71dcf174efd12244f4580111e29037bfc
Author: Alexey Serbin <[email protected]>
AuthorDate: Fri Feb 5 22:35:33 2021 -0800
[gutil] update map-util to benefit from C++17
This patch updates map-util to benefit from C++17 features such as
try_emplace() and insert_or_assign() for dictionary containers: see
[1], [2], [3], [4] for details. At least, with try_emplace() a new
element isn't ever constructed if the container already contains
an element with the specified key.
[1] https://en.cppreference.com/w/cpp/container/map/try_emplace
[2] https://en.cppreference.com/w/cpp/container/map/insert_or_assign
[3] https://en.cppreference.com/w/cpp/container/unordered_map/try_emplace
[4]
https://en.cppreference.com/w/cpp/container/unordered_map/insert_or_assign
Change-Id: I248c03e604855434ea3a0891c311461a455b428e
Reviewed-on: http://gerrit.cloudera.org:8080/17035
Reviewed-by: Bankim Bhavsar <[email protected]>
Tested-by: Kudu Jenkins
---
src/kudu/gutil/map-util.h | 59 ++++++++++++++++++++++++++++-------------------
1 file changed, 35 insertions(+), 24 deletions(-)
diff --git a/src/kudu/gutil/map-util.h b/src/kudu/gutil/map-util.h
index dc089b8..a0a5ea2 100644
--- a/src/kudu/gutil/map-util.h
+++ b/src/kudu/gutil/map-util.h
@@ -439,12 +439,30 @@ typename Collection::mapped_type& InsertKeyOrDie(
//
// Emplace*()
//
+
+// Dancing with std::enable_if() is necessary to make these two functions
+// below work for both dictionary-like and set-like containers as well.
+// The idea is that for dictionary-like containers Collection::value_type
+// is always pair<const key_type, mapped_type>, so it cannot be the same
+// as key type.
template <class Collection, class... Args>
-bool EmplaceIfNotPresent(Collection* const collection,
- Args&&... args) {
+typename std::enable_if<
+ std::is_same<typename Collection::key_type,
+ typename Collection::value_type>::value,
+ bool>::type
+EmplaceIfNotPresent(Collection* const collection, Args&&... args) {
return collection->emplace(std::forward<Args>(args)...).second;
}
+template <class Collection, class... Args>
+typename std::enable_if<
+ !std::is_same<typename Collection::key_type,
+ typename Collection::value_type>::value,
+ bool>::type
+EmplaceIfNotPresent(Collection* const collection, Args&&... args) {
+ return collection->try_emplace(std::forward<Args>(args)...).second;
+}
+
// Emplaces the given key-value pair into the collection. Returns true if the
// given key didn't previously exist. If the given key already existed in the
// map, its value is changed to the given "value" and false is returned.
@@ -452,22 +470,15 @@ template <class Collection>
bool EmplaceOrUpdate(Collection* const collection,
const typename Collection::key_type& key,
typename Collection::mapped_type&& value) {
- typedef typename Collection::mapped_type mapped_type;
- auto it = collection->find(key);
- if (it == collection->end()) {
- collection->emplace(key, std::forward<mapped_type>(value));
- return true;
- }
- it->second = std::forward<mapped_type>(value);
- return false;
+ return collection->insert_or_assign(
+ key, std::forward<typename Collection::mapped_type>(value)).second;
}
-// 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.
+// Given the key and parameters to construct the mapped object in-place,
+// EmplaceOrDie() returns reference to the mapped object for dictionary-like
+// containers or constant reference to the element itself for set-like ones.
+// See the comment for EmplaceIfNotPresent() for details behind the template
+// meta-programming details.
template <class Collection, class... Args>
typename std::enable_if<
std::is_same<typename Collection::key_type,
@@ -515,18 +526,18 @@ LookupOrInsert(Collection* const collection,
}
// It's similar to LookupOrInsert() but uses the emplace and r-value mechanics
-// to achieve the desired results. The constructor of the new element is called
-// with exactly the same arguments as supplied to emplace, forwarded via
-// std::forward<Args>(args). The element may be constructed even if there
-// already is an element with the same key in the container, in which case the
-// newly constructed element will be destroyed immediately.
+// to achieve the desired results, constructing the element in-place in the
+// container. The constructor of the new element is called with exactly the
same
+// arguments as supplied to emplace, forwarded via std::forward<Args>(args).
+// The element is constructed only if there was no element with the specified
+// key in the container.
// For details, see
-// https://en.cppreference.com/w/cpp/container/map/emplace
-// https://en.cppreference.com/w/cpp/container/unordered_map/emplace
+// https://en.cppreference.com/w/cpp/container/map/try_emplace
+// https://en.cppreference.com/w/cpp/container/unordered_map/try_emplace
template <class Collection, class... Args>
typename Collection::mapped_type&
LookupOrEmplace(Collection* const collection, Args&&... args) {
- return collection->emplace(std::forward<Args>(args)...).first->second;
+ return collection->try_emplace(std::forward<Args>(args)...).first->second;
}
// Counts the number of equivalent elements in the given "sequence", and stores