From: Yuao Ma Date: Thu, 2 Jul 2026 12:32:17 +0000 (+0800) Subject: libstdc++: implement LWG3662 basic_string::append/assign(NTBS, pos, n) suboptimal X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7084db3f6e1cc68b422fdff81c823861d19c01ed;p=thirdparty%2Fgcc.git 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 --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 65d92ebfbcf..fd9419220a4 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 7c945f6b998..0f1a2e082d0 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 d70fc190b45..d9ccbd76896 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 #include #include // 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 1922874de7f..d0d95fb3f27 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 #include #include // 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 1bd3deb30f4..75f2dcf0130 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 #include #include // 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 e7fcb231dff..821cde246bd 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 #include #include // 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()