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
              {

Reply via email to