libstdc++: Define std::string::resize_and_overwrite for C++11 and COW string
commit95c2b0cc9eaa5b9fbec34e8c5399c7d8f07f329b
authorJonathan Wakely <jwakely@redhat.com>
Wed, 16 Aug 2023 17:22:38 +0000 (16 18:22 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 17 Aug 2023 19:24:17 +0000 (17 20:24 +0100)
treefec9bb1d44197cc37fd2a40ec58307ac8376376f
parentdc48d1d1d4458773f89f21b2f019f66ddf88f2e5
libstdc++: Define std::string::resize_and_overwrite for C++11 and COW string

There are several places in the library where we can improve performance
using resize_and_overwrite so it's inconvenient only being able to use
it in C++23 mode, and only for cxx11 strings. This adds it for COW
strings, and also adds __resize_and_overwrite as an extension for C++11
mode.

The new __resize_and_overwrite is available for C++11 and later, so
within the library we can use that consistently even in C++23.  In order
to avoid making a copy (which might not be possible for non-copyable,
non-movable types) the callable is passed to resize_and_overwrite as an
lvalue reference.  Unlike wrapping it in std::ref(op) this ensures that
invoking it as std::move(op)(n, p) will use the correct value category.
It also avoids any overhead that would be added by wrapping it in a
lambda like [&op](auto p, auto n) { return std::move(op)(p, n); }.

Adjust std::format to use the new __resize_and_overwrite, which we can
assume exists because we only use std::basic_string<char> and
std::basic_string<wchar_t>, so no program-defined specializations.

The uses in <experimental/internet> cannot be replaced, because those
are type-dependent on an Allocator template parameter, which could mean
they use program-defined specializations of std::basic_string that don't
have the __resize_and_overwrite extension.

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h (__resize_and_overwrite): New
function.
* include/bits/basic_string.tcc (__resize_and_overwrite): New
function.
(resize_and_overwrite): Simplify by using reserve instead of
growing the string manually. Adjust for C++11 compatibility.
* include/bits/cow_string.h (resize_and_overwrite): New
function.
(__resize_and_overwrite): New function.
* include/bits/version.def (__cpp_lib_string_resize_and_overwrite):
Do not depend on cxx11abi.
* include/bits/version.h: Regenerate.
* include/std/format (__formatter_fp::_S_resize_and_overwrite):
Remove.
(__formatter_fp::format, __formatter_fp::_M_localize): Use
__resize_and_overwrite instead of _S_resize_and_overwrite.
* testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc:
Adjust for C++11 compatibility when included by ...
* testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite_ext.cc:
New test.
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/include/bits/cow_string.h
libstdc++-v3/include/bits/version.def
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/std/format
libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite_ext.cc [new file with mode: 0644]