Implement the debug versions of new overloads from P2077.

libstdc++-v3/ChangeLog:
        PR libstdc++/117404
        * include/debug/map.h (extract, erase): Define overloads.
        * include/debug/multimap.h: Same.
        * include/debug/multiset.h: Same.
        * include/debug/set.h: Same.
        * include/debug/unordered_map: Same (2x).
        * include/debug/unordered_set: Same (2x), rename some locals.
---
 libstdc++-v3/include/debug/map.h         | 32 ++++++++++++
 libstdc++-v3/include/debug/multimap.h    | 29 +++++++++++
 libstdc++-v3/include/debug/multiset.h    | 29 +++++++++++
 libstdc++-v3/include/debug/set.h         | 32 ++++++++++++
 libstdc++-v3/include/debug/unordered_map | 53 ++++++++++++++++++++
 libstdc++-v3/include/debug/unordered_set | 63 +++++++++++++++++++++---
 6 files changed, 232 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 0fc7afae385..47d1fe6b3ef 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -476,6 +476,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<map> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = find(__key);
+         if (__position != end())
+           return extract(__position);
+         return {};
+       }
+# endif
+
       insert_return_type
       insert(node_type&& __nh)
       {
@@ -538,6 +550,26 @@ namespace __debug
          }
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      // Note that for some types _Kt this may erase more than
+      // one element, such as if _Kt::operator< checks only part
+      // of the key.
+      template <__heterogeneous_tree_key<map> _Kt>
+       size_type
+       erase(_Kt&& __x)
+       {
+         auto __victims = _Base::equal_range(__x);
+         size_type __count = 0;
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             this->_M_invalidate_if(_Equal(__victim));
+             _Base::erase(__victim++);
+             ++__count;
+           }
+         return __count;
+       }
+# endif
+
 #if __cplusplus >= 201103L
       iterator
       erase(const_iterator __first, const_iterator __last)
diff --git a/libstdc++-v3/include/debug/multimap.h 
b/libstdc++-v3/include/debug/multimap.h
index 4137186c527..4b2591fdcfa 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -360,6 +360,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<multimap> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = find(__key);
+         if (__position != end())
+           return extract(__position);
+         return {};
+       }
+# endif
+
       iterator
       insert(node_type&& __nh)
       { return { _Base::insert(std::move(__nh)), this }; }
@@ -420,6 +432,23 @@ namespace __debug
        return __count;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<multimap> _Kt>
+       size_type
+       erase(_Kt&& __x)
+       {
+         auto __victims = _Base::equal_range(__x);
+         size_type __count = 0;
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             this->_M_invalidate_if(_Equal(__victim));
+             _Base::erase(__victim++);
+             ++__count;
+           }
+         return __count;
+       }
+# endif
+
 #if __cplusplus >= 201103L
       iterator
       erase(const_iterator __first, const_iterator __last)
diff --git a/libstdc++-v3/include/debug/multiset.h 
b/libstdc++-v3/include/debug/multiset.h
index 6fa499228f5..2b70dcd8b1f 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -331,6 +331,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<multiset> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = find(__key);
+         if (__position != end())
+           return extract(__position);
+         return {};
+       }
+#endif
+
       iterator
       insert(node_type&& __nh)
       { return { _Base::insert(std::move(__nh)), this }; }
@@ -387,6 +399,23 @@ namespace __debug
        return __count;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<multiset> _Kt>
+       size_type
+       erase(_Kt&& __x)
+       {
+         auto __victims = _Base::equal_range(__x);
+         size_type __count = 0;
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             this->_M_invalidate_if(_Equal(__victim));
+             _Base::erase(__victim++);
+             ++__count;
+           }
+         return __count;
+       }
+# endif
+
 #if __cplusplus >= 201103L
       _GLIBCXX_ABI_TAG_CXX11
       iterator
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index 99701d4a6d7..81c2fa6e739 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -340,6 +340,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_tree_key<set> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = find(__key);
+         if (__position != end())
+           return extract(__position);
+         return {};
+       }
+#endif
+
       insert_return_type
       insert(node_type&& __nh)
       {
@@ -398,6 +410,26 @@ namespace __debug
          }
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      // Note that for some types _Kt this may erase more than
+      // one element, such as if _Kt::operator< checks only part
+      // of the key.
+      template <__heterogeneous_tree_key<set> _Kt>
+       size_type
+       erase(_Kt&& __x)
+       {
+         auto __victims = _Base::equal_range(__x);
+         size_type __count = 0;
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             this->_M_invalidate_if(_Equal(__victim));
+             _Base::erase(__victim++);
+             ++__count;
+           }
+         return __count;
+       }
+#endif
+
 #if __cplusplus >= 201103L
       _GLIBCXX_ABI_TAG_CXX11
       iterator
