Changes in v2:
- Fix numerous errors revealed by actual testing.
- Delete excess overloads in unordered_multimap and
unordered_multiset.
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 0fc7afae385..d6d2600d904 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,14 +409,23 @@ 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>
insert_or_assign(const key_type& __k, _Obj&& __obj)
@@ -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 99701d4a6d7..9180a87285b 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 4bde18c917b..1dda76dcf32 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 };