get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2226899/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226899,
    "url": "http://patchwork.ozlabs.org/api/patches/2226899/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.1@forge-stage.sourceware.org/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.1@forge-stage.sourceware.org>",
    "list_archive_url": null,
    "date": "2026-04-22T19:08:44",
    "name": "[v1,1/1] libstdc++: Fix std::erase_if behavior for std::__debug containers",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "d7746582e479abab8dace85886b0868943fad601",
    "submitter": {
        "id": 93220,
        "url": "http://patchwork.ozlabs.org/api/people/93220/?format=api",
        "name": "François Dumont via Sourceware Forge",
        "email": "forge-bot+fdumont@forge-stage.sourceware.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.1@forge-stage.sourceware.org/mbox/",
    "series": [
        {
            "id": 501110,
            "url": "http://patchwork.ozlabs.org/api/series/501110/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501110",
            "date": "2026-04-22T19:05:12",
            "name": "libstdc++: Fix std::erase_if behavior for std::__debug::deque",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501110/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226899/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226899/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g1C155Nf5z1yGs\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 07:24:57 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id E40C446A26C6\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 21:24:55 +0000 (GMT)",
            "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id AE22A42939A7\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 19:09:42 +0000 (GMT)",
            "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id 88560435DD\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 19:09:42 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org E40C446A26C6",
            "OpenDKIM Filter v2.11.0 sourceware.org AE22A42939A7"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org AE22A42939A7",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org AE22A42939A7",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776884982; cv=none;\n b=X5atxl2YlshywrvY7fIuA8MJYQxITs4HiQ7yEc9mnv4F2JFy5Tp7FNWSOVGWcagHIAYp4Ix4yDgoLwcSmpnX3zLBEqjSbWN4nb5Xf/kbFB48OPEnXdN8nzeAi5Lbr0Vh/Xpzv7P8YgKd1wIkKjYoYr5NhLMEkq+Y/U8Nm1fQ5t8=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776884982; c=relaxed/simple;\n bh=NtGb89n2u5/d/ofluWw88j9N98Ahx1GwXKgZhlvitbI=;\n h=From:Date:Subject:MIME-Version:To:Message-ID;\n b=AO4KJuJCHJrnzOw+3zzYm84TeHMnezMAncOUlE3rqI9QRNH+8K0q9mIq8pXpexfmMfHt86JQoeyB91ckqLKJVZZ0wbOH68pi3t3ZVwygd6YT5YUK9wPAt/h0Fn4QBHY01l8wKOfjP+m1lvA0f2B/WxBdFEAqSwl1OTnF/IAELrM=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "=?utf-8?q?Fran=C3=A7ois_Dumont_via_Sourceware_Forge?=\n <forge-bot+fdumont@forge-stage.sourceware.org>",
        "Date": "Wed, 22 Apr 2026 19:08:44 +0000",
        "Subject": "[PATCH v1 1/1] libstdc++: Fix std::erase_if behavior for std::__debug\n containers",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>",
        "Message-ID": "\n <bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.1@forge-stage.sourceware.org>",
        "X-Mailer": "batrachomyomachia",
        "X-Pull-Request-Organization": "gcc",
        "X-Pull-Request-Repository": "gcc-TEST",
        "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/131",
        "References": "\n <bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.0@forge-stage.sourceware.org>",
        "In-Reply-To": "\n <bmm.hhupnyl5bc.gcc.gcc-TEST.fdumont.131.1.0@forge-stage.sourceware.org>",
        "X-Patch-URL": "\n https://forge.sourceware.org/fdumont/gcc-TEST/commit/add9e3dd616da332ea69afbb583fd0cfdfc970cf",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n fdumont@gcc.gnu.org",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: François Dumont <frs.dumont@gmail.com>\n\nComplete fix of std::erase_if/std::erase for all std::__debug containers and\n__gnu_debug::basic_string. Make sure that iterators erased by this function\nwill be properly detected as such by the debug container and so considered as\ninvalid.\n\nDoing so introduce a new std::__detail::__erase_if function dealing, similarly\nto std::__detail::__erase_node_if, with non-node containers.\n\nlibstdc++-v3/ChangeLog:\n\n\t* include/bits/erase_if.h (__detail::__erase_if): New.\n\t* include/debug/deque (std::erase_if<>(__debug::deque<>&, _Pred): Use latter.\n\t* include/debug/inplace_vector (std::erase_if<>(__debug::inplace_vector<>&, _Pred)):\n\tLikewise.\n\t* include/debug/vector (std::erase_if<>(__debug::vector<>&, _Pred)): Likewise.\n\t* include/std/deque: Include erase_if.h.\n\t(std::erase_if<>(std::vector<>&, _Pred)): Adapt to use __detail::__erase_if.\n\t* include/std/inplace_vector (std::erase_if<>(std::inplace_vector<>&, _Pred)):\n\tLikewise.\n\t* include/std/string (std::erase_if<>(std::basic_string<>&, _Pred)): Likewise.\n\t* include/std/vector (std::erase_if<>(std::vector<>&, _Pred)): Likewise.\n\t* include/debug/forward_list\n\t(std::erase_if<>(__debug::forward_list<>&, _Pred)): New.\n\t(std::erase<>(__debug::forward_list<>&, const _Up&)): New.\n\t* include/debug/list\n\t(std::erase_if<>(__debug::list<>&, _Pred)): New.\n\t(std::erase<>(__debug::list<>&, const _Up&)): New.\n\t* include/debug/map (std::erase_if<>(__debug::map<>&, _Pred)): New.\n\t(std::erase_if<>(__debug::multimap<>&, _Pred)): New.\n\t* include/debug/set (std::erase_if<>(__debug::set<>&, _Pred)): New.\n\t(std::erase_if<>(__debug::multiset<>&, _Pred)): New.\n\t* include/debug/string\n\t(std::erase_if<>(__gnu_debug::basic_string<>&, _Pred)): New.\n\t(std::erase<>(__gnu_debug::basic_string<>&, const _Up&)): New.\n\t* include/debug/unordered_map\n\t(std::erase_if<>(__debug::unordered_map<>&, _Pred)): New.\n\t(std::erase_if<>(__debug::unordered_multimap<>&, _Pred)): New.\n\t* include/debug/unordered_set\n\t(std::erase_if<>(__debug::unordered_set<>&, _Pred)): New.\n\t(std::erase_if<>(__debug::unordered_multiset<>&, _Pred)): New.\n\t* include/std/forward_list (std::erase_if<>(std::forward_list<>&, _Pred)):\n\tAdapt to work exclusively for normal implementation.\n\t(std::erase<>(std::forward_list<>&, const _Up&)): Likewise.\n\t* include/std/list (std::erase_if<>(std::list<>&, _Pred)): Likewise.\n\t(std::erase<>(std::list<>&, const _Up&)): Likewise.\n\t* include/std/map (std::erase_if<>(std::map<>&, _Pred)): Likewise.\n\t(std::erase_if<>(std::multimap<>&, _Pred)): Likewise.\n\t* include/debug/set (std::erase_if<>(std::set<>&, _Pred)): Likewise.\n\t(std::erase_if<>(std::multiset<>&, _Pred)): Likewise.\n\t* include/std/unordered_map\n\t(std::erase_if<>(std::unordered_map<>&, _Pred)): Likewise.\n\t(std::erase_if<>(std::unordered_multimap<>&, _Pred)): Likewise.\n\t* include/std/unordered_set\n\t(std::erase_if<>(std::unordered_set<>&, _Pred)): Likewise.\n\t(std::erase_if<>(std::unordered_multiset<>&, _Pred)): Likewise.\n\t* testsuite/21_strings/basic_string/debug/erase.cc: New test case.\n\t* testsuite/23_containers/forward_list/debug/erase.cc: New test case.\n\t* testsuite/23_containers/forward_list/debug/invalidation/erase.cc: New test case.\n\t* testsuite/23_containers/list/debug/erase.cc: New test case.\n\t* testsuite/23_containers/list/debug/invalidation/erase.cc: New test case.\n\t* testsuite/23_containers/map/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/map/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/multimap/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/multimap/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/multiset/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/multiset/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/set/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/set/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_map/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_map/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_multimap/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_multimap/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_multiset/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_multiset/debug/invalidation/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_set/debug/erase_if.cc: New test case.\n\t* testsuite/23_containers/unordered_set/debug/invalidation/erase_if.cc: New test case.\n---\n libstdc++-v3/include/bits/erase_if.h          | 22 ++++++++++++\n libstdc++-v3/include/debug/deque              | 16 ++-------\n libstdc++-v3/include/debug/forward_list       | 21 ++++++++++++\n libstdc++-v3/include/debug/inplace_vector     | 15 ++------\n libstdc++-v3/include/debug/list               | 21 ++++++++++++\n libstdc++-v3/include/debug/map                | 21 ++++++++++++\n libstdc++-v3/include/debug/set                | 19 +++++++++++\n libstdc++-v3/include/debug/string             | 20 +++++++++++\n libstdc++-v3/include/debug/unordered_map      | 20 +++++++++++\n libstdc++-v3/include/debug/unordered_set      | 20 +++++++++++\n libstdc++-v3/include/debug/vector             | 14 +-------\n libstdc++-v3/include/std/deque                | 15 ++------\n libstdc++-v3/include/std/forward_list         |  8 ++---\n libstdc++-v3/include/std/inplace_vector       | 13 ++-----\n libstdc++-v3/include/std/list                 |  8 ++---\n libstdc++-v3/include/std/map                  | 25 ++++++--------\n libstdc++-v3/include/std/set                  | 24 ++++++-------\n libstdc++-v3/include/std/string               | 11 ++----\n libstdc++-v3/include/std/unordered_map        | 29 +++++++---------\n libstdc++-v3/include/std/unordered_set        | 26 ++++++--------\n libstdc++-v3/include/std/vector               | 15 ++------\n .../21_strings/basic_string/debug/erase.cc    | 25 ++++++++++++++\n .../23_containers/forward_list/debug/erase.cc | 26 ++++++++++++++\n .../forward_list/debug/invalidation/erase.cc  | 27 +++++++++++++++\n .../23_containers/list/debug/erase.cc         | 29 ++++++++++++++++\n .../list/debug/invalidation/erase.cc          | 30 ++++++++++++++++\n .../23_containers/map/debug/erase_if.cc       | 33 ++++++++++++++++++\n .../map/debug/invalidation/erase_if.cc        | 34 +++++++++++++++++++\n .../23_containers/multimap/debug/erase_if.cc  | 33 ++++++++++++++++++\n .../multimap/debug/invalidation/erase_if.cc   | 34 +++++++++++++++++++\n .../23_containers/multiset/debug/erase_if.cc  | 31 +++++++++++++++++\n .../multiset/debug/invalidation/erase_if.cc   | 32 +++++++++++++++++\n .../23_containers/set/debug/erase_if.cc       | 31 +++++++++++++++++\n .../set/debug/invalidation/erase_if.cc        | 32 +++++++++++++++++\n .../unordered_map/debug/erase_if.cc           | 33 ++++++++++++++++++\n .../debug/invalidation/erase_if.cc            | 34 +++++++++++++++++++\n .../unordered_multimap/debug/erase_if.cc      | 33 ++++++++++++++++++\n .../debug/invalidation/erase_if.cc            | 34 +++++++++++++++++++\n .../unordered_multiset/debug/erase_if.cc      | 31 +++++++++++++++++\n .../debug/invalidation/erase_if.cc            | 32 +++++++++++++++++\n .../unordered_set/debug/erase_if.cc           | 31 +++++++++++++++++\n .../debug/invalidation/erase_if.cc            | 32 +++++++++++++++++\n 42 files changed, 886 insertions(+), 154 deletions(-)\n create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/debug/erase.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/debug/erase.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/debug/invalidation/erase.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/debug/erase.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/debug/invalidation/erase.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/map/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/map/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/multimap/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/multimap/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/multiset/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/multiset/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/set/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/set/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_map/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_map/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/invalidation/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_set/debug/erase_if.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_set/debug/invalidation/erase_if.cc",
    "diff": "diff --git a/libstdc++-v3/include/bits/erase_if.h b/libstdc++-v3/include/bits/erase_if.h\nindex a445a53bcfbf..d5a5278d1282 100644\n--- a/libstdc++-v3/include/bits/erase_if.h\n+++ b/libstdc++-v3/include/bits/erase_if.h\n@@ -35,6 +35,7 @@\n #endif\n \n #include <bits/c++config.h>\n+#include <bits/stl_algobase.h>\n \n // Used by C++17 containers and Library Fundamentals v2 headers.\n #if __cplusplus >= 201402L\n@@ -44,6 +45,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \n   namespace __detail\n   {\n+    template<typename _Container, typename _UnsafeContainer,\n+\t     typename _Predicate>\n+      _GLIBCXX20_CONSTEXPR\n+      typename _Container::size_type\n+      __erase_if(_Container& __cont, _UnsafeContainer& __ucont,\n+\t\t _Predicate __pred)\n+      {\n+\tconst auto __osz = __ucont.size();\n+\tconst auto __end = __ucont.end();\n+\tauto __removed = std::__remove_if(__ucont.begin(), __end,\n+\t\t\t\t\t  std::move(__pred));\n+\tif (__removed != __end)\n+\t  {\n+\t    __cont.erase(__niter_wrap(__cont.cbegin(), __removed),\n+\t\t\t __cont.cend());\n+\t    return __osz - __ucont.size();\n+\t  }\n+\n+\treturn 0;\n+      }\n+\n     template<typename _Container, typename _UnsafeContainer,\n \t     typename _Predicate>\n       typename _Container::size_type\ndiff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque\nindex b3e72eb30163..9fba4ffc4997 100644\n--- a/libstdc++-v3/include/debug/deque\n+++ b/libstdc++-v3/include/debug/deque\n@@ -778,19 +778,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     inline typename __debug::deque<_Tp, _Alloc>::size_type\n     erase_if(__debug::deque<_Tp, _Alloc>& __cont, _Predicate __pred)\n     {\n-      _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __unsafe_cont = __cont;\n-      const auto __osz = __cont.size();\n-      const auto __end = __unsafe_cont.end();\n-      auto __removed = std::__remove_if(__unsafe_cont.begin(), __end,\n-\t\t\t\t\tstd::move(__pred));\n-      if (__removed != __end)\n-\t{\n-\t  __cont.erase(__niter_wrap(__cont.begin(), __removed),\n-\t\t       __cont.end());\n-\t  return __osz - __cont.size();\n-\t}\n-\n-      return 0;\n+      return __detail::__erase_if(__cont, __cont._M_base(), std::move(__pred));\n     }\n \n   template<typename _Tp, typename _Alloc, typename _Up = _Tp>\n@@ -798,7 +786,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     erase(__debug::deque<_Tp, _Alloc>& __cont, const _Up& __value)\n     { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); }\n _GLIBCXX_END_NAMESPACE_VERSION\n-#endif // __cpp_lib_erase_if\n+#endif // __glibcxx_erase_if\n } // namespace std\n \n #endif\ndiff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list\nindex 1fe3a4f2830b..7d615978000e 100644\n--- a/libstdc++-v3/include/debug/forward_list\n+++ b/libstdc++-v3/include/debug/forward_list\n@@ -981,6 +981,27 @@ namespace __debug\n     { __lx.swap(__ly); }\n \n } // namespace __debug\n+\n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Tp, typename _Alloc, typename _Predicate>\n+    inline typename __debug::forward_list<_Tp, _Alloc>::size_type\n+    erase_if(__debug::forward_list<_Tp, _Alloc>& __cont, _Predicate __pred)\n+    { return __cont.remove_if(__pred); }\n+\n+  template<typename _Tp, typename _Alloc,\n+\t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\n+    inline typename __debug::forward_list<_Tp, _Alloc>::size_type\n+    erase(__debug::forward_list<_Tp, _Alloc>& __cont, const _Up& __value)\n+    {\n+      // _GLIBCXX_RESOLVE_LIB_DEFECTS\n+      // 4135. helper lambda of std::erase for list should specify return type\n+      return std::erase_if(__cont, [&](const auto& __elem) -> bool {\n+\t  return __elem == __value;\n+      });\n+    }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+#endif // __glibcxx_erase_if\n } // namespace std\n \n namespace __gnu_debug\ndiff --git a/libstdc++-v3/include/debug/inplace_vector b/libstdc++-v3/include/debug/inplace_vector\nindex c7e301efc621..750b0a7343ca 100644\n--- a/libstdc++-v3/include/debug/inplace_vector\n+++ b/libstdc++-v3/include/debug/inplace_vector\n@@ -566,13 +566,13 @@ namespace __debug\n       noexcept( noexcept(__x.swap(__y)) )\n       { __x.swap(__y); }\n \n-    private:\n       constexpr _Base&\n       _M_base() noexcept { return *this; }\n \n       constexpr const _Base&\n       _M_base() const noexcept { return *this; }\n \n+    private:\n       constexpr void\n       _M_invalidate_after_nth(difference_type __n) noexcept\n       {\n@@ -663,17 +663,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     {\n       if constexpr (_Nm != 0)\n \t{\n-\t  _GLIBCXX_STD_C::inplace_vector<_Tp, _Nm>& __ucont = __cont;\n-\t  const auto __osz = __cont.size();\n-\t  const auto __end = __ucont.end();\n-\t  auto __removed = std::__remove_if(__ucont.begin(), __end,\n-\t\t\t\t\t    std::move(__pred));\n-\t  if (__removed != __end)\n-\t    {\n-\t      __cont.erase(__niter_wrap(__cont.cbegin(), __removed),\n-\t\t\t   __cont.cend());\n-\t      return __osz - __cont.size();\n-\t    }\n+\t  return __detail::__erase_if(__cont, __cont._M_base(),\n+\t\t\t\t      std::move(__pred));\n \t}\n \n       return 0;\ndiff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list\nindex 48ec1966d97e..d06e9e4c2f84 100644\n--- a/libstdc++-v3/include/debug/list\n+++ b/libstdc++-v3/include/debug/list\n@@ -1031,6 +1031,27 @@ namespace __debug\n     { __lhs.swap(__rhs); }\n \n } // namespace __debug\n+\n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Tp, typename _Alloc, typename _Predicate>\n+    inline typename __debug::list<_Tp, _Alloc>::size_type\n+    erase_if(__debug::list<_Tp, _Alloc>& __cont, _Predicate __pred)\n+    { return __cont.remove_if(__pred); }\n+\n+  template<typename _Tp, typename _Alloc,\n+\t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\n+    inline typename __debug::list<_Tp, _Alloc>::size_type\n+    erase(__debug::list<_Tp, _Alloc>& __cont, const _Up& __value)\n+    {\n+      // _GLIBCXX_RESOLVE_LIB_DEFECTS\n+      // 4135. helper lambda of std::erase for list should specify return type\n+      return std::erase_if(__cont, [&](const auto& __elem) -> bool {\n+\t  return __elem == __value;\n+      });\n+    }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+#endif // __glibcxx_erase_if\n } // namespace std\n \n namespace __gnu_debug\ndiff --git a/libstdc++-v3/include/debug/map b/libstdc++-v3/include/debug/map\nindex 360325f03ad2..b07c17f2320e 100644\n--- a/libstdc++-v3/include/debug/map\n+++ b/libstdc++-v3/include/debug/map\n@@ -45,4 +45,25 @@ namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {\n #include <debug/map.h>\n #include <debug/multimap.h>\n \n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+namespace std _GLIBCXX_VISIBILITY(default)\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::map<_Key, _Tp, _Compare, _Alloc>::size_type\n+    erase_if(__debug::map<_Key, _Tp, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+\n+  template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::multimap<_Key, _Tp, _Compare, _Alloc>::size_type\n+    erase_if(__debug::multimap<_Key, _Tp, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n+#endif // __glibcxx_erase_if\n+\n #endif\ndiff --git a/libstdc++-v3/include/debug/set b/libstdc++-v3/include/debug/set\nindex 6645032c349c..508c0cd05fd2 100644\n--- a/libstdc++-v3/include/debug/set\n+++ b/libstdc++-v3/include/debug/set\n@@ -43,4 +43,23 @@ namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {\n #include <debug/set.h>\n #include <debug/multiset.h>\n \n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+namespace std _GLIBCXX_VISIBILITY(default)\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Key, typename _Compare, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::set<_Key, _Compare, _Alloc>::size_type\n+    erase_if(__debug::set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+\n+  template<typename _Key, typename _Compare, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::multiset<_Key, _Compare, _Alloc>::size_type\n+    erase_if(__debug::multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n+#endif // __glibcxx_erase_if\n+\n #endif\ndiff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string\nindex 6d30d7d036ac..d5ee1d9e1938 100644\n--- a/libstdc++-v3/include/debug/string\n+++ b/libstdc++-v3/include/debug/string\n@@ -1331,6 +1331,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     : __is_fast_hash<hash<std::basic_string<_CharT>>>\n     { };\n \n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+  template<typename _CharT, typename _Traits, typename _Alloc,\n+\t   typename _Predicate>\n+    constexpr typename __gnu_debug::basic_string<_CharT,\n+\t\t\t\t\t\t _Traits, _Alloc>::size_type\n+    erase_if(__gnu_debug::basic_string<_CharT, _Traits, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    {\n+      return __detail::__erase_if(__cont, __cont._M_base(), std::move(__pred));\n+    }\n+\n+  template<typename _CharT, typename _Traits, typename _Alloc,\n+\t   typename _Up _GLIBCXX26_DEF_VAL_T(_CharT)>\n+    constexpr typename __gnu_debug::basic_string<_CharT,\n+\t\t\t\t\t\t _Traits, _Alloc>::size_type\n+    erase(__gnu_debug::basic_string<_CharT, _Traits, _Alloc>& __cont,\n+\t  const _Up& __value)\n+    { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); }\n+#endif // __glibcxx_erase_if\n+\n _GLIBCXX_END_NAMESPACE_VERSION\n }\n #endif /* C++11 */\ndiff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map\nindex 8e286b733362..4bde18c917b2 100644\n--- a/libstdc++-v3/include/debug/unordered_map\n+++ b/libstdc++-v3/include/debug/unordered_map\n@@ -1748,6 +1748,26 @@ namespace __debug\n #endif\n \n } // namespace __debug\n+\n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Key, typename _Tp, typename _Hash, typename _CPred,\n+\t   typename _Alloc, typename _Predicate>\n+    inline typename __debug::unordered_map<_Key, _Tp, _Hash,\n+\t\t\t\t\t   _CPred, _Alloc>::size_type\n+    erase_if(__debug::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+\n+  template<typename _Key, typename _Tp, typename _Hash, typename _CPred,\n+\t   typename _Alloc, typename _Predicate>\n+    inline typename __debug::unordered_multimap<_Key, _Tp, _Hash,\n+\t\t\t\t\t\t_CPred, _Alloc>::size_type\n+    erase_if(__debug::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+#endif // __glibcxx_erase_if\n } // namespace std\n \n #endif // C++11\ndiff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set\nindex 8951604f03bf..de999a76890e 100644\n--- a/libstdc++-v3/include/debug/unordered_set\n+++ b/libstdc++-v3/include/debug/unordered_set\n@@ -1597,6 +1597,26 @@ namespace __debug\n #endif\n \n } // namespace __debug\n+\n+#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+  template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::unordered_set<_Key, _Hash,\n+\t\t\t\t\t   _CPred, _Alloc>::size_type\n+    erase_if(__debug::unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+\n+  template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,\n+\t   typename _Predicate>\n+    inline typename __debug::unordered_multiset<_Key, _Hash,\n+\t\t\t\t\t\t_CPred, _Alloc>::size_type\n+    erase_if(__debug::unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }\n+_GLIBCXX_END_NAMESPACE_VERSION\n+#endif // __glibcxx_erase_if\n } // namespace std\n \n #endif // C++11\ndiff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector\nindex e652260860a2..61e5ff78a7a4 100644\n--- a/libstdc++-v3/include/debug/vector\n+++ b/libstdc++-v3/include/debug/vector\n@@ -1043,19 +1043,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     constexpr typename __debug::vector<_Tp, _Alloc>::size_type\n     erase_if(__debug::vector<_Tp, _Alloc>& __cont, _Predicate __pred)\n     {\n-      _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __unsafe_cont = __cont;\n-      const auto __osz = __cont.size();\n-      const auto __end = __unsafe_cont.end();\n-      auto __removed = std::__remove_if(__unsafe_cont.begin(), __end,\n-\t\t\t\t\tstd::move(__pred));\n-      if (__removed != __end)\n-\t{\n-\t  __cont.erase(__niter_wrap(__cont.begin(), __removed),\n-\t\t       __cont.end());\n-\t  return __osz - __cont.size();\n-\t}\n-\n-      return 0;\n+      return __detail::__erase_if(__cont, __cont._M_base(), std::move(__pred));\n     }\n \n   template<typename _Tp, typename _Alloc, typename _Up = _Tp>\ndiff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque\nindex ea426196ca54..3899b68e7367 100644\n--- a/libstdc++-v3/include/std/deque\n+++ b/libstdc++-v3/include/std/deque\n@@ -68,6 +68,7 @@\n #include <bits/stl_uninitialized.h>\n #include <bits/stl_deque.h>\n #include <bits/range_access.h>\n+#include <bits/erase_if.h>\n #include <bits/deque.tcc>\n \n #define __glibcxx_want_algorithm_default_value_type\n@@ -103,19 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Tp, typename _Alloc, typename _Predicate>\n     inline typename _GLIBCXX_STD_C::deque<_Tp, _Alloc>::size_type\n     erase_if(_GLIBCXX_STD_C::deque<_Tp, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      const auto __osz = __cont.size();\n-      const auto __end = __cont.end();\n-      auto __removed = std::__remove_if(__cont.begin(), __end,\n-\t\t\t\t\tstd::move(__pred));\n-      if (__removed != __end)\n-\t{\n-\t  __cont.erase(__removed, __end);\n-\t  return __osz - __cont.size();\n-\t}\n-\n-      return 0;\n-    }\n+    { return __detail::__erase_if(__cont, __cont, std::move(__pred)); }\n \n   template<typename _Tp, typename _Alloc,\n \t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\ndiff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list\nindex 413fcaf3b4c4..ff0c58455cf5 100644\n--- a/libstdc++-v3/include/std/forward_list\n+++ b/libstdc++-v3/include/std/forward_list\n@@ -75,14 +75,14 @@ namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Tp, typename _Alloc, typename _Predicate>\n-    inline typename forward_list<_Tp, _Alloc>::size_type\n-    erase_if(forward_list<_Tp, _Alloc>& __cont, _Predicate __pred)\n+    inline typename _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::forward_list<_Tp, _Alloc>& __cont, _Predicate __pred)\n     { return __cont.remove_if(__pred); }\n \n   template<typename _Tp, typename _Alloc,\n \t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\n-    inline typename forward_list<_Tp, _Alloc>::size_type\n-    erase(forward_list<_Tp, _Alloc>& __cont, const _Up& __value)\n+    inline typename _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>::size_type\n+    erase(_GLIBCXX_STD_C::forward_list<_Tp, _Alloc>& __cont, const _Up& __value)\n     {\n       // _GLIBCXX_RESOLVE_LIB_DEFECTS\n       // 4135. helper lambda of std::erase for list should specify return type\ndiff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector\nindex df95c1e5c021..c22a9e1f9b40 100644\n--- a/libstdc++-v3/include/std/inplace_vector\n+++ b/libstdc++-v3/include/std/inplace_vector\n@@ -46,6 +46,7 @@\n #include <bits/stl_construct.h>\n #include <bits/stl_uninitialized.h>\n #include <bits/stl_algo.h> // rotate\n+#include <bits/erase_if.h>\n \n namespace std _GLIBCXX_VISIBILITY(default)\n {\n@@ -1339,17 +1340,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER\n \t     _Predicate __pred)\n     {\n       if constexpr (_Nm != 0)\n-\t{\n-\t  const auto __osz = __cont.size();\n-\t  const auto __end = __cont.end();\n-\t  auto __removed = std::__remove_if(__cont.begin(), __end,\n-\t\t\t\t\t    std::move(__pred));\n-\t  if (__removed != __end)\n-\t    {\n-\t      __cont.erase(__removed, __end);\n-\t      return __osz - __cont.size();\n-\t    }\n-\t}\n+\treturn __detail::__erase_if(__cont, __cont, std::move(__pred));\n \n       return 0;\n     }\ndiff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list\nindex 3feff4d7b8b0..a3e7c81680a9 100644\n--- a/libstdc++-v3/include/std/list\n+++ b/libstdc++-v3/include/std/list\n@@ -99,14 +99,14 @@ namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Tp, typename _Alloc, typename _Predicate>\n-    inline typename list<_Tp, _Alloc>::size_type\n-    erase_if(list<_Tp, _Alloc>& __cont, _Predicate __pred)\n+    inline typename _GLIBCXX_STD_C::list<_Tp, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::list<_Tp, _Alloc>& __cont, _Predicate __pred)\n     { return __cont.remove_if(__pred); }\n \n   template<typename _Tp, typename _Alloc,\n \t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\n-    inline typename list<_Tp, _Alloc>::size_type\n-    erase(list<_Tp, _Alloc>& __cont, const _Up& __value)\n+    inline typename _GLIBCXX_STD_C::list<_Tp, _Alloc>::size_type\n+    erase(_GLIBCXX_STD_C::list<_Tp, _Alloc>& __cont, const _Up& __value)\n     {\n       // _GLIBCXX_RESOLVE_LIB_DEFECTS\n       // 4135. helper lambda of std::erase for list should specify return type\ndiff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map\nindex b4d39959f0d1..88e549411afd 100644\n--- a/libstdc++-v3/include/std/map\n+++ b/libstdc++-v3/include/std/map\n@@ -101,29 +101,26 @@ _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n #endif // C++17\n \n-#if __cplusplus > 201703L\n+#ifdef __cpp_lib_erase_if // C++ >= 20 && HOSTED\n namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename map<_Key, _Tp, _Compare, _Alloc>::size_type\n-    erase_if(map<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>& __ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    inline typename _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n \n   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename multimap<_Key, _Tp, _Compare, _Alloc>::size_type\n-    erase_if(multimap<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>& __ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    inline typename _GLIBCXX_STD_C::multimap<_Key, _Tp,\n+\t\t\t\t\t     _Compare, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n-#endif // C++20\n+#endif // __cpp_lib_erase_if\n \n #endif /* _GLIBCXX_MAP */\ndiff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set\nindex 95b9e26a99fb..af6d3814b4b1 100644\n--- a/libstdc++-v3/include/std/set\n+++ b/libstdc++-v3/include/std/set\n@@ -95,29 +95,25 @@ _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n #endif // C++17\n \n-#if __cplusplus > 201703L\n+#ifdef __cpp_lib_erase_if // C++ >= 20 && HOSTED\n namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Key, typename _Compare, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename set<_Key, _Compare, _Alloc>::size_type\n-    erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    inline typename _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n \n   template<typename _Key, typename _Compare, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename multiset<_Key, _Compare, _Alloc>::size_type\n-    erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    inline typename _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __cont,\n+\t     _Predicate __pred)\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n-#endif // C++20\n+#endif // __cpp_lib_erase_if\n \n #endif /* _GLIBCXX_SET */\ndiff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string\nindex 3748e64964f9..c2b37391fc7a 100644\n--- a/libstdc++-v3/include/std/string\n+++ b/libstdc++-v3/include/std/string\n@@ -54,6 +54,7 @@\n #include <bits/stdexcept_throw.h>\n #include <bits/stl_algobase.h>\n #include <bits/range_access.h>\n+#include <bits/erase_if.h>\n #include <bits/basic_string.h>\n #include <bits/basic_string.tcc>\n #if (_GLIBCXX_HOSTED && __cpp_exceptions && __cplusplus > 202302L \\\n@@ -108,15 +109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t   typename _Predicate>\n     constexpr typename basic_string<_CharT, _Traits, _Alloc>::size_type\n     erase_if(basic_string<_CharT, _Traits, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      using namespace __gnu_cxx;\n-      const auto __osz = __cont.size();\n-      const auto __end = __cont.end();\n-      auto __removed = std::__remove_if(__cont.begin(), __end,\n-\t\t\t\t\tstd::move(__pred));\n-      __cont.erase(__removed, __end);\n-      return __osz - __cont.size();\n-    }\n+    { return __detail::__erase_if(__cont, __cont, std::move(__pred)); }\n \n   template<typename _CharT, typename _Traits, typename _Alloc,\n \t   typename _Up _GLIBCXX26_DEF_VAL_T(_CharT)>\ndiff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map\nindex c49c5c6835f5..9166f569ab1d 100644\n--- a/libstdc++-v3/include/std/unordered_map\n+++ b/libstdc++-v3/include/std/unordered_map\n@@ -80,35 +80,30 @@ _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n #endif // C++17\n \n-#if __cplusplus > 201703L\n+#ifdef __cpp_lib_erase_if // C++ >= 20 && HOSTED\n namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Key, typename _Tp, typename _Hash, typename _CPred,\n \t   typename _Alloc, typename _Predicate>\n-    inline typename unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>::size_type\n-    erase_if(unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,\n+    inline typename _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,\n+\t\t\t\t\t\t  _CPred, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,\n+\t\t\t\t\t   _CPred, _Alloc>& __cont,\n \t     _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>&\n-\t__ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n \n   template<typename _Key, typename _Tp, typename _Hash, typename _CPred,\n \t   typename _Alloc, typename _Predicate>\n-    inline typename unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>::\n-\t\t    size_type\n-    erase_if(unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,\n+    inline typename _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,\n+\t\t\t\t\t\t      _CPred, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,\n+\t\t\t\t\t\t_CPred, _Alloc>& __cont,\n \t     _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>&\n-\t__ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n-#endif // C++20\n+#endif // __cpp_lib_erase_if\n \n #endif // C++11\n \ndiff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set\nindex 512d542a0b58..157f72ce32df 100644\n--- a/libstdc++-v3/include/std/unordered_set\n+++ b/libstdc++-v3/include/std/unordered_set\n@@ -78,34 +78,28 @@ _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n #endif // C++17\n \n-#if __cplusplus > 201703L\n+#ifdef __cpp_lib_erase_if // C++ >= 20 && HOSTED\n namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename unordered_set<_Key, _Hash, _CPred, _Alloc>::size_type\n-    erase_if(unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont,\n+    inline typename _GLIBCXX_STD_C::unordered_set<_Key, _Hash,\n+\t\t\t\t\t\t  _CPred, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont,\n \t     _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>&\n-\t__ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n \n   template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,\n \t   typename _Predicate>\n-    inline typename unordered_multiset<_Key, _Hash, _CPred, _Alloc>::size_type\n-    erase_if(unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont,\n+    inline typename _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash,\n+\t\t\t\t\t\t      _CPred, _Alloc>::size_type\n+    erase_if(_GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont,\n \t     _Predicate __pred)\n-    {\n-      _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>&\n-\t__ucont = __cont;\n-      return __detail::__erase_nodes_if(__cont, __ucont, __pred);\n-    }\n+    { return __detail::__erase_nodes_if(__cont, __cont, __pred); }\n _GLIBCXX_END_NAMESPACE_VERSION\n } // namespace std\n-#endif // C++20\n+#endif // __cpp_lib_erase_if\n \n #endif // C++11\n \ndiff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector\nindex 61c750f94ff2..343483e95191 100644\n--- a/libstdc++-v3/include/std/vector\n+++ b/libstdc++-v3/include/std/vector\n@@ -68,6 +68,7 @@\n #include <bits/stl_vector.h>\n #include <bits/stl_bvector.h>\n #include <bits/range_access.h>\n+#include <bits/erase_if.h>\n \n #ifndef _GLIBCXX_EXPORT_TEMPLATE\n # include <bits/vector.tcc>\n@@ -114,19 +115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   template<typename _Tp, typename _Alloc, typename _Predicate>\n     constexpr typename _GLIBCXX_STD_C::vector<_Tp, _Alloc>::size_type\n     erase_if(_GLIBCXX_STD_C::vector<_Tp, _Alloc>& __cont, _Predicate __pred)\n-    {\n-      const auto __osz = __cont.size();\n-      const auto __end = __cont.end();\n-      auto __removed = std::__remove_if(__cont.begin(), __end,\n-\t\t\t\t\tstd::move(__pred));\n-      if (__removed != __end)\n-\t{\n-\t  __cont.erase(__removed, __end);\n-\t  return __osz - __cont.size();\n-\t}\n-\n-      return 0;\n-    }\n+    { return __detail::__erase_if(__cont, __cont, std::move(__pred)); }\n \n   template<typename _Tp, typename _Alloc,\n \t   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>\ndiff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/erase.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/erase.cc\nnew file mode 100644\nindex 000000000000..b381ad157382\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/erase.cc\n@@ -0,0 +1,25 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/string>\n+#include <testsuite_hooks.h>\n+\n+using __gnu_debug::string;\n+\n+void test01()\n+{\n+  string str(\"abcdefghijklmnopqrstuvwxyz\");\n+\n+  auto before = str.begin();\n+  auto last = str.end() - 1;\n+\n+  VERIFY( std::erase(str, 'd') == 1 );\n+\n+  VERIFY(before._M_singular());\n+  VERIFY(last._M_singular());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/erase.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/erase.cc\nnew file mode 100644\nindex 000000000000..061dfcbd9e31\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/erase.cc\n@@ -0,0 +1,26 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <forward_list>\n+#include <testsuite_hooks.h>\n+\n+void test01()\n+{\n+  std::forward_list<int> fl({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });\n+\n+  auto before = ++fl.begin();\n+  auto match = std::next(fl.begin(), 6);\n+  auto last = std::next(fl.begin(), 9);\n+\n+  VERIFY( std::erase(fl, 6) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/invalidation/erase.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/invalidation/erase.cc\nnew file mode 100644\nindex 000000000000..15194173cc34\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/invalidation/erase.cc\n@@ -0,0 +1,27 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/forward_list>\n+#include <testsuite_hooks.h>\n+\n+using __gnu_debug::forward_list;\n+\n+void test01()\n+{\n+  forward_list<int> fl({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });\n+\n+  auto before = ++fl.begin();\n+  auto match = std::next(fl.begin(), 6);\n+  auto last = std::next(fl.begin(), 9);\n+\n+  VERIFY( std::erase(fl, 6) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/debug/erase.cc b/libstdc++-v3/testsuite/23_containers/list/debug/erase.cc\nnew file mode 100644\nindex 000000000000..d6210daf3446\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/debug/erase.cc\n@@ -0,0 +1,29 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <list>\n+#include <testsuite_hooks.h>\n+\n+void test01()\n+{\n+  std::list<int> l;\n+\n+  for (int i = 0; i != 10; ++i)\n+    l.push_back(i);\n+\n+  auto before = ++l.begin();\n+  auto match = std::next(l.begin(), 6);\n+  auto last = --l.end();\n+\n+  VERIFY( std::erase(l, 6) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/debug/invalidation/erase.cc b/libstdc++-v3/testsuite/23_containers/list/debug/invalidation/erase.cc\nnew file mode 100644\nindex 000000000000..57137fd08d62\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/debug/invalidation/erase.cc\n@@ -0,0 +1,30 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/list>\n+#include <testsuite_hooks.h>\n+\n+using __gnu_debug::list;\n+\n+void test01()\n+{\n+  list<int> l;\n+\n+  for (int i = 0; i != 10; ++i)\n+    l.push_back(i);\n+\n+  auto before = ++l.begin();\n+  auto match = std::next(l.begin(), 6);\n+  auto last = --l.end();\n+\n+  VERIFY( std::erase(l, 6) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/map/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/map/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..dfdfc1340fac\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/map/debug/erase_if.cc\n@@ -0,0 +1,33 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+void test01()\n+{\n+  std::map<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = ++m.begin();\n+  auto match = std::next(m.begin(), 6);\n+  auto last = std::next(m.begin(), 9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/map/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/map/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..ee080c31160f\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/map/debug/invalidation/erase_if.cc\n@@ -0,0 +1,34 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+using __gnu_debug::map;\n+\n+void test01()\n+{\n+  map<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = ++m.begin();\n+  auto match = std::next(m.begin(), 6);\n+  auto last = std::next(m.begin(), 9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..30b6b65e703c\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/erase_if.cc\n@@ -0,0 +1,33 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+void test01()\n+{\n+  std::multimap<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = ++m.begin();\n+  auto match = std::next(m.begin(), 6);\n+  auto last = std::next(m.begin(), 9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..c9f740ea4e6f\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/invalidation/erase_if.cc\n@@ -0,0 +1,34 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+using __gnu_debug::multimap;\n+\n+void test01()\n+{\n+  multimap<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = ++m.begin();\n+  auto match = std::next(m.begin(), 6);\n+  auto last = std::next(m.begin(), 9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..e54eaa797f87\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/erase_if.cc\n@@ -0,0 +1,31 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+void test01()\n+{\n+  std::multiset<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = ++s.begin();\n+  auto match = std::next(s.begin(), 6);\n+  auto last = std::next(s.begin(), 9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..c85b76fc506d\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/invalidation/erase_if.cc\n@@ -0,0 +1,32 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+using __gnu_debug::multiset;\n+\n+void test01()\n+{\n+  multiset<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = ++s.begin();\n+  auto match = std::next(s.begin(), 6);\n+  auto last = std::next(s.begin(), 9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/set/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/set/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..e8c64628a658\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/set/debug/erase_if.cc\n@@ -0,0 +1,31 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+void test01()\n+{\n+  std::set<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = ++s.begin();\n+  auto match = std::next(s.begin(), 6);\n+  auto last = std::next(s.begin(), 9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/set/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/set/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..99dde9bfcf29\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/set/debug/invalidation/erase_if.cc\n@@ -0,0 +1,32 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+using __gnu_debug::set;\n+\n+void test01()\n+{\n+  set<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = ++s.begin();\n+  auto match = std::next(s.begin(), 6);\n+  auto last = std::next(s.begin(), 9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..e7ac643c8ec5\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/erase_if.cc\n@@ -0,0 +1,33 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <unordered_map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+void test01()\n+{\n+  std::unordered_map<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = m.find(1);\n+  auto match = m.find(6);\n+  auto last = m.find(9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..303692838ac4\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/invalidation/erase_if.cc\n@@ -0,0 +1,34 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/unordered_map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+using __gnu_debug::unordered_map;\n+\n+void test01()\n+{\n+  unordered_map<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = m.find(1);\n+  auto match = m.find(6);\n+  auto last = m.find(9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..e8d98c96e6b6\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/erase_if.cc\n@@ -0,0 +1,33 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <unordered_map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+void test01()\n+{\n+  std::unordered_multimap<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = m.find(1);\n+  auto match = m.find(6);\n+  auto last = m.find(9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..375393365051\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/invalidation/erase_if.cc\n@@ -0,0 +1,34 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/unordered_map>\n+#include <testsuite_hooks.h>\n+\n+auto is_six_pair = [](const std::pair<const int, int>& p)\n+{\n+  return p.first == 6;\n+};\n+\n+using __gnu_debug::unordered_multimap;\n+\n+void test01()\n+{\n+  unordered_multimap<int, int> m;\n+  for (int i = 0; i != 10; ++i)\n+    m.insert({ i, i });\n+\n+  auto before = m.find(1);\n+  auto match = m.find(6);\n+  auto last = m.find(9);\n+\n+  VERIFY( std::erase_if(m, is_six_pair) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..8969a9dad5f1\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/erase_if.cc\n@@ -0,0 +1,31 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <unordered_set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+void test01()\n+{\n+  std::unordered_multiset<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = s.find(1);\n+  auto match = s.find(6);\n+  auto last = s.find(9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..f5ec00e2c1a6\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/invalidation/erase_if.cc\n@@ -0,0 +1,32 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/unordered_set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+using __gnu_debug::unordered_multiset;\n+\n+void test01()\n+{\n+  unordered_multiset<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = s.find(1);\n+  auto match = s.find(6);\n+  auto last = s.find(9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/erase_if.cc\nnew file mode 100644\nindex 000000000000..c725b94558ab\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/erase_if.cc\n@@ -0,0 +1,31 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-debug-mode \"\" }\n+\n+#include <unordered_set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+void test01()\n+{\n+  std::unordered_set<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = s.find(1);\n+  auto match = s.find(6);\n+  auto last = s.find(9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/invalidation/erase_if.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/invalidation/erase_if.cc\nnew file mode 100644\nindex 000000000000..61c1cffca222\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/invalidation/erase_if.cc\n@@ -0,0 +1,32 @@\n+// { dg-do run { target c++20 } }\n+\n+#include <debug/unordered_set>\n+#include <testsuite_hooks.h>\n+\n+auto is_six = [](int p)\n+{ return p == 6; };\n+\n+using __gnu_debug::unordered_set;\n+\n+void test01()\n+{\n+  unordered_set<int> s;\n+  for (int i = 0; i != 10; ++i)\n+    s.insert(i);\n+\n+  auto before = s.find(1);\n+  auto match = s.find(6);\n+  auto last = s.find(9);\n+\n+  VERIFY( std::erase_if(s, is_six) == 1 );\n+\n+  VERIFY(before._M_dereferenceable());\n+  VERIFY(match._M_singular());\n+  VERIFY(last._M_dereferenceable());\n+}\n+\n+int main()\n+{\n+  test01();\n+  return 0;\n+}\n",
    "prefixes": [
        "v1",
        "1/1"
    ]
}