Skip to content

[libc++][ranges] Implement P1899 ranges::stride_view. #65200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 171 commits into
base: main
Choose a base branch
from

Conversation

hawkinsw
Copy link
Contributor

@hawkinsw hawkinsw commented Sep 2, 2023

Implement ranges::stride_view in libc++. Migrating to this GitHub from Phabricator (https://reviews.llvm.org/D156924).

Closes #105198

@hawkinsw hawkinsw requested a review from a team as a code owner September 2, 2023 06:55
@cor3ntin cor3ntin added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. ranges Issues related to `<ranges>` labels Sep 2, 2023
@var-const var-const self-assigned this Sep 2, 2023
@hawkinsw
Copy link
Contributor Author

hawkinsw commented Sep 2, 2023

Thank you all for the feedback on this work. I am really excited to get to participate. As I said, I have committed small amounts of code in the past but this is my first attempt at doing a significant amount of implementation. I have already learned a ton and look forward to learning more!

@hawkinsw
Copy link
Contributor Author

hawkinsw commented Sep 4, 2023

I just used a fixup! commit to add some additional code. I followed the new best practices and I hope that I did it correctly. Please let me know if I did not follow the instructions properly!

@hawkinsw
Copy link
Contributor Author

hawkinsw commented Sep 7, 2023

I know how busy you all must be with the transition to GitHub. I am going to continue to work on writing tests and look forward to any feedback you have!

@hawkinsw hawkinsw changed the title WIP: [libc++][ranges] Implement ranges::stride_view. [libc++][ranges] Implement ranges::stride_view. Sep 11, 2023
@hawkinsw
Copy link
Contributor Author

Removed the WIP tag (and added an amend fixup commit to accomplish the same thing with in the git realm). I can't wait to hear how I can improve the implementation!!

Will

using difference_type = range_difference_t<_Base>;
using value_type = range_value_t<_Base>;
using iterator_concept =
_If<random_access_range<_Base>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this needs the cost of lazy SFINAE. and that's a lot of instantiations. Can we reduce it some?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EricWF Sorry to have to ask ... I know what each of the words "lazy" and "SFINAE" means but in combination I am not entirely sure to what you are referring. Could you point me to something that I use to educate myself so that I can fix this antipattern? Sorry again to have to ask!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EricWF I now realized what you meant and believe that the fixup I am about to submit will resolve this! Thanks again for the feedback!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't be so presumptuous as to Resolve this conversation, but let me know if what I just changed seems better.

@hawkinsw hawkinsw requested a review from EricWF September 13, 2023 15:46
Copy link
Contributor

@JMazurkiewicz JMazurkiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick review of product code. Also, please rebase.

I'm not maintainer, but I've already implemented `views::stride` in microsoft/STL/pull/2981, so my comments might be useful :)

Comment on lines 269 to 285
// [range.stride], stride view
using std::ranges::stride_view;

namespace views {
using std::ranges::views::stride;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std module is available in C++20 as an extensions, we should add language guards:

Suggested change
// [range.stride], stride view
using std::ranges::stride_view;
namespace views {
using std::ranges::views::stride;
}
#if _LIBCPP_STD_VER >= 23
// [range.stride], stride view
using std::ranges::stride_view;
namespace views {
using std::ranges::views::stride;
}
#endif // _LIBCPP_STD_VER >= 23

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to make sure that I understand:

In C++20 there is an extension that would enable the use of this module. std::ranges::stride_view is only available as of C++23. So, in the case where this module was used as an extension in a C++20-compatible compiler, without this guard there would be a problem.

I hope that I am understanding correctly! Great catch!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In C++20 there is an extension that would enable the use of this module.

Yes, it is documented here: https://libcxx.llvm.org/Modules.html

std::ranges::stride_view is only available as of C++23. So, in the case where this module was used as an extension in a C++20-compatible compiler, without this guard there would be a problem.

Yes, I've got bitten by it too while implementing views::chunk_by.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I appreciate you pointing this out and I am glad that I understood your point. I believe that I have addressed the comment. If so, would you mind if I marked the conversation resolved?

@hawkinsw
Copy link
Contributor Author

@JMazurkiewicz Thank you for your incredibly helpful comments. I have a few things to do at $dayjob but I will address them as soon as possible. Thank you again for taking the time to comment.

@hawkinsw
Copy link
Contributor Author

Hello again and sorry to bother. I would love to make any changes to the implementation that you think are necessary. I have really enjoyed the opportunity to implement stride_view and I have already started on slide_view!

@hawkinsw hawkinsw self-assigned this Sep 27, 2023
@Zingam
Copy link
Contributor

Zingam commented Sep 29, 2023

Hello again and sorry to bother. I would love to make any changes to the implementation that you think are necessary. I have really enjoyed the opportunity to implement stride_view and I have already started on slide_view!

Please update the status page and any papers: libcxx/docs/Status/RangesViews.csv
Also this PR needs a lot more tests.

@hawkinsw
Copy link
Contributor Author

Hello again and sorry to bother. I would love to make any changes to the implementation that you think are necessary. I have really enjoyed the opportunity to implement stride_view and I have already started on slide_view!

Please update the status page and any papers: libcxx/docs/Status/RangesViews.csv Also this PR needs a lot more tests.

Thank you for the feedback! Are you asking for an update to remove you as an implementer? Refer to the this URL for the PR? I believe that the paper listed in the CSV is the right one? I am sorry if I am missing something obvious.

@Zingam
Copy link
Contributor

Zingam commented Sep 30, 2023

Thank you for the feedback! Are you asking for an update to remove you as an implementer? Refer to the this URL for the PR? I believe that the paper listed in the CSV is the right one? I am sorry if I am missing something obvious.

Please change the URL to point to this PR, also mark which papers this PR implements as complete. You probably need to add the paper to the release notes, when this PR is approved.

Copy link
Member

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the long delay! I only went through the stride_view.h header and haven't looked at the tests closely yet, but I wanted to give you the feedback I have so far. Thanks a lot for all the work on the patch!


public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride)
: __base_(std::move(__base)), __stride_(__stride) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we test with a move-only __base?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that I addressed this in a93fef8

