diff options
author | Abseil Team <absl-team@google.com> | 2022-02-23 06:56:15 -0800 |
---|---|---|
committer | rogeeff <rogeeff@google.com> | 2022-02-23 10:24:01 -0500 |
commit | 0ad7994f10624cd1538b1287e56cae5ac9c0cb40 (patch) | |
tree | 2b8d698744e29cacfa524aee77930f69a27794e3 /absl/container | |
parent | 808bc202fc13e85a7948db0d7fb58f0f051200b1 (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.h | 31 | ||||
-rw-r--r-- | absl/container/btree_set.h | 21 | ||||
-rw-r--r-- | absl/container/btree_test.cc | 16 | ||||
-rw-r--r-- | absl/container/internal/btree.h | 36 |
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); |