summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Evan Brown <ezb@google.com>2023-11-13 13:02:58 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-11-13 13:03:44 -0800
commit716fa00789b60ff52473eabc3ac201eb61744392 (patch)
tree5ecbb3e77c5c1bae4892ac3af2f1be344d6eebd9
parentc046692abc3163776923095e2009c4e10050f605 (diff)
Partial roll forward of reentrant validation with the validation itself disabled. This will make it easier to roll back and forwards in the future (if needed) without causing merge conflicts in unrelated code.
PiperOrigin-RevId: 582059046 Change-Id: I66dc6527e7a0b351367b7a391c2d653fe793143f
-rw-r--r--absl/container/internal/raw_hash_set.h33
-rw-r--r--absl/container/internal/raw_hash_set_test.cc16
2 files changed, 27 insertions, 22 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 9d643605..067ea0da 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -2161,7 +2161,7 @@ class raw_hash_set {
alignas(slot_type) unsigned char raw[sizeof(slot_type)];
slot_type* slot = reinterpret_cast<slot_type*>(&raw);
- PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
+ construct(slot, std::forward<Args>(args)...);
const auto& elem = PolicyTraits::element(slot);
return PolicyTraits::apply(InsertSlot<true>{*this, std::move(*slot)}, elem);
}
@@ -2266,7 +2266,7 @@ class raw_hash_set {
// a better match if non-const iterator is passed as an argument.
void erase(iterator it) {
AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
- PolicyTraits::destroy(&alloc_ref(), it.slot());
+ destroy(it.slot());
erase_meta_only(it);
}
@@ -2558,10 +2558,9 @@ class raw_hash_set {
std::pair<iterator, bool> operator()(const K& key, Args&&...) && {
auto res = s.find_or_prepare_insert(key);
if (res.second) {
- PolicyTraits::transfer(&s.alloc_ref(), s.slot_array() + res.first,
- &slot);
+ s.transfer(s.slot_array() + res.first, &slot);
} else if (do_destroy) {
- PolicyTraits::destroy(&s.alloc_ref(), &slot);
+ s.destroy(&slot);
}
return {s.iterator_at(res.first), res.second};
}
@@ -2570,13 +2569,25 @@ class raw_hash_set {
slot_type&& slot;
};
+ // TODO(b/303305702): re-enable reentrant validation.
+ template <typename... Args>
+ inline void construct(slot_type* slot, Args&&... args) {
+ PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
+ }
+ inline void destroy(slot_type* slot) {
+ PolicyTraits::destroy(&alloc_ref(), slot);
+ }
+ inline void transfer(slot_type* to, slot_type* from) {
+ PolicyTraits::transfer(&alloc_ref(), to, from);
+ }
+
inline void destroy_slots() {
const size_t cap = capacity();
const ctrl_t* ctrl = control();
slot_type* slot = slot_array();
for (size_t i = 0; i != cap; ++i) {
if (IsFull(ctrl[i])) {
- PolicyTraits::destroy(&alloc_ref(), slot + i);
+ destroy(slot + i);
}
}
}
@@ -2639,7 +2650,7 @@ class raw_hash_set {
size_t new_i = target.offset;
total_probe_length += target.probe_length;
SetCtrl(common(), new_i, H2(hash), sizeof(slot_type));
- PolicyTraits::transfer(&alloc_ref(), new_slots + new_i, old_slots + i);
+ transfer(new_slots + new_i, old_slots + i);
}
}
if (old_capacity) {
@@ -2749,7 +2760,7 @@ class raw_hash_set {
reserve(size);
for (iterator it = that.begin(); it != that.end(); ++it) {
insert(std::move(PolicyTraits::element(it.slot())));
- PolicyTraits::destroy(&that.alloc_ref(), it.slot());
+ that.destroy(it.slot());
}
that.dealloc();
that.common() = CommonFields{};
@@ -2840,8 +2851,7 @@ class raw_hash_set {
// POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...).
template <class... Args>
void emplace_at(size_t i, Args&&... args) {
- PolicyTraits::construct(&alloc_ref(), slot_array() + i,
- std::forward<Args>(args)...);
+ construct(slot_array() + i, std::forward<Args>(args)...);
assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) ==
iterator_at(i) &&
@@ -2907,8 +2917,7 @@ class raw_hash_set {
}
static void transfer_slot_fn(void* set, void* dst, void* src) {
auto* h = static_cast<raw_hash_set*>(set);
- PolicyTraits::transfer(&h->alloc_ref(), static_cast<slot_type*>(dst),
- static_cast<slot_type*>(src));
+ h->transfer(static_cast<slot_type*>(dst), static_cast<slot_type*>(src));
}
// Note: dealloc_fn will only be used if we have a non-standard allocator.
static void dealloc_fn(CommonFields& common, const PolicyFunctions&) {
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 1ca4464a..8577272e 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -409,19 +409,15 @@ struct StringTable
using Base::Base;
};
-struct IntTable
- : raw_hash_set<IntPolicy, hash_default_hash<int64_t>,
- std::equal_to<int64_t>, std::allocator<int64_t>> {
- using Base = typename IntTable::raw_hash_set;
+template <typename T>
+struct ValueTable : raw_hash_set<ValuePolicy<T>, hash_default_hash<T>,
+ std::equal_to<T>, std::allocator<T>> {
+ using Base = typename ValueTable::raw_hash_set;
using Base::Base;
};
-struct Uint8Table
- : raw_hash_set<Uint8Policy, hash_default_hash<uint8_t>,
- std::equal_to<uint8_t>, std::allocator<uint8_t>> {
- using Base = typename Uint8Table::raw_hash_set;
- using Base::Base;
-};
+using IntTable = ValueTable<int64_t>;
+using Uint8Table = ValueTable<uint8_t>;
template <typename T>
struct CustomAlloc : std::allocator<T> {