Short example (from https://stackoverflow.com/q/67573305/2069064): #include <ranges> template <typename T> using iota = std::ranges::iota_view<T, T>; template <typename T> using iota_iter = std::ranges::iterator_t<iota<T>>; static_assert(std::same_as< std::reverse_iterator<iota_iter<int64_t>>::reference, int64_t>); This assertion fails when compiling with -std=c++20 (because the reference type is 'void') but passes with -std=gnu++20. The direct reason is that the difference_type of the iota_view iterator is __int128, which is considered a signed_integral with gnu++20 but not c++20. But the reason this matters is because std::reverse_iterator<I>::reference is defined as std::iterator_traits<I>::reference (which checks that I satsifies cpp17-input-iterator which has the signed_integral constraint) instead of being defined as std::iter_reference_t<I> (which has no such check). With the latter implementation, the assertion above would pass on either version. The result is that reversing an iota_view<int64_t, int64_t> isn't a range on -std=c++20.
The assertion also fails when __int128 isn't available (which can be simulated by compiling with -U__SIZEOF_INT128__), because in that case iota_view's difference_type is the integer-like class type __max_diff_type, and integer-like class types aren't integral even in GNU mode.
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:d5cbe0f0d4b7bc11f80b2236521f90ec94e95767 commit r12-946-gd5cbe0f0d4b7bc11f80b2236521f90ec94e95767 Author: Patrick Palka <ppalka@redhat.com> Date: Thu May 20 14:08:17 2021 -0400 libstdc++: Implement missing P0896R4 changes to reverse_iterator [PR100639] This implements the P0896R4 changes to reverse_iterator's member types value_type, difference_type and reference in C++20 mode, which fixes taking the reverse_iterator of an iterator with a non-integral difference_type (such as iota_view<long long>). libstdc++-v3/ChangeLog: PR libstdc++/100639 * include/bits/stl_iterator.h (reverse_iterator::difference_type): In C++20 mode, define in terms of iter_difference_t as per P0896R4. (reverse_iterator::reference): Likewise, but with iter_reference_t. (reverse_iterator::value_type): Likewise, but with iter_value_t. * testsuite/std/ranges/adaptors/reverse.cc (test08): New test. * testsuite/24_iterators/reverse_iterator/100639.cc: New test.
The releases/gcc-11 branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:a50cc70f1b5ce3ae11528095fa3a1feadb206357 commit r11-8540-ga50cc70f1b5ce3ae11528095fa3a1feadb206357 Author: Patrick Palka <ppalka@redhat.com> Date: Thu May 20 14:08:17 2021 -0400 libstdc++: Implement missing P0896R4 changes to reverse_iterator [PR100639] This implements the P0896R4 changes to reverse_iterator's member types value_type, difference_type and reference in C++20 mode, which fixes taking the reverse_iterator of an iterator with a non-integral difference_type (such as iota_view<long long>). libstdc++-v3/ChangeLog: PR libstdc++/100639 * include/bits/stl_iterator.h (reverse_iterator::difference_type): In C++20 mode, define in terms of iter_difference_t as per P0896R4. (reverse_iterator::reference): Likewise, but with iter_reference_t. (reverse_iterator::value_type): Likewise, but with iter_value_t. * testsuite/std/ranges/adaptors/reverse.cc (test08): New test. * testsuite/24_iterators/reverse_iterator/100639.cc: New test. (cherry picked from commit d5cbe0f0d4b7bc11f80b2236521f90ec94e95767)
The releases/gcc-10 branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:c8bd39bc10eac3028dbf509b27457172360e6e8c commit r10-9902-gc8bd39bc10eac3028dbf509b27457172360e6e8c Author: Patrick Palka <ppalka@redhat.com> Date: Thu May 20 14:08:17 2021 -0400 libstdc++: Implement missing P0896R4 changes to reverse_iterator [PR100639] This implements the P0896R4 changes to reverse_iterator's member types value_type, difference_type and reference in C++20 mode, which fixes taking the reverse_iterator of an iterator with a non-integral difference_type (such as iota_view<long long>). libstdc++-v3/ChangeLog: PR libstdc++/100639 * include/bits/stl_iterator.h (reverse_iterator::difference_type): In C++20 mode, define in terms of iter_difference_t as per P0896R4. (reverse_iterator::reference): Likewise, but with iter_reference_t. (reverse_iterator::value_type): Likewise, but with iter_value_t. * testsuite/std/ranges/adaptors/reverse.cc (test08): New test. * testsuite/24_iterators/reverse_iterator/100639.cc: New test. (cherry picked from commit d5cbe0f0d4b7bc11f80b2236521f90ec94e95767)
Fixed for 10.4/11.2/12