aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dimitry@andric.com>2026-01-05 21:07:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2026-04-25 14:14:21 +0000
commit17f1a5e638f845e171ab4e3db2a07bf8c6ac3388 (patch)
tree84fd5bf8307977ece091e0703a8b8ca49cf4451c
parent987ac31018cba9f1763ad3acfb68b933f58a4c52 (diff)
libcxx-compat: fix llvmorg-21-init-12415-g3a86e0bd29f3:
[libc++] Optimize std::getline (#121346) ``` ----------------------------------------------- Benchmark old new ----------------------------------------------- BM_getline_string 318 ns 32.4 ns ``` Move the __bump_stream() lamda in <istream> to a separate function, so this will compile with clang 18 and lower, in C++03 mode and earlier. PR: 292067 MFC after: 1 month
-rw-r--r--contrib/llvm-project/libcxx/include/istream28
-rw-r--r--contrib/llvm-project/libcxx/include/streambuf4
2 files changed, 19 insertions, 13 deletions
diff --git a/contrib/llvm-project/libcxx/include/istream b/contrib/llvm-project/libcxx/include/istream
index 93def61a8b47..61abf3f1c254 100644
--- a/contrib/llvm-project/libcxx/include/istream
+++ b/contrib/llvm-project/libcxx/include/istream
@@ -1259,6 +1259,18 @@ operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _
return __is;
}
+template <class _CharT, class _Traits>
+inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void __bump_stream(
+ const _CharT* __first, _CharT& __1buf, std::basic_streambuf<_CharT, _Traits>& __buffer, ptrdiff_t __diff) {
+ if (__first == std::addressof(__1buf)) {
+ _LIBCPP_ASSERT_INTERNAL(__diff == 0 || __diff == 1, "trying to bump stream further than buffer size");
+ if (__diff != 0)
+ __buffer.sbumpc();
+ } else {
+ __buffer.__gbump_ptrdiff(__diff);
+ }
+}
+
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm) {
@@ -1285,31 +1297,21 @@ getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _All
__last = std::addressof(__1buf) + 1;
}
- auto __bump_stream = [&](ptrdiff_t __diff) {
- if (__first == std::addressof(__1buf)) {
- _LIBCPP_ASSERT_INTERNAL(__diff == 0 || __diff == 1, "trying to bump stream further than buffer size");
- if (__diff != 0)
- __buffer.sbumpc();
- } else {
- __buffer.__gbump_ptrdiff(__diff);
- }
- };
-
const auto* const __match = _Traits::find(__first, __last - __first, __dlm);
if (__match)
__last = __match;
if (auto __cap = __str.max_size() - __str.size(); __cap > static_cast<size_t>(__last - __first)) {
__str.append(__first, __last);
- __bump_stream(__last - __first);
+ __bump_stream(__first, __1buf, __buffer, __last - __first);
if (__match) {
- __bump_stream(1); // Remove the matched character
+ __bump_stream(__first, __1buf, __buffer, 1); // Remove the matched character
break;
}
} else {
__str.append(__first, __cap);
- __bump_stream(__cap);
+ __bump_stream(__first, __1buf, __buffer, __cap);
__state |= ios_base::failbit;
break;
}
diff --git a/contrib/llvm-project/libcxx/include/streambuf b/contrib/llvm-project/libcxx/include/streambuf
index 585ae7af65aa..bc34ac19131d 100644
--- a/contrib/llvm-project/libcxx/include/streambuf
+++ b/contrib/llvm-project/libcxx/include/streambuf
@@ -379,6 +379,10 @@ private:
char_type* __nout_ = nullptr;
char_type* __eout_ = nullptr;
+ template <class _CharT2, class _Traits2>
+ _LIBCPP_HIDE_FROM_ABI_AFTER_V1 friend void __bump_stream(
+ const _CharT2* __first, _CharT2& __1buf, std::basic_streambuf<_CharT2, _Traits2>& __buffer, ptrdiff_t __diff);
+
template <class _CharT2, class _Traits2, class _Allocator>
_LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT2, _Traits2>&
getline(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Allocator>&, _CharT2);