tcbrindle / flux

A C++20 library for sequence-orientated programming
https://tristanbrindle.com/flux/
Boost Software License 1.0
472 stars 29 forks source link

Add join_with adaptor #124

Closed tcbrindle closed 2 weeks ago

tcbrindle commented 1 year ago

C++23 adds std::views::join_with, which takes a range-of-ranges and a pattern and produces the elements of the inner ranges with the pattern interspersed.

We should have it too.

As always though, naming is hard. Our version of views::join is called flatten, to avoid the confusion that occurs in the ranges world between views::join (which takes a range-of-ranges) and views::concat (which takes a variadic pack of ranges and glues them together). So we could call our version flatten_with, following the same pattern. On the other hand, Range-V3 (unlike C++23) instead provides a second overload of views::join which takes an extra parameter. We could do the same and provide another overload of flatten, although I'm not particularly keen on that.

Another option could be to name our version of the adaptor just join, as it performs the opposite action to split: that is, seq.split(pattern).join(pattern) and seq_of_seqs.join(pattern).split(pattern) should each end up as a long-winded round-trip. Split and join as the complement of each other seems pretty nice, but it does again raise the possibility of join being mixed up with chain (our version of views::concat).

Yet another option could be intersperse or interleave, although either name seems more like it should take a pair (or pack?) of sequences and alternate between an element of the first sequence and an element of the second sequence until one is exhausted.

(D provides roundRobin(), which takes a variadic number of ranges and produces elements of each in turn until all are exhausted, which is a slightly different algorithm -- though I like that one too.)