diff options
author | Evan Brown <ezb@google.com> | 2024-03-12 14:29:39 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-03-12 14:31:30 -0700 |
commit | 038561296676d1cae4a3cee30f8c924befbb6083 (patch) | |
tree | 724042c21eb6dfc0913a1eff86ffc7da3e0f4274 /absl/container/internal | |
parent | 3c1f9be71ee280539f02e57c5e461b0271f54e91 (diff) |
Add extern templates for common swisstable types.
Motivation: mitigate linker input size increase from swisstable optimizations.
Note: the changes in raw_hash_set.h are fixing build errors that happened when adding the explicit instantiations. The change in unchecked_deref is because set iterators have const reference access whereas map iterators have mutable reference access and the function is never actually called for sets (it's used in raw_hash_map) so it wasn't needed before. I'm not sure why the soo_slot/soo_iterator problems didn't cause compile errors earlier.
PiperOrigin-RevId: 615174043
Change-Id: Iac5eb2332a76e9b70021156fbb2b8def47a5391d
Diffstat (limited to 'absl/container/internal')
-rw-r--r-- | absl/container/internal/raw_hash_set.h | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 258458b0..575491c7 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1839,7 +1839,7 @@ class HashSetResizeHelper { // Reads `capacity` and updates all other fields based on the result of // the allocation. // - // It also may do the folowing actions: + // It also may do the following actions: // 1. initialize control bytes // 2. initialize slots // 3. deallocate old slots. @@ -2204,9 +2204,14 @@ class raw_hash_set { bool is_soo() const { return fits_in_soo(capacity()); } bool is_full_soo() const { return is_soo() && !empty(); } - // Give an early error when key_type is not hashable/eq. - auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k)); - auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k)); + // Give an early error when key_type is not hashable/eq. Definitions are + // provided because otherwise explicit template instantiation fails on MSVC. + auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k)) { + ABSL_UNREACHABLE(); + } + auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k)) { + ABSL_UNREACHABLE(); + } using AllocTraits = absl::allocator_traits<allocator_type>; using SlotAlloc = typename absl::allocator_traits< @@ -2395,7 +2400,18 @@ class raw_hash_set { const_iterator operator++(int) { return inner_++; } friend bool operator==(const const_iterator& a, const const_iterator& b) { + // Suppress erroneous uninitialized memory errors on GCC. This seems to be + // because the slot pointer in the inner_ iterator is uninitialized, even + // though that pointer is not used when uninitialized. + // Similar bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112637. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif return a.inner_ == b.inner_; +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif } friend bool operator!=(const const_iterator& a, const const_iterator& b) { return !(a == b); @@ -3719,7 +3735,9 @@ class raw_hash_set { return const_cast<raw_hash_set*>(this)->iterator_at(i); } - reference unchecked_deref(iterator it) { return it.unchecked_deref(); } + reference unchecked_deref(iterator it) { + return const_cast<reference>(it.unchecked_deref()); + } private: friend struct RawHashSetTestOnlyAccess; @@ -3769,13 +3787,13 @@ class raw_hash_set { return static_cast<slot_type*>(common().soo_data()); } const slot_type* soo_slot() const { - return reinterpret_cast<raw_hash_set*>(this)->soo_slot(); + return const_cast<raw_hash_set*>(this)->soo_slot(); } iterator soo_iterator() { return {SooControl(), soo_slot(), common().generation_ptr()}; } const_iterator soo_iterator() const { - return reinterpret_cast<raw_hash_set*>(this)->soo_iterator(); + return const_cast<raw_hash_set*>(this)->soo_iterator(); } HashtablezInfoHandle infoz() { assert(!is_soo()); |