[libcxx-commits] [libcxx] [libc++] `std::ranges::advance`: avoid unneeded bounds checks when advancing iterator (PR #84126)

Jan Kokemüller via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 2 00:00:48 PDT 2024


================
@@ -109,33 +108,13 @@ constexpr void check_backward(int* first, int* last, std::iter_difference_t<It>
     auto it = stride_counting_iterator(It(last));
     auto sent = stride_counting_iterator(It(first));
     static_assert(std::bidirectional_iterator<stride_counting_iterator<It>>);
+    static_assert(Count == !std::sized_sentinel_for<It, It>);
 
     (void)std::ranges::advance(it, n, sent);
 
-    if constexpr (std::sized_sentinel_for<It, It>) {
-      if (expected == first) {
-        // In this case, the algorithm can just do `it = std::move(sent);`
-        // instead of doing iterator arithmetic:
-        // <https://eel.is/c++draft/iterators#range.iter.op.advance-4.1>
-        assert(it.stride_count() == 0);
-        assert(it.stride_displacement() == 0);
-      } else {
-        assert(it.stride_count() == 1);
-        assert(it.stride_displacement() == 1);
-      }
-      assert(it.equals_count() == 0);
-    } else {
-      assert(it.stride_count() == -M);
-      assert(it.stride_displacement() == M);
-      if (-n > -M) {
-        // We "hit" the bound, so there is one extra equality check.
-        assert(it.equals_count() == -M + 1);
-      } else {
-        assert(it.equals_count() == -M);
-      }
-      // In any case, there must not be more than `-n` bounds checks.
-      assert(it.equals_count() <= -n);
-    }
+    assert(it.stride_count() == expected_stride_count);
----------------
jiixyj wrote:

done! I initialize the `Expected` struct before the calls to `check_backward` though, this way I could get rid of the three temporary `int`s.

https://github.com/llvm/llvm-project/pull/84126


More information about the libcxx-commits mailing list