get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2196880,
    "url": "http://patchwork.ozlabs.org/api/patches/2196880/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260216114202.725232-1-tkaminsk@redhat.com/",
    "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": "<20260216114202.725232-1-tkaminsk@redhat.com>",
    "list_archive_url": null,
    "date": "2026-02-16T11:40:52",
    "name": "libstdc++: Implement rvalue overload for basic_string::substr() [PR119745]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "1e3641ded818d6f5470c4c6260e1d0033b13b1fb",
    "submitter": {
        "id": 90409,
        "url": "http://patchwork.ozlabs.org/api/people/90409/?format=api",
        "name": "Tomasz Kamiński",
        "email": "tkaminsk@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260216114202.725232-1-tkaminsk@redhat.com/mbox/",
    "series": [
        {
            "id": 492299,
            "url": "http://patchwork.ozlabs.org/api/series/492299/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=492299",
            "date": "2026-02-16T11:40:52",
            "name": "libstdc++: Implement rvalue overload for basic_string::substr() [PR119745]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492299/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196880/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196880/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\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=ga6pVCEc;\n\tdkim-atps=neutral",
            "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\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=ga6pVCEc",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "sourceware.org; spf=pass smtp.mailfrom=redhat.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"
        ],
        "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 4fF19q6qn5z1xwF\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 16 Feb 2026 22:43:09 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id EDAFB4BAD16B\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 16 Feb 2026 11:43:04 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id 8D2EC4BA23F9\n for <gcc-patches@gcc.gnu.org>; Mon, 16 Feb 2026 11:42:09 +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-695-ZQ5ajuNiNPevsHTeTFwFRg-1; Mon,\n 16 Feb 2026 06:42:06 -0500",
            "from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111])\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 E602918005AD; Mon, 16 Feb 2026 11:42:04 +0000 (UTC)",
            "from localhost (unknown [10.44.33.164])\n by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 4A9D618003F5; Mon, 16 Feb 2026 11:42:03 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org EDAFB4BAD16B",
            "OpenDKIM Filter v2.11.0 sourceware.org 8D2EC4BA23F9"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 8D2EC4BA23F9",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 8D2EC4BA23F9",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1771242129; cv=none;\n b=qcXsIZ28tEueGxayxsY4BsHHblebTP1j/Zq5CtDbqrdQY+6oYNzJnfHHiKKqkSUuTyZXgJOYv80DPsqz5dvKd0/5uTeDbWunWi6Q4QFaqzm7gxRWOOIV6eJH4kh8Riyw17AD4+4loSVHBhi42lJsM/yo4BLR7ovESUOU+rTGjKI=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1771242129; c=relaxed/simple;\n bh=lWwl5VNq2S0bf4gT3Zr3v4UEL2fyINoC+fUk0Mtshz4=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=ui4HlJ7L/mOyONeAThMXp1vh7soAa5fRCNAbXhKmVi4b/HxOanPZXCnovH0vuxK8PDZ3wuVQgcVa77CTH9aYqwOeCFy1DDgsH6IV/m7Fe1bDI6CdmXgAzwn+V/XL9ellH2mRZu1HCRQxvjXLJYCzEl6UnjAn1ypfW/x/8PtoPfU=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1771242129;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=5/6Strv6AX8cRrBtlthKBWlzIrJ8Z74grY8Jgi0hI/Y=;\n b=ga6pVCEc0CFAbmCleRXVZlR+kINwq2vkZPjP4k1V+HcL2VpdAMIEnoK35mIHoMdrTMdwSv\n 6RR/a+u1qNjKV7gZEqXDhXORAYmZSN4MM5+sfgy1bGlH2/UbCU/yv/r77a/0RM0ODaN891\n 4nYvy1pzML9hoPc5MJJiVKHPF2nFEvA=",
        "X-MC-Unique": "ZQ5ajuNiNPevsHTeTFwFRg-1",
        "X-Mimecast-MFC-AGG-ID": "ZQ5ajuNiNPevsHTeTFwFRg_1771242125",
        "From": "=?utf-8?q?Tomasz_Kami=C5=84ski?= <tkaminsk@redhat.com>",
        "To": "libstdc++@gcc.gnu.org,\n\tgcc-patches@gcc.gnu.org",
        "Subject": "[PATCH] libstdc++: Implement rvalue overload for\n basic_string::substr() [PR119745]",
        "Date": "Mon, 16 Feb 2026 12:40:52 +0100",
        "Message-ID": "<20260216114202.725232-1-tkaminsk@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.111",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "V4drxcUBbcvs3LYw6IftG_kqvEa67UuydwBAiSc1Bkc_1771242125",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; 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": "This paper implement the changes from P2438R2 basic_string::substr() &&\npaper into C++26. The additional substr and constructor overload are\nimplemented only for SSO string, as they require mutating the content\n(if reused), and thus would require copy of the string anyway for COW\nstrings. (In consequence allocators implicitly constructible from int\nremain ambiguous for C++11 ABI strings, see r16-7497-gfa1149534d8580).\n\nIn addition to cases when the allocators are not compatible (equal),\nthis patch does not reuse (transfer) allocator storage, if the selected\nsubstring fits inside the SSO buffer, so we do not risk keeping large\nchunk of memory for few characters. (This also covers cases when the\nsource stored the content in the local buffer).\n\nAs this additional overloads are meant to be optimization, in contrast\nto move constructor, the source is left unmodified if the allocation\nis not transferred. This avoid introducing a write (of null terminator)\nto previously untouched, heap allocated, memory.\n\nSeparate overloads for and substr(size_type __pos, size_type __n)\nsubstr(size_type __pos == 0), that delegate to corresponding constructor,\nare provided to avoid the check of __n against the length() in the later\ncase.\n\nFinally, the signatures of existing substr() overload are not modified\n(no longer required since C++20), which avoid any impact on the ABI.\n\n\tPR libstdc++/119745\n\nlibstdc++-v3/ChangeLog:\n\n\t* include/bits/basic_string.h (basic_string::_M_construct)\n\t[__cplusplus >= 202302L]: Declare.\n\t(basic_string::basic_string(basic_string&&, size_type, const _Alloc&))\n\t(basic_string(basic_string&&, size_type, size_type, const _Alloc&))\n\t(basic_string::substr(size_type, size_type) &&)\n\t((basic_string::substr(size_type) &&) [__cplusplus >= 202302L]: Define.\n\t* include/bits/basic_string.tcc (basic_string::_M_construct)\n\t[__cplusplus >= 202302L]: Define.\n\t* testsuite/21_strings/basic_string/operations/substr/rvalue.cc: New test.\n---\nTestint on x86-64-linux. Locally all test passed, and the\nsubstr/rvalue.cc with all standard modes, -m32, cxx11 and debug passed.\n\nOK for trunk when all tests passes?\n\n libstdc++-v3/include/bits/basic_string.h      |  37 ++\n libstdc++-v3/include/bits/basic_string.tcc    |  32 ++\n .../basic_string/operations/substr/rvalue.cc  | 334 ++++++++++++++++++\n 3 files changed, 403 insertions(+)\n create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/operations/substr/rvalue.cc",
    "diff": "diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h\nindex cd6f312f1bd..04377706cc2 100644\n--- a/libstdc++-v3/include/bits/basic_string.h\n+++ b/libstdc++-v3/include/bits/basic_string.h\n@@ -354,6 +354,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \tvoid\n \t_M_construct(const _CharT *__c, size_type __n);\n \n+#if __cplusplus >= 202302L\n+      constexpr void\n+      _M_construct(basic_string&& __str, size_type __pos,  size_type __n);\n+#endif\n+\n       _GLIBCXX20_CONSTEXPR\n       allocator_type&\n       _M_get_allocator()\n@@ -671,6 +676,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \t\t     std::forward_iterator_tag());\n       }\n \n+#if __cplusplus >= 202302L\n+      _GLIBCXX20_CONSTEXPR\n+      basic_string(basic_string&& __str, size_type __pos,\n+\t\t   const _Alloc& __a = _Alloc())\n+      : _M_dataplus(_M_local_data(), __a)\n+      {\n+\t__pos = __str._M_check(__pos, \"string::string\");\n+\t_M_construct(std::move(__str), __pos, __str.length() - __pos);\n+      }\n+\n+      _GLIBCXX20_CONSTEXPR\n+      basic_string(basic_string&& __str, size_type __pos, size_type __n,\n+\t\t   const _Alloc& __a = _Alloc())\n+      : _M_dataplus(_M_local_data(), __a)\n+      {\n+\t__pos = __str._M_check(__pos, \"string::string\");\n+\t_M_construct(std::move(__str), __pos, __str._M_limit(__pos, __n));\n+      }\n+#endif\n+\n       /**\n        *  @brief  Construct string initialized by a character %array.\n        *  @param  __s  Source character %array.\n@@ -3442,6 +3467,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n       { return basic_string(*this,\n \t\t\t    _M_check(__pos, \"basic_string::substr\"), __n); }\n \n+#if __cplusplus >= 202302L\n+      _GLIBCXX_NODISCARD\n+      constexpr basic_string\n+      substr(size_type __pos = 0) &&\n+      { return basic_string(std::move(*this), __pos); }\n+     \n+      _GLIBCXX_NODISCARD\n+      constexpr basic_string\n+      substr(size_type __pos, size_type __n) &&\n+      { return basic_string(std::move(*this), __pos, __n); }\n+#endif // __cplusplus\n+\n #ifdef __glibcxx_string_subview // >= C++26\n       /**\n        *  @brief  Get a subview.\ndiff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc\nindex 75ffea42ced..ab5b06d86f8 100644\n--- a/libstdc++-v3/include/bits/basic_string.tcc\n+++ b/libstdc++-v3/include/bits/basic_string.tcc\n@@ -302,6 +302,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \ttraits_type::assign(_M_data()[__n], _CharT());\n     }\n \n+#if __cplusplus >= 202302L\n+  template<typename _CharT, typename _Traits, typename _Alloc>\n+    constexpr void\n+    basic_string<_CharT, _Traits, _Alloc>::\n+    _M_construct(basic_string&& __str, size_type __pos,  size_type __n)\n+    {\n+      const _CharT* __start = __str._M_data() + __pos;\n+      if (__n < _S_local_capacity)\n+\t{\n+\t  _M_init_local_buf();\n+\t  traits_type::copy(_M_local_buf, __start, __n);\n+\t  _M_set_length(__n);\n+\t  return;\n+\t}\n+\n+      if constexpr (!allocator_traits<_Alloc>::is_always_equal::value)\n+\tif (get_allocator() != __str.get_allocator())\n+\t  {\n+       \t    _M_construct<false>(__start, __n);\n+\t    return;\n+\t  }\n+\n+      _M_data(__str._M_data());\n+      _M_capacity(__str._M_allocated_capacity);\n+      __str._M_data(__str._M_use_local_data());\n+      __str._M_set_length(0);\n+\n+      _S_move(_M_data(), _M_data() + __pos, __n);\n+      _M_set_length(__n);\n+    }\n+#endif\n+\n   template<typename _CharT, typename _Traits, typename _Alloc>\n     _GLIBCXX20_CONSTEXPR\n     void\ndiff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/substr/rvalue.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/substr/rvalue.cc\nnew file mode 100644\nindex 00000000000..1c8d9f7aeb0\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/substr/rvalue.cc\n@@ -0,0 +1,334 @@\n+// { dg-do run { target c++26 } }\n+\n+#include <string_view>\n+#include <testsuite_hooks.h>\n+#include <testsuite_allocator.h>\n+\n+// When selection is short enought to fit into SSO, the rhs\n+// is left unchanged.\n+template<typename CharT, typename Allocator>\n+constexpr void\n+do_test_short_in(const CharT* cstr, Allocator alloc)\n+{\n+  using StringView = std::basic_string_view<CharT>;\n+  using String = std::basic_string<CharT, std::char_traits<CharT>, Allocator>;\n+\n+  const Allocator defAlloc;\n+  String src, res;\n+\n+  // substr(0)\n+  src = String(cstr, alloc);\n+  res = std::move(src).substr(0);\n+  VERIFY( res == StringView(cstr).substr(0) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res1(std::move(src), 0);\n+  VERIFY( res1 == StringView(cstr).substr(0) );\n+  VERIFY( res1.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res2(std::move(src), 0, alloc);\n+  VERIFY( res2 == StringView(cstr).substr(0) );\n+  VERIFY( res2.get_allocator() == alloc );\n+  VERIFY( src == cstr );\n+\n+  // substr(1)\n+  src = String(cstr, alloc);\n+  res = std::move(src).substr(1);\n+  VERIFY( res == StringView(cstr).substr(1) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res3(std::move(src), 1);\n+  VERIFY( res3 == StringView(cstr).substr(1) );\n+  VERIFY( res3.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res4(std::move(src), 1, alloc);\n+  VERIFY( res4 == StringView(cstr).substr(1) );\n+  VERIFY( res4.get_allocator() == alloc );\n+  VERIFY( src == cstr );\n+\n+  // substr(1, 1000)\n+  src = String(cstr, alloc);\n+  res = std::move(src).substr(1, 1000);\n+  VERIFY( res == StringView(cstr).substr(1, 1000) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res5(std::move(src), 1, 1000);\n+  VERIFY( res5 == StringView(cstr).substr(1, 1000) );\n+  VERIFY( res5.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res6(std::move(src), 1, 1000, alloc);\n+  VERIFY( res6 == StringView(cstr).substr(1, 1000) );\n+  VERIFY( res6.get_allocator() == alloc );\n+  VERIFY( src == cstr );\n+}\n+\n+template<typename CharT, typename Allocator>\n+constexpr void\n+do_test_short_sel(const CharT* cstr, Allocator alloc)\n+{\n+  using StringView = std::basic_string_view<CharT>;\n+  using String = std::basic_string<CharT, std::char_traits<CharT>, Allocator>;\n+\n+  const Allocator defAlloc;\n+  String src, res;\n+\n+  // substr(0, 2)\n+  src = String(cstr, alloc);\n+  res = std::move(src).substr(0, 2);\n+  VERIFY( res == StringView(cstr).substr(0, 2) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res1(std::move(src), 0, 2);\n+  VERIFY( res1 == StringView(cstr).substr(0, 2) );\n+  VERIFY( res1.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res2(std::move(src), 0, 2, alloc);\n+  VERIFY( res2 == StringView(cstr).substr(0, 2) );\n+  VERIFY( res2.get_allocator() == alloc );\n+  VERIFY( src == cstr );\n+\n+  // substr(1, 2)\n+  src = String(cstr, alloc);\n+  res = std::move(src).substr(1, 2);\n+  VERIFY( res == StringView(cstr).substr(1, 2) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res3(std::move(src), 1, 2);\n+  VERIFY( res3 == StringView(cstr).substr(1, 2) );\n+  VERIFY( res3.get_allocator() == defAlloc );\n+  VERIFY( src == cstr );\n+\n+  src = String(cstr, alloc);\n+  String res4(std::move(src), 1, 2, alloc);\n+  VERIFY( res4 == StringView(cstr).substr(1, 2) );\n+  VERIFY( res4.get_allocator() == alloc );\n+  VERIFY( src == cstr );\n+}\n+\n+// If the selection is long enugh to do not fit into SSO,\n+// the memory is moved if allocators are compatible.\n+template<typename CharT, typename Allocator>\n+constexpr void\n+do_test_long(const CharT* cstr, Allocator alloc)\n+{\n+  using StringView = std::basic_string_view<CharT>;\n+  using String = std::basic_string<CharT, std::char_traits<CharT>, Allocator>;\n+\n+  const Allocator defAlloc;\n+  String src, res;\n+  const CharT* data;\n+\n+  auto verifyMove = [&](const String& str)\n+  {\n+    // Only SSO string provide rvalue overloads of\n+    // substr and corresponding constructor.\n+#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI\n+    if (str.get_allocator() == alloc) {\n+      VERIFY( str.data() == data );\n+      VERIFY( src.empty() );\n+    } else\n+#endif\n+      VERIFY( src == cstr );\n+  };\n+\n+  // substr(0)\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  res = std::move(src).substr(0);\n+  VERIFY( res == StringView(cstr).substr(0) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  verifyMove(res);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res1(std::move(src), 0);\n+  VERIFY( res1 == StringView(cstr).substr(0) );\n+  VERIFY( res1.get_allocator() == defAlloc );\n+  verifyMove(res1);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res2(std::move(src), 0, alloc);\n+  VERIFY( res2 == StringView(cstr).substr(0) );\n+  VERIFY( res2.get_allocator() == alloc );\n+  verifyMove(res2);\n+\n+  // substr(5)\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  res = std::move(src).substr(5);\n+  VERIFY( res == StringView(cstr).substr(5) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  verifyMove(res);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res3(std::move(src), 5);\n+  VERIFY( res3 == StringView(cstr).substr(5) );\n+  VERIFY( res3.get_allocator() == defAlloc );\n+  verifyMove(res3);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res4(std::move(src), 5, alloc);\n+  VERIFY( res4 == StringView(cstr).substr(5) );\n+  verifyMove(res4);\n+\n+  // substr(0, 50)\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  res = std::move(src).substr(0, 50);\n+  VERIFY( res == StringView(cstr).substr(0, 50) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  verifyMove(res);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res5(std::move(src), 0, 50);\n+  VERIFY( res5 == StringView(cstr).substr(0, 50) );\n+  VERIFY( res5.get_allocator() == defAlloc );\n+  verifyMove(res5);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res6(std::move(src), 0, 50, alloc);\n+  VERIFY( res6 == StringView(cstr).substr(0, 50) );\n+  VERIFY( res6.get_allocator() == alloc );\n+  verifyMove(res6);\n+\n+  // substr(5, 50)\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  res = std::move(src).substr(5, 50);\n+  VERIFY( res == StringView(cstr).substr(5, 50) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  verifyMove(res);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res7(std::move(src), 5, 50);\n+  VERIFY( res7 == StringView(cstr).substr(5, 50) );\n+  VERIFY( res7.get_allocator() == defAlloc );\n+  verifyMove(res7);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res8(std::move(src), 5, 50, alloc);\n+  VERIFY( res8 == StringView(cstr).substr(5, 50) );\n+  VERIFY( res8.get_allocator() == alloc );\n+  verifyMove(res8);\n+\n+  // substr(5, 100)\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  res = std::move(src).substr(5, 1000);\n+  VERIFY( res == StringView(cstr).substr(5, 1000) );\n+  VERIFY( res.get_allocator() == defAlloc );\n+  verifyMove(res);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res9(std::move(src), 5, 1000);\n+  VERIFY( res9 == StringView(cstr).substr(5, 1000) );\n+  VERIFY( res9.get_allocator() == defAlloc );\n+  verifyMove(res9);\n+\n+  src = String(cstr, alloc);\n+  data = src.data();\n+  String res10(std::move(src), 5, 1000, alloc);\n+  VERIFY( res10 == StringView(cstr).substr(5, 1000) );\n+  VERIFY( res10.get_allocator() == alloc );\n+  verifyMove(res10);\n+}\n+\n+template<typename CharT, typename Allocator>\n+constexpr void\n+do_test_alloc(const CharT* sht, const CharT* lng, Allocator alloc)\n+{\n+  do_test_short_in(sht, alloc);\n+  do_test_short_sel(sht, alloc);\n+  do_test_short_sel(lng, alloc);\n+  do_test_long(lng, alloc);\n+}\n+\n+template<typename CharT>\n+constexpr void\n+do_test_bounds(const CharT* cstr)\n+{\n+  using String = std::basic_string<CharT>;\n+  try\n+  {\n+    auto res = String(cstr).substr(10);\n+    VERIFY(false);\n+  } catch (const std::out_of_range&) {\n+    VERIFY(true);\n+  }\n+\n+  try\n+  {\n+    auto res = String(cstr).substr(10, 20);\n+    VERIFY(false);\n+  } catch (const std::out_of_range&) {\n+    VERIFY(true);\n+  }\n+\n+  try\n+  {\n+    String res(String(cstr), 10);\n+    VERIFY(false);\n+  } catch (const std::out_of_range&) {\n+    VERIFY(true);\n+  }\n+\n+  try\n+  {\n+    String res(String(cstr), 10, 20);\n+    VERIFY(false);\n+  } catch (const std::out_of_range&) {\n+    VERIFY(true);\n+  }\n+}\n+\n+template<typename CharT>\n+constexpr void\n+do_test(const CharT* sht, const CharT* lng)\n+{\n+  do_test_alloc(sht, lng, std::allocator<CharT>());\n+  if ! consteval {\n+    do_test_alloc(sht, lng, __gnu_test::uneq_allocator<CharT>());\n+    do_test_alloc(sht, lng, __gnu_test::uneq_allocator<CharT>(42));\n+    do_test_bounds(sht);\n+  }\n+}\n+\n+constexpr bool\n+test_all()\n+{\n+  do_test(\"abcd\", \"some very very long string, that will not use SSO, and have  at least fifty characters\");\n+  do_test(L\"ab\", L\"some very very long string, that will not use SSO, and have  at least fifty characters\");\n+\n+  return true;\n+}\n+\n+int main()\n+{ \n+  test_all();\n+}\n",
    "prefixes": []
}