[committed] libstdc++: debug impls for heterogeneous insertion overloads (P2363) [PR117402]

Nathan Myers ncm@cantrip.org
Wed Mar 4 09:09:09 GMT 2026


Implement the debug versions of new overloads from P2363.

Also, simplify implementation of other overloads to match.

libstdc++-v3/ChangeLog:
	PR libstdc++/117402
	* include/debug/map.h (try_emplace (2x), insert_or_assign (2x)):
	Define heterogeneous overloads, simplify existing overloads.
	* include/debug/unordered_map: Same.
	* include/debug/set.h (insert (2x)):
	Define heterogeneous overloads.
	* include/debug/unordered_set: Same.
---
 libstdc++-v3/include/debug/map.h         | 83 +++++++++++++++++-------
 libstdc++-v3/include/debug/set.h         | 21 ++++++
 libstdc++-v3/include/debug/unordered_map | 64 +++++++++++++++---
 libstdc++-v3/include/debug/unordered_set | 26 ++++++++
 4 files changed, 161 insertions(+), 33 deletions(-)

diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 47d1fe6b3ef..3a4ee3e223d 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -382,18 +382,26 @@ namespace __debug
 	  return { { __res.first, this }, __res.second };
 	}
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<map> _Kt, typename... _Args>
+	pair<iterator, bool>
+	try_emplace(_Kt&& __k, _Args&&... __args)
+	{
+	  auto __res = _Base::try_emplace(
+	    std::forward<_Kt>(__k), std::forward<_Args>(__args)...);
+	  return { { __res.first, this }, __res.second };
+	}
+#endif
+
       template <typename... _Args>
         iterator
         try_emplace(const_iterator __hint, const key_type& __k,
                     _Args&&... __args)
         {
 	  __glibcxx_check_insert(__hint);
-	  return
-	    {
-	      _Base::try_emplace(__hint.base(), __k,
-				 std::forward<_Args>(__args)...),
-	      this
-	    };
+	  auto __it = _Base::try_emplace(__hint.base(), __k,
+	    std::forward<_Args>(__args)...);
+	  return { __it, this };
 	}
 
       template <typename... _Args>
@@ -401,13 +409,22 @@ namespace __debug
         try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
         {
 	  __glibcxx_check_insert(__hint);
-	  return
-	    {
-	      _Base::try_emplace(__hint.base(), std::move(__k),
-				 std::forward<_Args>(__args)...),
-	      this
-	    };
+	  auto __it = _Base::try_emplace(__hint.base(), std::move(__k),
+	    std::forward<_Args>(__args)...);
+	  return { __it, this };
+	}
+
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<map> _Kt, typename... _Args>
+	iterator
+	try_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)
+	{
+	  __glibcxx_check_insert(__hint);
+	  auto __it = _Base::try_emplace(__hint.base(),
+	    std::forward<_Kt>(__k), std::forward<_Args>(__args)...);
+	  return { __it, this };
 	}
+# endif
 
       template <typename _Obj>
         std::pair<iterator, bool>
@@ -427,18 +444,26 @@ namespace __debug
 	  return { { __res.first, this }, __res.second };
 	}
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<map> _Kt, typename _Obj>
+	std::pair<iterator, bool>
+	insert_or_assign(_Kt&& __k, _Obj&& __obj)
+	{
+	  auto __res = _Base::insert_or_assign(
+	    std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
+	  return { { __res.first, this }, __res.second };
+	}
+#endif
+
       template <typename _Obj>
         iterator
         insert_or_assign(const_iterator __hint,
                          const key_type& __k, _Obj&& __obj)
 	{
 	  __glibcxx_check_insert(__hint);
-	  return
-	    {
-	      _Base::insert_or_assign(__hint.base(), __k,
-				      std::forward<_Obj>(__obj)),
-	      this
-	    };
+	  auto __it = _Base::insert_or_assign(__hint.base(), __k,
+	    std::forward<_Obj>(__obj));
+	  return { __it, this };
 	}
 
       template <typename _Obj>
@@ -446,13 +471,23 @@ namespace __debug
         insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
         {
 	  __glibcxx_check_insert(__hint);
-	  return
-	    {
-	      _Base::insert_or_assign(__hint.base(), std::move(__k),
-				      std::forward<_Obj>(__obj)),
-	      this
-	    };
+	  auto __it = _Base::insert_or_assign(__hint.base(), std::move(__k),
+	    std::forward<_Obj>(__obj));
+	  return { __it, this };
+	}
+
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<map> _Kt, typename _Obj>
+	iterator
+	insert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)
+	{
+	  __glibcxx_check_insert(__hint);
+	  auto __it = _Base::insert_or_assign(__hint.base(),
+	    std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
+	  return { __it, this };
 	}
+# endif
+
 #endif // C++17
 
 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index 81c2fa6e739..5a0e22a0fbc 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -283,6 +283,16 @@ namespace __debug
       }
 #endif
 
