<div dir="ltr">Nah - I was thinking of something where zip wouldn't need any changes, potentially. One possibility:<br><br>    * iterator adapter that takes a (potentially finite) range of T and produces an infinite range of Optional<T> (with elements beyond the original range being empty Optionals)<br>    * same as the above, except potentially finite range of T to an infinite range of T where the elements beyond the original range are default constructed<br>    * A range truncation helper that just does something like: iterator_range trunc(R r, size_t t) { return {adl_begin(r), std::next(adl_end(r), t)}; }<br>    * then you do something like: trunc(zip(inf_opt(R1), inf_opt(R2)), max(size(R1), size(R2)))<br><br>This allows the use of these infinite/padded ranges in other situations apart from zipping.<br><br>But maybe that's niche enough/not worth generalizing over pre-emptively. I'm not sure. Just a thought.</div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jun 25, 2018 at 5:40 PM Michael Kruse via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Meinersbur added a comment.<br>
<br>
Is the following what you are thinking about?<br>
<br>
An `zip_infinite` begin-iterator, that never reaches the end (maybe with two flavors: `zip_infinite_default` and `zip_infinite_optional`) and return a `None`/value-initialized value for any iterator past the list. Then one can use that with an end iterator, such as `end_any` (-> zip_shortest) or `end_all` (-> `zip_longest`).<br>
<br>
Unfortunately, in the `zip_infinite_default`-case, we cannot distinguish between the default value end the end of the list. We'd have to look into the iterator's list of iterators, which makes this implementation-specific again.<br>
<br>
Alternatively, `zip_infinite` could return tuples of iterators, which `end_any`/`end_all` could compare to the end iterators. However, the current implementation of `zip_shortest` does not need to store the end-iterators for `operator++` (because in contrast to the others, it does not need to check whether one of the sequences is past the the end), making the implementation less efficient than it needs to. (template specialization of `shortest_iterator<zip_infinite<T>>` maybe?)<br>
<br>
<br>
<br>
================<br>
Comment at: include/llvm/ADT/STLExtras.h:757-785<br>
+template <typename... Args> class zip_longest_default_range {<br>
+public:<br>
+  using iterator = zip_longest_default_iterator<decltype(<br>
+      std::begin(std::declval<Args>()))...>;<br>
+  using iterator_category = typename iterator::iterator_category;<br>
+  using value_type = typename iterator::value_type;<br>
+  using difference_type = typename iterator::difference_type;<br>
----------------<br>
The `zip_*_range` classes (including `zippy`) might no be needed: `iterator_range` could be used as well.<br>
<br>
<br>
Repository:<br>
  rL LLVM<br>
<br>
<a href="https://reviews.llvm.org/D48348" rel="noreferrer" target="_blank">https://reviews.llvm.org/D48348</a><br>
<br>
<br>
<br>
</blockquote></div>