[libcxx-commits] [libcxx] [libcxx] Speed up xsgetn for always_noconv (PR #212010)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 25 04:32:33 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: aokblast

<details>
<summary>Changes</summary>

In the always_noconv path, optimize character reads in the same way as xsgetn.

Unlike fread, getwc has different semantics, so the same optimization cannot be applied to wide characters. Therefore, only optimize the char path.

---
Full diff: https://github.com/llvm/llvm-project/pull/212010.diff


1 Files Affected:

- (modified) libcxx/src/std_stream.h (+23) 


``````````diff
diff --git a/libcxx/src/std_stream.h b/libcxx/src/std_stream.h
index 4b9d3a34b2441..214acc9e88b70 100644
--- a/libcxx/src/std_stream.h
+++ b/libcxx/src/std_stream.h
@@ -45,6 +45,7 @@ class _LIBCPP_HIDDEN __stdinbuf : public basic_streambuf<_CharT, char_traits<_Ch
 protected:
   virtual int_type underflow();
   virtual int_type uflow();
+  virtual streamsize xsgetn(char_type* __s, streamsize __n);
   virtual int_type pbackfail(int_type __c = traits_type::eof());
   virtual void imbue(const locale& __loc);
 
@@ -199,6 +200,28 @@ typename __stdinbuf<_CharT>::int_type __stdinbuf<_CharT>::__getchar(bool __consu
   return traits_type::to_int_type(__1buf);
 }
 
+template <class _CharT>
+streamsize __stdinbuf<_CharT>::xsgetn(char_type* __s, streamsize __n) {
+  if constexpr (is_same<_CharT, char>::value) {
+    if (__always_noconv_) {
+      streamsize __i = 0;
+      if (__i < __n && __last_consumed_is_next_) {
+        __s[__i++]               = traits_type::to_char_type(__last_consumed_);
+        __last_consumed_         = traits_type::eof();
+        __last_consumed_is_next_ = false;
+      }
+      if (__i < __n) {
+        size_t __nread = fread(__s + __i, 1, static_cast<size_t>(__n - __i), __file_);
+        if (__nread > 0)
+          __last_consumed_ = traits_type::to_int_type(__s[__i + __nread - 1]);
+        __i += static_cast<streamsize>(__nread);
+      }
+      return __i;
+    }
+  }
+  return basic_streambuf<char_type, traits_type>::xsgetn(__s, __n);
+}
+
 template <class _CharT>
 typename __stdinbuf<_CharT>::int_type __stdinbuf<_CharT>::pbackfail(int_type __c) {
   if (traits_type::eq_int_type(__c, traits_type::eof())) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/212010


More information about the libcxx-commits mailing list