get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2194811,
    "url": "http://patchwork.ozlabs.org/api/patches/2194811/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260210004855.1562521-1-ncm@cantrip.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": "<20260210004855.1562521-1-ncm@cantrip.org>",
    "list_archive_url": null,
    "date": "2026-02-10T00:47:20",
    "name": "[PATCHv6] libstdc++: container heterogenous insertion (P2363) [PR117402]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e6538ce261207107f771e917d655e4e31149d125",
    "submitter": {
        "id": 90892,
        "url": "http://patchwork.ozlabs.org/api/people/90892/?format=api",
        "name": "Nathan Myers",
        "email": "ncm@cantrip.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260210004855.1562521-1-ncm@cantrip.org/mbox/",
    "series": [
        {
            "id": 491585,
            "url": "http://patchwork.ozlabs.org/api/series/491585/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=491585",
            "date": "2026-02-10T00:47:20",
            "name": "[PATCHv6] libstdc++: container heterogenous insertion (P2363) [PR117402]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/491585/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2194811/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2194811/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;\n dmarc=none (p=none dis=none) header.from=cantrip.org",
            "sourceware.org; spf=fail smtp.mailfrom=cantrip.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=205.139.111.44"
        ],
        "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 4f92yk2Dgfz1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 11:49:47 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 345464BBC0FF\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 00:49:40 +0000 (GMT)",
            "from us-smtp-delivery-44.mimecast.com\n (us-smtp-delivery-44.mimecast.com [205.139.111.44])\n by sourceware.org (Postfix) with ESMTP id BACA64BBC0FF\n for <gcc-patches@gcc.gnu.org>; Tue, 10 Feb 2026 00:49:04 +0000 (GMT)",
            "from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-444-jmHGtdV3MeqLNHmnvHpHgw-1; Mon,\n 09 Feb 2026 19:49:00 -0500",
            "from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 119BC18003F5; Tue, 10 Feb 2026 00:49:00 +0000 (UTC)",
            "from redhat.redhat.com (unknown [10.2.16.56])\n by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 65D9219560A3; Tue, 10 Feb 2026 00:48:57 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 345464BBC0FF",
            "OpenDKIM Filter v2.11.0 sourceware.org BACA64BBC0FF"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org BACA64BBC0FF",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org BACA64BBC0FF",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770684544; cv=none;\n b=frPBYn/Sg38c4YCAt9E7k3wUy1FstiM6ztBuO8wXOt3XboidHr87BFyVt0Gfh14BOposC+6Ksx8QPIHzwc17iNqQtV3u7jLCCqL+9qz1z0NyRc/EpGnyuOl2ZndCJkNQSIeR4tiMLMPswTsH7PnPq24gf0YXDrWdveqZ/Ul/Bw0=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1770684544; c=relaxed/simple;\n bh=Qn69IrFzInGKHT5Q6VDWRpCClOxsvedDcZIOJOQ4K0Y=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=ODcgzGkhFlDcbFI4ZK5LTSiww1/J3Xth5qFz5Yac3AiL7lwLfnO7hJzmIG0hSW/KE4aP4SSThq6Hpgew4yYvV9I/atUUM72QCOk4jQeljd+j2ZlgVb4hyZ9DsF82UsoBD74jyJdTjxXfhC2bVENqvS+RI+8jENdkx7BpSogSjQ0=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "X-MC-Unique": "jmHGtdV3MeqLNHmnvHpHgw-1",
        "X-Mimecast-MFC-AGG-ID": "jmHGtdV3MeqLNHmnvHpHgw_1770684540",
        "From": "Nathan Myers <ncm@cantrip.org>",
        "To": "gcc-patches@gcc.gnu.org,\n\tlibstdc++@gcc.gnu.org",
        "Subject": "[PATCHv6] libstdc++: container heterogenous insertion (P2363)\n [PR117402]",
        "Date": "Mon,  9 Feb 2026 19:47:20 -0500",
        "Message-ID": "<20260210004855.1562521-1-ncm@cantrip.org>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.12",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "--FgePuH9hm3sOxwmknLIEYNTBdzlgKTa9eproqRnaE_1770684540",
        "X-Mimecast-Originator": "cantrip.org",
        "Content-Transfer-Encoding": "quoted-printable",
        "content-type": "text/plain; charset=WINDOWS-1252; x-default=true",
        "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>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "Changes in v6: (Note, this was recently mis-posted as v5.)\n  - More testing for op[] and at(): move-from key argument when and\n   only when permitted.\n\nChanges in v5:\n  - Fix typos in set/modifiers/hetero/insert.cc.\n  - Fix chart in commit message.\n\nChanges in v4:\n  - Rebase on committed P2077 erasures.\n  - Remove conditional compilation on impl helpers in\n   bits/stl_tree.h, hashtable.h, hashtable_policy.h.\n  - Regularize ChangeLog format.\n  - Test propagation of heterogeneous key's value category\n   through to conversion to key_type.\n  - Test propagation of variadic-arguments' value categories\n   from try_emplace through to underlying constructors.\n  - Regularize template argument name s/_Mapped/_Obj/.\n\nChanges in v3:\n  - Make tests run, and pass.\n  - Note added members in Changelog.\n\nChange in v2: fix remaining regression, SEGV in 92878_92947.cc.\n\nImplements P2353R5 \"Extending associative containers with the\nremaining heterogeneous overloads\". Adds overloads templated on\nheterogeneous key types for several members of associative\ncontainers, particularly insertions:\n\n                      un-   un-  un-  unordered\n set  map  mset mmap  set   map  mset mmap\n  @    .    .    .     @     .    .    .   insert\n  .    @    .    .     .     @    .    .   op[], at, try_emplace,\n                                            insert_or_assign\n  .    .    .    .     @     @    @    @   bucket\n\n(Nothing is added to the multiset or multimap tree containers.)\nAll the insert*() and try_emplace() members also get a hinted\noverload.  The at() members get const and non-const overloads.\n\nThe new overloads enforce concept __heterogeneous_tree_key or\n__heterogeneous_hash_key, as in P2077, to enforce that the\nfunction objects provided meet requirements, and that the key\nsupplied is not an iterator or the native key. Insertions\nimplicitly construct the required key_type object from the\nargument, by move where permitted.\n\nDoxygen annotations are improved.\n\nlibstdc++-v3/ChangeLog:\n\tPR libstdc++/117402\n\t* include/bits/stl_map.h (operator[], at (2x), try_emplace (2x),\n\tinsert_or_assign (2x)): Add overloads.\n\t* include/bits/unordered_map.h: Same, plus...\n\t(bucket (2x)): Add overloads.\n\t* include/bits/stl_set.h (insert (2x)): Add overloads.\n\t* include/bits/unordered_set.h: Same, plus...\n\t(bucket (2x)): Add overloads.\n\t* include/bits/hashtable.h (_M_bucket_tr, _M_insert_tr): Define.\n\t* include/bits/hashtable_policy.h (_M_index_to_tr, _M_at_tr (2x),\n\t_M_index_to_tr): Define.\n\t* include/bits/stl_tree.h (_M_get_insert_unique_pos_tr,\n\t_M_get_insert_hint_unique_pos_tr): Define.\n\t* include/bits/version.def (associative_heterogeneous_insertion):\n\tDefine.\n\t* include/bits/version.h: Regenerate.\n\t* include/std/map (__glibcxx_want_associative_heterogeneous_insertion):\n\tDefine macro.\n\t* include/std/set: Same.\n\t* include/std/unordered_map: Same.\n\t* include/std/unordered_set: Same.\n\t* testsuite/23_containers/map/modifiers/hetero/insert.cc: New tests.\n\t* testsuite/23_containers/set/modifiers/hetero/insert.cc: Same.\n\t* testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc:\n\tSame.\n\t* testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc:\n\tSame.\n\t* testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc:\n\tSame.\n\t* testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc:\n\tSame.\n---\n libstdc++-v3/include/bits/hashtable.h         |  27 ++\n libstdc++-v3/include/bits/hashtable_policy.h  |  60 ++-\n libstdc++-v3/include/bits/stl_map.h           | 126 ++++++-\n libstdc++-v3/include/bits/stl_set.h           |  21 ++\n libstdc++-v3/include/bits/stl_tree.h          | 106 +++++-\n libstdc++-v3/include/bits/unordered_map.h     |  96 +++++\n libstdc++-v3/include/bits/unordered_set.h     |  32 ++\n libstdc++-v3/include/bits/version.def         |   8 +\n libstdc++-v3/include/bits/version.h           |  10 +\n libstdc++-v3/include/std/map                  |   1 +\n libstdc++-v3/include/std/set                  |   1 +\n libstdc++-v3/include/std/unordered_map        |   1 +\n libstdc++-v3/include/std/unordered_set        |   1 +\n .../map/modifiers/hetero/insert.cc            | 341 +++++++++++++++++\n .../set/modifiers/hetero/insert.cc            | 120 ++++++\n .../unordered_map/modifiers/hetero/insert.cc  | 353 ++++++++++++++++++\n .../modifiers/hetero/insert.cc                |  57 +++\n .../modifiers/hetero/insert.cc                |  56 +++\n .../unordered_set/modifiers/hetero/insert.cc  | 134 +++++++\n 19 files changed, 1544 insertions(+), 7 deletions(-)\n create mode 100644 libstdc++-v3/testsuite/23_containers/map/modifiers/hetero/insert.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/set/modifiers/hetero/insert.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc",
    "diff": "diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h\nindex 48695c013f3..fc7a5aae595 100644\n--- a/libstdc++-v3/include/bits/hashtable.h\n+++ b/libstdc++-v3/include/bits/hashtable.h\n@@ -700,6 +700,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       bucket(const key_type& __k) const\n       { return _M_bucket_index(this->_M_hash_code(__k)); }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26, P2363\n+      template <typename _Kt>\n+\tsize_type\n+\t_M_bucket_tr(const _Kt& __k) const\n+\t{ return _M_bucket_index(this->_M_hash_code_tr(__k)); }\n+#endif\n+\n       local_iterator\n       begin(size_type __bkt)\n       {\n@@ -1097,6 +1104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \tstd::pair<iterator, bool>\n \ttry_emplace(const_iterator, _KType&& __k, _Args&&... __args)\n \t{\n+\t  // Note we ignore the hint argument.\n \t  __hash_code __code;\n \t  size_type __bkt;\n \t  if (auto __loc = _M_locate(__k))\n@@ -1117,6 +1125,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t  __node._M_node = nullptr;\n \t  return { __it, true };\n \t}\n+\n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26, P2363\n+      template<typename _Kt>\n+\tstd::pair<iterator, bool>\n+\t_M_insert_tr(_Kt&& __k)\n+\t{\n+\t  auto __loc = _M_locate_tr(__k);\n+\t  if (__loc)\n+\t    return { iterator(__loc), false };\n+\n+\t  _Scoped_node __node(\n+\t    this->_M_allocate_node(std::forward<_Kt>(__k)), this);\n+\t  auto __it = _M_insert_unique_node(\n+\t    __loc._M_bucket_index, __loc._M_hash_code, __node._M_node);\n+\t  __node._M_node = nullptr;\n+\t  return { __it, true };\n+\t}\n+#endif\n #endif\n \n       void\n@@ -2363,6 +2389,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t__node._M_node = nullptr;\n \treturn { __pos, true };\n       }\n+\n #pragma GCC diagnostic pop\n \n   template<typename _Key, typename _Value, typename _Alloc,\ndiff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h\nindex 6d7bde1e785..92fa6e82e5b 100644\n--- a/libstdc++-v3/include/bits/hashtable_policy.h\n+++ b/libstdc++-v3/include/bits/hashtable_policy.h\n@@ -872,6 +872,33 @@ namespace __detail\n \t  __throw_out_of_range(__N(\"unordered_map::at\"));\n \treturn __ite->second;\n       }\n+\n+      // op[] for transparent heterogeneous key\n+      template <typename _Kt>\n+\tmapped_type&\n+\t_M_index_to_tr(const _Kt& __k);\n+\n+      // _GLIBCXX_RESOLVE_LIB_DEFECTS\n+      // DR 761. unordered_map needs an at() member function.\n+      template <typename _Kt>\n+\tmapped_type&\n+\t_M_at_tr(const _Kt& __k)\n+\t{\n+\t  auto __ite = static_cast<__hashtable*>(this)->_M_find_tr(__k);\n+\t  if (!__ite._M_cur)\n+\t    __throw_out_of_range(__N(\"unordered_map::at\"));\n+\t  return __ite->second;\n+\t}\n+\n+      template <typename _Kt>\n+\tconst mapped_type&\n+\t_M_at_tr(const _Kt& __k) const\n+\t{\n+\t  auto __ite = static_cast<const __hashtable*>(this)->_M_find_tr(__k);\n+\t  if (!__ite._M_cur)\n+\t    __throw_out_of_range(__N(\"unordered_map::at\"));\n+\t  return __ite->second;\n+\t}\n     };\n \n   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,\n@@ -901,6 +928,33 @@ namespace __detail\n       return __pos->second;\n     }\n \n+  // op[] for heterogeneous keys\n+  template<typename _Key, typename _Val, typename _Alloc, typename _Equal,\n+\t   typename _Hash, typename _RangeHash, typename _Unused,\n+\t   typename _RehashPolicy, typename _Traits>\n+    template <typename _Kt>\n+      auto\n+      _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,\n+\t\t_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::\n+      _M_index_to_tr(const _Kt& __k)\n+      -> mapped_type&\n+    {\n+      __hashtable* __h = static_cast<__hashtable*>(this);\n+      __hash_code __code = __h->_M_hash_code_tr(__k);\n+      size_t __bkt = __h->_M_bucket_index(__code);\n+      if (auto __node = __h->_M_find_node_tr(__bkt, __k, __code))\n+\treturn __node->_M_v().second;\n+\n+      typename __hashtable::_Scoped_node __node {\n+\t__h, std::piecewise_construct,\n+\tstd::tuple<key_type>(__k), std::tuple<>()\n+      };\n+      auto __pos\n+\t= __h->_M_insert_unique_node(__bkt, __code, __node._M_node);\n+      __node._M_node = nullptr;\n+      return __pos->second;\n+    }\n+\n   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,\n \t   typename _Hash, typename _RangeHash, typename _Unused,\n \t   typename _RehashPolicy, typename _Traits>\n@@ -1413,8 +1467,7 @@ namespace __detail\n       template<typename _Kt>\n \tbool\n \t_M_key_equals_tr(const _Kt& __k,\n-\t\t\t const _Hash_node_value<_Value,\n-\t\t\t\t\t     __hash_cached::value>& __n) const\n+\t  const _Hash_node_value<_Value, __hash_cached::value>& __n) const\n \t{\n \t  static_assert(\n \t    __is_invocable<const _Equal&, const _Kt&, const _Key&>{},\n@@ -1439,8 +1492,7 @@ namespace __detail\n       template<typename _Kt>\n \tbool\n \t_M_equals_tr(const _Kt& __k, __hash_code __c,\n-\t\t     const _Hash_node_value<_Value,\n-\t\t\t\t\t    __hash_cached::value>& __n) const\n+\t  const _Hash_node_value<_Value, __hash_cached::value>& __n) const\n \t{\n \t  if constexpr (__hash_cached::value)\n \t    if (__c != __n._M_hash_code)\ndiff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h\nindex 4cb0c982c3d..f4b0982af72 100644\n--- a/libstdc++-v3/include/bits/stl_map.h\n+++ b/libstdc++-v3/include/bits/stl_map.h\n@@ -511,6 +511,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       max_size() const _GLIBCXX_NOEXCEPT\n       { return _M_t.max_size(); }\n \n+      ///@{\n       // [23.3.1.2] element access\n       /**\n        *  @brief  Subscript ( @c [] ) access to %map data.\n@@ -560,6 +561,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       }\n #endif\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt>\n+\tmapped_type&\n+\toperator[](_Kt&& __k)\n+\t{ return try_emplace(std::forward<_Kt>(__k)).first->second; }\n+#endif\n+      ///@}\n+\n+      ///@{\n       // _GLIBCXX_RESOLVE_LIB_DEFECTS\n       // DR 464. Suggestion for new member functions in standard containers.\n       /**\n@@ -578,6 +588,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \treturn (*__i).second;\n       }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt>\n+\tmapped_type&\n+\tat(const _Kt& __k)\n+\t{\n+\t  iterator __i = lower_bound(__k);\n+\t  if (__i == end() || key_comp()(__k, (*__i).first))\n+\t    __throw_out_of_range(__N(\"map::at\"));\n+\t  return (*__i).second;\n+\t}\n+#endif\n+\n       const mapped_type&\n       at(const key_type& __k) const\n       {\n@@ -587,6 +609,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \treturn (*__i).second;\n       }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt>\n+\tconst mapped_type&\n+\tat(const _Kt& __k) const\n+\t{\n+\t  const_iterator __i = lower_bound(__k);\n+\t  if (__i == end() || key_comp()(__k, (*__i).first))\n+\t    __throw_out_of_range(__N(\"map::at\"));\n+\t  return (*__i).second;\n+\t}\n+#endif\n+      ///@}\n+\n       // modifiers\n #if __cplusplus >= 201103L\n       /**\n@@ -728,6 +763,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n #endif // C++17\n \n #ifdef __glibcxx_map_try_emplace // C++ >= 17 && HOSTED\n+      ///@{\n       /**\n        *  @brief Attempts to build and insert a std::pair into the %map.\n        *\n@@ -781,6 +817,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  return {__i, false};\n \t}\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt, typename ..._Args>\n+\tpair<iterator, bool>\n+\ttry_emplace(_Kt&& __k, _Args&&... __args)\n+\t{\n+\t  iterator __i = lower_bound(__k);\n+\t  if (__i == end() || key_comp()(__k, (*__i).first))\n+\t    {\n+\t      __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,\n+\t\tstd::forward_as_tuple(std::forward<_Kt>(__k)),\n+\t\tstd::forward_as_tuple(std::forward<_Args>(__args)...));\n+\t      return {__i, true};\n+\t    }\n+\t  return {__i, false};\n+\t}\n+#endif\n+      ///@}\n+\n+      ///@{\n       /**\n        *  @brief Attempts to build and insert a std::pair into the %map.\n        *\n@@ -845,6 +900,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t}\n #endif\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt, typename ..._Args>\n+\titerator\n+\ttry_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)\n+\t{\n+\t  iterator __i;\n+\t  auto __true_hint = _M_t._M_get_insert_hint_unique_pos_tr(__hint, __k);\n+\t  if (__true_hint.second)\n+\t    __i = _M_t._M_emplace_hint_unique(iterator(__true_hint.second),\n+\t\tstd::piecewise_construct,\n+\t\tstd::forward_as_tuple(std::forward<_Kt>(__k)),\n+\t\tstd::forward_as_tuple(std::forward<_Args>(__args)...));\n+\t  else\n+\t    __i = iterator(__true_hint.first);\n+\t  return __i;\n+\t}\n+#endif\n+      ///@}\n+\n+      ///@{\n       /**\n        *  @brief Attempts to insert a std::pair into the %map.\n        *  @param __x Pair to be inserted (see std::make_pair for easy\n@@ -896,7 +971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  return _M_t._M_emplace_unique(std::forward<_Pair>(__x));\n \t}\n #endif\n-      /// @}\n+      ///@}\n \n #if __cplusplus >= 201103L\n       /**\n@@ -929,6 +1004,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t}\n #endif\n \n+      ///@{\n       /**\n        *  @brief Attempts to insert a std::pair into the %map.\n        *  @param  __position  An iterator that serves as a hint as to where the\n@@ -992,6 +1068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t{ _M_t._M_insert_range_unique(__first, __last); }\n \n #if __cplusplus > 201402L\n+      ///@{\n       /**\n        *  @brief Attempts to insert or assign a std::pair into the %map.\n        *  @param __k    Key to use for finding a possibly existing pair in\n@@ -1046,6 +1123,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  return {__i, false};\n \t}\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt, typename _Obj>\n+\tpair<iterator, bool>\n+\tinsert_or_assign(_Kt&& __k, _Obj&& __obj)\n+\t{\n+\t  iterator __i = lower_bound(__k);\n+\t  if (__i == end() || key_comp()(__k, (*__i).first))\n+\t    {\n+\t      __i = _M_t._M_emplace_hint_unique(__i,\n+\t\tstd::piecewise_construct,\n+\t\tstd::forward_as_tuple(std::forward<_Kt>(__k)),\n+\t\tstd::forward_as_tuple(std::forward<_Obj>(__obj)));\n+\t      return {__i, true};\n+\t    }\n+\t  (*__i).second = std::forward<_Obj>(__obj);\n+\t  return {__i, false};\n+\t}\n+#endif\n+      ///@}\n+#endif\n+\n+#if __cplusplus > 201402L\n+      ///@{\n       /**\n        *  @brief Attempts to insert or assign a std::pair into the %map.\n        *  @param  __hint  An iterator that serves as a hint as to where the\n@@ -1105,9 +1205,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  (*__i).second = std::forward<_Obj>(__obj);\n \t  return __i;\n \t}\n+\n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<map> _Kt, typename _Obj>\n+\titerator\n+\tinsert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)\n+\t{\n+\t  iterator __i;\n+\t  auto __true_hint =\n+\t    _M_t._M_get_insert_hint_unique_pos_tr(__hint, __k);\n+\t  if (__true_hint.second)\n+\t    {\n+\t      return _M_t._M_emplace_hint_unique(\n+\t\titerator(__true_hint.second),\n+\t\tstd::piecewise_construct,\n+\t\tstd::forward_as_tuple(std::forward<_Kt>(__k)),\n+\t\tstd::forward_as_tuple(std::forward<_Obj>(__obj)));\n+\t    }\n+\t  __i = iterator(__true_hint.first);\n+\t  (*__i).second = std::forward<_Obj>(__obj);\n+\t  return __i;\n+\t}\n+#endif\n+      ///@}\n #endif\n \n #if __cplusplus >= 201103L\n+      ///@{\n       // _GLIBCXX_RESOLVE_LIB_DEFECTS\n       // DR 130. Associative erase should return an iterator.\n       /**\ndiff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h\nindex d3a4c089110..d3e876039d8 100644\n--- a/libstdc++-v3/include/bits/stl_set.h\n+++ b/libstdc++-v3/include/bits/stl_set.h\n@@ -517,6 +517,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t}\n #endif\n \n+      ///@{\n       /**\n        *  @brief Attempts to insert an element into the %set.\n        *  @param  __x  Element to be inserted.\n@@ -548,6 +549,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       }\n #endif\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<set> _Kt>\n+\tpair<iterator, bool>\n+\tinsert(_Kt&& __x)\n+\t{\n+\t  auto __p = _M_t._M_insert_unique(std::forward<_Kt>(__x));\n+\t  return {__p.first, __p.second};\n+\t}\n+#endif\n+      ///@}\n+\n+      ///@{\n       /**\n        *  @brief Attempts to insert an element into the %set.\n        *  @param  __position  An iterator that serves as a hint as to where the\n@@ -577,6 +590,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       { return _M_t._M_insert_unique_(__position, std::move(__x)); }\n #endif\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_tree_key<set> _Kt>\n+\titerator\n+\tinsert(const_iterator __position, _Kt&& __x)\n+\t{ return _M_t._M_insert_unique_(__position, std::forward<_Kt>(__x)); }\n+#endif\n+      ///@}\n+\n       /**\n        *  @brief A template function that attempts to insert a range\n        *  of elements.\ndiff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h\nindex 5d361b55028..ebe4810bcbc 100644\n--- a/libstdc++-v3/include/bits/stl_tree.h\n+++ b/libstdc++-v3/include/bits/stl_tree.h\n@@ -1459,6 +1459,10 @@ namespace __rb_tree\n       pair<_Base_ptr, _Base_ptr>\n       _M_get_insert_unique_pos(const key_type& __k);\n \n+      template <typename _Kt>\n+\tpair<_Base_ptr, _Base_ptr>\n+\t_M_get_insert_unique_pos_tr(const _Kt& __k);\n+\n       pair<_Base_ptr, _Base_ptr>\n       _M_get_insert_equal_pos(const key_type& __k);\n \n@@ -1466,6 +1470,11 @@ namespace __rb_tree\n       _M_get_insert_hint_unique_pos(const_iterator __pos,\n \t\t\t\t    const key_type& __k);\n \n+      template <typename _Kt>\n+\tpair<_Base_ptr, _Base_ptr>\n+\t_M_get_insert_hint_unique_pos_tr(\n+\t  const_iterator __pos, const _Kt& __k);\n+\n       pair<_Base_ptr, _Base_ptr>\n       _M_get_insert_hint_equal_pos(const_iterator __pos,\n \t\t\t\t   const key_type& __k);\n@@ -2060,7 +2069,7 @@ namespace __rb_tree\n       _M_move_assign(_Rb_tree&, false_type);\n #endif\n \n-#if __glibcxx_node_extract // >= C++17\n+#ifdef __glibcxx_node_extract // >= C++17\n       static _Node_ptr\n       _S_adapt(typename _Node_alloc_traits::pointer __ptr)\n       {\n@@ -2810,6 +2819,40 @@ namespace __rb_tree\n       return _Res(__j._M_node, _Base_ptr());\n     }\n \n+  template<typename _Key, typename _Val, typename _KeyOfValue,\n+\t   typename _Compare, typename _Alloc>\n+    template <typename _Kt>\n+      pair<\n+\ttypename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+\t  _Base_ptr,\n+\ttypename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+\t  _Base_ptr>\n+      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+      _M_get_insert_unique_pos_tr(const _Kt& __k)\n+    {\n+      typedef pair<_Base_ptr, _Base_ptr> _Res;\n+      _Base_ptr __x = _M_begin();\n+      _Base_ptr __y = _M_end();\n+      bool __comp = true;\n+      while (__x)\n+\t{\n+\t  __y = __x;\n+\t  __comp = _M_key_compare(__k, _S_key(__x));\n+\t  __x = __comp ? _S_left(__x) : _S_right(__x);\n+\t}\n+      iterator __j = iterator(__y);\n+      if (__comp)\n+\t{\n+\t  if (__j == begin())\n+\t    return _Res(__x, __y);\n+\t  else\n+\t    --__j;\n+\t}\n+      if (_M_key_compare(_S_key(__j._M_node), __k))\n+\treturn _Res(__x, __y);\n+      return _Res(__j._M_node, _Base_ptr());\n+    }\n+\n   template<typename _Key, typename _Val, typename _KeyOfValue,\n \t   typename _Compare, typename _Alloc>\n     pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,\n@@ -2936,6 +2979,65 @@ namespace __rb_tree\n \treturn _Res(__position._M_node, _Base_ptr());\n     }\n \n+  template<typename _Key, typename _Val, typename _KeyOfValue,\n+\t   typename _Compare, typename _Alloc>\n+    template <typename _Kt>\n+      pair<\n+\ttypename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+\t  _Base_ptr,\n+\ttypename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+\t  _Base_ptr>\n+      _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::\n+      _M_get_insert_hint_unique_pos_tr(\n+\t  const_iterator __position, const _Kt& __k)\n+      {\n+\ttypedef pair<_Base_ptr, _Base_ptr> _Res;\n+\n+\t// end()\n+\tif (__position._M_node == _M_end())\n+\t  {\n+\t    if (size() > 0 && _M_key_compare(_S_key(_M_rightmost()), __k))\n+\t      return _Res(_Base_ptr(), _M_rightmost());\n+\t    else\n+\t      return _M_get_insert_unique_pos_tr(__k);\n+\t  }\n+\telse if (_M_key_compare(__k, _S_key(__position._M_node)))\n+\t  {\n+\t    // First, try before...\n+\t    iterator __before(__position._M_node);\n+\t    if (__position._M_node == _M_leftmost()) // begin()\n+\t      return _Res(_M_leftmost(), _M_leftmost());\n+\t    else if (_M_key_compare(_S_key((--__before)._M_node), __k))\n+\t      {\n+\t\tif (!_S_right(__before._M_node))\n+\t\t  return _Res(_Base_ptr(), __before._M_node);\n+\t\telse\n+\t\t  return _Res(__position._M_node, __position._M_node);\n+\t      }\n+\t    else\n+\t      return _M_get_insert_unique_pos_tr(__k);\n+\t  }\n+\telse if (_M_key_compare(_S_key(__position._M_node), __k))\n+\t  {\n+\t    // ... then try after.\n+\t    iterator __after(__position._M_node);\n+\t    if (__position._M_node == _M_rightmost())\n+\t      return _Res(_Base_ptr(), _M_rightmost());\n+\t    else if (_M_key_compare(__k, _S_key((++__after)._M_node)))\n+\t      {\n+\t\tif (!_S_right(__position._M_node))\n+\t\t  return _Res(_Base_ptr(), __position._M_node);\n+\t\telse\n+\t\t  return _Res(__after._M_node, __after._M_node);\n+\t      }\n+\t    else\n+\t      return _M_get_insert_unique_pos_tr(__k);\n+\t  }\n+\telse\n+\t  // Equivalent keys.\n+\t  return _Res(__position._M_node, _Base_ptr());\n+      }\n+\n   template<typename _Key, typename _Val, typename _KeyOfValue,\n \t   typename _Compare, typename _Alloc>\n #if __cplusplus >= 201103L\n@@ -3155,7 +3257,7 @@ namespace __rb_tree\n \t  return __z._M_insert(__res);\n \treturn __z._M_insert_equal_lower();\n       }\n-#endif\n+#endif  // >= C++11\n \n \n   template<typename _Key, typename _Val, typename _KeyOfValue,\ndiff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h\nindex 9b74cba8675..1bd2906ace4 100644\n--- a/libstdc++-v3/include/bits/unordered_map.h\n+++ b/libstdc++-v3/include/bits/unordered_map.h\n@@ -456,6 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \templace(_Args&&... __args)\n \t{ return _M_h.emplace(std::forward<_Args>(__args)...); }\n \n+      ///@{\n       /**\n        *  @brief Attempts to build and insert a std::pair into the\n        *  %unordered_map.\n@@ -520,6 +521,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n #endif // node_extract\n \n #ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED\n+      ///@{\n       /**\n        *  @brief Attempts to build and insert a std::pair into the\n        *  %unordered_map.\n@@ -558,6 +560,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t\t\t\t  std::forward<_Args>(__args)...);\n \t}\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename ..._Args>\n+\tpair<iterator, bool>\n+\ttry_emplace(_Kt&& __k, _Args&&... __args)\n+\t{\n+\t  return _M_h.try_emplace(cend(),\n+\t    std::forward<_Kt>(__k), std::forward<_Args>(__args)...);\n+\t}\n+#endif\n+      ///@}\n+\n+      ///@{\n       /**\n        *  @brief Attempts to build and insert a std::pair into the\n        *  %unordered_map.\n@@ -605,6 +619,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t}\n #endif // __glibcxx_unordered_map_try_emplace\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename ..._Args>\n+\titerator\n+\ttry_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)\n+\t{\n+\t  return _M_h.try_emplace(__hint,\n+\t    std::forward<_Kt>(__k), std::forward<_Args>(__args)...).first;\n+\t}\n+#endif\n+      ///@}\n+\n       ///@{\n       /**\n        *  @brief Attempts to insert a std::pair into the %unordered_map.\n@@ -722,6 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n #endif\n \n #ifdef __glibcxx_unordered_map_try_emplace // >= C++17 && HOSTED\n+      ///@{\n       /**\n        *  @brief Attempts to insert a std::pair into the %unordered_map.\n        *  @param __k    Key to use for finding a possibly existing pair in\n@@ -765,6 +791,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  return __ret;\n \t}\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>\n+\tpair<iterator, bool>\n+\tinsert_or_assign(_Kt&& __k, _Obj&& __obj)\n+\t{\n+\t  auto __ret = _M_h.try_emplace(\n+\t    cend(), std::forward<_Kt>(__k), std::forward<_Obj>(__obj));\n+\t  if (!__ret.second)\n+\t    __ret.first->second = std::forward<_Obj>(__obj);\n+\t  return __ret;\n+\t}\n+#endif\n+      ///@}\n+\n+      ///@{\n       /**\n        *  @brief Attempts to insert a std::pair into the %unordered_map.\n        *  @param  __hint  An iterator that serves as a hint as to where the\n@@ -813,6 +854,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t    __ret.first->second = std::forward<_Obj>(__obj);\n \t  return __ret.first;\n \t}\n+\n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>\n+\titerator\n+\tinsert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)\n+\t{\n+\t  auto __ret = _M_h.try_emplace(__hint,\n+\t    std::forward<_Kt>(__k), std::forward<_Obj>(__obj));\n+\t  if (!__ret.second)\n+\t    __ret.first->second = std::forward<_Obj>(__obj);\n+\t  return __ret.first;\n+\t}\n+#endif\n+      ///@}\n #endif // unordered_map_try_emplace\n \n       ///@{\n@@ -1089,6 +1144,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       mapped_type&\n       operator[](key_type&& __k)\n       { return _M_h[std::move(__k)]; }\n+\n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt>\n+\tmapped_type&\n+\toperator[](_Kt&& __k)\n+      {\n+\treturn try_emplace(std::forward<_Kt>(__k)).first->second;\n+      }\n+#endif\n       ///@}\n \n       ///@{\n@@ -1103,9 +1167,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       at(const key_type& __k)\n       { return _M_h.at(__k); }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt>\n+\tmapped_type&\n+\tat(const _Kt& __k)\n+\t{ return _M_h._M_at_tr(__k); }\n+#endif\n+\n       const mapped_type&\n       at(const key_type& __k) const\n       { return _M_h.at(__k); }\n+\n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt>\n+\tconst mapped_type&\n+\tat(const _Kt& __k) const\n+\t{ return _M_h._M_at_tr(__k); }\n+#endif\n       ///@}\n \n       // bucket interface.\n@@ -1129,6 +1207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket_size(size_type __n) const\n       { return _M_h.bucket_size(__n); }\n \n+      ///@{\n       /*\n        * @brief  Returns the bucket index of a given element.\n        * @param  __key  A key instance.\n@@ -1138,6 +1217,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket(const key_type& __key) const\n       { return _M_h.bucket(__key); }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_map> _Kt>\n+\tsize_type\n+\tbucket(const _Kt& __key) const\n+\t{ return _M_h._M_bucket_tr(__key); }\n+#endif\n+      ///@}\n+\n       /**\n        *  @brief  Returns a read/write iterator pointing to the first bucket\n        *         element.\n@@ -2176,6 +2263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket_size(size_type __n) const\n       { return _M_h.bucket_size(__n); }\n \n+      ///@{\n       /*\n        * @brief  Returns the bucket index of a given element.\n        * @param  __key  A key instance.\n@@ -2185,6 +2273,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket(const key_type& __key) const\n       { return _M_h.bucket(__key); }\n \n+#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26\n+      template <__heterogeneous_hash_key<unordered_multimap> _Kt>\n+\tsize_type\n+\tbucket(const _Kt& __key) const\n+\t{ return _M_h._M_bucket_tr(__key); }\n+#endif\n+      ///@}\n+\n       /**\n        *  @brief  Returns a read/write iterator pointing to the first bucket\n        *         element.\ndiff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h\nindex 22b2ad9caf4..044b49e6cd4 100644\n--- a/libstdc++-v3/include/bits/unordered_set.h\n+++ b/libstdc++-v3/include/bits/unordered_set.h\n@@ -493,6 +493,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       std::pair<iterator, bool>\n       insert(value_type&& __x)\n       { return _M_h.insert(std::move(__x)); }\n+\n+#if __glibcxx_associative_heterogeneous_insertion // P2363R5\n+      template <__heterogeneous_hash_key<unordered_set> _Kt>\n+\tstd::pair<iterator, bool>\n+\tinsert(_Kt&&  __x)\n+\t{ return _M_h._M_insert_tr(std::forward<_Kt>(__x)); }\n+#endif\n       ///@}\n \n       ///@{\n@@ -522,6 +529,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       iterator\n       insert(const_iterator __hint, value_type&& __x)\n       { return _M_h.insert(__hint, std::move(__x)); }\n+\n+#if __glibcxx_associative_heterogeneous_insertion // P2363R5\n+      template <__heterogeneous_hash_key<unordered_set> _Kt>\n+\titerator\n+\tinsert(const_iterator, _Kt&& __x)\n+\t{ return _M_h._M_insert_tr(std::forward<_Kt>(__x)).first; }\n+#endif\n       ///@}\n \n       /**\n@@ -876,6 +890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket_size(size_type __n) const\n       { return _M_h.bucket_size(__n); }\n \n+      ///@{\n       /*\n        * @brief  Returns the bucket index of a given element.\n        * @param  __key  A key instance.\n@@ -885,6 +900,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket(const key_type& __key) const\n       { return _M_h.bucket(__key); }\n \n+#if __glibcxx_associative_heterogeneous_insertion // P2363R5\n+      template <__heterogeneous_hash_key<unordered_set> _Kt>\n+\tsize_type\n+\tbucket(const _Kt& __key) const\n+\t{ return _M_h._M_bucket_tr(__key); }\n+#endif\n+      ///@}\n+\n       ///@{\n       /**\n        *  @brief  Returns a read-only (constant) iterator pointing to the first\n@@ -1884,6 +1907,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket_size(size_type __n) const\n       { return _M_h.bucket_size(__n); }\n \n+      ///@{\n       /*\n        * @brief  Returns the bucket index of a given element.\n        * @param  __key  A key instance.\n@@ -1893,6 +1917,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       bucket(const key_type& __key) const\n       { return _M_h.bucket(__key); }\n \n+#if __glibcxx_associative_heterogeneous_insertion // P2363R5\n+      template <__heterogeneous_hash_key<unordered_multiset> _Kt>\n+\tsize_type\n+\tbucket(const _Kt& __key) const\n+\t{ return _M_h._M_bucket_tr(__key); }\n+#endif\n+      ///@}\n+\n       ///@{\n       /**\n        *  @brief  Returns a read-only (constant) iterator pointing to the first\ndiff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def\nindex 4b8e9d43ec2..01725999c52 100644\n--- a/libstdc++-v3/include/bits/version.def\n+++ b/libstdc++-v3/include/bits/version.def\n@@ -1641,6 +1641,14 @@ ftms = {\n   };\n };\n \n+ftms = {\n+  name = associative_heterogeneous_insertion;\n+  values = {\n+    v = 202306;\n+    cxxmin = 26;\n+  };\n+};\n+\n ftms = {\n   name = is_scoped_enum;\n   values = {\ndiff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h\nindex 7602225cb6d..b376c428ced 100644\n--- a/libstdc++-v3/include/bits/version.h\n+++ b/libstdc++-v3/include/bits/version.h\n@@ -1811,6 +1811,16 @@\n #endif /* !defined(__cpp_lib_associative_heterogeneous_erasure) */\n #undef __glibcxx_want_associative_heterogeneous_erasure\n \n+#if !defined(__cpp_lib_associative_heterogeneous_insertion)\n+# if (__cplusplus >  202302L)\n+#  define __glibcxx_associative_heterogeneous_insertion 202306L\n+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_associative_heterogeneous_insertion)\n+#   define __cpp_lib_associative_heterogeneous_insertion 202306L\n+#  endif\n+# endif\n+#endif /* !defined(__cpp_lib_associative_heterogeneous_insertion) */\n+#undef __glibcxx_want_associative_heterogeneous_insertion\n+\n #if !defined(__cpp_lib_is_scoped_enum)\n # if (__cplusplus >= 202100L)\n #  define __glibcxx_is_scoped_enum 202011L\ndiff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map\nindex 91612cf42c4..66edadbc6dc 100644\n--- a/libstdc++-v3/include/std/map\n+++ b/libstdc++-v3/include/std/map\n@@ -80,6 +80,7 @@\n #define __glibcxx_want_nonmember_container_access\n #define __glibcxx_want_tuple_like\n #define __glibcxx_want_associative_heterogeneous_erasure\n+#define __glibcxx_want_associative_heterogeneous_insertion\n #include <bits/version.h>\n \n #if __cplusplus >= 201703L\ndiff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set\nindex 28eef1fc490..dc550f1d0b6 100644\n--- a/libstdc++-v3/include/std/set\n+++ b/libstdc++-v3/include/std/set\n@@ -78,6 +78,7 @@\n #define __glibcxx_want_node_extract\n #define __glibcxx_want_nonmember_container_access\n #define __glibcxx_want_associative_heterogeneous_erasure\n+#define __glibcxx_want_associative_heterogeneous_insertion\n #include <bits/version.h>\n \n #if __cplusplus >= 201703L\ndiff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map\nindex f63be4104c5..e9cf191e749 100644\n--- a/libstdc++-v3/include/std/unordered_map\n+++ b/libstdc++-v3/include/std/unordered_map\n@@ -57,6 +57,7 @@\n #define __glibcxx_want_unordered_map_try_emplace\n #define __glibcxx_want_tuple_like\n #define __glibcxx_want_associative_heterogeneous_erasure\n+#define __glibcxx_want_associative_heterogeneous_insertion\n #include <bits/version.h>\n \n #if __cplusplus >= 201703L\ndiff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set\nindex 45e6a915eb9..ee16489290e 100644\n--- a/libstdc++-v3/include/std/unordered_set\n+++ b/libstdc++-v3/include/std/unordered_set\n@@ -55,6 +55,7 @@\n #define __glibcxx_want_node_extract\n #define __glibcxx_want_nonmember_container_access\n #define __glibcxx_want_associative_heterogeneous_erasure\n+#define __glibcxx_want_associative_heterogeneous_insertion\n #include <bits/version.h>\n \n #if __cplusplus >= 201703L\ndiff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..73db5d28b26\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/hetero/insert.cc\n@@ -0,0 +1,341 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <map>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <compare>\n+#include <cstring>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(std::string_view str) : s(str) {}\n+  X(Y&& y);\n+  X(const Y& y);\n+  friend auto operator<=>(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  Y(std::string_view sv) : s(sv) {}\n+  Y(int n) : s(std::string('a', n)) {}\n+  Y(const Y& a, const Y& b) : s(a.s + \"1\" + b.s) { }\n+  Y(const Y& a, Y&& b)      : s(a.s + \"2\" + b.s) { b.s.clear(); }\n+  Y(Y&& a, const Y& b)      : s(a.s + \"3\" + b.s) { a.s.clear(); }\n+  Y(Y&& a, Y&& b)           : s(a.s + \"4\" + b.s) { a.s.clear(), b.s.clear(); }\n+  friend auto operator<=>(Y const& a, Y const& b) = default;\n+  friend auto operator<=>(X const& a, Y const& b) { return a.s <=> b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+using cmp = std::less<void>;\n+\n+void test1()  // op[]\n+{\n+  std::map<X, Y, cmp> amap{cmp{}};\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+  Y x{\"dei\"}, y{\"deh\"}, z{\"deg\"};\n+  amap[z] = 4;\n+  VERIFY(amap.size() == 4);\n+  VERIFY(z.s.size() == 3);  // not moved from.\n+\n+  amap[std::move(z)] = 5;\n+  VERIFY(amap.size() == 4);\n+  VERIFY(z.s.size() == 3);  // not moved from.\n+\n+  VERIFY(amap[std::move(y)] == Y{});\n+  VERIFY(amap.size() == 5);\n+  VERIFY(y.s.empty());      // moved from.\n+\n+  amap[std::move(x)] = 7;\n+  VERIFY(amap.size() == 6);\n+  VERIFY(x.s.empty());      // moved from\n+}\n+\n+void test2() // at()\n+{\n+  std::map<X, Y, cmp> amap{cmp{}};\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  Y y{\"def\"};\n+  try\n+    {\n+      VERIFY(2 == amap.at(y));\n+      VERIFY(amap.size() == 3);\n+      VERIFY(4 == (amap.at(std::move(y)) = 4));\n+      VERIFY(amap.size() == 3);\n+      VERIFY(y.s.size() == 3);  // not moved from\n+    }\n+  catch(...) { VERIFY(false); }\n+  try\n+  {\n+    amap.at(Y{\"deg\"}) = 4;\n+    VERIFY(false);  // Should have thrown.\n+  }\n+  catch (std::out_of_range&) { VERIFY(amap.size() == 3); }\n+  catch (...) { VERIFY(false); } // Wrong exception.\n+\n+  auto const& amapr{amap};\n+  Y z{\"deh\"};\n+  try\n+    {\n+      amapr.at(std::move(z));\n+      VERIFY(false);  // Should have thrown.\n+    }\n+  catch (std::out_of_range&) {  }\n+  catch (...) { VERIFY(false); } // Wrong exception.\n+  VERIFY(amapr.size() == 3);\n+  VERIFY(z.s.size() == 3);  // not moved from\n+}\n+\n+void test3()  // try_emplace\n+{\n+  std::map<X, Y, cmp> amap{cmp{}};\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  { // Fail, already there\n+    auto a = amap;\n+    auto [it, res] = a.try_emplace(Y{\"def\"}, Y{\"xyz\"});\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{2});\n+  }\n+  { // Fail, already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.try_emplace(std::move(y), std::move(z));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Succeed, construct\n+    auto a = amap;\n+    Y m(\"m\"), n(\"n\"), o(\"o\"), p(\"p\"), dek(\"dek\");\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"deg\"}, m, n);\n+      VERIFY(res);\n+      VERIFY(a.size() == 4);\n+      VERIFY(it->first == X{\"deg\"});\n+      VERIFY(it->second == Y{\"m1n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.size() == 1);\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"deh\"}, m, std::move(n));\n+      VERIFY(res);\n+      VERIFY(a.size() == 5);\n+      VERIFY(it->first == X{\"deh\"});\n+      VERIFY(it->second == Y{\"m2n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.empty());\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"dei\"}, std::move(m), o);\n+      VERIFY(res);\n+      VERIFY(a.size() == 6);\n+      VERIFY(it->first == X{\"dei\"});\n+      VERIFY(it->second == Y{\"m3o\"});\n+      VERIFY(m.s.empty());\n+      VERIFY(o.s.size() == 1);\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"dej\"}, std::move(o), std::move(p));\n+      VERIFY(res);\n+      VERIFY(a.size() == 7);\n+      VERIFY(it->first == X{\"dej\"});\n+      VERIFY(it->second == Y{\"o4p\"});\n+      VERIFY(o.s.empty());\n+      VERIFY(p.s.empty());\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(std::move(dek), Y(\"q\"), Y(\"r\"));\n+      VERIFY(res);\n+      VERIFY(a.size() == 8);\n+      VERIFY(dek.s.empty());\n+      VERIFY(it->first == X{\"dek\"});\n+      VERIFY(it->second == Y{\"q4r\"});\n+    }\n+  }\n+  { // Succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto [it, res] = a.try_emplace(std::move(y), std::move(z));\n+    VERIFY(res);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty()); // moved from\n+  }\n+  { // Hinted, fail\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, fail, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, succeed, construct\n+    auto a = amap;\n+    Y m(\"m\"), n(\"n\"), o(\"o\"), p(\"p\"), dek(\"dek\");\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"deg\"}, m, n);\n+      VERIFY(a.size() == 4);\n+      VERIFY(it->first == X{\"deg\"});\n+      VERIFY(it->second == Y{\"m1n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.size() == 1);\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"deh\"}, m, std::move(n));\n+      VERIFY(a.size() == 5);\n+      VERIFY(it->first == X{\"deh\"});\n+      VERIFY(it->second == Y{\"m2n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.empty());\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"dei\"}, std::move(m), o);\n+      VERIFY(a.size() == 6);\n+      VERIFY(it->first == X{\"dei\"});\n+      VERIFY(it->second == Y{\"m3o\"});\n+      VERIFY(m.s.empty());\n+      VERIFY(o.s.size() == 1);\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"dej\"}, std::move(o), std::move(p));\n+      VERIFY(a.size() == 7);\n+      VERIFY(it->first == X{\"dej\"});\n+      VERIFY(it->second == Y{\"o4p\"});\n+      VERIFY(o.s.empty());\n+      VERIFY(p.s.empty());\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), std::move(dek), Y(\"q\"), Y(\"r\"));\n+      VERIFY(a.size() == 8);\n+      VERIFY(dek.s.empty());\n+      VERIFY(it->first == X{\"dek\"});\n+      VERIFY(it->second == Y{\"q4r\"});\n+    }\n+  }\n+  {  // Hinted, succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty());  // moved from\n+  }\n+}\n+\n+void test4()  // insert_or_assign\n+{\n+  std::map<X, Y, cmp> amap{cmp{}};\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  { // Already there, replace\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(y, z);\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(std::move(y), std::move(z));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.empty());      // moved from\n+  }\n+  { // Succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(std::move(y), std::move(z));\n+    VERIFY(res);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty()); // moved from\n+  }\n+  { // Hinted, already there, replace\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), y, z);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.empty());      // moved from\n+  }\n+  {  // Hinted, succeed\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), y, z);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  {  // Hinted, succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), std::move(y), std::move(z));\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty());  // moved from\n+    VERIFY(z.s.empty());  // moved from\n+  }\n+}\n+\n+int main()\n+{\n+  test1();\n+  test2();\n+  test3();\n+  test4();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..ac13b514778\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/hetero/insert.cc\n@@ -0,0 +1,120 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <set>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <compare>\n+#include <cstring>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(std::string_view str) : s(str) {}\n+  X(Y&& y);\n+  X(const Y& y);\n+\n+  friend auto operator<=>(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(std::string_view sv) : s(sv) {}\n+  Y(int a, int b = 0) : s(std::string('a', a + b)) {}\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  friend auto operator<=>(Y const& a, Y const& b) = default;\n+  friend auto operator<=>(X const& a, Y const& b) { return a.s <=> b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+using cmp = std::less<void>;\n+\n+void test1()  // insert\n+{\n+  std::set<X, cmp> aset{cmp{}};\n+  aset.insert({X{\"abc\"}, X{\"def\"}, X{\"ghi\"}});\n+\n+  { // Fail\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto [it, res] = a.insert(y);\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Fail, move\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto [it, res] = a.insert(std::move(y));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Succeed\n+    auto a = aset;\n+    Y y{\"deg\"};\n+    auto [it, res] = a.insert(y);\n+    VERIFY(res);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deg\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Succeed, move\n+    auto a = aset;\n+    Y y{\"deg\"};\n+    auto [it, res] = a.insert(std::move(y));\n+    VERIFY(res);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deg\");\n+    VERIFY(y.s.empty());  // moved\n+  }\n+\n+\n+  { // Hinted, fail\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto it = a.insert(a.begin(), y);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, fail, move\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto it = a.insert(a.begin(), std::move(y));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, succeed\n+    auto a = aset;\n+    Y y{\"deh\"};\n+    auto it = a.insert(a.begin(), y);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deh\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, succeed, move\n+    auto a = aset;\n+    Y y{\"deh\"};\n+    auto it = a.insert(a.begin(), std::move(y));\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deh\");\n+    VERIFY(y.s.empty());  // moved\n+  }\n+}\n+\n+int main()\n+{\n+  test1();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..8f7f88ce9e1\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/hetero/insert.cc\n@@ -0,0 +1,353 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <unordered_map>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <functional>\n+#include <compare>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(std::string_view str) : s(str) {}\n+  X(Y&& y);\n+  X(const Y& y);\n+  friend bool operator==(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  Y(std::string_view sv) : s(sv) {}\n+  Y(int n) : s(std::string('a', n)) {}\n+  Y(const Y& a, const Y& b) : s(a.s + \"1\" + b.s) { }\n+  Y(const Y& a, Y&& b)      : s(a.s + \"2\" + b.s) { b.s.clear(); }\n+  Y(Y&& a, const Y& b)      : s(a.s + \"3\" + b.s) { a.s.clear(); }\n+  Y(Y&& a, Y&& b)           : s(a.s + \"4\" + b.s) { a.s.clear(), b.s.clear(); }\n+  friend bool operator==(Y const& a, Y const& b) = default;\n+  friend bool operator==(X const& a, Y const& b) { return a.s == b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+struct Hash {\n+  using is_transparent = void;\n+  template <typename T>\n+    auto operator()(T const& t) const\n+    { return std::hash<decltype(T::s)>{}(t.s); }\n+};\n+\n+using Equal = std::equal_to<void>;\n+\n+void test1()  // op[]\n+{\n+  std::unordered_map<X, Y, Hash, Equal> amap;\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  Y x{\"dei\"}, y{\"deh\"}, z{\"deg\"};\n+  amap[z] = 4;\n+  VERIFY(amap.size() == 4);\n+  VERIFY(z.s.size() == 3);  // not moved from.\n+\n+  amap[std::move(z)] = 5;\n+  VERIFY(amap.size() == 4);\n+  VERIFY(z.s.size() == 3);  // not moved from.\n+\n+  VERIFY(amap[std::move(y)] == Y{});\n+  VERIFY(amap.size() == 5);\n+  VERIFY(y.s.empty());      // moved from.\n+\n+  amap[std::move(x)] = 7;\n+  VERIFY(amap.size() == 6);\n+  VERIFY(x.s.empty());      // moved from\n+}\n+\n+void test2() // at()\n+{\n+  std::unordered_map<X, Y, Hash, Equal> amap;\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  Y x{\"def\"};\n+  try\n+    {\n+      VERIFY(2 == amap.at(x));\n+      VERIFY(amap.size() == 3);\n+      VERIFY(x.s.size() == 3);   // not moved from\n+      VERIFY(4 == (amap.at(x) = 4));\n+      VERIFY(amap.size() == 3);\n+      VERIFY(x.s.size() == 3);   // not moved from\n+    }\n+  catch(...) { VERIFY(false); }\n+\n+  Y z{\"deg\"};\n+  try\n+  {\n+    amap.at(z) = 4;\n+    VERIFY(false);  // Should have thrown.\n+  }\n+  catch (std::out_of_range&) { VERIFY(amap.size() == 3); }\n+  catch (...) { VERIFY(false); } // Wrong exception.\n+  VERIFY(z.s.size() == 3);   // not moved from\n+\n+  Y y{\"deh\"};\n+  auto const& amapr{amap};\n+  try\n+    {\n+      amapr.at(y);\n+      VERIFY(false);  // Should have thrown.\n+    }\n+  catch (std::out_of_range&) {  }\n+  catch (...) { VERIFY(false); } // Wrong exception.\n+  VERIFY(amapr.size() == 3);\n+  VERIFY(y.s.size() == 3);  // not moved from\n+}\n+\n+void test3()  // try_emplace\n+{\n+  std::unordered_map<X, Y, Hash, Equal> amap;\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  { // Fail, already there\n+    auto a = amap;\n+    auto [it, res] = a.try_emplace(Y{\"def\"}, Y{\"xyz\"});\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{2});\n+  }\n+  { // Fail, already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.try_emplace(std::move(y), std::move(z));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Succeed, construct\n+    auto a = amap;\n+    Y m(\"m\"), n(\"n\"), o(\"o\"), p(\"p\"), dek(\"dek\");\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"deg\"}, m, n);\n+      VERIFY(res);\n+      VERIFY(a.size() == 4);\n+      VERIFY(it->first == X{\"deg\"});\n+      VERIFY(it->second == Y{\"m1n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.size() == 1);\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"deh\"}, m, std::move(n));\n+      VERIFY(res);\n+      VERIFY(a.size() == 5);\n+      VERIFY(it->first == X{\"deh\"});\n+      VERIFY(it->second == Y{\"m2n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.empty());\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"dei\"}, std::move(m), o);\n+      VERIFY(res);\n+      VERIFY(a.size() == 6);\n+      VERIFY(it->first == X{\"dei\"});\n+      VERIFY(it->second == Y{\"m3o\"});\n+      VERIFY(m.s.empty());\n+      VERIFY(o.s.size() == 1);\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(Y{\"dej\"}, std::move(o), std::move(p));\n+      VERIFY(res);\n+      VERIFY(a.size() == 7);\n+      VERIFY(it->first == X{\"dej\"});\n+      VERIFY(it->second == Y{\"o4p\"});\n+      VERIFY(o.s.empty());\n+      VERIFY(p.s.empty());\n+    }\n+    {\n+      auto [it, res] = a.try_emplace(std::move(dek), Y(\"q\"), Y(\"r\"));\n+      VERIFY(res);\n+      VERIFY(a.size() == 8);\n+      VERIFY(dek.s.empty());\n+      VERIFY(it->first == X{\"dek\"});\n+      VERIFY(it->second == Y{\"q4r\"});\n+    }\n+  }\n+  { // Succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto [it, res] = a.try_emplace(std::move(y), std::move(z));\n+    VERIFY(res);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty()); // moved from\n+  }\n+  { // Hinted, fail\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, fail, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{2});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, succeed, construct\n+    auto a = amap;\n+    Y m(\"m\"), n(\"n\"), o(\"o\"), p(\"p\"), dek(\"dek\");\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"deg\"}, m, n);\n+      VERIFY(a.size() == 4);\n+      VERIFY(it->first == X{\"deg\"});\n+      VERIFY(it->second == Y{\"m1n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.size() == 1);\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"deh\"}, m, std::move(n));\n+      VERIFY(a.size() == 5);\n+      VERIFY(it->first == X{\"deh\"});\n+      VERIFY(it->second == Y{\"m2n\"});\n+      VERIFY(m.s.size() == 1);\n+      VERIFY(n.s.empty());\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"dei\"}, std::move(m), o);\n+      VERIFY(a.size() == 6);\n+      VERIFY(it->first == X{\"dei\"});\n+      VERIFY(it->second == Y{\"m3o\"});\n+      VERIFY(m.s.empty());\n+      VERIFY(o.s.size() == 1);\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), Y{\"dej\"}, std::move(o), std::move(p));\n+      VERIFY(a.size() == 7);\n+      VERIFY(it->first == X{\"dej\"});\n+      VERIFY(it->second == Y{\"o4p\"});\n+      VERIFY(o.s.empty());\n+      VERIFY(p.s.empty());\n+    }\n+    {\n+      auto it = a.try_emplace(a.begin(), std::move(dek), Y(\"q\"), Y(\"r\"));\n+      VERIFY(a.size() == 8);\n+      VERIFY(dek.s.empty());\n+      VERIFY(it->first == X{\"dek\"});\n+      VERIFY(it->second == Y{\"q4r\"});\n+    }\n+  }\n+  {  // Hinted, succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.try_emplace(a.begin(), std::move(y), std::move(z));\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty());  // moved from\n+  }\n+}\n+\n+void test4()  // insert_or_assign\n+{\n+  std::unordered_map<X, Y, Hash, Equal> amap;\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"ghi\"}, 3}});\n+\n+  { // Already there, replace\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(y, z);\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(std::move(y), std::move(z));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(a.at(Y{\"def\"}) == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.empty());      // moved from\n+  }\n+  { // Succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto [it, res] = a.insert_or_assign(std::move(y), std::move(z));\n+    VERIFY(res);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty()); // moved from\n+    VERIFY(z.s.empty()); // moved from\n+  }\n+  { // Hinted, already there, replace\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), y, z);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  { // Hinted, already there, move\n+    auto a = amap;\n+    Y y{\"def\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), std::move(y), std::move(z));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->first == X{\"def\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.empty());      // moved from\n+  }\n+  {  // Hinted, succeed\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), y, z);\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.size() == 3);  // not moved from\n+    VERIFY(z.s.size() == 3);  // not moved from\n+  }\n+  {  // Hinted, succeed, move\n+    auto a = amap;\n+    Y y{\"tuv\"}, z{\"xyz\"};\n+    auto it = a.insert_or_assign(a.begin(), std::move(y), std::move(z));\n+    VERIFY(it->first == X{\"tuv\"});\n+    VERIFY(it->second == Y{\"xyz\"});\n+    VERIFY(a.size() == 4);\n+    VERIFY(y.s.empty());  // moved from\n+    VERIFY(z.s.empty());  // moved from\n+  }\n+}\n+\n+int main()\n+{\n+  test1();\n+  test2();\n+  test3();\n+  test4();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..6430201c9c6\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/hetero/insert.cc\n@@ -0,0 +1,57 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <unordered_map>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <functional>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(std::string_view str) : s(str) {}\n+  X(Y&& y);\n+  X(const Y& y);\n+  friend bool operator==(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  Y(std::string_view sv) : s(sv) {}\n+  Y(int a, int b = 0) : s(std::string('a', a + b)) {}\n+  friend bool operator==(Y const& a, Y const& b) = default;\n+  friend bool operator==(X const& a, Y const& b) { return a.s == b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+struct Hash {\n+  using is_transparent = void;\n+  template <typename T>\n+    auto operator()(T const& t) const\n+    { return std::hash<decltype(T::s)>{}(t.s); }\n+};\n+\n+using Equal = std::equal_to<void>;\n+\n+void test1()  // bucket\n+{\n+  std::unordered_multimap<X, Y, Hash, Equal> amap;\n+  amap.insert({{X{\"abc\"}, 1}, {X{\"def\"}, 2}, {X{\"def\"}, 3}, {X{\"ghi\"}, 3}});\n+\n+  auto const& amapr{amap};\n+  VERIFY(amapr.bucket(X{\"def\"}) == amapr.bucket(Y{\"def\"}));\n+}\n+\n+int main()\n+{\n+  test1();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..59ed43c16d2\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/hetero/insert.cc\n@@ -0,0 +1,56 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <unordered_set>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <functional>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(Y&& y);\n+  X(const Y& y);\n+  X(std::string_view str) : s(str) {}\n+  friend bool operator==(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  Y(std::string_view sv) : s(sv) {}\n+  friend bool operator==(Y const& a, Y const& b) = default;\n+  friend bool operator==(X const& a, Y const& b) { return a.s == b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+struct Hash {\n+  using is_transparent = void;\n+  template <typename T>\n+    auto operator()(T const& t) const\n+    { return std::hash<decltype(T::s)>{}(t.s); }\n+};\n+\n+using Equal = std::equal_to<void>;\n+\n+void test1()  // bucket\n+{\n+  std::unordered_multiset<X, Hash, Equal> aset{};\n+  aset.insert({X{\"abc\"}, X{\"def\"}, X{\"def\"}, X{\"ghi\"}});\n+\n+  auto const& asetr{aset};\n+  VERIFY(asetr.bucket(X{\"def\"}) == asetr.bucket(Y{\"def\"}));\n+}\n+\n+int main()\n+{\n+  test1();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc\nnew file mode 100644\nindex 00000000000..320143f2ea4\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/hetero/insert.cc\n@@ -0,0 +1,134 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <unordered_set>\n+#include <string>\n+#include <string_view>\n+#include <utility>\n+#include <functional>\n+#include <testsuite_hooks.h>\n+\n+struct Y;\n+\n+struct X {\n+  std::string s;\n+  X(std::string_view str) : s(str) {}\n+  X(Y&& y);\n+  X(const Y& y);\n+  friend bool operator==(X const& a, X const& b) = default;\n+};\n+\n+struct Y {\n+  std::string s;\n+  Y() = default;\n+  Y(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+  Y(const Y& y) = default;\n+  Y& operator=(Y&& y) { s = std::move(y.s); y.s.clear(); return *this; }\n+  Y& operator=(const Y& y) = default;\n+  Y(int a, int b = 0) : s(std::string('a', a + b)) {}\n+  Y(std::string_view sv) : s(sv) {}\n+  friend bool operator==(Y const& a, Y const& b) = default;\n+  friend bool operator==(X const& a, Y const& b) { return a.s == b.s; }\n+};\n+\n+X::X(Y&& y) : s(std::move(y.s)) { y.s.clear(); }\n+X::X(const Y& y) : s(y.s) {}\n+\n+struct Hash {\n+  using is_transparent = void;\n+  template <typename T>\n+    auto operator()(T const& t) const { return std::hash<decltype(T::s)>{}(t.s); }\n+};\n+\n+using Equal = std::equal_to<void>;\n+\n+void test1()  // insert\n+{\n+  std::unordered_set<X, Hash, Equal> aset;\n+  aset.insert({X{\"abc\"}, X{\"def\"}, X{\"ghi\"}});\n+\n+  { // Fail\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto [it, res] = a.insert(y);\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Fail, move\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto [it, res] = a.insert(std::move(y));\n+    VERIFY(!res);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Succeed\n+    auto a = aset;\n+    Y y{\"deg\"};\n+    auto [it, res] = a.insert(y);\n+    VERIFY(res);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deg\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Succeed, move\n+    auto a = aset;\n+    Y y{\"deg\"};\n+    auto [it, res] = a.insert(std::move(y));\n+    VERIFY(res);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deg\");\n+    VERIFY(y.s.empty());  // moved\n+  }\n+\n+\n+  { // Hinted, fail\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto it = a.insert(a.begin(), y);\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, fail, move\n+    auto a = aset;\n+    Y y{\"def\"};\n+    auto it = a.insert(a.begin(), std::move(y));\n+    VERIFY(a.size() == 3);\n+    VERIFY(it->s == \"def\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, succeed\n+    auto a = aset;\n+    Y y{\"deh\"};\n+    auto it = a.insert(a.begin(), y);\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deh\");\n+    VERIFY(y.s.size() == 3);  // not moved\n+  }\n+  { // Hinted, succeed, move\n+    auto a = aset;\n+    Y y{\"deh\"};\n+    auto it = a.insert(a.begin(), std::move(y));\n+    VERIFY(a.size() == 4);\n+    VERIFY(it->s == \"deh\");\n+    VERIFY(y.s.empty());  // moved\n+  }\n+}\n+\n+void test2()  // bucket\n+{\n+  std::unordered_set<X, Hash, Equal> aset{};\n+  aset.insert({X{\"abc\"}, X{\"def\"}, X{\"ghi\"}});\n+\n+  auto const& asetr{aset};\n+  VERIFY(asetr.bucket(X{\"def\"}) == asetr.bucket(Y{\"def\"}));\n+}\n+\n+int main()\n+{\n+  test1();\n+  test2();\n+}\n",
    "prefixes": [
        "PATCHv6"
    ]
}