[libcxx-commits] [PATCH] D121248: [libc++][ranges] Implement ranges::find{, _if, _if_not}
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Mar 8 13:12:33 PST 2022
Quuxplusone added a subscriber: tcanens.
Quuxplusone added a comment.
Thanks, LGTM % comments. That was some quick turnaround time!
================
Comment at: libcxx/include/__algorithm/ranges_find.h:39
+ _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
+ auto __pred = [&](const auto& __e) { return __value == __e; };
+ return __find_if::__fn::__go(std::move(__first), std::move(__last), __pred, __proj);
----------------
(1) https://eel.is/c++draft/algorithms#alg.find-1.4 says `__e == __value`, which agrees with my prejudices too (thankfully). I believe this is observable by the user. Consider adding a regression test.
Ditto throughout.
(2) What you've got now is attractive, but it "flattens" the type of `*__first` into `const auto&`, which might unexpectedly const-qualify and/or lvalue-qualify it, which might(?) affect the resolution of `operator==`. Can you investigate whether this is OK (due to the requirements of `indirect_binary_predicate`)? You might need to use `auto&&` here. (@tcanens, thoughts?)
...Actually, you've already started using `auto&&` in `find_if_not`, implying maybe you found a regression test? Please add a similar test for `find` and `find_if`.
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:49
+ test_iterators<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
+ test_iterators<forward_iterator<int*>>();
+ test_iterators<random_access_iterator<int*>>();
----------------
Please also test `bidirectional_iterator<int*>`, `int*`, and `const int*`.
Ditto throughout.
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:61
+ int a[] = {1, 2, 3, 4};
+ auto ret = std::ranges::find(a, a + 4, a + 3, [](int& i){ return &i; });
+ assert(ret == a + 3);
----------------
IIUC, you meant this one to use the range overload. I wonder if this works, or if it's ambiguous...
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:68
+ [[maybe_unused]] std::same_as<std::ranges::dangling> auto ret =
+ std::ranges::find(std::array {1, 2}, 3);
+ }
----------------
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:85
+
+ { // count predicate invocation count
+ {
----------------
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp:34
+ int a[] = {1, 2, 3, 4};
+ std::same_as<It> auto ret = std::ranges::find_if(It(a), Sent(It(a + 4)), [c = 0](int) mutable { return c++ > 2; });
+ assert(base(ret) == a + 3);
----------------
This isn't a valid predicate; also I don't understand the point of doing `c++` here anyway. Are you just trying to make sure the predicate is called non-const? In that case, you could just `[](int x) mutable { return x == 2; }` — the `mutable` makes the type not const-callable.
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp:68
+ [[maybe_unused]] std::same_as<std::ranges::dangling> auto ret =
+ std::ranges::find_if(std::array {1, 2}, [](int){ return false; });
+ }
----------------
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp:68
+ [[maybe_unused]] std::same_as<std::ranges::dangling> auto ret =
+ std::ranges::find_if_not(std::array {1, 2}, [](int){ return true; });
+ }
----------------
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D121248/new/
https://reviews.llvm.org/D121248
More information about the libcxx-commits
mailing list