aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-11-01 12:44:00 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-11-13 20:21:38 +0000
commit9fcbbb3d104717447cffb65f6ef000969a7b7bb4 (patch)
tree0bddad63551fbbfad43e8613063d11f724257aa7
parent19d0720f68c2617f1b9b686d3884333b60ca75da (diff)
downloadgcc-9fcbbb3d104717447cffb65f6ef000969a7b7bb4.zip
gcc-9fcbbb3d104717447cffb65f6ef000969a7b7bb4.tar.gz
gcc-9fcbbb3d104717447cffb65f6ef000969a7b7bb4.tar.bz2
libstdc++: Refactor _Hashtable::operator=(initializer_list<value_type>)
This replaces a call to _M_insert_range with open coding the loop. This will allow removing the node generator parameter from _M_insert_range in a later commit. libstdc++-v3/ChangeLog: * include/bits/hashtable.h (operator=(initializer_list)): Refactor to not use _M_insert_range. Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
-rw-r--r--libstdc++-v3/include/bits/hashtable.h35
1 files changed, 32 insertions, 3 deletions
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index b36142b..872fcac 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -610,6 +610,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
_Hashtable&
operator=(initializer_list<value_type> __l)
{
@@ -617,16 +619,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_before_begin._M_nxt = nullptr;
clear();
- // We consider that all elements of __l are going to be inserted.
+ // We assume that all elements of __l are likely to be inserted.
auto __l_bkt_count = _M_rehash_policy._M_bkt_for_elements(__l.size());
- // Do not shrink to keep potential user reservation.
+ // Excess buckets might have been intentionally reserved by the user,
+ // so rehash if we need to grow, but don't shrink.
if (_M_bucket_count < __l_bkt_count)
rehash(__l_bkt_count);
- this->_M_insert_range(__l.begin(), __l.end(), __roan, __unique_keys{});
+ _ExtractKey __ex;
+ for (auto& __e : __l)
+ {
+ const key_type& __k = __ex(__e);
+
+ if constexpr (__unique_keys::value)
+ if (this->size() <= __small_size_threshold())
+ {
+ auto __it = _M_begin();
+ for (; __it; __it = __it->_M_next())
+ if (this->_M_key_equals(__k, *__it))
+ break;
+ if (__it)
+ continue; // Found existing element with equivalent key
+ }
+
+ __hash_code __code = this->_M_hash_code(__k);
+ size_type __bkt = _M_bucket_index(__code);
+
+ if constexpr (__unique_keys::value)
+ if (_M_find_node(__bkt, __k, __code))
+ continue; // Found existing element with equivalent key
+
+ _M_insert_unique_node(__bkt, __code, __roan(__e));
+ }
+
return *this;
}
+#pragma GCC diagnostic pop
~_Hashtable() noexcept;