Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(831)

Unified Diff: base/containers/flat_tree.h

Issue 2944523002: Improving flat containers interface. (Closed)
Patch Set: Review, round 2. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/containers/flat_tree.h
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h
index afbbf95c4fdda48db3065cb86c202c9ef169e1f6..050d6185f6a88b1d4b262c653736d97e90f40710 100644
--- a/base/containers/flat_tree.h
+++ b/base/containers/flat_tree.h
@@ -9,6 +9,8 @@
#include <iterator>
#include <vector>
+#include "base/template_util.h"
+
namespace base {
enum FlatContainerDupes {
@@ -55,6 +57,18 @@ Iterator LastUnique(Iterator first, Iterator last, BinaryPredicate compare) {
return replacable;
}
+// Concepts -------------------------------------------------------------------
+
+template <typename Y>
vmpstr 2017/06/23 21:45:14 T?
dyaroshev 2017/06/26 11:47:29 Not applicable.
+using HasIsTransparentMember = typename Y::is_transparent;
+
+template <typename T>
+constexpr bool TransparentCompare() {
+ return is_detected_c<HasIsTransparentMember, T>();
+}
+
+// Implementation -------------------------------------------------------------
+
// Implementation of a sorted vector for backing flat_set and flat_map. Do not
// use directly.
//
@@ -234,9 +248,11 @@ class flat_tree {
// Prefer base::EraseIf() or some other variation on erase(remove(), end())
// idiom when deleting multiple non-consecutive elements.
+ iterator erase(iterator position);
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
- size_type erase(const key_type& key);
+ template <typename K>
+ size_type erase(const K& key);
// --------------------------------------------------------------------------
// Comparators.
@@ -249,20 +265,32 @@ class flat_tree {
//
// Search operations have O(log(size)) complexity.
- size_type count(const key_type& key) const;
+ template <typename K>
+ size_type count(const K& key) const;
+
+ template <typename K>
+ iterator find(const K& key);
- iterator find(const key_type& key);
- const_iterator find(const key_type& key) const;
+ template <typename K>
+ const_iterator find(const K& key) const;
- std::pair<iterator, iterator> equal_range(const key_type& ket);
- std::pair<const_iterator, const_iterator> equal_range(
- const key_type& key) const;
+ template <typename K>
+ std::pair<iterator, iterator> equal_range(const K& key);
- iterator lower_bound(const key_type& key);
- const_iterator lower_bound(const key_type& key) const;
+ template <typename K>
+ std::pair<const_iterator, const_iterator> equal_range(const K& key) const;
- iterator upper_bound(const key_type& key);
- const_iterator upper_bound(const key_type& key) const;
+ template <typename K>
+ iterator lower_bound(const K& key);
+
+ template <typename K>
+ const_iterator lower_bound(const K& key) const;
+
+ template <typename K>
+ iterator upper_bound(const K& key);
+
+ template <typename K>
+ const_iterator upper_bound(const K& key) const;
// --------------------------------------------------------------------------
// General operations.
@@ -317,12 +345,22 @@ class flat_tree {
explicit KeyValueCompare(const key_compare& key_comp)
: key_comp_(key_comp) {}
- bool operator()(const value_type& left, const key_type& right) const {
- GetKeyFromValue extractor;
- return key_comp_(extractor(left), right);
+ template <typename T, typename U>
+ bool operator()(const T& lhs, const U& rhs) const {
+ return key_comp_(extract_if_value_type(lhs), extract_if_value_type(rhs));
}
private:
+ const key_type& extract_if_value_type(const value_type& v) const {
+ GetKeyFromValue extractor;
+ return extractor(v);
+ }
+
+ template <typename K>
+ const K& extract_if_value_type(const K& k) const {
+ return k;
+ }
+
const key_compare& key_comp_;
};
@@ -767,14 +805,21 @@ auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::emplace_hint(
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase(
+ iterator position) -> iterator {
+ return impl_.body_.erase(position);
+}
+
+template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase(
const_iterator position) -> iterator {
// We have to cast away const because of crbug.com/677044.
- return impl_.body_.erase(const_cast_it(position));
+ return erase(const_cast_it(position));
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
-auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase(
- const key_type& val) -> size_type {
+template <typename K>
+auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase(const K& val)
+ -> size_type {
auto eq_range = equal_range(val);
auto res = std::distance(eq_range.first, eq_range.second);
// We have to cast away const because of crbug.com/677044.
@@ -809,35 +854,40 @@ auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::value_comp() const
// Search operations.
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::count(
- const key_type& key) const -> size_type {
+ const K& key) const -> size_type {
auto eq_range = equal_range(key);
return std::distance(eq_range.first, eq_range.second);
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
-auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find(
- const key_type& key) -> iterator {
+template <typename K>
+auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find(const K& key)
+ -> iterator {
return const_cast_it(as_const().find(key));
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find(
- const key_type& key) const -> const_iterator {
+ const K& key) const -> const_iterator {
auto eq_range = equal_range(key);
return (eq_range.first == eq_range.second) ? end() : eq_range.first;
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range(
- const key_type& key) -> std::pair<iterator, iterator> {
+ const K& key) -> std::pair<iterator, iterator> {
auto res = as_const().equal_range(key);
return {const_cast_it(res.first), const_cast_it(res.second)};
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range(
- const key_type& key) const -> std::pair<const_iterator, const_iterator> {
+ const K& key) const -> std::pair<const_iterator, const_iterator> {
auto lower = lower_bound(key);
GetKeyFromValue extractor;
@@ -848,29 +898,41 @@ auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range(
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound(
- const key_type& key) -> iterator {
+ const K& key) -> iterator {
return const_cast_it(as_const().lower_bound(key));
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound(
- const key_type& key) const -> const_iterator {
+ const K& key) const -> const_iterator {
+ // If the compare is not transparent -> construct key_type once.
+ conditional_t<TransparentCompare<key_compare>(), const K&, const key_type&>
vmpstr 2017/06/23 21:45:14 I think just const std::conditional<TransparentCom
dyaroshev 2017/06/26 11:47:29 You forgot "typename". Anyways, not applicable any
+ key_ref = key; // Only compile when conversion is implicit.
+
KeyValueCompare key_value(impl_.get_key_comp());
- return std::lower_bound(begin(), end(), key, key_value);
+ return std::lower_bound(begin(), end(), key_ref, key_value);
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound(
- const key_type& key) -> iterator {
+ const K& key) -> iterator {
return const_cast_it(as_const().upper_bound(key));
}
template <class Key, class Value, class GetKeyFromValue, class KeyCompare>
+template <typename K>
auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound(
- const key_type& key) const -> const_iterator {
+ const K& key) const -> const_iterator {
KeyValueCompare key_value(impl_.get_key_comp());
- return std::upper_bound(begin(), end(), key, key_value);
+
+ // If the compare is not transparent -> construct key_type once.
+ conditional_t<TransparentCompare<key_compare>(), const K&, const key_type&>
+ key_ref = key; // Only compile when conversion is implicit.
+ return std::upper_bound(begin(), end(), key_ref, key_value);
}
// ----------------------------------------------------------------------------

Powered by Google App Engine
This is Rietveld 408576698