struct __fn {
template <viewable_range _Range>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const
noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n}))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be slightly easier to read if the three repetitions of the expression were vertically aligned. I think the best way to achieve that is using a /* */ comment like this -- see e.g. as_rvalue_view.h for an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever use of the block comment! I believe that this is addressed in accfb24af355238748e22653b46ed3c08db2208d.

@var-const var-const removed their assignment Oct 3, 2023
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions h,,cpp,inc -- libcxx/include/__ranges/stride_view.h libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/base.nodiscard.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/subscript.nodiscard.verify.cpp libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/decrement.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h libcxx/include/ranges libcxx/include/version libcxx/modules/std/ranges.inc libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
View the diff from clang-format here.
diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp
index 71d2325c8..c032e1e94 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp
@@ -46,12 +46,12 @@ static_assert(HasOnlyConstBegin<std::ranges::stride_view<SimpleCommonConstView>>
 static_assert(HasConstAndNonConstBegin<std::ranges::stride_view<UnSimpleConstView>>);
 
 constexpr bool test() {
-  const auto unsimple_const_view    = UnSimpleConstView();
-  const auto sv_unsimple_const = std::ranges::stride_view(unsimple_const_view, 1);
+  const auto unsimple_const_view = UnSimpleConstView();
+  const auto sv_unsimple_const   = std::ranges::stride_view(unsimple_const_view, 1);
   static_assert(std::same_as<decltype(*sv_unsimple_const.begin()), double&>);
 
-  auto simple_const_view    = SimpleCommonConstView();
-  auto sv_simple_const = std::ranges::stride_view(simple_const_view, 1);
+  auto simple_const_view = SimpleCommonConstView();
+  auto sv_simple_const   = std::ranges::stride_view(simple_const_view, 1);
   static_assert(std::same_as<decltype(*sv_simple_const.begin()), int&>);
 
   return true;

@hawkinsw hawkinsw force-pushed the stride_view branch 4 times, most recently from f33b89b to 861dbbb Compare October 31, 2023 22:13
hawkinsw added 18 commits May 28, 2025 08:14
Fix verifier error triggered by bad auto format.
Explicitly import vector where needed (for modules).
Improve base nodiscard test (and fix CI).
Remove libcxx/include/libcxx.imp from git.
Update status and release documentation.
Use constexpr if for operator- overload.
Consolidate class nodiscard verify tests.
Consolidate class nodiscard verify tests.
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
hawkinsw added 11 commits May 30, 2025 08:41
Update includes.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Mark internal typedef-like name as _LIBCPP_NODEBUG.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Make clang-format happy.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Base nodiscard test cleanup.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
base test cleanups.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Make clang-format happy.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Update begin tests.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Finish renaming UnsimpleConstView to UnSimpleConstView.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Final cleanup of begin tests.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Begin cleanup of end tests.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Cleanup unneeded includes in types.h.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. ranges Issues related to `<ranges>`
Projects
None yet
Development

Successfully merging this pull request may close these issues.

P1899R3: stride_view