{"id":2226196,"url":"http://patchwork.ozlabs.org/api/patches/2226196/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhub8n5f78.gcc.gcc-TEST.redi.15.1.3@forge-stage.sourceware.org/","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/projects/17/?format=json","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.hhub8n5f78.gcc.gcc-TEST.redi.15.1.3@forge-stage.sourceware.org>","list_archive_url":null,"date":"2026-04-22T10:25:12","name":"[v1,03/12] libstdc++: Refactor Hashtable insertion [PR115285]","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"2743768371b08fd3b49190ad7c2ecf77580a40dd","submitter":{"id":93210,"url":"http://patchwork.ozlabs.org/api/people/93210/?format=json","name":"Jonathan Wakely via Sourceware Forge","email":"forge-bot+redi@forge-stage.sourceware.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhub8n5f78.gcc.gcc-TEST.redi.15.1.3@forge-stage.sourceware.org/mbox/","series":[{"id":500966,"url":"http://patchwork.ozlabs.org/api/series/500966/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/list/?series=500966","date":"2026-04-22T10:25:11","name":"WIP: libstdc++: Refactor hash table code","version":1,"mbox":"http://patchwork.ozlabs.org/series/500966/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226196/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226196/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=38.145.34.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 [38.145.34.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 4g0wgm2nflz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 20:39:00 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 0E81C4C91758\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 10:38:58 +0000 (GMT)","from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 032D34BBCD99\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 10:26:15 +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 D20C7405A2\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 10:26:14 +0000 (UTC)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 0E81C4C91758","OpenDKIM Filter v2.11.0 sourceware.org 032D34BBCD99"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 032D34BBCD99","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 032D34BBCD99","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776853575; cv=none;\n b=CuAGv5XbrsDPLyrCeOJ/NQ4Arw6x8CJLbXt2ic+mEx5ndOZfHHFApxCECeygn3LwnHU/UCMr70fhhih67zcmcptEJFmuecV9TLxN5753twhiY45wYc//fuIEAD7SZfpR8P1q2+YhSmN7yOSFJNzsGQSIcomuzVMxWaGCbMaEpig=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776853575; c=relaxed/simple;\n bh=QjbIqXIn3ONZ+x0UuXOqGPhy88RHh+TCLil05JS7da4=;\n h=From:Date:Subject:To:Message-ID;\n b=OgRHo+6mH0vPdiQEIrCUYxMqaZnubeySfjY5PZWpdFzSV/TBYOnKSVo57mkHDc+tp9VnuTMXTgnlkNxpY8aBJ51N29cosRccQH3l+liR/n3rSXiKmhfcLY5VjikBe8rfLBsad4xdqQzEOwIbPmEai6KgNc1gyzdCZvoXHRSnTVQ=","ARC-Authentication-Results":"i=1; server2.sourceware.org","From":"Jonathan Wakely via Sourceware Forge\n <forge-bot+redi@forge-stage.sourceware.org>","Date":"Wed, 22 Apr 2026 10:25:12 +0000","Subject":"[PATCH v1 03/12] libstdc++: Refactor Hashtable insertion [PR115285]","To":"gcc-patches mailing list <gcc-patches@gcc.gnu.org>","Message-ID":"\n <bmm.hhub8n5f78.gcc.gcc-TEST.redi.15.1.3@forge-stage.sourceware.org>","X-Mailer":"batrachomyomachia","X-Requested-Reviewer":"fdumont","X-Pull-Request-Organization":"gcc","X-Pull-Request-Repository":"gcc-TEST","X-Pull-Request":"https://forge.sourceware.org/gcc/gcc-TEST/pulls/15","References":"\n <bmm.hhub8n5f78.gcc.gcc-TEST.redi.15.1.0@forge-stage.sourceware.org>","In-Reply-To":"\n <bmm.hhub8n5f78.gcc.gcc-TEST.redi.15.1.0@forge-stage.sourceware.org>","X-Patch-URL":"\n https://forge.sourceware.org/redi/gcc/commit/941aa9a8c9a242861d6d911ba052903832d87003","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>, redi@gcc.gnu.org","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"},"content":"From: Jonathan Wakely <jwakely@redhat.com>\n\nThis completely reworks the internal member functions for insertion into\nunordered containers. Currently we use a mixture of tag dispatching (for\nunique vs non-unique keys) and template specialization (for maps vs\nsets) to correctly implement insert and emplace members.\n\nThis removes a lot of complexity and indirection by using 'if constexpr'\nto select the appropriate member function to call.\n\nPreviously there were four overloads of _M_emplace, for unique keys and\nnon-unique keys, and for hinted insertion and non-hinted. However two of\nthose were redundant, because we always ignore the hint for unique keys\nand always use a hint for non-unique keys. Those four overloads have\nbeen replaced by two new non-overloaded function templates:\n_M_emplace_uniq and _M_emplace_multi. The former is for unique keys and\ndoesn't take a hint, and the latter is for non-unique keys and takes a\nhint.\n\nIn the body of _M_emplace_uniq there are special cases to handle\nemplacing values from which a key_type can be extracted directly. This\nmeans we don't need to allocate a node and construct a value_type that\nmight be discarded if an equivalent key is already present. The special\ncase applies when emplacing the key_type into std::unordered_set, or\nwhen emplacing std::pair<cv key_type, X> into std::unordered_map, or\nwhen emplacing two values into std::unordered_map where the first has\ntype cv key_type. For the std::unordered_set case, obviously if we're\ninserting something that's already the key_type, we can look it up\ndirectly. For the std::unordered_map cases, we know that the inserted\nstd::pair<const key_type, mapped_type> would have its first element\ninitialized from first member of a std::pair value, or from the first of\ntwo values, so if that is a key_type, we can look that up directly.\n\nAll the _M_insert overloads used a node generator parameter, but apart\nfrom the one case where _M_insert_range was called from\n_Hashtable::operator=(initializer_list<value_type>), that parameter was\nalways the _AllocNode type, never the _ReuseOrAllocNode type. Because\noperator=(initializer_list<value_type>) was rewritten in an earlier\ncommit, all calls to _M_insert now use _AllocNode, so there's no reason\nto pass the generator as a template parameter when inserting.\n\nThe multiple overloads of _Hashtable::_M_insert can all be removed now,\nbecause the _Insert_base::insert members now call either _M_emplace_uniq\nor _M_emplace_multi directly, only passing a hint to the latter. Which\none to call is decided using 'if constexpr (__unique_keys::value)' so\nthere is no unnecessary code instantiation, and overload resolution is\nmuch simpler.\n\nThe partial specializations of the _Insert class template can be\nentirely removed, moving the minor differences in 'insert' member\nfunctions into the common _Insert_base base class. The different\nbehaviour for maps and sets can be implemented using enable_if\nconstraints and 'if constexpr'. With the _Insert class template no\nlonger needed, the _Insert_base class template can be renamed to\n_Insert. This is a minor simplification for the complex inheritance\nhierarchy used by _Hashtable, removing one base class. It also means\none less class template instantiation, and no need to match the right\npartial specialization of _Insert. The _Insert base class could be\nremoved entirely by moving all its 'insert' members into _Hashtable,\nbecause without any variation in specializations of _Insert there is no\nreason to use a base class to define those members. That is left for a\nlater commit.\n\nConsistently using _M_emplace_uniq or _M_emplace_multi for insertion\nmeans we no longer attempt to avoid constructing a value_type object to\nfind its key, removing the PR libstdc++/96088 optimizations. This fixes\nthe bugs caused by those optimizations, such as PR libstdc++/115285, but\ncauses regressions in the expected number of allocations and temporary\nobjects constructed for the PR 96088 tests.  It should be noted that the\n\"regressions\" in the 96088 tests put us exactly level with the number of\nallocations done by libc++ for those same tests.\n\nTo mitigate this to some extent, _M_emplace_uniq detects when the\nemplace arguments already contain a key_type (either as the sole\nargument, for unordered_set, or as the first part of a pair of\narguments, for unordered_map). In that specific case we don't need to\nallocate a node and construct a value type to check for an existing\nelement with equivalent key.\n\nThe remaining regressions in the number of allocations and temporaries\nshould be addressed separately, with more conservative optimizations\nspecific to std::string. That is not part of this commit.\n\nlibstdc++-v3/ChangeLog:\n\n\tPR libstdc++/115285\n\t* include/bits/hashtable.h (_Hashtable::_M_emplace): Replace\n\twith _M_emplace_uniq and _M_emplace_multi.\n\t(_Hashtable::_S_forward_key, _Hashtable::_M_insert_unique)\n\t(_Hashtable::_M_insert_unique_aux, _Hashtable::_M_insert):\n\tRemove.\n\t* include/bits/hashtable_policy.h (_ConvertToValueType):\n\tRemove.\n\t(_Insert_base::_M_insert_range): Remove overload for unique keys\n\tand rename overload for non-unique keys to ...\n\t(_Insert_base::_M_insert_range_multi): ... this.\n\t(_Insert_base::insert): Call _M_emplace_uniq or _M_emplace_multi\n\tinstead of _M_insert.  Add insert overloads from _Insert.\n\t(_Insert_base): Rename to _Insert.\n\t(_Insert): Remove\n\t* testsuite/23_containers/unordered_map/96088.cc: Adjust\n\texpected number of allocations.\n\t* testsuite/23_containers/unordered_set/96088.cc: Likewise.\n---\n libstdc++-v3/include/bits/hashtable.h         | 236 ++++++------------\n libstdc++-v3/include/bits/hashtable_policy.h  | 228 ++++++-----------\n .../23_containers/unordered_map/96088.cc      |  21 +-\n .../23_containers/unordered_set/96088.cc      |  14 +-\n 4 files changed, 177 insertions(+), 322 deletions(-)","diff":"diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h\nindex 872fcac22d09..eeffa15e5259 100644\n--- a/libstdc++-v3/include/bits/hashtable.h\n+++ b/libstdc++-v3/include/bits/hashtable.h\n@@ -371,13 +371,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t       typename _ExtractKeya, typename _Equala,\n \t       typename _Hasha, typename _RangeHasha, typename _Unuseda,\n \t       typename _RehashPolicya, typename _Traitsa>\n-\tfriend struct __detail::_Insert_base;\n-\n-      template<typename _Keya, typename _Valuea, typename _Alloca,\n-\t       typename _ExtractKeya, typename _Equala,\n-\t       typename _Hasha, typename _RangeHasha, typename _Unuseda,\n-\t       typename _RehashPolicya, typename _Traitsa,\n-\t       bool _Constant_iteratorsa>\n \tfriend struct __detail::_Insert;\n \n       template<typename _Keya, typename _Valuea, typename _Alloca,\n@@ -940,77 +933,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \n       template<typename... _Args>\n \tstd::pair<iterator, bool>\n-\t_M_emplace(true_type __uks, _Args&&... __args);\n+\t_M_emplace_uniq(_Args&&... __args);\n \n-      template<typename... _Args>\n-\titerator\n-\t_M_emplace(false_type __uks, _Args&&... __args)\n-\t{ return _M_emplace(cend(), __uks, std::forward<_Args>(__args)...); }\n-\n-      // Emplace with hint, useless when keys are unique.\n-      template<typename... _Args>\n-\titerator\n-\t_M_emplace(const_iterator, true_type __uks, _Args&&... __args)\n-\t{ return _M_emplace(__uks, std::forward<_Args>(__args)...).first; }\n-\n-      template<typename... _Args>\n-\titerator\n-\t_M_emplace(const_iterator, false_type __uks, _Args&&... __args);\n-\n-      template<typename _Kt, typename _Arg, typename _NodeGenerator>\n-\tstd::pair<iterator, bool>\n-\t_M_insert_unique(_Kt&&, _Arg&&, _NodeGenerator&);\n-\n-      template<typename _Arg, typename _NodeGenerator>\n-\tstd::pair<iterator, bool>\n-\t_M_insert_unique_aux(_Arg&& __arg, _NodeGenerator& __node_gen)\n-\t{\n-\t  using _Kt = decltype(_ExtractKey{}(std::forward<_Arg>(__arg)));\n-\t  constexpr bool __is_key_type\n-\t    = is_same<__remove_cvref_t<_Kt>, key_type>::value;\n-\t  using _Fwd_key = __conditional_t<__is_key_type, _Kt&&, key_type>;\n-\t  return _M_insert_unique(\n-\t    static_cast<_Fwd_key>(_ExtractKey{}(std::forward<_Arg>(__arg))),\n-\t    std::forward<_Arg>(__arg), __node_gen);\n-\t}\n-\n-      template<typename _Arg, typename _NodeGenerator>\n-\tstd::pair<iterator, bool>\n-\t_M_insert(_Arg&& __arg, _NodeGenerator& __node_gen,\n-\t\t  true_type /* __uks */)\n-\t{\n-\t  using __detail::_Identity;\n-\t  using _Vt = __conditional_t<is_same<_ExtractKey, _Identity>::value\n-\t\t\t\t\t|| __is_pair<__remove_cvref_t<_Arg>>,\n-\t\t\t\t      _Arg&&, value_type>;\n-\t  return _M_insert_unique_aux(\n-\t\t   static_cast<_Vt>(std::forward<_Arg>(__arg)), __node_gen);\n-\t}\n+#pragma GCC diagnostic push\n+#pragma GCC diagnostic ignored \"-Wc++14-extensions\" // variable templates\n+      template<typename _Arg, typename _DArg = __remove_cvref_t<_Arg>,\n+\t       typename = _ExtractKey>\n+\tstatic constexpr bool __is_key_type = false;\n \n-      template<typename _Arg, typename _NodeGenerator>\n-\titerator\n-\t_M_insert(_Arg&& __arg, _NodeGenerator& __node_gen,\n-\t\t  false_type __uks)\n-\t{\n-\t  return _M_insert(cend(), std::forward<_Arg>(__arg),\n-\t\t\t   __node_gen, __uks);\n-\t}\n+      template<typename _Arg>\n+\tstatic constexpr bool\n+\t__is_key_type<_Arg, key_type, __detail::_Identity> = true;\n \n-      // Insert with hint, not used when keys are unique.\n-      template<typename _Arg, typename _NodeGenerator>\n-\titerator\n-\t_M_insert(const_iterator, _Arg&& __arg,\n-\t\t  _NodeGenerator& __node_gen, true_type __uks)\n-\t{\n-\t  return\n-\t    _M_insert(std::forward<_Arg>(__arg), __node_gen, __uks).first;\n-\t}\n+      template<typename _Arg, typename _Arg1, typename _Arg2>\n+\tstatic constexpr bool\n+\t__is_key_type<_Arg, pair<_Arg1, _Arg2>, __detail::_Select1st>\n+\t  = is_same<__remove_cvref_t<_Arg1>, key_type>::value;\n+#pragma GCC diagnostic pop\n \n-      // Insert with hint when keys are not unique.\n-      template<typename _Arg, typename _NodeGenerator>\n+      template<typename... _Args>\n \titerator\n-\t_M_insert(const_iterator, _Arg&&,\n-\t\t  _NodeGenerator&, false_type __uks);\n+\t_M_emplace_multi(const_iterator, _Args&&... __args);\n \n       size_type\n       _M_erase(true_type __uks, const key_type&);\n@@ -1022,19 +965,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       _M_erase(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n);\n \n     public:\n+#pragma GCC diagnostic push\n+#pragma GCC diagnostic ignored \"-Wc++17-extensions\" // if constexpr\n       // Emplace\n       template<typename... _Args>\n \t__ireturn_type\n \templace(_Args&&... __args)\n-\t{ return _M_emplace(__unique_keys{}, std::forward<_Args>(__args)...); }\n+\t{\n+\t  if constexpr (__unique_keys::value)\n+\t    return _M_emplace_uniq(std::forward<_Args>(__args)...);\n+\t  else\n+\t    return _M_emplace_multi(cend(), std::forward<_Args>(__args)...);\n+\t}\n \n       template<typename... _Args>\n \titerator\n \templace_hint(const_iterator __hint, _Args&&... __args)\n \t{\n-\t  return _M_emplace(__hint, __unique_keys{},\n-\t\t\t    std::forward<_Args>(__args)...);\n+\t  if constexpr (__unique_keys::value)\n+\t    return _M_emplace_uniq(std::forward<_Args>(__args)...).first;\n+\t  else\n+\t    return _M_emplace_multi(__hint, std::forward<_Args>(__args)...);\n \t}\n+#pragma GCC diagnostic pop\n \n       // Insert member functions via inheritance.\n \n@@ -1328,9 +1281,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t    _M_bucket_count = __bkt_count;\n \t  }\n \n-\t__alloc_node_gen_t __node_gen(*this);\n \tfor (; __f != __l; ++__f)\n-\t  _M_insert(*__f, __node_gen, __uks);\n+\t  _M_emplace_multi(cend(), *__f);\n       }\n \n   template<typename _Key, typename _Value, typename _Alloc,\n@@ -2160,6 +2112,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       return __prev_n;\n     }\n \n+#pragma GCC diagnostic push\n+#pragma GCC diagnostic ignored \"-Wc++17-extensions\" // if constexpr\n   template<typename _Key, typename _Value, typename _Alloc,\n \t   typename _ExtractKey, typename _Equal,\n \t   typename _Hash, typename _RangeHash, typename _Unused,\n@@ -2168,33 +2122,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       auto\n       _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n \t\t _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::\n-      _M_emplace(true_type /* __uks */, _Args&&... __args)\n+      _M_emplace_uniq(_Args&&... __args)\n       -> pair<iterator, bool>\n       {\n-\t// First build the node to get access to the hash code\n-\t_Scoped_node __node { this, std::forward<_Args>(__args)...  };\n-\tconst key_type& __k = _ExtractKey{}(__node._M_node->_M_v());\n+\tconst key_type* __kp = nullptr;\n+\n+\tif constexpr (sizeof...(_Args) == 1)\n+\t  {\n+\t    if constexpr (__is_key_type<_Args...>)\n+\t      {\n+\t\tconst auto& __key = _ExtractKey{}(__args...);\n+\t\t__kp = std::__addressof(__key);\n+\t      }\n+\t  }\n+\telse if constexpr (sizeof...(_Args) == 2)\n+\t  {\n+\t    pair<const _Args&...> __refs(__args...);\n+\t    if constexpr (__is_key_type<pair<_Args...>>)\n+\t      {\n+\t\tconst auto& __key = _ExtractKey{}(__refs);\n+\t\t__kp = std::__addressof(__key);\n+\t      }\n+\t  }\n+\n+\t_Scoped_node __node { __node_ptr(), this }; // Do not create node yet.\n+\t__hash_code __code = 0;\n+\tsize_type __bkt = 0;\n+\n+\tif (__kp == nullptr)\n+\t  {\n+\t    // Didn't extract a key from the args, so build the node.\n+\t    __node._M_node\n+\t\t  = this->_M_allocate_node(std::forward<_Args>(__args)...);\n+\t    const key_type& __key = _ExtractKey{}(__node._M_node->_M_v());\n+\t    __kp = std::__addressof(__key);\n+\t  }\n+\n \tconst size_type __size = size();\n \tif (__size <= __small_size_threshold())\n \t  {\n \t    for (auto __it = _M_begin(); __it; __it = __it->_M_next())\n-\t      if (this->_M_key_equals(__k, *__it))\n-\t\t// There is already an equivalent node, no insertion\n+\t      if (this->_M_key_equals(*__kp, *__it))\n+\t\t// There is already an equivalent node, no insertion.\n \t\treturn { iterator(__it), false };\n \t  }\n \n-\t__hash_code __code = this->_M_hash_code(__k);\n-\tsize_type __bkt = _M_bucket_index(__code);\n+\t__code = this->_M_hash_code(*__kp);\n+\t__bkt = _M_bucket_index(__code);\n+\n \tif (__size > __small_size_threshold())\n-\t  if (__node_ptr __p = _M_find_node(__bkt, __k, __code))\n-\t    // There is already an equivalent node, no insertion\n+\t  if (__node_ptr __p = _M_find_node(__bkt, *__kp, __code))\n+\t    // There is already an equivalent node, no insertion.\n \t    return { iterator(__p), false };\n \n+\tif (!__node._M_node)\n+\t  __node._M_node\n+\t\t= this->_M_allocate_node(std::forward<_Args>(__args)...);\n+\n \t// Insert the node\n \tauto __pos = _M_insert_unique_node(__bkt, __code, __node._M_node);\n \t__node._M_node = nullptr;\n \treturn { __pos, true };\n       }\n+#pragma GCC diagnostic pop\n \n   template<typename _Key, typename _Value, typename _Alloc,\n \t   typename _ExtractKey, typename _Equal,\n@@ -2204,12 +2194,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       auto\n       _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n \t\t _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::\n-      _M_emplace(const_iterator __hint, false_type /* __uks */,\n-\t\t _Args&&... __args)\n+      _M_emplace_multi(const_iterator __hint, _Args&&... __args)\n       -> iterator\n       {\n \t// First build the node to get its hash code.\n-\t_Scoped_node __node { this, std::forward<_Args>(__args)...  };\n+\t_Scoped_node __node { this, std::forward<_Args>(__args)... };\n \tconst key_type& __k = _ExtractKey{}(__node._M_node->_M_v());\n \n \tauto __res = this->_M_compute_hash_code(__hint._M_cur, __k);\n@@ -2335,71 +2324,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n       return iterator(__node);\n     }\n \n-  // Insert v if no element with its key is already present.\n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits>\n-    template<typename _Kt, typename _Arg, typename _NodeGenerator>\n-      auto\n-      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::\n-      _M_insert_unique(_Kt&& __k, _Arg&& __v,\n-\t\t       _NodeGenerator& __node_gen)\n-      -> pair<iterator, bool>\n-      {\n-\tconst size_type __size = size();\n-\tif (__size <= __small_size_threshold())\n-\t  for (auto __it = _M_begin(); __it; __it = __it->_M_next())\n-\t    if (this->_M_key_equals_tr(__k, *__it))\n-\t      return { iterator(__it), false };\n-\n-\t__hash_code __code = this->_M_hash_code_tr(__k);\n-\tsize_type __bkt = _M_bucket_index(__code);\n-\n-\tif (__size > __small_size_threshold())\n-\t  if (__node_ptr __node = _M_find_node_tr(__bkt, __k, __code))\n-\t    return { iterator(__node), false };\n-\n-\t_Scoped_node __node {\n-\t  __node_builder_t::_S_build(std::forward<_Kt>(__k),\n-\t\t\t\t     std::forward<_Arg>(__v),\n-\t\t\t\t     __node_gen),\n-\t  this\n-\t};\n-\tauto __pos\n-\t  = _M_insert_unique_node(__bkt, __code, __node._M_node);\n-\t__node._M_node = nullptr;\n-\treturn { __pos, true };\n-      }\n-\n-  // Insert v unconditionally.\n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits>\n-    template<typename _Arg, typename _NodeGenerator>\n-      auto\n-      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::\n-      _M_insert(const_iterator __hint, _Arg&& __v,\n-\t\t_NodeGenerator& __node_gen,\n-\t\tfalse_type /* __uks */)\n-      -> iterator\n-      {\n-\t// First allocate new node so that we don't do anything if it throws.\n-\t_Scoped_node __node{ __node_gen(std::forward<_Arg>(__v)), this };\n-\n-\t// Second compute the hash code so that we don't rehash if it throws.\n-\tauto __res = this->_M_compute_hash_code(\n-\t  __hint._M_cur, _ExtractKey{}(__node._M_node->_M_v()));\n-\n-\tauto __pos\n-\t  = _M_insert_multi_node(__res.first, __res.second, __node._M_node);\n-\t__node._M_node = nullptr;\n-\treturn __pos;\n-      }\n-\n   template<typename _Key, typename _Value, typename _Alloc,\n \t   typename _ExtractKey, typename _Equal,\n \t   typename _Hash, typename _RangeHash, typename _Unused,\ndiff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h\nindex 7a3c66c37fd6..caedb0258ef4 100644\n--- a/libstdc++-v3/include/bits/hashtable_policy.h\n+++ b/libstdc++-v3/include/bits/hashtable_policy.h\n@@ -947,16 +947,15 @@ namespace __detail\n \t\t_RangeHash, _Unused, _RehashPolicy, _Traits, __uniq>\n     { };\n \n-  /**\n-   *  Primary class template _Insert_base.\n-   *\n-   *  Defines @c insert member functions appropriate to all _Hashtables.\n-   */\n+#pragma GCC diagnostic push\n+#pragma GCC diagnostic ignored \"-Wc++17-extensions\" // if constexpr\n+\n+  // Defines `insert` member functions for _Hashtables.\n   template<typename _Key, typename _Value, typename _Alloc,\n \t   typename _ExtractKey, typename _Equal,\n \t   typename _Hash, typename _RangeHash, typename _Unused,\n \t   typename _RehashPolicy, typename _Traits>\n-    struct _Insert_base\n+    struct _Insert\n     {\n     protected:\n       using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,\n@@ -981,19 +980,14 @@ namespace __detail\n       using __node_alloc_type = typename __hashtable_alloc::__node_alloc_type;\n       using __node_gen_type = _AllocNode<__node_alloc_type>;\n \n+      [[__gnu__::__always_inline__]]\n       __hashtable&\n       _M_conjure_hashtable()\n       { return *(static_cast<__hashtable*>(this)); }\n \n-      template<typename _InputIterator, typename _NodeGetter>\n-\tvoid\n-\t_M_insert_range(_InputIterator __first, _InputIterator __last,\n-\t\t\t_NodeGetter&, true_type __uks);\n-\n-      template<typename _InputIterator, typename _NodeGetter>\n+      template<typename _InputIterator>\n \tvoid\n-\t_M_insert_range(_InputIterator __first, _InputIterator __last,\n-\t\t\t_NodeGetter&, false_type __uks);\n+\t_M_insert_range_multi(_InputIterator __first, _InputIterator __last);\n \n     public:\n       using iterator = _Node_iterator<_Value, __constant_iterators::value,\n@@ -1011,16 +1005,40 @@ namespace __detail\n       insert(const value_type& __v)\n       {\n \t__hashtable& __h = _M_conjure_hashtable();\n-\t__node_gen_type __node_gen(__h);\n-\treturn __h._M_insert(__v, __node_gen, __unique_keys{});\n+\tif constexpr (__unique_keys::value)\n+\t  return __h._M_emplace_uniq(__v);\n+\telse\n+\t  return __h._M_emplace_multi(__h.cend(), __v);\n       }\n \n       iterator\n       insert(const_iterator __hint, const value_type& __v)\n       {\n \t__hashtable& __h = _M_conjure_hashtable();\n-\t__node_gen_type __node_gen(__h);\n-\treturn __h._M_insert(__hint, __v, __node_gen, __unique_keys{});\n+\tif constexpr (__unique_keys::value)\n+\t  return __h._M_emplace_uniq(__v).first;\n+\telse\n+\t  return __h._M_emplace_multi(__hint, __v);\n+      }\n+\n+      __ireturn_type\n+      insert(value_type&& __v)\n+      {\n+\t__hashtable& __h = _M_conjure_hashtable();\n+\tif constexpr (__unique_keys::value)\n+\t  return __h._M_emplace_uniq(std::move(__v));\n+\telse\n+\t  return __h._M_emplace_multi(__h.cend(), std::move(__v));\n+      }\n+\n+      iterator\n+      insert(const_iterator __hint, value_type&& __v)\n+      {\n+\t__hashtable& __h = _M_conjure_hashtable();\n+\tif constexpr (__unique_keys::value)\n+\t  return __h._M_emplace_uniq(std::move(__v)).first;\n+\telse\n+\t  return __h._M_emplace_multi(__hint, std::move(__v));\n       }\n \n #ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED\n@@ -1056,39 +1074,52 @@ namespace __detail\n \tinsert(_InputIterator __first, _InputIterator __last)\n \t{\n \t  __hashtable& __h = _M_conjure_hashtable();\n-\t  __node_gen_type __node_gen(__h);\n-\t  return _M_insert_range(__first, __last, __node_gen, __unique_keys{});\n+\t  if constexpr (__unique_keys::value)\n+\t    for (; __first != __last; ++__first)\n+\t      __h._M_emplace_uniq(*__first);\n+\t  else\n+\t    return _M_insert_range_multi(__first, __last);\n \t}\n-    };\n \n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits>\n-    template<typename _InputIterator, typename _NodeGetter>\n-      void\n-      _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t   _Hash, _RangeHash, _Unused,\n-\t\t   _RehashPolicy, _Traits>::\n-      _M_insert_range(_InputIterator __first, _InputIterator __last,\n-\t\t      _NodeGetter& __node_gen, true_type __uks)\n-      {\n-\t__hashtable& __h = _M_conjure_hashtable();\n-\tfor (; __first != __last; ++__first)\n-\t  __h._M_insert(*__first, __node_gen, __uks);\n-      }\n+      // This overload is only defined for maps, not sets.\n+      template<typename _Pair,\n+\t       typename = _Require<__not_<is_same<_Key, _Value>>,\n+\t\t\t\t   is_constructible<value_type, _Pair&&>>>\n+\t__ireturn_type\n+\tinsert(_Pair&& __v)\n+\t{\n+\t  __hashtable& __h = this->_M_conjure_hashtable();\n+\t  if constexpr (__unique_keys::value)\n+\t    return __h._M_emplace_uniq(std::forward<_Pair>(__v));\n+\t  else\n+\t    return __h._M_emplace_multi(__h.cend(), std::forward<_Pair>(__v));\n+\t}\n+\n+      // This overload is only defined for maps, not sets.\n+      template<typename _Pair,\n+\t       typename = _Require<__not_<is_same<_Key, _Value>>,\n+\t\t\t\t   is_constructible<value_type, _Pair&&>>>\n+\titerator\n+\tinsert(const_iterator __hint, _Pair&& __v)\n+\t{\n+\t  __hashtable& __h = this->_M_conjure_hashtable();\n+\t  if constexpr (__unique_keys::value)\n+\t    return __h._M_emplace_uniq(std::forward<_Pair>(__v));\n+\t  else\n+\t    return __h._M_emplace_multi(__hint, std::forward<_Pair>(__v));\n+\t}\n+    };\n+#pragma GCC diagnostic pop\n \n   template<typename _Key, typename _Value, typename _Alloc,\n \t   typename _ExtractKey, typename _Equal,\n \t   typename _Hash, typename _RangeHash, typename _Unused,\n \t   typename _RehashPolicy, typename _Traits>\n-    template<typename _InputIterator, typename _NodeGetter>\n+    template<typename _InputIterator>\n       void\n-      _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t   _Hash, _RangeHash, _Unused,\n-\t\t   _RehashPolicy, _Traits>::\n-      _M_insert_range(_InputIterator __first, _InputIterator __last,\n-\t\t      _NodeGetter& __node_gen, false_type __uks)\n+      _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash,\n+\t      _Unused, _RehashPolicy, _Traits>::\n+      _M_insert_range_multi(_InputIterator __first, _InputIterator __last)\n       {\n \tusing __rehash_guard_t = typename __hashtable::__rehash_guard_t;\n \tusing __pair_type = std::pair<bool, std::size_t>;\n@@ -1105,120 +1136,13 @@ namespace __detail\n \t\t\t\t\t\t__n_elt);\n \n \tif (__do_rehash.first)\n-\t  __h._M_rehash(__do_rehash.second, __uks);\n+\t  __h._M_rehash(__do_rehash.second, false_type{});\n \n \t__rehash_guard._M_guarded_obj = nullptr;\n \tfor (; __first != __last; ++__first)\n-\t  __h._M_insert(*__first, __node_gen, __uks);\n+\t  __h._M_emplace_multi(__h.cend(), *__first);\n       }\n \n-  /**\n-   *  Primary class template _Insert.\n-   *\n-   *  Defines @c insert member functions that depend on _Hashtable policies,\n-   *  via partial specializations.\n-   */\n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits,\n-\t   bool _Constant_iterators = _Traits::__constant_iterators::value>\n-    struct _Insert;\n-\n-  /// Specialization.\n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits>\n-    struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t   _Hash, _RangeHash, _Unused,\n-\t\t   _RehashPolicy, _Traits, true>\n-    : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t\t  _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>\n-    {\n-      using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,\n-\t\t\t\t       _Equal, _Hash, _RangeHash, _Unused,\n-\t\t\t\t       _RehashPolicy, _Traits>;\n-\n-      using value_type = typename __base_type::value_type;\n-      using iterator = typename __base_type::iterator;\n-      using const_iterator =  typename __base_type::const_iterator;\n-      using __ireturn_type = typename __base_type::__ireturn_type;\n-\n-      using __unique_keys = typename __base_type::__unique_keys;\n-      using __hashtable = typename __base_type::__hashtable;\n-      using __node_gen_type = typename __base_type::__node_gen_type;\n-\n-      using __base_type::insert;\n-\n-      __ireturn_type\n-      insert(value_type&& __v)\n-      {\n-\t__hashtable& __h = this->_M_conjure_hashtable();\n-\t__node_gen_type __node_gen(__h);\n-\treturn __h._M_insert(std::move(__v), __node_gen, __unique_keys{});\n-      }\n-\n-      iterator\n-      insert(const_iterator __hint, value_type&& __v)\n-      {\n-\t__hashtable& __h = this->_M_conjure_hashtable();\n-\t__node_gen_type __node_gen(__h);\n-\treturn __h._M_insert(__hint, std::move(__v), __node_gen,\n-\t\t\t     __unique_keys{});\n-      }\n-    };\n-\n-  /// Specialization.\n-  template<typename _Key, typename _Value, typename _Alloc,\n-\t   typename _ExtractKey, typename _Equal,\n-\t   typename _Hash, typename _RangeHash, typename _Unused,\n-\t   typename _RehashPolicy, typename _Traits>\n-    struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t   _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>\n-    : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,\n-\t\t\t  _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>\n-    {\n-      using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,\n-\t\t\t\t       _Equal, _Hash, _RangeHash, _Unused,\n-\t\t\t\t       _RehashPolicy, _Traits>;\n-      using value_type = typename __base_type::value_type;\n-      using iterator = typename __base_type::iterator;\n-      using const_iterator =  typename __base_type::const_iterator;\n-\n-      using __unique_keys = typename __base_type::__unique_keys;\n-      using __hashtable = typename __base_type::__hashtable;\n-      using __ireturn_type = typename __base_type::__ireturn_type;\n-\n-      using __base_type::insert;\n-\n-      template<typename _Pair>\n-\tusing __is_cons = std::is_constructible<value_type, _Pair&&>;\n-\n-      template<typename _Pair>\n-\tusing _IFcons = std::enable_if<__is_cons<_Pair>::value>;\n-\n-      template<typename _Pair>\n-\tusing _IFconsp = typename _IFcons<_Pair>::type;\n-\n-      template<typename _Pair, typename = _IFconsp<_Pair>>\n-\t__ireturn_type\n-\tinsert(_Pair&& __v)\n-\t{\n-\t  __hashtable& __h = this->_M_conjure_hashtable();\n-\t  return __h._M_emplace(__unique_keys{}, std::forward<_Pair>(__v));\n-\t}\n-\n-      template<typename _Pair, typename = _IFconsp<_Pair>>\n-\titerator\n-\tinsert(const_iterator __hint, _Pair&& __v)\n-\t{\n-\t  __hashtable& __h = this->_M_conjure_hashtable();\n-\t  return __h._M_emplace(__hint, __unique_keys{},\n-\t\t\t\tstd::forward<_Pair>(__v));\n-\t}\n-   };\n-\n   template<typename _Policy>\n     using __has_load_factor = typename _Policy::__has_load_factor;\n \ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc\nindex ee41675a16ba..ca7a8c8604c9 100644\n--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc\n@@ -47,7 +47,8 @@ test01()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n void\n@@ -67,7 +68,8 @@ test02()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n std::size_t\n@@ -96,7 +98,8 @@ test11()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n std::size_t\n@@ -124,7 +127,8 @@ test12()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n struct hash_string_functor\n@@ -154,7 +158,8 @@ test21()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n struct hash_string_view_noexcept_functor\n@@ -184,7 +189,8 @@ test22()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n struct hash_string_view_functor\n@@ -214,7 +220,8 @@ test23()\n   VERIFY( um.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 4 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n+  // Allocated another node and a pair<const std::string, std::string>:\n+  VERIFY( __gnu_test::counter::get()._M_increments == 7 );\n }\n \n void\ndiff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc\nindex 59e1ad124010..b3c19d5a16c3 100644\n--- a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc\n+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc\n@@ -47,7 +47,7 @@ test01()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n void\n@@ -67,7 +67,7 @@ test02()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n std::size_t\n@@ -96,7 +96,7 @@ test11()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n std::size_t\n@@ -125,7 +125,7 @@ test12()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n struct hash_string_functor\n@@ -155,7 +155,7 @@ test21()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n struct hash_string_view_noexcept_functor\n@@ -185,7 +185,7 @@ test22()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n struct hash_string_view_functor\n@@ -215,7 +215,7 @@ test23()\n   VERIFY( us.size() == 1 );\n \n   VERIFY( __gnu_test::counter::count() == 3 );\n-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );\n+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );\n }\n \n void\n","prefixes":["v1","03/12"]}