[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 16:03:53 PST 2022
Quuxplusone added inline comments.
================
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
----------------
philnik wrote:
> 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`).
philnik's code is consistent with the standard's own weird formatting, which we do use in plenty of synopsis comments:
```
template<class T>
constexpr R
function_name(Args);
```
But immediately above this new stuff, the older stuff seems to be doing more libc++-code-style formatting:
```
template<class T>
constexpr R function_name(Args);
```
and immediately below, the //really// old stuff seems to be doing yet a third thing:
```
template<class T>
constexpr R
function_name(Args);
```
I personally don't mind the discrepancy, although it would be nice to make everything consistent one way or another.
================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:54-58
+ {
+ int a[] = {1, 2, 3, 4};
+ auto ret = std::ranges::find(a, a + 4, a + 3, [](int& i){ return &i; });
+ assert(ret == a + 3);
+ }
----------------
ldionne wrote:
> These projection tests are really clever. Something like this would be easier to read:
>
> ```
> struct Point { int x; int y; };
> Point points[] = {....};
> auto ret = std::ranges::find(points, points + 4, 3, [](Point const& p) { return p.x; });
> assert(ret == ....);
> ```
>
I agree it's hard to read, but part of the point of the projection test is to verify that we're calling the projection specifically on `*first`, never on a //copy// of `*first`. So "this projection returns the address of the argument" is important to the test.
However, we could do this:
```
assert(std::ranges::find(a, a + 4, 3, [](int& i) { return &i - a; }) == a + 3);
```
to avoid passing `a, a + 4, a + 3` in close proximity.
================
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);
+ }
----------------
philnik wrote:
> 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.
Just for simplicity... Ah, but I see, I was forgetting that `std::array<int>{1, 2}` doesn't work, it needs to be `std::array<int, 2>{1, 2}`, which is indeed another step uglier.
In that case, I'll settle for `std::array{1, 2}` with no space between the type name and the brace. :)
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