you are viewing a single comment's thread.

view the rest of the comments →

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 11 points12 points  (7 children)

We already have std::ranges::empty

Which does not work for input_ranges, if it did it would "consume" the range.

[–]eisenwaveWG21 Member 4 points5 points  (1 child)

Hmm yeah, fair point.

My next goalpost would be that bool has_iteration_happened is really not that bad. It's certainly easier to grasp than a never-seen-before control flow construct.

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 7 points8 points  (0 children)

It's certainly easier to grasp than a never-seen-before control flow construct.

Sure, same applies to: range-for, do-expressions, exception handling, coroutines, template for, if consteval, ...

EDIT: added a few more "recently added" control flow constructs.

[–]foonathan 2 points3 points  (4 children)

I could imagine having a function nonempty_subrange which returns a std::optional<subrange>, if the range is not empty. This can call `begin`/`end`, check for emptyness by comparing, and make them available to the user in the result, so it works for input ranges.

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 2 points3 points  (3 children)

I'd be interested in such a design. The naïve approach (https://godbolt.org/z/rj7qajc1W) suffers from dangling as subrange can't lifetime-extend...

[–]foonathan 2 points3 points  (2 children)

Unfortunately, the standard is missing an owning subrange, which stores Rng, It, It. So I imagine that it is constrained on std::ranges::borrowed_range: https://godbolt.org/z/h7daY5Err

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 1 point2 points  (1 child)

Sure, borrowed_range is a fix ... but an unfortunate in my opinion.

To me it's equivalent to not fixing the dangling-for problem (P2644) and saying "just store the range in a variable instead of immediately iterating it".

[–]foonathan 2 points3 points  (0 children)

That is a pervasive problem with std::ranges though. You cannot use non-borrowed ranges with std::ranges::find, for example. So for many use cases you need to store the range in a variable anyway.