[libcxx-commits] [PATCH] D102020: [libcxx][ranges] Add class ref_view.

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 11 12:12:13 PDT 2021

Quuxplusone requested changes to this revision.
Quuxplusone added inline comments.
This revision now requires changes to proceed.

Comment at: libcxx/include/CMakeLists.txt:45
+  __ranges/ref_view.h
Please alphabetize.

Comment at: libcxx/include/__ranges/ref_view.h:13-14
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/concepts.h>
+#include <__ranges/access.h>
Please alphabetize.

Comment at: libcxx/include/__ranges/ref_view.h:39-42
+  template<class _Range>
+  concept sized_range = range<_Range> && requires(_Range& t) {
+    ranges::size(t);
+  };
The `sized_range` concept should go in the same header that defines `ranges::size`.

I'm fairly confident that `concept borrowed_range` doesn't belong in `ref_view.h` either, but I have no particular suggestion of where it //should// go.  It's also a duplicate of `concept __can_borrow` from `__ranges/access.h`; please figure something out.

Comment at: libcxx/include/__ranges/ref_view.h:75
+    // TODO: This needs to use contiguous_range.
+    constexpr auto data() const requires contiguous_iterator<iterator_t<_Range>>
+    { return ranges::data(*__range); }
Nit: For readability, I'd like to see the `requires`-clauses on line 75 and 71 line-broken and indented the same way you've done on line 68.

Comment at: libcxx/include/__ranges/ref_view.h:84
+// clang-format off
Nit: I'd prefer to see all of these noisy `// clang-format {off,on}` comments eliminated. (I'm planning to do that once this code stabilizes, anyway. Just complainin'. It'd make all your PRs four lines shorter!)

Comment at: libcxx/include/ranges:86
 #include <__ranges/size.h>
+#include <__ranges/ref_view.h>
 #include <__ranges/view_interface.h>
Please alphabetize.

Comment at: libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp:21
+namespace ranges = std::ranges;
In @cjdb's tests he's been using `namespace stdr = std::ranges`, which has two advantages: shortness and greppability. I think you should make the switch. (My personal preference is `namespace rg`, but we've already got `stdr` in the codebase, and anyway it's easy to switch from anything to anything, as long as it's //not// `namespace ranges`.)

Comment at: libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp:30-33
+  constexpr friend int* begin(Range const& range) { return globalBuff + range.start; }
+  constexpr friend int* end(Range const&) { return globalBuff + 8; }
+  constexpr friend int* begin(Range& range) { return globalBuff + range.start; }
+  constexpr friend int* end(Range&) { return globalBuff + 8; }
`friend constexpr`, not `constexpr friend` — but also, why are these friends instead of member `begin`/`end`? Making them members would be a lot less typing.

Comment at: libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp:43
+static_assert(!ValidRefView<int (&)[4]>);
But `ValidRefView<int[4]>` would be OK, right?

Comment at: libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp:82-83
+bool operator==(const cpp20_input_iterator<int*> &lhs, int* rhs) { return lhs.base() == rhs; }
+bool operator==(int* lhs, const cpp20_input_iterator<int*> &rhs) { return rhs.base() == lhs; }
Isn't this the sort of thing that the reversed synthesized candidates are supposed to handle for us?
Orthogonally: hidden friend plz... or actually, wait, what? You're adding comparison operators to `cpp20_input_iterator` //itself?// That doesn't seem right. You should just make `Cpp20InputRange::end()` return a value of type `cpp20_input_iterator::sentinel`.

Comment at: libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp:105
+    Range range;
+    ranges::ref_view<Range> view{range};
+    assert(view.begin() == globalBuff);
Throughout: I'd like to see these tests use `stdr::ref_view<Range> view = range;` instead of direct-curly-brace-initialization.

Comment at: libcxx/test/support/test_iterators.h:645-648
+  constexpr cpp20_input_iterator() = default;
-  cpp20_input_iterator(cpp20_input_iterator&&) = default;
-  cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default;
+  constexpr cpp20_input_iterator(cpp20_input_iterator&&) = default;
+  constexpr cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default;
Defaulted SMFs are constexpr (and noexcept) by default. You don't need this diff.

Comment at: libcxx/test/support/test_iterators.h:657-666
+  constexpr cpp20_input_iterator& operator++() {
     return *this;
-  void operator++(int) { ++base_; }
+  constexpr void operator++(int) { ++base_; }
This looks good. While you're in the vicinity, I recommend moving `cpp20_input_iterator` up next to the other test iterators (namely, next to `cpp17_input_iterator`), and making it look like them:
- remove the C++20 `iter_value_t` dependency, just use `iterator_traits` like they do
- remove the `[[nodiscard]]` cruft
- add the missing `base(I)` free function
- add the missing deleted `operator,`
- ifdef it to C++14-and-later since its definition doesn't depend on anything from '17 or '20 (except `iter_value_t` which we can remove)
- add a nested type `struct sentinel {}` which is comparable to `cpp20_input_iterator<T>` (via hidden friends)

Ping me if you want me to just do this.

  rG LLVM Github Monorepo



More information about the libcxx-commits mailing list