Adaptors#

adjacent#

template<distance_t N>
requires (N > 0)
auto adjacent(multipass_sequence auto seq) -> multipass_sequence auto#

Given a compile-time size N and a multipass sequence seq, returns a new sequence which yields sliding windows of size N as an N-tuple of elements of seq. If seq has fewer than N elements, the adapted sequence will be empty.

The returned sequence is always a multipass_sequence. It is also
  • bidirectional when seq is bidirectional

  • random-access when seq is random-access

  • sized when seq is sized

  • bounded when seq is both bounded and bidirectional

The slide() adaptor is similar to adjacent(), but takes its window size as a run-time rather than a compile-time parameter, and returns length-n subsequences rather than tuples.

Equivalent to:

zip(seq, drop(seq, 1), drop(seq, 2), ..., drop(seq, N-1));
Template Parameters:

N – The size of the sliding window. Must be greater than zero.

Parameters:

seq – A multipass sequence.

Returns:

A sequence adaptor whose element type is a std::tuple of size N, or a std::pair if N == 2.

Example:
std::vector vec{1, 2, 3, 4, 5};

std::vector<int> sums;

// adjacent<3> yields 3-tuples which we can destructure
for (auto [a, b, c] : flux::adjacent<3>(std::move(vec))) {
    sums.push_back(a + b + c);
}

assert((sums == std::vector{1 + 2 + 3,
                            2 + 3 + 4,
                            3 + 4 + 5}));
See also:

adjacent_filter#

template<multipass_sequence Seq, typename Pred>
requires std::predicate<Pred&, element_t<Seq>, element_t<Seq>>
auto adjacent_filter(Seq seq, Pred pred) -> multipass_sequence auto;#

Applies the given binary predicate pred to each pair of adjacent elements of seq. If the predicate returns false, the second element of the pair does not appear in the resulting sequence. The first element of seq is always included in the output.

The resulting sequence is always multipass; it is also a bidirectional_sequence if Seq is bidirectional, and a bounded_sequence if Seq is bounded.

A common use for adjacent_filter() is to remove adjacent equal elements from a sequence, which can be achieved by passing std::not_equal_to{} as the predicate. The dedup() function is a handy alias for adjacent_filter(not_equal_to{}).

Parameters:
  • seq – A multipass sequence

  • pred – A binary predicate to compare sequence elements

Returns:

The filtered sequence

Example:

std::array nums{1, 1, 2, 3, 3, 2, 2};

// The adjacent_filter adaptor applies the given predicate to each pair
// of elements in the sequence, and if the predicate returns false then
// the second element of the pair is discarded
auto filtered1 = flux::adjacent_filter(nums, std::less{});
assert(flux::equal(filtered1, std::array{1, 2, 3}));

// For the common case of removing adjacent equal elements, Flux provides
// the dedup() function as shorthand for adjacent_filter(std::not_equal_to{})
auto filtered2 = flux::dedup(nums);
assert(flux::equal(filtered2, std::array{1, 2, 3, 2}));

// We can use adjacent_filter with a custom comparator as well
auto compare = [](auto p1, auto p2) { return p1.first != p2.first; };
std::pair<int, int> pairs[] = {{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}};

auto filtered3 = flux::adjacent_filter(flux::ref(pairs), compare);
assert(flux::equal(filtered3,
                   std::array{std::pair{1, 2}, std::pair{2, 5}}));
See also:

adjacent_map#

template<distance_t N>
auto adjacent_map(multipass_sequence auto seq, auto func) -> multipass_sequence auto;#

cache_last#

template<sequence Seq>
requires see_below
auto cache_last(Seq seq) -> sequence auto;#

cartesian_product#

auto cartesian_product(sequence auto seq0, multipass_sequence auto... seqs) -> sequence auto;#

cartesian_product_map#

template<typename Func, sequence Seq0, multipass_sequence... Seqs>
requires std::regular_invocable<Func&, element_t<Seq0>, element_t<Seqs>...>
auto cartesian_product_with(Func func, Seq0 seq0, Seqs... seqs) -> sequence auto;#

chain#

template<sequence Seq0, sequence... Seqs>
requires see_below
auto chain(Seq0 seq0, Seqs... seqs) -> sequence auto;#

chunk#

auto chunk(sequence auto seq, std::integral auto chunk_sz) -> sequence auto;#

chunk_by#

