#1867

Fix cycle counts when advancing by a negative offset

Openloaff123wants to merge intofrom

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_str ranges 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.cpp target with MSVC 14.51.36231 using /EHsc /permissive- /bigobj; both /std:c++17 and /std:c++20 builds and executables exit successfully.
  • The identical regression source compiled against an include overlay containing the unchanged upstream cycle.hpp fails 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.

Activity

4
ericnieblerapproved changes28d ago
ericniebler19d ago

@loaff123 could you please have a look at the test failures?