+#ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<set> _Kt>
+	std::pair<iterator, bool>
+	insert(_Kt&& __x)
+	{
+	  auto __res = _Base::insert(std::forward<_Kt>(__x));
+	  return { { __res.first, this }, __res.second };
+	}
+#endif
+
       iterator
       insert(const_iterator __position, const value_type& __x)
       {
@@ -299,6 +309,17 @@ namespace __debug
       }
 #endif
 
+#ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_tree_key<set> _Kt>
+	iterator
+	insert(const_iterator __position, _Kt&& __x)
+	{
+	  __glibcxx_check_insert(__position);
+	  auto __it = _Base::insert(__position.base(), std::forward<_Kt>(__x));
+	  return { __it, this };
+	}
+#endif
+
       template <typename _InputIterator>
 	void
 	insert(_InputIterator __first, _InputIterator __last)
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 75c55cca141..17171628deb 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -500,6 +500,17 @@ namespace __debug
 	  return { { __res.first, this }, __res.second };
 	}
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename... _Args>
+	pair<iterator, bool>
+	try_emplace(_Kt&& __k, _Args&&... __args)
+	{
+	  auto __res = _Base::try_emplace(std::forward<_Kt>(__k),
+	    std::forward<_Args>(__args)...);
+	  return { { __res.first, this }, __res.second };
+	}
+# endif
+
       template <typename... _Args>
 	iterator
 	try_emplace(const_iterator __hint, const key_type& __k,
@@ -516,10 +527,21 @@ namespace __debug
 	try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
 	{
 	  __glibcxx_check_insert(__hint);
-	  return { _Base::try_emplace(__hint.base(), std::move(__k),
-				      std::forward<_Args>(__args)...),
-		   this };
+	  auto __it = _Base::try_emplace(__hint.base(), std::move(__k),
+	    std::forward<_Args>(__args)...);
+	  return { __it, this };
 	}
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename... _Args>
+	iterator
+	try_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)
+	{
+	  __glibcxx_check_insert(__hint);
+	  auto __it = _Base::try_emplace(__hint.base(),
+	    std::forward<_Kt>(__k), std::forward<_Args>(__args)...);
+	  return { __it, this };
+	}
+# endif
 
       template <typename _Obj>
 	pair<iterator, bool>
@@ -539,15 +561,26 @@ namespace __debug
 	  return { { __res.first, this }, __res.second };
 	}
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>
+	pair<iterator, bool>
+	insert_or_assign(_Kt&& __k, _Obj&& __obj)
+	{
+	  auto __res = _Base::insert_or_assign(
+	    std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
+	  return { { __res.first, this }, __res.second };
+	}
+# endif
+
       template <typename _Obj>
 	iterator
 	insert_or_assign(const_iterator __hint, const key_type& __k,
 			 _Obj&& __obj)
 	{
 	  __glibcxx_check_insert(__hint);
-	  return { _Base::insert_or_assign(__hint.base(), __k,
-					   std::forward<_Obj>(__obj)),
-		   this };
+	  auto __it = _Base::insert_or_assign(__hint.base(), __k,
+	    std::forward<_Obj>(__obj));
+	  return { __it, this };
 	}
 
       template <typename _Obj>
@@ -555,10 +588,23 @@ namespace __debug
 	insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
 	{
 	  __glibcxx_check_insert(__hint);
-	  return { _Base::insert_or_assign(__hint.base(), std::move(__k),
-					   std::forward<_Obj>(__obj)),
-		   this };
+	  auto __it = _Base::insert_or_assign(__hint.base(), std::move(__k),
+	    std::forward<_Obj>(__obj));
+	  return { __it, this };
 	}
+
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>
+	iterator
+	insert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)
+	{
+	  __glibcxx_check_insert(__hint);
+	  auto __it = _Base::insert_or_assign(__hint.base(),
+	    std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
+	  return { __it, this };
+	}
+# endif
+
 #endif // C++17
 
 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index e0795f5bbc7..bafc06f6aa3 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -413,6 +413,18 @@ namespace __debug
 	return { { __res.first, this }, __res.second };
       }
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_set> _Kt>
+	std::pair<iterator, bool>
+	insert(_Kt&& __obj)
+	{
+	  size_type __bucket_count = this->bucket_count();
+	  auto __res = _Base::insert(std::forward<_Kt>(__obj));
+	  _M_check_rehashed(__bucket_count);
+	  return { { __res.first, this }, __res.second };
+	}
+#endif
+
       iterator
       insert(const_iterator __hint, value_type&& __obj)
       {
@@ -423,6 +435,20 @@ namespace __debug
 	return { __it, this };
       }
 
+# ifdef __glibcxx_associative_heterogeneous_insertion
+      template <__heterogeneous_hash_key<unordered_set> _Kt>
+	iterator
+	insert(const_iterator __hint, _Kt&& __obj)
+	{
+	  __glibcxx_check_insert(__hint);
+	  size_type __bucket_count = this->bucket_count();
+	  auto __it = _Base::insert(
+	    __hint.base(), std::forward<_Kt>(__obj));
+	  _M_check_rehashed(__bucket_count);
+	  return { __it, this };
+	}
+#endif
+
       void
       insert(std::initializer_list<value_type> __l)
       {
-- 
2.52.0



More information about the Libstdc++ mailing list