[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 Mar 19 11:57:50 PDT 2024


================
@@ -42,6 +42,13 @@ constexpr void check_forward(int* first, int* last, std::iter_difference_t<It> n
     // regardless of the iterator category.
     assert(it.stride_count() == M);
     assert(it.stride_displacement() == M);
+    if (n == 0) {
+      assert(it.equals_count() == 0);
+    } else {
+      assert(it.equals_count() > 0);
+      assert(it.equals_count() == M || it.equals_count() == M + 1);
----------------
jiixyj wrote:

The M case is the "normal" case where the iterator is incremented without the bound being "hit" (it may equal the bound though, but this last equals check shouldn't be executed).

The "M + 1" case happens when the advancing `while` loop is exited because of the bounds check, so the bound is "hit". Example: Calling `std::ranges::advance(it, 999999, s)` on a range `{ 42, 3, 4 }` (size 3) will do 4 (3 + 1) bounds checks.

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


More information about the libcxx-commits mailing list