diff options
| author | Dimitry Andric <dimitry@andric.com> | 2026-01-05 21:07:58 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2026-04-25 14:14:21 +0000 |
| commit | 17f1a5e638f845e171ab4e3db2a07bf8c6ac3388 (patch) | |
| tree | 84fd5bf8307977ece091e0703a8b8ca49cf4451c | |
| parent | 987ac31018cba9f1763ad3acfb68b933f58a4c52 (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/istream | 28 | ||||
| -rw-r--r-- | contrib/llvm-project/libcxx/include/streambuf | 4 |
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); |
