aboutsummaryrefslogtreecommitdiff
path: root/absl/container/btree_map.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/btree_map.h')
-rw-r--r--absl/container/btree_map.h153
1 files changed, 118 insertions, 35 deletions
diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h
index ea49d446..286817f1 100644
--- a/absl/container/btree_map.h
+++ b/absl/container/btree_map.h
@@ -35,14 +35,17 @@
//
// However, these types should not be considered drop-in replacements for
// `std::map` and `std::multimap` as there are some API differences, which are
-// noted in this header file.
+// noted in this header file. The most consequential differences with respect to
+// migrating to b-tree from the STL types are listed in the next paragraph.
+// Other API differences are minor.
//
// Importantly, insertions and deletions may invalidate outstanding iterators,
// pointers, and references to elements. Such invalidations are typically only
// an issue if insertion and deletion operations are interleaved with the use of
// more than one iterator, pointer, or reference simultaneously. For this
// reason, `insert()` and `erase()` return a valid iterator at the current
-// position.
+// position. Another important difference is that key-types must be
+// copy-constructible.
#ifndef ABSL_CONTAINER_BTREE_MAP_H_
#define ABSL_CONTAINER_BTREE_MAP_H_
@@ -53,6 +56,14 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+namespace container_internal {
+
+template <typename Key, typename Data, typename Compare, typename Alloc,
+ int TargetNodeSize, bool IsMulti>
+struct map_params;
+
+} // namespace container_internal
+
// absl::btree_map<>
//
// An `absl::btree_map<K, V>` is an ordered associative container of
@@ -74,7 +85,7 @@ class btree_map
: public container_internal::btree_map_container<
container_internal::btree<container_internal::map_params<
Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
- /*Multi=*/false>>> {
+ /*IsMulti=*/false>>> {
using Base = typename btree_map::btree_map_container;
public:
@@ -366,8 +377,8 @@ class btree_map
// Determines whether an element comparing equal to the given `key` exists
// within the `btree_map`, returning `true` if so or `false` otherwise.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::contains;
// btree_map::count()
@@ -378,8 +389,8 @@ class btree_map
// the `btree_map`. Note that this function will return either `1` or `0`
// since duplicate elements are not allowed within a `btree_map`.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::count;
// btree_map::equal_range()
@@ -395,10 +406,34 @@ class btree_map
//
// Finds an element with the passed `key` within the `btree_map`.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::find;
+ // btree_map::lower_bound()
+ //
+ // template <typename K> iterator lower_bound(const K& key):
+ // template <typename K> const_iterator lower_bound(const K& key) const:
+ //
+ // Finds the first element with a key that is not less than `key` within the
+ // `btree_map`.
+ //
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
+ using Base::lower_bound;
+
+ // btree_map::upper_bound()
+ //
+ // template <typename K> iterator upper_bound(const K& key):
+ // template <typename K> const_iterator upper_bound(const K& key) const:
+ //
+ // Finds the first element with a key that is greater than `key` within the
+ // `btree_map`.
+ //
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
+ using Base::upper_bound;
+
// btree_map::operator[]()
//
// Returns a reference to the value mapped to the passed key within the
@@ -443,15 +478,11 @@ void swap(btree_map<K, V, C, A> &x, btree_map<K, V, C, A> &y) {
// absl::erase_if(absl::btree_map<>, Pred)
//
// Erases all elements that satisfy the predicate pred from the container.
+// Returns the number of erased elements.
template <typename K, typename V, typename C, typename A, typename Pred>
-void erase_if(btree_map<K, V, C, A> &map, Pred pred) {
- for (auto it = map.begin(); it != map.end();) {
- if (pred(*it)) {
- it = map.erase(it);
- } else {
- ++it;
- }
- }
+typename btree_map<K, V, C, A>::size_type erase_if(
+ btree_map<K, V, C, A> &map, Pred pred) {
+ return container_internal::btree_access::erase_if(map, std::move(pred));
}
// absl::btree_multimap
@@ -476,7 +507,7 @@ class btree_multimap
: public container_internal::btree_multimap_container<
container_internal::btree<container_internal::map_params<
Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
- /*Multi=*/true>>> {
+ /*IsMulti=*/true>>> {
using Base = typename btree_multimap::btree_multimap_container;
public:
@@ -669,9 +700,8 @@ class btree_multimap
// btree_multimap::merge()
//
- // Extracts elements from a given `source` btree_multimap into this
- // `btree_multimap`. If the destination `btree_multimap` already contains an
- // element with an equivalent key, that element is not extracted.
+ // Extracts all elements from a given `source` btree_multimap into this
+ // `btree_multimap`.
using Base::merge;
// btree_multimap::swap(btree_multimap& other)
@@ -691,8 +721,8 @@ class btree_multimap
// Determines whether an element comparing equal to the given `key` exists
// within the `btree_multimap`, returning `true` if so or `false` otherwise.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::contains;
// btree_multimap::count()
@@ -702,8 +732,8 @@ class btree_multimap
// Returns the number of elements comparing equal to the given `key` within
// the `btree_multimap`.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::count;
// btree_multimap::equal_range()
@@ -720,10 +750,34 @@ class btree_multimap
//
// Finds an element with the passed `key` within the `btree_multimap`.
//
- // Supports heterogeneous lookup, provided that the map is provided a
- // compatible heterogeneous comparator.
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
using Base::find;
+ // btree_multimap::lower_bound()
+ //
+ // template <typename K> iterator lower_bound(const K& key):
+ // template <typename K> const_iterator lower_bound(const K& key) const:
+ //
+ // Finds the first element with a key that is not less than `key` within the
+ // `btree_multimap`.
+ //
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
+ using Base::lower_bound;
+
+ // btree_multimap::upper_bound()
+ //
+ // template <typename K> iterator upper_bound(const K& key):
+ // template <typename K> const_iterator upper_bound(const K& key) const:
+ //
+ // Finds the first element with a key that is greater than `key` within the
+ // `btree_multimap`.
+ //
+ // Supports heterogeneous lookup, provided that the map has a compatible
+ // heterogeneous comparator.
+ using Base::upper_bound;
+
// btree_multimap::get_allocator()
//
// Returns the allocator function associated with this `btree_multimap`.
@@ -751,17 +805,46 @@ void swap(btree_multimap<K, V, C, A> &x, btree_multimap<K, V, C, A> &y) {
// absl::erase_if(absl::btree_multimap<>, Pred)
//
// Erases all elements that satisfy the predicate pred from the container.
+// Returns the number of erased elements.
template <typename K, typename V, typename C, typename A, typename Pred>
-void erase_if(btree_multimap<K, V, C, A> &map, Pred pred) {
- for (auto it = map.begin(); it != map.end();) {
- if (pred(*it)) {
- it = map.erase(it);
- } else {
- ++it;
- }
- }
+typename btree_multimap<K, V, C, A>::size_type erase_if(
+ btree_multimap<K, V, C, A> &map, Pred pred) {
+ return container_internal::btree_access::erase_if(map, std::move(pred));
}
+namespace container_internal {
+
+// A parameters structure for holding the type parameters for a btree_map.
+// Compare and Alloc should be nothrow copy-constructible.
+template <typename Key, typename Data, typename Compare, typename Alloc,
+ int TargetNodeSize, bool IsMulti>
+struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, IsMulti,
+ /*IsMap=*/true, map_slot_policy<Key, Data>> {
+ using super_type = typename map_params::common_params;
+ using mapped_type = Data;
+ // This type allows us to move keys when it is safe to do so. It is safe
+ // for maps in which value_type and mutable_value_type are layout compatible.
+ using slot_policy = typename super_type::slot_policy;
+ using slot_type = typename super_type::slot_type;
+ using value_type = typename super_type::value_type;
+ using init_type = typename super_type::init_type;
+
+ template <typename V>
+ static auto key(const V &value) -> decltype(value.first) {
+ return value.first;
+ }
+ static const Key &key(const slot_type *s) { return slot_policy::key(s); }
+ static const Key &key(slot_type *s) { return slot_policy::key(s); }
+ // For use in node handle.
+ static auto mutable_key(slot_type *s)
+ -> decltype(slot_policy::mutable_key(s)) {
+ return slot_policy::mutable_key(s);
+ }
+ static mapped_type &value(value_type *value) { return value->second; }
+};
+
+} // namespace container_internal
+
ABSL_NAMESPACE_END
} // namespace absl