template<multipass_sequence Seq, typename Pred>
requires std::predicate<Pred, element_t<Seq>, element_t<Seq>>
auto chunk_by(Seq seq, Pred pred) -> multipass_sequence auto;#

cursors#

auto cursors(multipass_sequence auto seq) -> multipass_sequence auto;#

Given a sequence seq, cursors(seq) returns a new sequence whose elements are the cursors of the original sequence. The cursors() sequence retains all the capabilities of the source sequence (bidirectional, random access, sized etc), up to contiguous_sequence.

This is basically a passthrough adaptor, except that read_at(seq, cur) returns a copy of cur.

Parameters:

seq – A multipass sequence

Returns:

A sequence whose elements are the cursors of seq

Example:

std::array const array{"alpha"sv, "bravo"sv, "charlie"sv, "delta"sv, "echo"sv};

auto long_words = flux::drop(array, 2);

// We can use the cursors() adaptor to iterate over the cursors of the
// sequence (in this case integer indices) and use those to read from the
// original sequence
for (auto idx : flux::cursors(long_words)) {
    std::cout << idx << ": " << long_words[idx] << '\n';
}
// prints
// 2: charlie
// 3: delta
// 4: echo

cycle#

template<sequence Seq>
requires multipass_sequence<Seq> || infinite_sequence<Seq>
auto cycle(Seq seq) -> infinite_sequence auto;#
template<multipass_sequence Seq>
auto cycle(Seq seq, std::integral auto count) -> multipass_sequence auto;#

Repeats the elements of seq endlessly (for the first overload) or count times (for the second overload).

For the first overload, if Seq is already an infinite_sequence, it is passed through unchanged.

Otherwise, both overloads require a multipass_sequence, and the output is always a multipass_sequence. The adapted sequence is also a bidirectional_sequence when Seq is both bidirectional and bounded, and a random_access_sequence when Seq is random-access and bounded.

For the second overload, the returned sequence is additionally always a bounded_sequence (even if Seq is not), and a sized_sequence when the source sequence is sized.

To avoid “spooky action at a distance” (where mutating s[n] would change the value of some other s[m]) cycle() provides only immutable access to the elements of seq: that is, it behaves as if seq were first passed through read_only().

Caution

In order to provide random-access functionality, cursors for cycled sequences keep a size_t count of how many times they have looped round. For very long-running programs using the infinite version of cycle() it may be possible to overflow this counter. (Assuming 1000 iterations per second, this would take approximately 49 days on a machine with a 32-bit size_t, or around 500 million years on a 64-bit machine.)

While this won’t cause undefined behaviour, it’s possible to encounter incorrect results or runtime errors when using the random-access functions on cursors which have overflowed.

Parameters:
  • seq – A sequence to cycle through

  • count – The number of times to loop through the sequence before terminating. If not supplied, the sequence will be repeated endlessly.

Returns:

An adapted sequence which repeatedly loops through the elements of seq.

Example:

std::array arr{1, 2, 3};

// cycle(seq) returns an infinite sequence. It's common to use this in
// combination with take() to turn it back into a finite sequence:
auto cycled1 = flux::take(flux::cycle(arr), 5);
assert(flux::equal(cycled1, std::array{1, 2, 3, 1, 2}));

// We can also use a cycled sequence as an argument to zip():
std::string_view letters = "ABCDE";
auto zipped = flux::zip(letters, flux::cycle(arr));
using P = std::pair<char const&, int const&>;
assert(flux::equal(zipped, std::array{
    P{'A', 1}, P{'B', 2}, P{'C', 3}, P{'D', 1}, P{'E', 2}
}));

// Alternatively, we can provide a second argument to cycle(seq, n) to
// get a finite sequence which repeats the source n times:
auto cycled2 = flux::cycle(arr, 3);
assert(flux::equal(cycled2, std::array{1, 2, 3, 1, 2, 3, 1, 2, 3}));
assert(flux::sum(cycled2) == 18);

// Note that both versions of cycle() only provide immutable access to their
// elements. The following would be a compile error:
// flux::fill(cycled2, 99); // ERROR: cannot assign to const reference
See also:

dedup#

template<multipass_sequence Seq>
requires std::equality_comparable<element_t<Seq>>
auto dedup(Seq seq) -> multipass_sequence auto;#

An alias for adjacent_filter(seq, std::ranges::not_equal_to{}). This can be used to remove adjacent elements from a sequence.

See also:

drop#

