[libcxx-commits] [libcxx] [libc++] Optimize filebuf::seekoff (PR #211788)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jul 27 08:09:19 PDT 2026
================
@@ -995,24 +995,80 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
std::__throw_bad_cast();
int __width = __cv_->encoding();
- if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
+ if (__file_ == nullptr || (__width <= 0 && __off != 0))
return pos_type(off_type(-1));
- // __width > 0 || __off == 0
- int __whence;
+
+ auto __byte_off = __width <= 0 ? 0 : __width * __off;
+
+ int __whence = 0;
switch (__way) {
- case ios_base::beg:
- __whence = SEEK_SET;
- break;
- case ios_base::cur:
+ case ios::beg: {
+ if (__off < 0)
+ return pos_type(off_type(-1));
+
+ pos_type __success_pos = __off;
+ __success_pos.state(__st_);
+
+ if (__always_noconv_ && __cm_ & ios::in) {
+ off_type __file_pos = __ftell(__file_);
+ auto __buffer_base_pos = __file_pos - (this->egptr() - this->eback());
+
+ // If the new position is within the buffer we can just move the current read pointer
+ if (__off >= __buffer_base_pos && __off <= __file_pos) {
+ this->setg(this->eback(), this->eback() + (__off - __buffer_base_pos), this->egptr());
+ return __success_pos;
+ } else {
+ // Otherwise drop the buffer and seek to the requested position
+ this->setg(nullptr, nullptr, nullptr);
+ __cm_ = 0;
+ if (__fseek(__file_, __byte_off, SEEK_SET))
+ return pos_type(off_type(-1));
+ return __success_pos;
+ }
+ }
----------------
ldionne wrote:
I think I'd add an `else` here. There is a lot of control flow and it's not evident that the `if (sync())` below is mutually exclusive with the `__always_noconv` check.
https://github.com/llvm/llvm-project/pull/211788
More information about the libcxx-commits
mailing list