[gcc r16-5871] libstdc++: implement P3044R2 - sub-string_view from string (string part)
Yuao Ma
yuao@gcc.gnu.org
Wed Dec 3 15:57:39 GMT 2025
https://gcc.gnu.org/g:6123cb8bfc39323e0c175dd374e6dfe9b2984ee7
commit r16-5871-g6123cb8bfc39323e0c175dd374e6dfe9b2984ee7
Author: Yuao Ma <c8ef@outlook.com>
Date: Tue Dec 2 23:35:40 2025 +0800
libstdc++: implement P3044R2 - sub-string_view from string (string part)
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h: Add subview.
* include/bits/cow_string.h: Add subview.
* include/std/string: Add FTM.
* testsuite/21_strings/basic_string/operations/subview/char.cc: New test.
* testsuite/21_strings/basic_string/operations/subview/wchar_t.cc: New test.
Diff:
---
libstdc++-v3/include/bits/basic_string.h | 19 +++++++++
libstdc++-v3/include/bits/cow_string.h | 19 +++++++++
libstdc++-v3/include/std/string | 1 +
.../basic_string/operations/subview/char.cc | 46 ++++++++++++++++++++++
.../basic_string/operations/subview/wchar_t.cc | 46 ++++++++++++++++++++++
5 files changed, 131 insertions(+)
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index c4b6b1064a94..b1db722402f2 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3442,6 +3442,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ return basic_string(*this,
_M_check(__pos, "basic_string::substr"), __n); }
+#ifdef __glibcxx_string_subview // >= C++26
+ /**
+ * @brief Get a subview.
+ * @param __pos Index of first character (default 0).
+ * @param __n Number of characters in subview (default remainder).
+ * @return The subview.
+ * @throw std::out_of_range If __pos > size().
+ *
+ * Construct and return a subview using the `__n` characters starting at
+ * `__pos`. If the string is too short, use the remainder of the
+ * characters. If `__pos` is beyond the end of the string, out_of_range
+ * is thrown.
+ */
+ [[nodiscard]]
+ constexpr basic_string_view<_CharT, _Traits>
+ subview(size_type __pos = 0, size_type __n = npos) const
+ { return __sv_type(*this).subview(__pos, __n); }
+#endif
+
/**
* @brief Compare to a string.
* @param __str String to compare against.
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index f9df2be20bed..e59897eef49d 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -2919,6 +2919,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return basic_string(*this,
_M_check(__pos, "basic_string::substr"), __n); }
+#ifdef __glibcxx_string_subview // >= C++26
+ /**
+ * @brief Get a subview.
+ * @param __pos Index of first character (default 0).
+ * @param __n Number of characters in subview (default remainder).
+ * @return The subview.
+ * @throw std::out_of_range If __pos > size().
+ *
+ * Construct and return a subview using the `__n` characters starting at
+ * `__pos`. If the string is too short, use the remainder of the
+ * characters. If `__pos` is beyond the end of the string, out_of_range
+ * is thrown.
+ */
+ [[nodiscard]]
+ constexpr basic_string_view<_CharT, _Traits>
+ subview(size_type __pos = 0, size_type __n = npos) const
+ { return __sv_type(*this).subview(__pos, __n); }
+#endif
+
/**
* @brief Compare to a string.
* @param __str String to compare against.
diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string
index 97ded057a87b..918b4158b475 100644
--- a/libstdc++-v3/include/std/string
+++ b/libstdc++-v3/include/std/string
@@ -63,6 +63,7 @@
#define __glibcxx_want_erase_if
#define __glibcxx_want_nonmember_container_access
#define __glibcxx_want_string_resize_and_overwrite
+#define __glibcxx_want_string_subview
#define __glibcxx_want_string_udls
#define __glibcxx_want_to_string
#include <bits/version.h>
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/char.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/char.cc
new file mode 100644
index 000000000000..c384948cc520
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/char.cc
@@ -0,0 +1,46 @@
+// { dg-do run { target c++26 } }
+
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <testsuite_hooks.h>
+
+void test01(void) {
+ typedef std::string::size_type csize_type;
+ typedef std::string::const_reference cref;
+ typedef std::string::reference ref;
+ csize_type csz01;
+
+ const char str_lit01[] = "rockaway, pacifica";
+ const std::string str01(str_lit01);
+ std::string_view str02;
+
+ csz01 = str01.size();
+ str02 = str01.subview(0, 1);
+ VERIFY(str02 == "r");
+ str02 = str01.subview(10);
+ VERIFY(str02 == "pacifica");
+
+ try {
+ str02 = str01.subview(csz01 + 1);
+ VERIFY(false);
+ } catch (std::out_of_range &fail) {
+ VERIFY(true);
+ } catch (...) {
+ VERIFY(false);
+ }
+
+ try {
+ str02 = str01.subview(csz01);
+ VERIFY(str02.size() == 0);
+ } catch (std::out_of_range &fail) {
+ VERIFY(false);
+ } catch (...) {
+ VERIFY(false);
+ }
+}
+
+int main() {
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/wchar_t.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/wchar_t.cc
new file mode 100644
index 000000000000..3b8e6a87fe60
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/subview/wchar_t.cc
@@ -0,0 +1,46 @@
+// { dg-do run { target c++26 } }
+
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <testsuite_hooks.h>
+
+void test01(void) {
+ typedef std::wstring::size_type csize_type;
+ typedef std::wstring::const_reference cref;
+ typedef std::wstring::reference ref;
+ csize_type csz01;
+
+ const wchar_t str_lit01[] = L"rockaway, pacifica";
+ const std::wstring str01(str_lit01);
+ std::wstring_view str02;
+
+ csz01 = str01.size();
+ str02 = str01.subview(0, 1);
+ VERIFY(str02 == L"r");
+ str02 = str01.subview(10);
+ VERIFY(str02 == L"pacifica");
+
+ try {
+ str02 = str01.subview(csz01 + 1);
+ VERIFY(false);
+ } catch (std::out_of_range &fail) {
+ VERIFY(true);
+ } catch (...) {
+ VERIFY(false);
+ }
+
+ try {
+ str02 = str01.subview(csz01);
+ VERIFY(str02.size() == 0);
+ } catch (std::out_of_range &fail) {
+ VERIFY(false);
+ } catch (...) {
+ VERIFY(false);
+ }
+}
+
+int main() {
+ test01();
+ return 0;
+}
More information about the Libstdc++-cvs
mailing list