public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][_Hashtable] Fix insertion of range of type convertible to value_type PR 56112
@ 2022-02-15  9:05 François Dumont
  2022-02-21 17:59 ` François Dumont
  2022-05-05 17:37 ` François Dumont
  0 siblings, 2 replies; 14+ messages in thread
From: François Dumont @ 2022-02-15  9:05 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

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

We have a regression regarding management of types convertible to 
value_type. It is an occurrence of PR 56112 but for the insert method.

     libstdc++: [_Hashtable] Insert range of types convertible to 
value_type PR 56112

     Fix insertion of range of types convertible to value_type.

     libstdc++-v3/ChangeLog:

             PR libstdc++/56112
             * include/bits/hashtable.h
             (_Hashtable<>::_M_insert_unique_aux): New.
             (_Hashtable<>::_S_to_value): New.
             (_Hashtable<>::_M_insert(_Arg&&, const _NodeGenerator&, 
true_type)): Use latters.
             * testsuite/23_containers/unordered_map/cons/56112.cc: Use 
dg-do compile.
             * testsuite/23_containers/unordered_set/cons/56112.cc: New 
test.

Tested under Linux x86_64.

Ok to commit ?

François

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

diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 5e1a417f7cd..5a502c02fe0 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -898,14 +898,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename _Arg, typename _NodeGenerator>
 	std::pair<iterator, bool>
-	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
-		  true_type /* __uks */)
+	_M_insert_unique_aux(_Arg&& __arg, const _NodeGenerator& __node_gen)
 	{
 	  return _M_insert_unique(
 	    _S_forward_key(_ExtractKey{}(std::forward<_Arg>(__arg))),
 	    std::forward<_Arg>(__arg), __node_gen);
 	}
 
+      template<typename _Kt>
+	static typename std::enable_if<std::is_same<_ExtractKey,
+						    __detail::_Identity>::value,
+				       _Kt&&>::type
+	_S_to_value(_Kt&& __x) noexcept
+	{ return std::forward<_Kt>(__x); }
+
+      template<typename _Kt, typename _Val>
+	static typename std::enable_if<std::is_same<_ExtractKey,
+						   __detail::_Select1st>::value,
+				       const std::pair<_Kt, _Val>&>::type
+	_S_to_value(const std::pair<_Kt, _Val>& __x) noexcept
+	{ return __x; }
+
+      template<typename _Kt, typename _Val>
+	static typename std::enable_if<std::is_same<_ExtractKey,
+						   __detail::_Select1st>::value,
+				       std::pair<_Kt, _Val>&&>::type
+	_S_to_value(std::pair<_Kt, _Val>&& __x) noexcept
+	{ return std::move(__x); }
+
+      static value_type&&
+      _S_to_value(value_type&& __x) noexcept
+      { return std::move(__x); }
+
+      static const value_type&
+      _S_to_value(const value_type& __x) noexcept
+      { return __x; }
+
+      template<typename _Arg, typename _NodeGenerator>
+	std::pair<iterator, bool>
+	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
+		  true_type /* __uks */)
+	{
+	  return _M_insert_unique_aux(
+	    _S_to_value(std::forward<_Arg>(__arg)), __node_gen);
+	}
+
       template<typename _Arg, typename _NodeGenerator>
 	iterator
 	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/56112.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/56112.cc
index c4cdeee234c..8ec0d89af69 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/56112.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/56112.cc
@@ -1,4 +1,4 @@
-// { dg-do run { target c++11 } }
+// { dg-do compile { target c++11 } }
 
 // Copyright (C) 2013-2022 Free Software Foundation, Inc.
 //
@@ -25,20 +25,23 @@ struct Key
   explicit Key(const int* p) : value(p) { }
   ~Key() { value = nullptr; }
 
-  bool operator==(const Key& k) const { return *value == *k.value; }
+  bool operator==(const Key& k) const
+  { return *value == *k.value; }
 
   const int* value;
 };
 
 struct hash
 {
-  std::size_t operator()(const Key& k) const noexcept { return *k.value; }
+  std::size_t operator()(const Key& k) const noexcept
+  { return *k.value; }
 };
 
 struct S
 {
   int value;
-  operator std::pair<const Key, int>() const { return {Key(&value), value}; }
+  operator std::pair<const Key, int>() const
+  { return {Key(&value), value}; }
 };
 
 int main()
@@ -46,4 +49,7 @@ int main()
     S s[1] = { {2} };
     std::unordered_map<Key, int, hash> m(s, s+1);
     std::unordered_multimap<Key, int, hash> mm(s, s+1);
+
+    m.insert(s, s + 1);
+    mm.insert(s, s + 1);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/56112.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/56112.cc
new file mode 100644
index 00000000000..aa34ed4c603
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/56112.cc
@@ -0,0 +1,55 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_map>
+#include <utility>
+
+struct Key
+{
+  explicit Key(const int* p) : value(p) { }
+  ~Key() { value = nullptr; }
+
+  bool operator==(const Key& k) const
+  { return *value == *k.value; }
+
+  const int* value;
+};
+
+struct hash
+{
+  std::size_t operator()(const Key& k) const noexcept
+  { return *k.value; }
+};
+
+struct S
+{
+  int value;
+  operator Key() const
+  { return Key(&value); }
+};
+
+int main()
+{
+    S s[1] = { {2} };
+    std::unordered_set<Key, hash> m(s, s+1);
+    std::unordered_multiset<Key, hash> mm(s, s+1);
+
+    m.insert(s, s + 1);
+    mm.insert(s, s + 1);
+}

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

end of thread, other threads:[~2022-06-14 21:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-15  9:05 [PATCH][_Hashtable] Fix insertion of range of type convertible to value_type PR 56112 François Dumont
2022-02-21 17:59 ` François Dumont
2022-02-21 20:54   ` Jonathan Wakely
2022-02-21 21:33     ` François Dumont
2022-05-05 17:37 ` François Dumont
2022-05-11 17:03   ` François Dumont
2022-05-18 17:39     ` François Dumont
2022-05-24 10:18   ` Jonathan Wakely
2022-05-24 10:22     ` Jonathan Wakely
2022-05-24 10:31       ` Jonathan Wakely
2022-05-25  5:09         ` [PATCH][_Hashtable] Fix insertion of range of type convertible to value_type PR 105714 François Dumont
2022-06-07 19:50           ` François Dumont
2022-06-14 21:53           ` Jonathan Wakely
2022-05-24 20:25     ` [PATCH][_Hashtable] Fix insertion of range of type convertible to value_type PR 56112 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).