[libcxx-commits] [PATCH] D144767: [libc++][ranges] Implement P2443R1: `views::chunk_by`

Jakub Mazurkiewicz via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jun 25 08:47:57 PDT 2023


JMazurkiewicz added a comment.

+comments



================
Comment at: libcxx/include/__ranges/chunk_by_view.h:57
+class chunk_by_view : public view_interface<chunk_by_view<_View, _Pred>> {
+  _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
----------------
var-const wrote:
> Question: can `__base_` actually have be empty?
Yes, when it is for example `ranges::empty_view`.


================
Comment at: libcxx/include/__ranges/chunk_by_view.h:62
+  using _Cache           = __non_propagating_cache<iterator_t<_View>>;
+  _Cache __cached_begin_ = _Cache();
+
----------------
var-const wrote:
> Is it necessary to explicitly call the default constructor of `__non_propagating_cache` here?
It's not, I've removed it.


================
Comment at: libcxx/include/__ranges/chunk_by_view.h:108
+    _LIBCPP_ASSERT(
+        __pred_.__has_value(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
+    auto __first = ranges::begin(__base_);
----------------
var-const wrote:
> var-const wrote:
> > var-const wrote:
> > > Nit: can you add a blank line after this line to separate error checking from the main flow of the function?
> > Hmm, it's interesting that the standard allows creating an unusable `chunk_by_view` -- just curious, do you know if there's a use case for that?
> I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?




================
Comment at: libcxx/include/__ranges/chunk_by_view.h:108
+    _LIBCPP_ASSERT(
+        __pred_.__has_value(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
+    auto __first = ranges::begin(__base_);
----------------
JMazurkiewicz wrote:
> var-const wrote:
> > var-const wrote:
> > > var-const wrote:
> > > > Nit: can you add a blank line after this line to separate error checking from the main flow of the function?
> > > Hmm, it's interesting that the standard allows creating an unusable `chunk_by_view` -- just curious, do you know if there's a use case for that?
> > I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> > I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> 
> 
> I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?




================
Comment at: libcxx/include/__ranges/chunk_by_view.h:108
+    _LIBCPP_ASSERT(
+        __pred_.__has_value(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
+    auto __first = ranges::begin(__base_);
----------------
JMazurkiewicz wrote:
> JMazurkiewicz wrote:
> > var-const wrote:
> > > var-const wrote:
> > > > var-const wrote:
> > > > > Nit: can you add a blank line after this line to separate error checking from the main flow of the function?
> > > > Hmm, it's interesting that the standard allows creating an unusable `chunk_by_view` -- just curious, do you know if there's a use case for that?
> > > I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> > > I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> > 
> > 
> > I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?
> 
> 
> Hmm, it's interesting that the standard allows creating an unusable chunk_by_view -- just curious, do you know if there's a use case for that?

I have no idea.

> I know it's in the standard, but it seems like this check is redundant with the one in `find-next`, or am I missing something?

This check is not redundant. I've explained why in comment in `assert.find-next.pass.cpp` file.


================
Comment at: libcxx/include/__ranges/chunk_by_view.h:203
+  template <class _Pred>
+    requires constructible_from<decay_t<_Pred>, _Pred>
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const
----------------
var-const wrote:
> Would any tests fail if we removed `decay_t` here?
No... until now. I've added extra test coverage in `adaptor.pass.cpp` (marked with `Test that one can call std::views::chunk_by with arbitrary stuff (...)` comment).


================
Comment at: libcxx/test/libcxx/ranges/range.adaptors/range.chunk.by/assert.find-next.pass.cpp:26
+  int input[] = {1, 2, 3};
+  auto view1  = std::views::chunk_by(input, ThrowOnCopyPred{});
+  auto view2  = std::views::chunk_by(input, ThrowOnCopyPred{});
----------------
var-const wrote:
> Question: is this the only (or easiest) way to get an invalid predicate? Would a default-constructed view work here, perhaps?
This is the easiest way (I think) to get `__find_next` to fail. If we used default constructed view here, then `begin()` would fail instead of `__find_next`.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/adaptor.pass.cpp:59
+  for (; b1 != e1 && b2 != e2; ++b1, ++b2) {
+    auto [chunk_e1, chunk_e2] = std::ranges::mismatch(*b1, *b2, [](int x, int y) {
+      const bool result = x == y;
----------------
var-const wrote:
> Question: is it possible to simply compare for equality, or do we necessarily have to use `mismatch`?
Yes, replaced with `std::ranges::equal`.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/pred.pass.cpp:33
+    Pred pred{42};
+    std::ranges::chunk_by_view<Range, Pred> const view(Range{}, pred);
+    std::same_as<Pred const&> decltype(auto) result = view.pred();
----------------
var-const wrote:
> Question: can a default-constructed `chunk_by_view` contain a valid predicate?
I don't think it is possible - default-constructed `__copyable_box` (or `__movable_box`) never contains a value.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp:44
+constexpr bool tests() {
+  // Check iterator pair
+  test<forward_iterator<int*>>();
----------------
var-const wrote:
> This actually uses a sentinel, right? (and vice versa below)
Yes, I've swapped comments again.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp:109
+
+  // Test with predicate that is invocable but not callable
+  {
----------------
var-const wrote:
> Question: can you elaborate?
All callables can be called like regular function `f()`, but not all invocables can (we need to use `std::invoke` for them). This tests checks if we use `std::invoke` properly or we just use `pred()` syntax.

I've added comment explaining this here and in `decrement.pass.cpp`.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp:112
+    std::array array = {1, 2, 3, -3, -2, -1};
+    auto v           = View{Iterator{array.begin()}, Sentinel{Iterator{array.end()}}} |
+             std::views::transform([](int x) { return IntWrapper{x}; });
----------------
var-const wrote:
> Nit: this formatting looks weird, is it produced by `clang-format`?
Yes, it is produced by `clang-format`. I'm going to fix it manually.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/types.compile.pass.cpp:43
+  {
+    testValueTypeAndDifferenceType<forward_iterator<int*>>();
+    testValueTypeAndDifferenceType<bidirectional_iterator<int*>>();
----------------
var-const wrote:
> Using `types::for_each` would help reduce the boilerplate in this file (here and with the static assertions below too probably).
Done for `testValueTypeAndDifferenceType`, but I don't think it is possible for `static_assert`ions.


================
Comment at: libcxx/test/std/ranges/range.adaptors/range.chunk.by/types.h:45
+template <class I, class S>
+View(I b, S e) -> View<I, S>;
+
----------------
var-const wrote:
> Question: why is this necessary? (Wouldn't the generated deduction guide do the same thing?)
Yes, it is necessary. Without this deduction guide I get `error: 'View' may not intend to support class template argument deduction` warning, but since tests use `-Werror` this ends up as a hard error.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144767/new/

https://reviews.llvm.org/D144767



More information about the libcxx-commits mailing list