diff --git a/libstdc++-v3/include/debug/unordered_map 
b/libstdc++-v3/include/debug/unordered_map
index 4bde18c917b..1ea480a4e8b 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -581,6 +581,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_map> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = _Base::find(__key);
+         if (__position != _Base::end())
+           return _M_extract(__position);
+         return {};
+       }
+#endif
+
       insert_return_type
       insert(node_type&& __nh)
       {
@@ -713,6 +725,18 @@ namespace __debug
        return __ret;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_map> _Kt>
+       size_type
+       erase(_Kt&& __key)
+       {
+         auto __victim = _Base::find(__key);
+         if (__victim != _Base::end())
+           return _M_erase(__victim), 1;
+         return 0;
+       }
+#endif
+
       iterator
       erase(const_iterator __it)
       {
@@ -1381,6 +1405,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_multimap> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = _Base::find(__key);
+         if (__position != _Base::end())
+           return _M_extract(__position);
+         return {};
+       }
+#endif
+
       iterator
       insert(node_type&& __nh)
       { return { _Base::insert(std::move(__nh)), this }; }
@@ -1510,6 +1546,23 @@ namespace __debug
        return __ret;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_multimap> _Kt>
+       size_type
+       erase(_Kt&& __key)
+       {
+         size_type __count(0);
+         auto __victims = _Base::equal_range(__key);
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             _M_invalidate(__victim);
+             __victim = _Base::erase(__victim);
+             ++__count;
+           }
+         return __count;
+       }
+#endif
+
       iterator
       erase(const_iterator __it)
       {
diff --git a/libstdc++-v3/include/debug/unordered_set 
b/libstdc++-v3/include/debug/unordered_set
index de999a76890..e26b52d7029 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -468,6 +468,18 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_set> _Kt>
+       node_type
+       extract(_Kt&& __key)
+       {
+         const auto __position = _Base::find(__key);
+         if (__position != _Base::end())
+           return _M_extract(__position);
+         return {};
+       }
+#endif
+
       insert_return_type
       insert(node_type&& __nh)
       {
@@ -598,6 +610,18 @@ namespace __debug
        return __ret;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_set> _Kt>
+       size_type
+       erase(_Kt&& __key)
+       {
+         auto __victim = _Base::find(__key);
+         if (__victim != _Base::end())
+           return _M_erase(__victim), 1;
+         return 0;
+       }
+#endif
+
       iterator
       erase(const_iterator __it)
       {
@@ -1202,6 +1226,17 @@ namespace __debug
        return {};
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_multiset> _Kt>
+       node_type
+       extract(const _Kt& __key)
+       {
+         const auto __position = _Base::find(__key);
+         return __position != _Base::end() ?
+           _M_extract(__position) : node_type{};
+       }
+#endif
+
       iterator
       insert(node_type&& __nh)
       { return { _Base::insert(std::move(__nh)), this }; }
@@ -1318,18 +1353,34 @@ namespace __debug
       size_type
       erase(const key_type& __key)
       {
-       size_type __ret(0);
-       auto __pair = _Base::equal_range(__key);
-       for (auto __victim = __pair.first; __victim != __pair.second;)
+       size_type __count(0);
+       auto __victims = _Base::equal_range(__key);
+       for (auto __victim = __victims.first; __victim != __victims.second;)
          {
            _M_invalidate(__victim);
            __victim = _Base::erase(__victim);
-           ++__ret;
+           ++__count;
          }
-
-       return __ret;
+       return __count;
       }
 
+# ifdef __glibcxx_associative_heterogeneous_erasure
+      template <__heterogeneous_hash_key<unordered_multiset> _Kt>
+       size_type
+       erase(_Kt&& __key)
+       {
+         size_type __count(0);
+         auto __victims = _Base::equal_range(__key);
+         for (auto __victim = __victims.first; __victim != __victims.second;)
+           {
+             _M_invalidate(__victim);
+             __victim = _Base::erase(__victim);
+             ++__count;
+           }
+         return __count;
+       }
+#endif
+
       iterator
       erase(const_iterator __it)
       {
-- 
2.52.0

Reply via email to