public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 3/5][_Hashtable] std::initializer_list insertion
@ 2022-06-20 16:58 François Dumont
  0 siblings, 0 replies; only message in thread
From: François Dumont @ 2022-06-20 16:58 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 722 bytes --]

libstdc++: [_Hashtable] Consider all initializer_list elements are inserted

When instantiated using an initializer_list the container is pre-sized 
based on
initializer_list size.

libstdc++-v3/ChangeLog:

     * include/bits/hashtable_policy.h 
(_Insert_base<>::insert(initializer_list<>)):
     Use assignment operator if container is empty and has default 
bucket count.
     * include/bits/hashtable.h (_Hashtable<>(initializer_list<>)): Use 
initializer_list
     size as bucket count hint if user did not provide any value that is 
to say if it is
     the default 0 value.
     * testsuite/23_containers/unordered_set/init-list.cc (test02): New 
test case.

Tested under Linux x86_64.

François

[-- Attachment #2: 3_hashtable_init_list.patch --]
[-- Type: text/x-patch, Size: 2227 bytes --]

diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index e53cbaf0644..b0d1bc1f08a 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -575,7 +575,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		 const _Hash& __hf = _Hash(),
 		 const key_equal& __eql = key_equal(),
 		 const allocator_type& __a = allocator_type())
-      : _Hashtable(__l.begin(), __l.end(), __bkt_count_hint,
+      : _Hashtable(__l.begin(), __l.end(),
+		   __bkt_count_hint == 0 ? __l.size() : __bkt_count_hint,
 		   __hf, __eql, __a, __unique_keys{})
       { }
 
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index e848ba1d3f7..139d0ec27df 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -969,7 +969,16 @@ namespace __detail
 
       void
       insert(initializer_list<value_type> __l)
-      { this->insert(__l.begin(), __l.end()); }
+      {
+	__hashtable& __h = _M_conjure_hashtable();
+	if (__h.empty() && __h.bucket_count() == 1)
+	  {
+	    __h = __l;
+	    return;
+	  }
+
+	this->insert(__l.begin(), __l.end());
+      }
 
       template<typename _InputIterator>
 	void
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc
index fc11498c718..70789d03e63 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc
@@ -48,8 +48,27 @@ void test01()
   VERIFY(m.count(1) == 0);
 }
 
+void test02()
+{
+  unordered_set<int> u({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
+  VERIFY( u.size() == 13 );
+  VERIFY( u.count(0) == 1 );
+  VERIFY( u.count(13) == 0 );
+
+  auto bkt_count = u.bucket_count();
+  u.insert({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
+  VERIFY( u.size() == 13 );
+  VERIFY( u.bucket_count() == bkt_count );
+
+  u.clear();
+  u.insert({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
+  VERIFY( u.size() == 13 );
+  VERIFY( u.bucket_count() == bkt_count );
+}
+
 int main()
 {
   __gnu_test::set_memory_limits();
   test01();
+  test02();
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-20 16:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-20 16:58 [PATCH 3/5][_Hashtable] std::initializer_list insertion François Dumont

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).