[libcxx-commits] [PATCH] D121248: [libc++][ranges] Implement ranges::find{, _if, _if_not}

Nikolas Klauser via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 8 15:33:35 PST 2022


philnik added inline comments.


================
Comment at: libcxx/include/__algorithm/ranges_find.h:48
+    auto __pred = [&](const auto& __e) { return __value == __e; };
+    return __find_if::__fn::__go(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+  }
----------------
ldionne wrote:
> I don't like that we are reaching into `__find_if::__fn` here. Instead, we should have something like this in `find_if.h`:
> 
> ```
> template <class _Ip, class _Sp, class _Pred, class _Proj>
> _LIBCPP_HIDE_FROM_ABI constexpr
> _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
>     for (; __first != __last; ++__first) {
>         if (std::invoke(__pred, std::invoke(__proj, *__first)))
>             break;
>     }
>     return __first;
> }
> ```
> 
> This provides a slightly (but not much) cleaner interface between the two headers, at least. TBH, I would support implementing this as `ranges::find_if(ranges::begin(__r), ranges::end(__r), __pred, std::move(__proj));` (and similarly for the iterator/sentinel version), even though I understand this will lead to additional moves over the current approach. In practice, I don't think this is likely to matter, since iterators should be cheap to copy (and hence to move), and same for projections.
> 
> So, I have a slight preference for implementation simplicity despite it causing additional moves, but if you want to keep it as-is, please use a namespace scope function at least (and add a libc++ specific test for the no-move behavior).
@Quuxplusone wants to add the tests in another PR.


================
Comment at: libcxx/include/algorithm:48-71
+  template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
+    requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+    constexpr I find(I first, S last, const T& value, Proj proj = {});              // since C++20
+  template<input_range R, class T, class Proj = identity>
+    requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+    constexpr borrowed_iterator_t<R>
+      find(R&& r, const T& value, Proj proj = {});                                  // since C++20
----------------
ldionne wrote:
> This looks weirdly formatted -- please try to indent the return types consistently, etc.
I'm not sure what you are asking for. The return types are all indented the same, and this is copied 1:1 from the standard (excluding the `// since C++20`).


================
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);
+  }
----------------
Quuxplusone wrote:
> 
I get why you want to avoid CTAD in template code, but what's wrong with it here? `std::array {1, 2}` is definitely easier to read than `std::array<int, 2> {1, 2}` and there is no chance that it deduces the wrong type.


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