diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -74,10 +74,20 @@ struct __fn final : private __function_like { private: + // Returns |a| >= |b| template _LIBCPP_HIDE_FROM_ABI - static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept { - return __a < 0 ? (__a <= __b) : (__a >= __b); + static constexpr bool __magnitude_geq(_Tp __a, _Tp __b) { + if (__a < 0) + if (__b < 0) + return __a <= __b; + else + return __a + __b <= 0; + else + if (__b < 0) + return __a + __b >= 0; + else + return __a >= __b; } template diff --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp @@ -145,11 +145,10 @@ // Note that we can only test ranges::advance with a negative n for iterators that // are sized sentinels for themselves, because ranges::advance is UB otherwise. // In particular, that excludes bidirectional_iterators since those are not sized sentinels. - // TODO: Enable these tests once we fix the bug in ranges::advance - // int* expected = n > size ? range : range + size - n; - // check_backward>(range, range+size, -n, expected); - // check_backward>( range, range+size, -n, expected); - // check_backward( range, range+size, -n, expected); + int* expected = n > size ? range : range + size - n; + check_backward>(range, range+size, -n, expected); + check_backward>( range, range+size, -n, expected); + check_backward( range, range+size, -n, expected); } } } diff --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count_sentinel.pass.cpp --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count_sentinel.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count_sentinel.pass.cpp @@ -28,9 +28,7 @@ assert(base(result) == expected); } -// TODO: Re-enable once we fix the bug in ranges::advance constexpr bool test() { -#if 0 int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; for (int size = 0; size != 10; ++size) { @@ -42,7 +40,6 @@ check( range, range+size, n, expected); } } -#endif return true; }