[libcxx-commits] [libcxx] [libc++][ranges] Avoid using `std::distance` in `ranges::contains_subrange` (PR #87155)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Mar 30 06:52:51 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
Either `std::distance` or `ranges::distance` are inefficient for non-sized ranges. Also, calculation the range in `int` type is seriously problematic.
This patch avoids using `distance` and calculation of the length of non-sized ranges.
Fixes #<!-- -->86833.
---
Full diff: https://github.com/llvm/llvm-project/pull/87155.diff
2 Files Affected:
- (modified) libcxx/include/__algorithm/ranges_contains_subrange.h (+4-6)
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp (+4)
``````````diff
diff --git a/libcxx/include/__algorithm/ranges_contains_subrange.h b/libcxx/include/__algorithm/ranges_contains_subrange.h
index 4cd03cbb537060..e4b1c78a4f282f 100644
--- a/libcxx/include/__algorithm/ranges_contains_subrange.h
+++ b/libcxx/include/__algorithm/ranges_contains_subrange.h
@@ -15,7 +15,6 @@
#include <__functional/ranges_operations.h>
#include <__functional/reference_wrapper.h>
#include <__iterator/concepts.h>
-#include <__iterator/distance.h>
#include <__iterator/indirectly_comparable.h>
#include <__iterator/projected.h>
#include <__ranges/access.h>
@@ -70,14 +69,13 @@ struct __fn {
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static
operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) {
- auto __n2 = 0;
if constexpr (sized_range<_Range2>) {
- __n2 = ranges::size(__range2);
+ if (ranges::size(__range2) == 0)
+ return true;
} else {
- __n2 = std::distance(cbegin(__range2), cend(__range2));
+ if (ranges::begin(__range2) == ranges::end(__range2))
+ return true;
}
- if (__n2 == 0)
- return true;
auto __ret = ranges::search(__range1, __range2, __pred, std::ref(__proj1), std::ref(__proj2));
return __ret.empty() == false;
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
index d48ee9e4e7e02e..761691c2afdcb9 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
@@ -309,6 +309,10 @@ constexpr bool test() {
});
});
+ assert(std::ranges::contains_subrange(
+ std::views::iota(0, 5), std::views::iota(0, 5) | std::views::filter([](int) { return true; })));
+ assert(!std::ranges::contains_subrange(std::views::iota(0ULL, 42ULL), std::views::iota(0ULL, 1ULL << 32)));
+
return true;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/87155
More information about the libcxx-commits
mailing list