]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: implement LWG3662 basic_string::append/assign(NTBS, pos, n) suboptimal
authorYuao Ma <c8ef@outlook.com>
Thu, 2 Jul 2026 12:32:17 +0000 (20:32 +0800)
committerYuao Ma <c8ef@outlook.com>
Thu, 2 Jul 2026 15:54:08 +0000 (23:54 +0800)
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.

libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/cow_string.h
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/2.cc
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/wchar_t/2.cc
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/3.cc
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/3.cc

index 65d92ebfbcf80d773499dc83480a12d94f6af9dd..fd9419220a49b5d469ba6088b856fb0affd9f352 100644 (file)
@@ -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
index 7c945f6b9983693440bb6b95aacd2d1f3534c74d..0f1a2e082d0a94528fa13fa122f2033b1771c078 100644 (file)
@@ -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
 
       /**
index d70fc190b4542cf798e015564d11ddbda4ac3a4f..d9ccbd768960f87b834fb71ada8d53b957ce51ab 100644 (file)
 
 // 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()
index 1922874de7f2bb98983ec5cc5585d029354c90f7..d0d95fb3f27bffa110def160540cc61f378f2738 100644 (file)
 
 // 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()
index 1bd3deb30f4743c17f5ee139e9c85b18cc093d84..75f2dcf01300d90c17fe5b129eaf9ecd6056f91d 100644 (file)
 
 // 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()
index e7fcb231dff62ed11900100b2dd0b0e3ba044b89..821cde246bd548e4d723a4e7cd4a7d4584f93246 100644 (file)
 
 // 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()