https://gcc.gnu.org/g:25996a53e81678cf87638801290e136cd2536c4d
commit r16-7890-g25996a53e81678cf87638801290e136cd2536c4d Author: Nathan Myers <[email protected]> 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) {