auto drop(sequence auto seq, std::integral auto count) -> sequence auto;#

Given a sequence seq and a non-negative integral value count, returns a new sequence which skips the first count elements of seq.

The returned sequence has the same capabilities as :var:seq. If seq has fewer than count elements, the returned sequence is empty.

Parameters:
  • seq – A sequence.

  • count – A non-negative integral value indicating the number of elements to be skipped.

Returns:

A sequence adaptor that yields the remaining elements of seq, with the first count elements skipped.

Example:

std::vector vec{1, 2, 3, 4, 5};

auto dropped = flux::drop(std::move(vec), 3);

assert(flux::size(dropped) == 2);
assert(flux::equal(dropped, std::vector{4, 5}));
See also:

drop_while#

template<sequence Seq, typename Pred>
requires std::predicate<Pred&, element_t<Seq>>
auto drop_while(Seq seq, Pred pred) -> sequence auto;#

filter#

template<sequence Seq, typename Pred>
requires std::predicate<Pred, element_t<Seq>&>
auto filter(Seq seq, Pred pred) -> sequence auto;#

flatten#

template<sequence Seq>
requires sequence<element_t<Seq>>
auto flatten(Seq seq) -> sequence auto;#

map#

template<sequence Seq, std::copy_constructable Func>
auto map(Seq seq, Func func) -> sequence auto;#

mask#

template<sequence Seq, sequence Mask>
requires boolean_testable<element_t<Mask>>
auto mask(Seq seq, Mask where) -> sequence auto;#

Given a sequence of values and a sequence of booleans, mask() yields those elements of seq for which the corresponding element of where evaluates to true. Iteration is complete when either of the two input sequences is exhausted.

The returned sequence models the lowest common category of the two input sequences, up to bidirectional_sequence. It is also a bounded_sequence and a sized_sequence when both inputs model these concepts.

Parameters:
  • seq – A sequence of values

  • where – A sequence whose element type is convertible to bool

Returns:

An adapted sequence whose elements are the elements of seq, filtered by the corresponding elements of where

Example:

std::array values{"one"sv, "two"sv, "three"sv, "four"sv, "five"sv};

std::array selectors{true, false, true, false, true};

// flux::mask() selects those elements of values for which the corresponding
// element of selectors is true
auto masked = flux::mask(values, selectors);
assert(flux::equal(masked, std::array{"one"sv, "three"sv, "five"sv}));

// Note that the selectors sequence can have any element type which is
// explicitly convertible to bool
std::array int_selectors{0, 0, 0, 1, 1};

auto masked2 = flux::mask(values, int_selectors);
assert(flux::equal(masked2, std::array{"four"sv, "five"sv}));
See also:

pairwise#

auto pairwise(multipass_sequence auto seq) -> multipass_sequence auto;#

Returns an adaptor which yields pairs of elements of seq. It is an alias for adjacent<2>().

Parameters:

seq – A multipass sequence.

Returns:

A multipass sequence yielding pairs of elements of seq.

pairwise_map#

template<multipass_sequence Seq, typename Func>
requires std::regular_invocable<Func&, element_t<Seq>, element_t<Seq>> && can_reference<std::invoke_result_t<Func&, element_t<Seq>, element_t<Seq>>>
auto pairwise_map(Seq seq, Func func) -> multipass_sequence auto;#

prescan#

template<sequence Seq, typename Func, std::movable Init>
requires foldable<Seq, Func, Init>
auto prescan(Seq seq, Func func, Init init) -> sequence auto;#

Returns a stateful sequence adaptor which yields “partial folds” using the binary function func.

First, this adaptor initialises an internal variable state to init and yields a read-only reference to this state. Then, for each successive element elem of the underlying sequence, it sets:

state = func(std::move(state), std::forward(elem));

and yields a read-only reference to the new state.

The final value yielded by this adaptor is the same as fold(seq, func, init).

Because this adaptor needs to maintain internal state, it is only ever single-pass. However it is a bounded_sequence when the underlying sequence is bounded and a sized_sequence when the underlying sequence is sized.

Unlike scan(), this function performs an exclusive scan, that is, the Nth element of the adapted sequence does not include the Nth element of the underlying sequence. The adaptor returned by prescan() always yields at least one element – the initial value – followed by the elements that would be yielded by the scan() adaptor.

Parameters:
  • seq – A sequence to adapt

  • func – A binary callable of the form R(R, element_t<Seq>), where R is constructible from Init

  • init – The initial value for the scan

