public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix std::unordered_map key range insertion
@ 2023-02-23 21:14 François Dumont
  2023-02-27  5:46 ` François Dumont
  0 siblings, 1 reply; 2+ messages in thread
From: François Dumont @ 2023-02-23 21:14 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

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

Hi

Based on my work on PR 96088 for std::map I imagine this use case of 
inserting a range of keys into an associative container. It behaves as 
operator[] by inserting a default value for each key.

I wonder if the Standard says that it should work. Or maybe we want to 
support it ?

I haven't checked if it used to work before we introduced the 
_ConvertToValueType type. I have no old enough gcc to do so.

It is not supported by std::map neither, even without 
_ConvertToValueType so I guess it was not working for std::unordered_map 
prior to it.

If it can be considered as a bug I'll create a PR.

François


[-- Attachment #2: umap.patch --]
[-- Type: text/x-patch, Size: 2821 bytes --]

diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index cce4e2844cf..4a89d0ee1c8 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -125,15 +125,15 @@ namespace __detail
 	{ return std::forward<_Kt>(__k); }
     };
 
-  template<typename _Value>
-    struct _ConvertToValueType<_Select1st, _Value>
+  template<typename _Key, typename _Value>
+    struct _ConvertToValueType<_Select1st, std::pair<_Key, _Value>>
     {
-      constexpr _Value&&
-      operator()(_Value&& __x) const noexcept
+      constexpr std::pair<_Key, _Value>&&
+      operator()(std::pair<_Key, _Value>&& __x) const noexcept
       { return std::move(__x); }
 
-      constexpr const _Value&
-      operator()(const _Value& __x) const noexcept
+      constexpr const std::pair<_Key, _Value>&
+      operator()(const std::pair<_Key, _Value>& __x) const noexcept
       { return __x; }
 
       template<typename _Kt, typename _Val>
@@ -145,6 +145,26 @@ namespace __detail
 	constexpr const std::pair<_Kt, _Val>&
 	operator()(const std::pair<_Kt, _Val>& __x) const noexcept
 	{ return __x; }
+
+      template<typename _Kt>
+	using __is_cons = std::is_constructible<_Key, _Kt&&>;
+
+      template<typename _Kt>
+	using _IFcons = std::enable_if<__is_cons<_Kt>::value>;
+
+      template<typename _Kt>
+	using _IFconsp = typename _IFcons<_Kt>::type;
+
+      template<typename _Kt, typename = _IFconsp<_Kt>>
+	std::pair<_Kt, _Value>
+	operator()(_Kt&& __kt) const
+	{
+	  return {
+	    std::piecewise_construct,
+	    std::forward_as_tuple(std::forward<_Kt>(__kt)),
+	    std::tuple<>()
+	  };
+	}
     };
 
   template<typename _ExKey>
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
index 754b529c67c..a3bf6ce5307 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
@@ -264,6 +264,28 @@ test03()
   }
 }
 
+void
+test04()
+{
+  const std::initializer_list<const char*> strlst =
+    { "long_str_for_dynamic_allocating" };
+  __gnu_test::counter::reset();
+  std::unordered_map<std::string, int,
+		     hash_string_view_functor,
+		     std::equal_to<std::string_view>> um;
+  um.insert(strlst.begin(), strlst.end());
+  VERIFY( um.size() == 1 );
+
+  VERIFY( __gnu_test::counter::count() == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+
+  um.insert(strlst.begin(), strlst.end());
+  VERIFY( um.size() == 1 );
+
+  VERIFY( __gnu_test::counter::count() == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+}
+
 int
 main()
 {
@@ -274,5 +296,6 @@ main()
   test21();
   test22();
   test03();
+  test04();
   return 0;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix std::unordered_map key range insertion
  2023-02-23 21:14 [PATCH] Fix std::unordered_map key range insertion François Dumont
@ 2023-02-27  5:46 ` François Dumont
  0 siblings, 0 replies; 2+ messages in thread
From: François Dumont @ 2023-02-27  5:46 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

Replying to my own questions.

This use case is not valid from a Standard point of view. So not a bug 
and no need to deal with that before next stage 1.

The question left is either we want to support it ?

François

On 23/02/23 22:14, François Dumont wrote:
> Hi
>
> Based on my work on PR 96088 for std::map I imagine this use case of 
> inserting a range of keys into an associative container. It behaves as 
> operator[] by inserting a default value for each key.
>
> I wonder if the Standard says that it should work. Or maybe we want to 
> support it ?
>
> I haven't checked if it used to work before we introduced the 
> _ConvertToValueType type. I have no old enough gcc to do so.
>
> It is not supported by std::map neither, even without 
> _ConvertToValueType so I guess it was not working for 
> std::unordered_map prior to it.
>
> If it can be considered as a bug I'll create a PR.
>
> François
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-02-27  5:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-23 21:14 [PATCH] Fix std::unordered_map key range insertion François Dumont
2023-02-27  5:46 ` 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).