[gcc r16-7890] libstdc++: debug impls for heterogeneous insertion overloads (P2363) [PR117402]

Nathan Myers ncm@gcc.gnu.org
Wed Mar 4 09:02:43 GMT 2026


https://gcc.gnu.org/g:25996a53e81678cf87638801290e136cd2536c4d

commit r16-7890-g25996a53e81678cf87638801290e136cd2536c4d
Author: Nathan Myers <ncm@cantrip.org>
Date:   Tue Feb 10 20:26:47 2026 -0500

    libstdc++: debug impls for heterogeneous insertion overloads (P2363) [PR117402]
    
    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.

Diff:
---
 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 47d1fe6b3efe..3a4ee3e223d2 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 81c2fa6e739f..5a0e22a0fbce 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 75c55cca141c..17171628deb4 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 e0795f5bbc71..bafc06f6aa36 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)
       {


More information about the Libstdc++-cvs mailing list