Returns:

A sequence adaptor which performs an exclusive scan of the elements of seq using func.

Example:

// We can compute the triangular numbers using prescan()
std::array const ints{1, 2, 3, 4, 5};

// Note that unlike scan(), the initial value for prescan() is required, and
// is the first element of the resulting sequence, which has one more element
// than the input
auto tri_nums = flux::prescan(ints, std::plus{}, 0);
assert(flux::equal(tri_nums, std::array{0, 1, 3, 6, 10, 15}));
See also:

read_only#

template<sequence Seq>
auto read_only(Seq seq) -> read_only_sequence auto;#

Returns an adapted sequence which prevents direct modification of the elements of seq. The returned sequence retains the capabilities of the source sequence, all the way up to contiguous_sequence.

If Seq is already a read_only_sequence, then it is returned unchanged. Otherwise, read_only() is equivalent to:

map(seq, [](auto&& elem) -> const_element_t<Seq> {
    return static_cast<const_element_t<Seq>>(std::forward(elem));
});

except that the returned sequence will be a contiguous_sequence if the source sequence models that concept. In this case, the pointer returned from data() will have type value_t<Seq> const*.

Parameters:

seq – A sequence

Returns:

An adapted sequence which provides read-only access to the elements of seq

Example:

// We can use the read_only_sequence concept to statically require a sequence
// whose elements are immutable
bool contains_a_two(flux::read_only_sequence auto&& seq)
{
    for (auto&& elem : seq) {
        if (elem == 2) { // What if we wrote `elem = 2` (assignment) by mistake?
            return true;
        }
    }
    return false;
}

int main()
{
    auto seq = flux::filter(std::vector{1, 2, 3, 4, 5}, flux::pred::even);

    // We cannot pass seq directly, as it yields mutable int& elements
    // contains_a_two(seq); // COMPILE ERROR

    // ...but we can use read_only() so that the sequence yields immutable
    // elements of type int const&.
    assert(contains_a_two(flux::read_only(std::move(seq))));
}
See also:

reverse#

template<bidirectional_sequence Seq>
requires bounded_sequence<Seq>
auto reverse(Seq seq) -> bidirectional_sequence auto;#

scan#

template<sequence Seq, typename Func, std::movable Init = value_t<Seq>>
requires foldable<Seq, Func, Init>
auto scan(Seq seq, Func func, Init init = {}) -> sequence auto;#

Returns a stateful sequence adaptor which yields “partial folds” using the binary function func.

First, this adaptor initialises an internal variable state to init. Then, for each successive element elem of the underlying sequence, it sets:

state = func(std::move(state), std::forward(elem));

and yields a read-only reference to the new state.

The final value yielded by this adaptor is the same as fold(seq, func, init).

Because this adaptor needs to maintain internal state, it is only ever single-pass. However it is a bounded_sequence when the underlying sequence is bounded and a sized_sequence when the underlying sequence is sized.

Unlike prescan(), this function performs an inclusive scan, that is, the Nth element of the adapted sequence includes the Nth element of the underlying sequence. The adapted sequence always yields the same number of elements as the underlying sequence.

Parameters:
  • seq – A sequence to adapt

  • func – A binary callable of the form R(R, element_t<Seq>), where R is constructible from Init

  • init – The initial value for the scan. If not supplied, a default constructed object of type value_t<Seq> is used.

Returns:

A sequence adaptor which performs an inclusive scan of the elements of seq using func.

Example:

// We can compute the triangular numbers using scan()
std::array const ints{1, 2, 3, 4, 5};

// Note that unlike prescan(), the initial value for scan() may be omitted
// (here defaulting to int{}), and the resulting sequence has the same number
// of elements as the original
auto tri_nums = flux::scan(ints, std::plus{});
assert(flux::equal(tri_nums, std::array{1, 3, 6, 10, 15}));
See also:

scan_first#

template<sequence Seq, typename Func>
requires foldable<Seq, Func, element_t<Seq>>
auto scan_first(Seq seq, Func func) -> sequence auto;#

Returns a stateful sequence adaptor which yields “partial folds” using the binary function func.

When iterated over, the returned sequence first initialises an internal variable state with the first element of the underlying sequence, and yields a read-only reference to this state. For each subsequent element elem, it sets:

state = func(std::move(state), std::forward(elem));

