Fixes #1856.
cycled_view::cursor::advance uses truncating division for the cycle count but normalizes a negative remainder into a nonnegative source offset. When an advance crosses a cycle boundary backward by a nonmultiple of the source length, the resulting iterator is one cycle too far ahead.
For example, over {1, 2}, begin() + 2 - 1 currently compares unequal to begin() + 1 and has distance 3 from begin. Dereferencing alone hides the error because the source values repeat.
Decrement the cycle count when the remainder is negative, giving it the floor-division result that matches the normalized source offset. Keep the existing nonnegative-position precondition after the correction.
The regression test covers:
- The original equality and distance reproducer
- Source lengths 1, 2, 3, and 5, across four cycles
- Every pair of nonnegative positions in the tested window, including partial backward crossings, whole-cycle jumps, and within-cycle movement
- Mutable and const cursor types and non-common
c_strranges with cached ends - Values, equality, distances, and both
+=and-=against expected iterators built using repeated++
Fresh Windows validation
- Applied cleanly to current
master(108f93c279c8f9cec175dac361084983d0176e99), which matches the recorded base; whitespace and exact reverse-check pass. - Compiled the complete
test/view/cycle.cpptarget with MSVC 14.51.36231 using/EHsc /permissive- /bigobj; both/std:c++17and/std:c++20builds and executables exit successfully. - The identical regression source compiled against an include overlay containing the unchanged upstream
cycle.hppfails with 2417 CHECK failures (exit 1) under C++20; the patched-header target exits 0. - MSVC C++14 is explicitly rejected by range-v3 configuration; it is not a supported passing configuration. The C++17 compile emitted the standard library
<source_location>availability warning, with no compile/runtime failure.
The supplied Linux records report configured GCC C++14/C++20 suites at 242/242 each, 277 public-header compile checks and a 6,507-pair independent oracle. Those broader results are historical, not rerun here. This run covers only the cycle target on Windows; full suites, docs/examples/performance, sanitizers, Clang/older GCC and hosted CI are not claimed. Historical LeakSanitizer was unavailable.
AI assistance was used to prepare and verify this contribution. Submitted for upstream review and broader CI.
@loaff123 could you please have a look at the test failures?