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()

Reply via email to