https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109400
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- For ranges::advance we could do something like this, but it feels like there should be a better way to customize ranges::advance for your own iterators: --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -712,6 +712,12 @@ namespace ranges struct __advance_fn final { + template<typename _Tp> + constexpr bool __is_istreambuf_iter = false; + template<typename _CharT> + constexpr bool __is_istreambuf_iter<std::istreambuf_iterator<_CharT>> + = __gnu_cxx::__is_char<_CharT>::__value; + template<input_or_output_iterator _It> constexpr void operator()(_It& __it, iter_difference_t<_It> __n) const @@ -737,6 +743,8 @@ namespace ranges while (++__n); } } + else if constexpr (__is_istreambuf_iter<_It>) + std::advance(__it, __n); else { // cannot decrement a non-bidirectional iterator @@ -754,6 +762,9 @@ namespace ranges __it = std::move(__bound); else if constexpr (sized_sentinel_for<_Sent, _It>) (*this)(__it, __bound - __it); + else if constexpr (__is_istreambuf_iter<_It> + && is_same_v<_Sent, default_sentinel_t>) + __it = _It(); else { while (__it != __bound) @@ -791,6 +802,11 @@ namespace ranges return __n; else if (__n > 0) { + if constexpr (__is_istreambuf_iter<_It>) + { + // TODO need access to __it._M_sbuf + } + iter_difference_t<_It> __m = 0; do {