and yields a read-only reference to the internal state. If seq is empty, the internal state is never initialised and the resulting sequence is also empty. For a non-empty sequence, the final value yielded by scan_first() is the same as would be obtained from fold_first(seq, func).

Because this adaptor needs to maintain internal state, it is only ever single-pass. However it is a bounded_sequence when the underlying sequence is bounded and a sized_sequence when the underlying sequence is sized.

Like scan(), this function performs an inclusive scan, that is, the Nth element of the adapted sequence includes the Nth element of the underlying sequence. The adapted sequence always yields the same number of elements as the underlying sequence. Unlike scan(), the first element of scan_first() is simply the first element of the underlying sequence, and the supplied func is only applied to subsequent elements (this is equivalent to the differing behaviours of fold() and fold_first() respectively).

Parameters:
  • seq – A sequence to adapt

  • func – A binary callable of the form R(R, element_t<Seq>), where R is constructible from element_t<Seq>

Returns:

A sequence adaptor which performs an inclusive scan of the elements of seq using func.

Example:

// We can compute the triangular numbers using scan_first()
std::array const ints{1, 2, 3, 4, 5};

// Note that unlike scan(), scan_first() never takes an initial value,
// and instead the first element of the resulting sequence is the same as
// the first element of the underlying sequence: the fold operation is only
// applied to subsequent elements.
auto tri_nums = flux::scan_first(ints, std::plus{});
assert(flux::equal(tri_nums, std::array{1, 3, 6, 10, 15}));
See also:

set_difference#

template<sequence Seq1, sequence Seq2, typename Cmp = std::ranges::less>
requires strict_weak_order_for<Cmp, Seq1> && strict_weak_order_for<Cmp, Seq2>
auto set_difference(Seq1 seq1, Seq2 seq2, Cmp cmp = {}) -> sequence auto;#

Returns a sequence adaptor which yields the set difference of the two input sequences seq1 and seq2, ordered by the given comparison function cmp.

This function assumes that both seq1 and seq2 are sorted with respect to the comparison function cmp. If the input sequences are not sorted, the contents of the resulting sequence is unspecified.

When the resulting sequence is iterated, it will output the elements from seq1 which are not found in the seq2 according to cmp. If some element is found m times in seq1 and n times in seq2, then the resulting sequence yields exactly std::max(m - n, 0) elements.

Parameters:
  • seq1 – The first sorted sequence.

  • seq2 – The second sorted sequence.

  • cmp – A binary predicate that takes two elements as arguments and returns true if the first element is less than the second.

Returns:

A sequence adaptor that yields those elements of seq1 which do not also appear in seq2.

Example:

std::array arr1{0, 1, 2, 3, 4, 5};
std::array arr2{   1,    3,    5};

auto merged = flux::set_difference(flux::ref(arr1), flux::ref(arr2));

assert(flux::equal(merged, std::array{0, 2, 4}));
See also:

set_intersection#

template<sequence Seq1, sequence Seq2, typename Cmp = std::ranges::less>
requires strict_weak_order_for<Cmp, Seq1> && strict_weak_order_for<Cmp, Seq2>
auto set_intersection(Seq1 seq1, Seq2 seq2, Cmp cmp = {}) -> sequence auto;#

Returns a sequence adaptor which yields the set intersection of the two input sequences seq1 and seq2, ordered by the given comparison function cmp.

This function assumes that both seq1 and seq2 are sorted with respect to the comparison function cmp. If the input sequences are not sorted, the contents of the resulting sequence is unspecified.

When the resulting sequence is iterated, it will output the elements from seq1 that are found in both sorted sequences according to cmp. If some element is found m times in seq1 and n times in seq2, then the resulting sequence yields exactly std::min(n, m) elements.

Parameters:
  • seq1 – The first sorted sequence.

  • seq2 – The second sorted sequence.

  • cmp – A binary predicate that takes two elements as arguments and returns true if the first element is less than the second.

Returns:

A sequence adaptor that represents the set intersection of the two input sequences.

Example:

std::array arr1{0, 1, 2, 3, 4, 5};
std::array arr2{   1,    3,    5};

auto merged = flux::set_intersection(flux::ref(arr1), flux::ref(arr2));

assert(flux::equal(merged, std::array{1, 3, 5}));
See also:

set_symmetric_difference#

