https://gcc.gnu.org/g:7084db3f6e1cc68b422fdff81c823861d19c01ed
commit r17-2095-g7084db3f6e1cc68b422fdff81c823861d19c01ed Author: Yuao Ma <[email protected]> Date: Thu Jul 2 20:32:17 2026 +0800 libstdc++: implement LWG3662 basic_string::append/assign(NTBS, pos, n) suboptimal This patch implements LWG3662 for both ABIs of strings. libstdc++-v3/ChangeLog: * include/bits/basic_string.h(append, assign): Add new overloads. * include/bits/cow_string.h(append, assign): Ditto. * testsuite/21_strings/basic_string/modifiers/append/char/2.cc: Test new overloads. * 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. Diff: --- libstdc++-v3/include/bits/basic_string.h | 28 ++++++++++++++++++++++ libstdc++-v3/include/bits/cow_string.h | 26 ++++++++++++++++++++ .../basic_string/modifiers/append/char/2.cc | 16 +++++++++++++ .../basic_string/modifiers/append/wchar_t/2.cc | 16 +++++++++++++ .../basic_string/modifiers/assign/char/3.cc | 16 +++++++++++++ .../basic_string/modifiers/assign/wchar_t/3.cc | 16 +++++++++++++ 6 files changed, 118 insertions(+) diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 65d92ebfbcf8..fd9419220a49 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1767,6 +1767,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 + std::__sv_check(__sv.size(), __pos, "basic_string::append"), std::__sv_limit(__sv.size(), __pos, __n)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal + /** + * @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) + { return append(__sv_type(__s).substr(__pos, __n)); } #endif // C++17 /** @@ -2040,6 +2054,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 + std::__sv_check(__sv.size(), __pos, "basic_string::assign"), std::__sv_limit(__sv.size(), __pos, __n)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal + /** + * @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) + { return assign(__sv_type(__s).substr(__pos, __n)); } #endif // C++17 #if __cplusplus >= 201103L diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index 7c945f6b9983..0f1a2e082d0a 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -1427,6 +1427,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + std::__sv_check(__sv.size(), __pos, "basic_string::append"), std::__sv_limit(__sv.size(), __pos, __n)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal + /** + * @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) + { return append(__sv_type(__s).substr(__pos, __n)); } #endif // C++17 /** @@ -1600,6 +1613,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + std::__sv_check(__sv.size(), __pos, "basic_string::assign"), std::__sv_limit(__sv.size(), __pos, __n)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3662. basic_string::append/assign(NTBS, pos, n) suboptimal + /** + * @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) + { return assign(__sv_type(__s).substr(__pos, __n)); } #endif // C++17 /** 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 d70fc190b454..d9ccbd768960 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 @@ -19,11 +19,13 @@ // 21.3.5 string modifiers +#include <stdexcept> #include <string> #include <testsuite_hooks.h> // 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 +57,20 @@ 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" ); + + try { + two.append("a\0b", 2, 1); + VERIFY( false ); + } + catch(std::out_of_range& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } } 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 1922874de7f2..d0d95fb3f27b 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 @@ -19,11 +19,13 @@ // 21.3.5 string modifiers +#include <stdexcept> #include <string> #include <testsuite_hooks.h> // 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 +57,20 @@ 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" ); + + try { + two.append(L"a\0b", 2, 1); + VERIFY( false ); + } + catch(std::out_of_range& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } } 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 1bd3deb30f47..75f2dcf01300 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 @@ -19,11 +19,13 @@ // 21.3.5 string modifiers +#include <stdexcept> #include <string> #include <testsuite_hooks.h> // 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 +49,20 @@ test03() one.assign(one.c_str() + 8, 6); VERIFY( one == "by the" ); + + one.assign(one.c_str(), 3, 3); + VERIFY( one == "the" ); + + try { + one.assign("a\0b", 2, 1); + VERIFY( false ); + } + catch(std::out_of_range& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } } 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 e7fcb231dff6..821cde246bd5 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 @@ -19,11 +19,13 @@ // 21.3.5 string modifiers +#include <stdexcept> #include <string> #include <testsuite_hooks.h> // 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 +49,20 @@ test03() one.assign(one.c_str() + 8, 6); VERIFY( one == L"by the" ); + + one.assign(one.c_str(), 3, 3); + VERIFY( one == L"the" ); + + try { + one.assign(L"a\0b", 2, 1); + VERIFY( false ); + } + catch(std::out_of_range& fail) { + VERIFY( true ); + } + catch(...) { + VERIFY( false ); + } } int main()
