Hi! This patch implements LWG3662 for C++11 ABI and COW ABI of strings.
Tested on x86_64 linux, ok for trunk? Thanks, Yuao
From fc49215982b5bcf47fcca9171e2a9a82f2fdec18 Mon Sep 17 00:00:00 2001 From: Yuao Ma <[email protected]> Date: Wed, 1 Jul 2026 22:36:33 +0800 Subject: [PATCH] libstdc++: implement LWG3662 basic_string::append/assign(NTBS, pos, n) suboptimal This patch implements LWG3662 for both ABIs of std::string. libstdc++-v3/ChangeLog: * include/bits/basic_string.h: Add new append/assign API. * include/bits/cow_string.h: Ditto. * testsuite/21_strings/basic_string/modifiers/append/char/2.cc: Test new API. * testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc: Ditto. * testsuite/21_strings/basic_string/modifiers/assign/char/3.cc: Ditto. * testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc: Ditto. --- libstdc++-v3/include/bits/basic_string.h | 31 +++++++++++++++++++ libstdc++-v3/include/bits/cow_string.h | 29 +++++++++++++++++ .../basic_string/modifiers/append/char/2.cc | 4 +++ .../modifiers/append/wchar_t/2.cc | 4 +++ .../basic_string/modifiers/assign/char/3.cc | 4 +++ .../modifiers/assign/wchar_t/3.cc | 4 +++ 6 files changed, 76 insertions(+) diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 65d92ebfbcf..69d45ceb01e 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1639,6 +1639,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return _M_append(__s, __n); } + /** + * @brief Append a C substring. + * @param __s The C string to append. + * @param __pos The position in the C string to append from. + * @param __n The number of characters to append. + * @return Reference to this string. + */ + _GLIBCXX20_CONSTEXPR + basic_string& + append(const _CharT* __s, size_type __pos, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "basic_string::append"); + return append(__sv_type(__s).substr(__pos, __n)); + } + /** * @brief Append multiple characters. * @param __n The number of characters to append. @@ -1902,6 +1918,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 traits_type::length(__s)); } + /** + * @brief Set value to a C substring. + * @param __s The C string to use. + * @param __pos The position in the C string to assign from. + * @param __n Number of characters to use. + * @return Reference to this string. + */ + _GLIBCXX20_CONSTEXPR + basic_string& + assign(const _CharT* __s, size_type __pos, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return assign(__sv_type(__s).substr(__pos, __n)); + } + /** * @brief Set value to multiple characters. * @param __n Length of the resulting string. diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index 7c945f6b998..e89feda7a3c 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -1345,6 +1345,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return this->append(__s, traits_type::length(__s)); } + /** + * @brief Append a C substring. + * @param __s The C string to append. + * @param __pos The position in the C string to append from. + * @param __n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __pos, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "basic_string::append"); + return append(__sv_type(__s).substr(__pos, __n)); + } + /** * @brief Append multiple characters. * @param __n The number of characters to append. @@ -1517,6 +1532,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return this->assign(__s, traits_type::length(__s)); } + /** + * @brief Set value to a C substring. + * @param __s The C string to use. + * @param __pos The position in the C string to assign from. + * @param __n Number of characters to use. + * @return Reference to this string. + */ + basic_string& + assign(const _CharT* __s, size_type __pos, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return assign(__sv_type(__s).substr(__pos, __n)); + } + /** * @brief Set value to multiple characters. * @param __n Length of the resulting string. diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/2.cc index d70fc190b45..5dd39347574 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/2.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/2.cc @@ -24,6 +24,7 @@ // append(const _CharT* __s, size_type __n) // append(const _CharT* __s) +// append(const _CharT* __s, size_type __pos, size_type __n) void test02() { @@ -55,6 +56,9 @@ test02() two.append(two.c_str(), 3); VERIFY( two == "Written in your eyeseyesWri" ); + + two.append(two.c_str(), 8, 2); + VERIFY( two == "Written in your eyeseyesWriin" ); } int main() diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc index 1922874de7f..fcc1ef54f28 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc @@ -24,6 +24,7 @@ // append(const _CharT* __s, size_type __n) // append(const _CharT* __s) +// append(const _CharT* __s, size_type __pos, size_type __n) void test02() { @@ -55,6 +56,9 @@ test02() two.append(two.c_str(), 3); VERIFY( two == L"Written in your eyeseyesWri" ); + + two.append(two.c_str(), 8, 2); + VERIFY( two == L"Written in your eyeseyesWriin" ); } int main() diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/3.cc index 1bd3deb30f4..a742c1ed3df 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/3.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/3.cc @@ -24,6 +24,7 @@ // assign(const _CharT* __s, size_type __n) // assign(const _CharT* __s) +// assign(const _CharT* __s, size_type __pos, size_type __n) void test03() { @@ -47,6 +48,9 @@ test03() one.assign(one.c_str() + 8, 6); VERIFY( one == "by the" ); + + one.assign(one.c_str(), 3, 3); + VERIFY( one == "the" ); } int main() diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc index e7fcb231dff..37ff7e1ca2b 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc @@ -24,6 +24,7 @@ // assign(const _CharT* __s, size_type __n) // assign(const _CharT* __s) +// assign(const _CharT* __s, size_type __pos, size_type __n) void test03() { @@ -47,6 +48,9 @@ test03() one.assign(one.c_str() + 8, 6); VERIFY( one == L"by the" ); + + one.assign(one.c_str(), 3, 3); + VERIFY( one == L"the" ); } int main() -- 2.54.0