template<sequence Seq1, sequence Seq2, typename Cmp = std::ranges::less>
requires see_below
auto set_symmetric_difference(Seq1 seq1, Seq2 seq2, Cmp cmp = {}) -> sequence auto;#

Returns a sequence adaptor which yields the set symmetric difference of the two input sequences seq1 and seq2, ordered by the given comparison function cmp.

This function assumes that both seq1 and seq2 are sorted with respect to the comparison function cmp. If the input sequences are not sorted, the contents of the resulting sequence is unspecified.

When the resulting sequence is iterated, it will output the elements that are found in either of the sequence, but not in both of them according to cmp. If some element is found m times in seq1 and n times in seq2, then the resulting sequence yields exactly std::abs(m - n) elements, preserving order:

  • if m > n, the final m - n of these elements from seq1

  • if m < n, the final n - m of these elements from seq2

Requires:

The expression in the requires clause is equivalent to:

std::common_reference_with<element_t<Seq1>, element_t<Seq2>> &&
std::common_reference_with<rvalue_element_t<Seq1>, rvalue_element_t<Seq2>> &&
requires { typename std::common_type_t<value_t<Seq1>, value_t<Seq2>>; } &&
strict_weak_order_for<Cmp, Seq1> &&
strict_weak_order_for<Cmp, Seq2>
Parameters:
  • seq1 – The first sequence to merge.

  • seq2 – The second sequence to merge.

Returns:

A sequence adaptor that yields elements of seq1 and seq2 which do not appear in both sequences.

Example:

std::array arr1{0, 1, 2, 3, 4, 5};
std::array arr2{   1,    3,    5, 6, 7};

auto merged = flux::set_symmetric_difference(flux::ref(arr1), flux::ref(arr2));

assert(flux::equal(merged, std::array{0, 2, 4, 6, 7}));
See also:

set_union#

template<sequence Seq1, sequence Seq2, typename Cmp = std::ranges::less>
requires see_below
auto set_union(Seq1 seq1, Seq2 seq2, Cmp cmp = {}) -> sequence auto;#

Returns a sequence adaptor which yields the set union of the two input sequences seq1 and seq2, ordered by the given comparison function cmp.

This function assumes that both seq1 and seq2 are sorted with respect to the comparison function cmp. If the input sequences are not sorted, the contents of the resulting sequence is unspecified.

When the resulting sequence is iterated, it will output the elements from the two input sequences in order according to cmp. If some element is found m times in seq1 and n times in seq2, then the resulting sequence yields exactly std::max(n, m) elements.

Requires:

The expression in the requires clause is equivalent to:

std::common_reference_with<element_t<Seq1>, element_t<Seq2>> &&
std::common_reference_with<rvalue_element_t<Seq1>, rvalue_element_t<Seq2>> &&
requires { typename std::common_type_t<value_t<Seq1>, value_t<Seq2>>; } &&
strict_weak_order_for<Cmp, Seq1> &&
strict_weak_order_for<Cmp, Seq2>
Parameters:
  • seq1 – The first sorted sequence to merge.

  • seq2 – The second sorted sequence to merge.

  • cmp – A binary predicate that takes two elements as arguments and returns true if the first element is less than the second.

Returns:

A sequence adaptor that represents the set union of the two input sequences.

Example:

std::array arr1{1, 3, 5};
std::array arr2{1, 2, 4, 6};

auto merged = flux::set_union(flux::ref(arr1), flux::ref(arr2));

assert(flux::equal(merged, std::array{1, 2, 3, 4, 5, 6}));
See also:

slide#

auto slide(multipass_sequence auto seq, std::integral auto win_sz) -> multipass_sequence auto;#

stride#

auto stride(sequence auto seq, std::integral auto stride_len) -> sequence auto;#

split#

template<multipass_sequence Seq, multipass_sequence Pattern>
requires std::equality_comparable_with<element_t<Seq>, element_t<Pattern>>
auto split(Seq seq, Pattern pattern) -> sequence auto;#
template<multipass_sequence Seq>
auto split(Seq seq, value_t<Seq> delim) -> sequence auto;#

take#

auto take(sequence auto seq, std::integral auto count) -> sequence auto;#

take_while#

template<sequence Seq, typename Pred>
requires std::predicate<Pred&, element_t<Seq>>
auto take_while(Seq seq, Pred pred) -> sequence auto;#

unchecked#

auto unchecked(sequence auto seq) -> sequence auto;#

zip#

auto zip(sequence auto... seqs) -> sequence auto;#