summaryrefslogtreecommitdiff
path: root/absl/container
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2022-02-23 06:56:15 -0800
committerGravatar rogeeff <rogeeff@google.com>2022-02-23 10:24:01 -0500
commit0ad7994f10624cd1538b1287e56cae5ac9c0cb40 (patch)
tree2b8d698744e29cacfa524aee77930f69a27794e3 /absl/container
parent808bc202fc13e85a7948db0d7fb58f0f051200b1 (diff)
Export of internal Abseil changes
-- 91d76b3ac9edff91f206d9eee60423c39eeeaf93 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 430442277 -- 9f8a87bcc5cc5b0fd8b7f0318f37d152fd8bea06 by Evan Brown <ezb@google.com>: Small refactoring to work towards allowing for node_btree_* containers. - Change common_params::transfer to rely on slot_policy transfer instead of manually doing construct/destruct. Transfer is not construct/destruct for node containers. - Move maps' value_compare into btree.h from btree_map.h so it can be reused for node_btree_map.h. - Also add a test for maps' value_compare protected members. PiperOrigin-RevId: 430245542 -- 0126e0b6295342317d9c9f0a66e2d7009b858426 by Martijn Vels <mvels@google.com>: Add CordRepSubString::Create function with hard checks on IsFlat() | IsExternal() This hardens internal invariants, IsFlat() || IsExternal() is a cheap, single predicted branch, and removes boilerplate code from cord.cc PiperOrigin-RevId: 429676041 -- ed98a92af49d9e238d9f1d1b69fb4eddcd1ccbc7 by Abseil Team <absl-team@google.com>: tweaks to status.h documentation to reflect general-purpose communication PiperOrigin-RevId: 429584104 GitOrigin-RevId: 91d76b3ac9edff91f206d9eee60423c39eeeaf93 Change-Id: I54d6d116a564f86a842b983ca76559bf9b388f72
Diffstat (limited to 'absl/container')
-rw-r--r--absl/container/btree_map.h31
-rw-r--r--absl/container/btree_set.h21
-rw-r--r--absl/container/btree_test.cc16
-rw-r--r--absl/container/internal/btree.h36
4 files changed, 64 insertions, 40 deletions
diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h
index ad484ce0..286817f1 100644
--- a/absl/container/btree_map.h
+++ b/absl/container/btree_map.h
@@ -59,7 +59,7 @@ ABSL_NAMESPACE_BEGIN
namespace container_internal {
template <typename Key, typename Data, typename Compare, typename Alloc,
- int TargetNodeSize, bool Multi>
+ int TargetNodeSize, bool IsMulti>
struct map_params;
} // namespace container_internal
@@ -85,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:
@@ -507,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:
@@ -817,9 +817,9 @@ 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 Multi>
-struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
- map_slot_policy<Key, Data>> {
+ 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
@@ -829,25 +829,6 @@ struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
using value_type = typename super_type::value_type;
using init_type = typename super_type::init_type;
- using original_key_compare = typename super_type::original_key_compare;
- // Reference: https://en.cppreference.com/w/cpp/container/map/value_compare
- class value_compare {
- template <typename Params>
- friend class btree;
-
- protected:
- explicit value_compare(original_key_compare c) : comp(std::move(c)) {}
-
- original_key_compare comp; // NOLINT
-
- public:
- auto operator()(const value_type &lhs, const value_type &rhs) const
- -> decltype(comp(lhs.first, rhs.first)) {
- return comp(lhs.first, rhs.first);
- }
- };
- using is_map_container = std::true_type;
-
template <typename V>
static auto key(const V &value) -> decltype(value.first) {
return value.first;
diff --git a/absl/container/btree_set.h b/absl/container/btree_set.h
index 78826830..7b6655ad 100644
--- a/absl/container/btree_set.h
+++ b/absl/container/btree_set.h
@@ -61,7 +61,7 @@ template <typename Key>
struct set_slot_policy;
template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
- bool Multi>
+ bool IsMulti>
struct set_params;
} // namespace container_internal
@@ -87,7 +87,7 @@ class btree_set
: public container_internal::btree_set_container<
container_internal::btree<container_internal::set_params<
Key, Compare, Alloc, /*TargetNodeSize=*/256,
- /*Multi=*/false>>> {
+ /*IsMulti=*/false>>> {
using Base = typename btree_set::btree_set_container;
public:
@@ -427,7 +427,7 @@ class btree_multiset
: public container_internal::btree_multiset_container<
container_internal::btree<container_internal::set_params<
Key, Compare, Alloc, /*TargetNodeSize=*/256,
- /*Multi=*/true>>> {
+ /*IsMulti=*/true>>> {
using Base = typename btree_multiset::btree_multiset_container;
public:
@@ -757,6 +757,12 @@ struct set_slot_policy {
}
template <typename Alloc>
+ static void transfer(Alloc *alloc, slot_type *new_slot, slot_type *old_slot) {
+ construct(alloc, new_slot, old_slot);
+ destroy(alloc, old_slot);
+ }
+
+ template <typename Alloc>
static void swap(Alloc * /*alloc*/, slot_type *a, slot_type *b) {
using std::swap;
swap(*a, *b);
@@ -771,14 +777,11 @@ struct set_slot_policy {
// A parameters structure for holding the type parameters for a btree_set.
// Compare and Alloc should be nothrow copy-constructible.
template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
- bool Multi>
-struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
- set_slot_policy<Key>> {
+ bool IsMulti>
+struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, IsMulti,
+ /*IsMap=*/false, set_slot_policy<Key>> {
using value_type = Key;
using slot_type = typename set_params::common_params::slot_type;
- using value_compare =
- typename set_params::common_params::original_key_compare;
- using is_map_container = std::false_type;
template <typename V>
static const V &key(const V &value) {
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index e829e0ba..4d4c64b2 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -1762,6 +1762,22 @@ TEST(Btree, ValueComp) {
EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)));
}
+// Test that we have the protected members from the std::map::value_compare API.
+// See https://en.cppreference.com/w/cpp/container/map/value_compare.
+TEST(Btree, MapValueCompProtected) {
+ struct key_compare {
+ bool operator()(int l, int r) const { return l < r; }
+ int id;
+ };
+ using value_compare = absl::btree_map<int, int, key_compare>::value_compare;
+ struct value_comp_child : public value_compare {
+ explicit value_comp_child(key_compare kc) : value_compare(kc) {}
+ int GetId() const { return comp.id; }
+ };
+ value_comp_child c(key_compare{10});
+ EXPECT_EQ(c.GetId(), 10);
+}
+
TEST(Btree, DefaultConstruction) {
absl::btree_set<int> s;
absl::btree_map<int, int> m;
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h
index 6c10b00f..a22c9bd7 100644
--- a/absl/container/internal/btree.h
+++ b/absl/container/internal/btree.h
@@ -335,8 +335,27 @@ constexpr bool compare_has_valid_result_type() {
std::is_convertible<compare_result_type, absl::weak_ordering>::value;
}
+template <typename original_key_compare, typename value_type>
+class map_value_compare {
+ template <typename Params>
+ friend class btree;
+
+ // Note: this `protected` is part of the API of std::map::value_compare. See
+ // https://en.cppreference.com/w/cpp/container/map/value_compare.
+ protected:
+ explicit map_value_compare(original_key_compare c) : comp(std::move(c)) {}
+
+ original_key_compare comp; // NOLINT
+
+ public:
+ auto operator()(const value_type &lhs, const value_type &rhs) const
+ -> decltype(comp(lhs.first, rhs.first)) {
+ return comp(lhs.first, rhs.first);
+ }
+};
+
template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
- bool Multi, typename SlotPolicy>
+ bool IsMulti, bool IsMap, typename SlotPolicy>
struct common_params {
using original_key_compare = Compare;
@@ -384,6 +403,12 @@ struct common_params {
using reference = value_type &;
using const_reference = const value_type &;
+ using value_compare =
+ absl::conditional_t<IsMap,
+ map_value_compare<original_key_compare, value_type>,
+ original_key_compare>;
+ using is_map_container = std::integral_constant<bool, IsMap>;
+
// For the given lookup key type, returns whether we can have multiple
// equivalent keys in the btree. If this is a multi-container, then we can.
// Otherwise, we can have multiple equivalent keys only if all of the
@@ -394,9 +419,9 @@ struct common_params {
// that we know has the same equivalence classes for all lookup types.
template <typename LookupKey>
constexpr static bool can_have_multiple_equivalent_keys() {
- return Multi || (IsTransparent<key_compare>::value &&
- !std::is_same<LookupKey, Key>::value &&
- !kIsKeyCompareStringAdapted);
+ return IsMulti || (IsTransparent<key_compare>::value &&
+ !std::is_same<LookupKey, Key>::value &&
+ !kIsKeyCompareStringAdapted);
}
enum {
@@ -435,8 +460,7 @@ struct common_params {
slot_policy::destroy(alloc, slot);
}
static void transfer(Alloc *alloc, slot_type *new_slot, slot_type *old_slot) {
- construct(alloc, new_slot, old_slot);
- destroy(alloc, old_slot);
+ slot_policy::transfer(alloc, new_slot, old_slot);
}
static void swap(Alloc *alloc, slot_type *a, slot_type *b) {
slot_policy::swap(alloc, a, b);