Class Subspace :: sus :: iter :: IteratorBase
The base class for all Iterator
types.
The Iterator
concept requires that a type
subclasses from IteratorBase
and is final
in order to be considered an
Iterator
. No code should refer to IteratorBase
except for defining the base class of an iterator, and it should be treated
as an implementation detail only.
Methods
Tests whether all elements of the iterator match a predicate.
If the predicate returns true
for all elements in the iterator, this
functions returns true
, otherwise false
. The function is
short-circuiting; it stops iterating on the first false
returned
from the predicate.
Returns true
if the iterator is empty.
Tests whether any elements of the iterator match a predicate.
If the predicate returns true
for any elements in the iterator, this
functions returns true
, otherwise false
. The function is
short-circuiting; it stops iterating on the first true
returned from
the predicate.
Returns false
if the iterator is empty.
Adaptor for use in ranged for loops.
Returns an iterator that refers to this iterator, and for which operations on it will also be applied to this iterator.
This is useful to allow applying iterator adapters while still retaining ownership of the original iterator.
Takes two iterators and creates a new iterator over both in sequence.
chain()
will return a new iterator which will first iterate over values
from the first iterator and then over values from the second iterator.
In other words, it links two iterators together, in a chain. 🔗
sus::iter::Once
is commonly used to adapt a single value into a chain of
other kinds of iteration.
Creates an iterator which clones all of its elements.
This is useful when you have an iterator over T&
, but you need an
iterator over T
.
There is no guarantee whatsoever about the clone method actually being called or optimized away. So code should not depend on either.
Lexicographically
compares the elements of this Iterator
with those of another.
sus::iter::IntoIteratorAny<Other>
Lexicographically
compares the elements of this Iterator
with those of another with
respect to the specified comparison function.
Transforms an iterator into a collection.
collect() can turn anything iterable into a relevant collection. If this is used anything like in Rust, it would be one of the more powerful methods in the subspace library, used in a variety of contexts.
The most basic pattern in which collect() is used is to turn one collection into another. You take a collection, call iter on it, do a bunch of transformations, and then collect() at the end.
collect() can also create instances of types that are not typical
collections. For example, a string can be built from chars, and an
iterator of Result<T, E> items can be collected into Result<Collection
Because collect() is so general, and C++ lacks strong type inference, collect() doesn't know the type of collection that you want to produce, so you will always need to pass it a type argument, such as:
sus::move(iter).collect<MyCollection<i32>>()
Transforms an iterator into a Vec.
This function is a shorthand for it.collect<Vec<Item>>()
in order to
avoid the need for specifying a template argument.
See collect()
for more details.
Creates an iterator which copies all of its elements.
This is useful when you have an iterator over T&
, but you need an iterator
over T
.
Consumes the iterator, and returns the number of elements that were in it.
The function walks the iterator until it sees an Option holding #None.
Panics
If the iterator has more than usize::MAX
elements in it the usize
will
catch overflow and panic. To avoid panic, you may use a fold over
OverflowInteger<usize>
that increments the count each iteration.
Repeats an iterator endlessly.
asdaa
Instead of stopping at None
, the iterator will instead start again, from
the beginning. After iterating again, it will start at the beginning
again. And again. And again. Forever. Note that in case the original
iterator is empty, the resulting iterator will also be empty.
The iterator must be Clone
as it will be cloned in order to be
repeatedly iterated.
Adaptor for use in ranged for loops.
Creates an iterator which gives the current iteration count as well as the next value.
The iterator returned yields pairs (i, val)
, where i
is the current
index of iteration and val
is the value returned by the iterator.
enumerate()
keeps its count as a usize
. If you want to count by a
different sized integer, the zip()
function provides similar
functionality.
Overflow Behavior
The method does no guarding against overflows, so enumerating more than
usize::MAX
elements either produces the wrong result or panics depending
on your build configuration. If debug assertions are enabled, a panic is
guaranteed.
Panics
The returned iterator might panic if the to-be-returned index would
overflow a usize
.
Determines if the elements of this Iterator
are equal to those of
another.
sus::iter::IntoIteratorAny<Other>
Determines if the elements of this Iterator
are equal to those of
another with respect to the specified equality function.
Creates an iterator which uses a closure to determine if an element should be yielded.
Given an element the closure must return true or false. The returned iterator will yield only the elements for which the closure returns true.
sus::fn::FnMut<MapFn, ::sus::fn::NonVoid (ItemT &&)>
::sus::option::__private::IsOptionType<R>::value
sus::fn::FnMut<MapFn, ::sus::fn::NonVoid (Item &&)>
::sus::option::__private::IsOptionType<R>::value
Searches for an element of an iterator that satisfies a predicate.
find()
takes a closure that returns true
or false
. It applies this
predicate to each element of the iterator, and if any of them return true,
then find()
returns Some(element)
. If they all return false
, it
returns None
.
find()
is short-circuiting; in other words, it will stop processing as
soon as the predicate returns true
.
If you need the index of the element, see position()
.
sus::fn::FnMut<FindFn, ::sus::fn::NonVoid (ItemT &&)>
::sus::option::__private::IsOptionType<R>::value
sus::fn::FnMut<FindFn, ::sus::fn::NonVoid (Item &&)>
::sus::option::__private::IsOptionType<R>::value
Applies function to the elements of iterator and returns the first non-none result.
sus::move(iter).find_map(f)
is equivalent to
sus::move(iter).filter_map(f).next()
.
Creates an iterator that works like map, but flattens nested structure.
The map()
adapter is very useful, but only when the closure argument
produces values. If it produces an iterator instead, there’s an extra
layer of indirection. flat_map()
will remove this extra layer on its
own.
You can think of flat_map(f)
as the semantic equivalent of mapping, and
then flattening as in map(f).flatten()
.
Another way of thinking about flat_map()
: map()
's closure returns one
item for each element, and flat_map()
's closure returns an iterator for
each element.
Creates an iterator that flattens nested structure.
This is useful when you have an iterator of iterators or an iterator of things that can be turned into iterators and you want to remove one level of indirection.
In other words, this type maps Iterator[Iterable[T]]
into Iterator[T]
.
Folds every element into an accumulator by applying an operation, returning the final result.
fold()
takes two arguments: an initial value, and a closure with two
arguments: an "accumulator", and an element. The closure returns the value
that the accumulator should have for the next iteration.
The initial value is the value the accumulator will have on the first call.
After applying this closure to every element of the iterator, fold()
returns the accumulator.
This operation is sometimes called "reduce" or "inject".
Folding is useful whenever you have a collection of something, and want to produce a single value from it.
Note: fold()
, and similar methods that traverse the entire iterator,
might not terminate for infinite iterators, even on traits for which a
result is determinable in finite time.
Note: reduce()
can be used to use the first element as the initial
value, if the accumulator type and item type is the same.
Note: fold()
combines elements in a left-associative fashion. For
associative operators like +
, the order the elements are combined in is
not important, but for non-associative operators like -
the order will
affect the final result. For a right-associative version of fold()
, see
rfold()
if the Iterator
also satisfies DoubleEndedIterator
.
Folding over References
The initial value type for fold will decay to a value (non-reference) by
default, due to the way C++ templates resolve types. In order to fold over
reference types, pass the type of the initial value explicitly as in the
following example, which will return the last reference in the
Iterator<i32&>
.
auto v = sus::Vec<i32>(1, 2, 3);
i32 init;
i32& out = v.iter_mut().fold<i32&>(
init, [](i32&, i32& v) -> i32& { return v; });
sus_check(&out == &v.last().unwrap());
Calls a closure on each element of an iterator.
This is equivalent to using a for loop on the iterator, although break and continue are not possible from a closure. It’s generally more idiomatic to use a for loop, but for_each may be more legible when processing items at the end of longer iterator chains. In some cases for_each may also be faster than a loop, because it avoids constructing a proxy type for the loop to consume.
Creates an iterator which ends after the first None.
After an iterator returns None
, future calls may or may not yield
Some(T)
again. fuse()
adapts an iterator, ensuring that after a None
is given, it will always return None forever.
This is useful for cases where the iterator may continue to be polled after it has returned None.
TODO: Implement a FusedIterator concept though a tag of some sort, so that fuse() can be a no-op in that case?
Determines if the elements of this Iterator are lexicographically greater than or equal to those of another.
Creates an iterator from a generator function that consumes the current iterator.
Coroutines can not be constexpr, so this function is not constexpr to avoid deeper compiler errors.
Determines if the elements of this Iterator are lexicographically greater than those of another.
Does something with each element of an iterator, passing the value on.
When using iterators, you’ll often chain several of them together. While
working on such code, you might want to check out what’s happening at
various parts in the pipeline. To do that, insert a call to inspect()
.
It’s more common for inspect()
to be used as a debugging tool than to
exist in your final code, but applications may find it useful in certain
situations when errors need to be logged before being discarded.
An Iterator also satisfies IntoIterator, which simply returns itself.
sus::iter::IntoIterator trait implementation.
Checks if the elements of this iterator are sorted.
That is, it returns true if for each consecutive element a
and b
,
a <= b
is true. If the iterator yields exactly zero or one element, true
is returned.
Checks if the elements of this iterator are sorted using the given comparator function.
Returns true if for each consecutive element a
and b
, a <= b
is
true. If the iterator yields exactly zero or one element, true is
returned.
Consumes the iterator, returning the last element.
This method will evaluate the iterator until it returns None
. While
doing so, it keeps track of the current element. After None
is returned,
last()
will then return the last element it saw.
Determines if the elements of this Iterator are lexicographically less than or equal to those of another.
Determines if the elements of this Iterator are lexicographically less than those of another.
Creates an iterator which uses a closure to map each element to another type.
The returned iterator's type is whatever is returned by the closure.
sus::fn::FnMut<MapFn, ::sus::fn::NonVoid (ItemT &&)>
::sus::option::__private::IsOptionType<R>::value
sus::fn::FnMut<MapFn, ::sus::fn::NonVoid (Item &&)>
::sus::option::__private::IsOptionType<R>::value
Creates an iterator that both yields elements based on a predicate and maps.
map_while()
takes a closure as an argument that returns Options. It will
call this closure on each element of the iterator, and yield elements
while it returns an Option with a value in it.
Returns the maximum element of an iterator.
If several elements are equally maximum, the last element is returned. If the iterator is empty, None is returned.
Note that f32
/f64
doesn’t implement StrongOrd
due to NaN being
incomparable. You can work around this by using Iterator::reduce
:
sus_check(
sus::Array<f32, 3>(2.4, f32::NAN, 1.3)
.into_iter()
.reduce(&f32::max)
.unwrap() ==
2.4
);
Returns the element that gives the maximum value with respect to the specified comparison function.
If several elements are equally maximum, the last element is returned. If the iterator is empty, None is returned.
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const std::remove_reference_t<ItemT> &)>
sus::cmp::Ord<Key>
!std::is_reference_v<Key>
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const std::remove_reference_t<Item> &)>
sus::cmp::Ord<Key>
!std::is_reference_v<Key>
Returns the element that gives the maximum value from the specified function.
If several elements are equally maximum, the last element is returned. If
the iterator is empty, None
is returned.
Returns the minimum element of an iterator.
If several elements are equally minimum, the first element is returned. If the iterator is empty, None is returned.
Note that f32
/f64
doesn’t implement StrongOrd
due to NaN being
incomparable. You can work around this by using Iterator::reduce
:
sus_check(
sus::Array<f32, 3>(2.4, f32::NAN, 1.3)
.into_iter()
.reduce(&f32::min)
.unwrap() ==
2.4
);
Returns the element that gives the minimum value with respect to the specified comparison function.
If several elements are equally minimum, the first element is returned. If the iterator is empty, None is returned.
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const std::remove_reference_t<ItemT> &)>
sus::cmp::Ord<Key>
!std::is_reference_v<Key>
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const std::remove_reference_t<Item> &)>
sus::cmp::Ord<Key>
!std::is_reference_v<Key>
Returns the element that gives the minimum value from the specified function.
If several elements are equally minimum, the first element is returned. If
the iterator is empty, None
is returned.
Determines if the elements of this Iterator
are not equal to those of
another.
Returns the nth element of the iterator.
Like most indexing operations, the count starts from zero, so nth(0u)
returns the first value, nth(1u)
the second, and so on.
Note that all preceding elements, as well as the returned element, will be
consumed from the iterator. That means that the preceding elements will be
discarded, and also that calling nth(0u)
multiple times on the same
iterator will return different elements.
nth()
will return None
if n
is greater than or equal to the length
of the iterator. It will stop at the first None
encountered in the
iterator and return None
.
Returns the nth element from the end of the iterator.
This is essentially the reversed version of Iterator::nth(). Although like most indexing operations, the count starts from zero, so nth_back(0) returns the first value from the end, nth_back(1) the second, and so on.
Note that all elements between the end and the returned element will be consumed, including the returned element. This also means that calling nth_back(0) multiple times on the same iterator will return different elements.
nth_back() will return None if n is greater than or equal to the length of
the iterator. It will stop at the first None
encountered in the
iterator and return None
.
sus::iter::IntoIteratorAny<Other>
sus::cmp::PartialOrd<ItemT, OtherItem>
sus::iter::IntoIteratorAny<Other>
sus::cmp::PartialOrd<Item, OtherItem>
Lexicographically
compares the elements of this Iterator
with those of another.
The comparison works like short-circuit evaluation, returning a result without comparing the remaining elements. As soon as an order can be determined, the evaluation stops and a result is returned.
For floating-point numbers, NaN does not have a total order and will
result in std::partial_ordering::unordered
when compared.
sus::iter::IntoIteratorAny<Other>
Lexicographically
compares the elements of this Iterator
with those of another with
respect to the specified comparison function.
Consumes an iterator, creating two disjoint collections from it.
The predicate passed to partition()
can return true
or false
.
partition()
returns a pair, all of the elements for which the predicate
returned true
, and all of the elements for which it returned false
.
Creates an iterator which can use the peek()
and peek_mut()
methods to
look at the next element of the iterator without consuming it. See their
documentation for more information.
A peekable iterator also supports conditionally pulling the next item out
of the iterator, which is built on top of peek()
.
Note that the underlying iterator is still advanced when peek()
or
peek_mut()
are called for the first time: In order to retrieve the next
element, next()
is called on the underlying iterator, hence any side
effects (i.e. anything other than fetching the next value) of the next()
method will occur.
Searches for an element in an iterator, returning its index.
position()
takes a closure that returns true
or false
. It applies
this closure to each element of the iterator, and if one of them
returns true
, then position()
returns Some(index)
. If all of
them return false
, it returns None
.
position()
is short-circuiting; in other words, it will stop
processing as soon as it finds a true
.
If position is called multiple times on the same iterator, the second search starts where the first left off, but always considers the first element seen to be at position 0.
Panics
The method does no guarding against overflows, so if there are more
than [usize::MAX
] non-matching elements, it will panic.
Iterates over the entire iterator, multiplying all the elements.
An empty iterator returns the "one" value of the type.
product()
can be used to multiply any type implementing
Product
,
including numerics, Option
and
Result
.
Panics
/
When calling product()
and a primitive integer type is being returned,
method will panic if the computation overflows.
Using product<OverflowInteger<T>>()
will allow the caller to handle
overflow without a panic.
Converts the iterator into a std::ranges::range
for use with the std
ranges library.
This provides stdlib compatibility for iterators in libraries that expect stdlib types.
The sus/iter/compat_ranges.h
header must be included separately
to use this method, to avoid pulling in large stdlib headers by
default.
Reduces the elements to a single one, by repeatedly applying a reducing operation.
If the iterator is empty, returns None
; otherwise, returns the
result of the reduction.
The reducing function is a closure with two arguments: an 'accumulator',
and an element. For iterators with at least one element, this is the same
as fold()
with the first element of the iterator as the initial
accumulator value, folding every subsequent element into it.
Reducing References
If the iterator is over references, the reduce()
function will be
limited to returning a reference; in most cases to one of the members in
the iterator.
To reduce and produce a new value, first apply .copied()
or .cloned()
and then reduce()
that, such as it.copied().reduce(...)
which will
ensure the reduce()
function is able to work with values instead of
references.
This example uses copied()
to copy each i32
and sum them.
auto a = sus::Array<i32, 3>(2, 3, 4);
auto out = a.iter().copied().reduce(
[](i32 acc, i32 v) { return acc + v; });
sus_check(out.as_value() == 2 + 3 + 4);
Reverses an iterator's direction.
Usually, iterators iterate from front to back. After using rev()
, an
iterator will instead iterate from back to front.
This is only possible if the iterator has an end, so rev()
only works on
DoubleEndedIterator
s.
Searches for an element of an iterator from the back that satisfies a predicate.
rfind()
takes a closure that returns true
or false
. It applies this
closure to each element of the iterator, starting at the end, and if any
of them return true
, then rfind()
returns Some(element)
. If they all
return false
, it returns None
.
rfind()
is short-circuiting; in other words, it will stop processing as
soon as the closure returns true
.
sus::fn::FnMut<F, ::sus::fn::NonVoid (B, ItemT)>
sus::iter::DoubleEndedIterator<Iter, ItemT>
std::convertible_to<std::invoke_result_t<F &, B &&, ItemT &&>, B>
!std::is_reference_v<B> ||
std::is_reference_v<std::invoke_result_t<F&, B &&, ItemT &&>>
sus::fn::FnMut<F, ::sus::fn::NonVoid (B, Item)>
sus::iter::DoubleEndedIterator<Iter, Item>
std::convertible_to<std::invoke_result_t<F &, B &&, Item &&>, B>
!std::is_reference_v<B> ||
std::is_reference_v<std::invoke_result_t<F&, B &&, Item &&>>
An iterator method that reduces the iterator’s elements to a single, final value, starting from the back.
This is the reverse version of
Iterator::fold()
: it takes
elements starting from the back of the iterator.
rfold()
takes two arguments: an initial value, and a closure with two
arguments: an "accumulator", and an element. The closure returns the value
that the accumulator should have for the next iteration.
The initial value is the value the accumulator will have on the first call.
After applying this closure to every element of the iterator, rfold()
returns the accumulator.
This operation is sometimes called "reduce" or "inject".
Folding is useful whenever you have a collection of something, and want to produce a single value from it.
Note: rfold()
combines elements in a right-associative fashion. For
associative operators like +
, the order the elements are combined in is
not important, but for non-associative operators like -
the order will
affect the final result. For a left-associative version of rfold()
, see
Iterator::fold()
.
Searches for an element in an iterator from the right, returning its index.
rposition()
takes a closure that returns true
or false
. It applies
this closure to each element of the iterator, starting from the end,
and if one of them returns true
, then rposition()
returns
Some(index)
. If all of them return false
, it returns None
.
rposition()
is short-circuiting; in other words, it will stop
processing as soon as it finds a true
.
Because this requires the iterator to satisfy ExactSizeIterator, which
means its length can be represented in a usize
, this function can not
overflow and will not panic.
sus::fn::FnMut<F, ::sus::fn::NonVoid (State &, ItemT &&)>
::sus::option::__private::IsOptionType<R>::value
!std::is_reference_v<State>
sus::fn::FnMut<F, ::sus::fn::NonVoid (State &, Item &&)>
::sus::option::__private::IsOptionType<R>::value
!std::is_reference_v<State>
An iterator adapter which, like fold()
, holds internal state, but unlike
fold()
, produces a new iterator.
To write a function with internal state that receives the current iterator
as input and yields items in arbitrary ways, see generate()
. scan()
is
a less general tool where the given function is executed for each item in
the iterator in order. However scan()
is constexpr while generator
coroutiunes can not be.
scan()
takes two arguments: an initial value which seeds the internal
state, and a closure with two arguments, the first being a mutable
reference to the internal state and the second an iterator element. The
closure can mutate the internal state to share state between iterations.
On iteration, the closure will be applied to each element of the iterator
and the return value from the closure, an Option
, is returned by the
next method. Thus the closure can return Some(value)
to yield value, or
None
to end the iteration.
Creates an iterator that skips the first n
elements.
skip(n)
skips elements until n
elements are skipped or the end of the
iterator is reached (whichever happens first). After that, all the
remaining elements are yielded. In particular, if the original iterator is
too short, then the returned iterator is empty.
Creates an iterator that skips elements based on a predicate.
skip_while() takes a closure as an argument. It will call this closure on each element of the iterator, and ignore elements until it returns false.
After false is returned, the closure is not called again, and the remaining elements are all yielded.
Creates an iterator starting at the same point, but stepping by the given amount at each iteration.
The first element of the iterator will always be returned, regardless of the step given. After that, skipped elements will be lazily walked over as needed.
step_by()
behaves like the sequence next()
, nth(step-1)
,
self.nth(step-1)
, ...
Panics
The step
must be greater than 0, or the function will panic. A step size
of 1 returns every element.
sus::iter::IntoIteratorAny<Other>
sus::cmp::StrongOrd<ItemT, OtherItem>
sus::iter::IntoIteratorAny<Other>
sus::cmp::StrongOrd<Item, OtherItem>
Lexicographically
compares the elements of this Iterator
with those of another.
Strong ordering requires each item being compared that compares equal to
share the same identity (be replaceable). Typically Ord
is
sufficient, which is required for cmp()
and cmp_by()
, where items that
compare equivalent may still have different internal state.
The comparison works like short-circuit evaluation, returning a result without comparing the remaining elements. As soon as an order can be determined, the evaluation stops and a result is returned.
sus::iter::IntoIteratorAny<Other>
Lexicographically
compares the elements of this Iterator
with those of another with
respect to the specified comparison function.
Sums the elements of an iterator.
Takes each element, adds them together, and returns the result.
An empty iterator returns the zero value of the type.
sum()
can be used to multiply any type implementing
Sum
,
including numerics, Option
and
Result
.
Panics
/
When calling sum()
and a primitive integer type is being returned,
method will panic if the computation overflows.
Using sum<OverflowInteger<T>>()
will allow the caller to handle overflow
without a panic.
Creates an iterator that yields the first n
elements, or fewer if the
underlying iterator ends sooner.
take(n)
yields elements until n
elements are yielded or the end of the
iterator is reached (whichever happens first). The returned iterator is a
prefix of length n
if the original iterator contains at least n
elements, otherwise it contains all of the (fewer than n
) elements of
the original iterator.
Creates an iterator that yields elements based on a predicate.
take_while()
takes a closure as an argument. It will call this closure
on each element of the iterator, and yield elements while it returns
true
.
After false is returned, the closure is not called again, and the remaining elements will not be yielded.
sus::ops::Try<ItemT>
sus::iter::FromIterator<C, ::sus::ops::TryOutputType<ItemT>>
!std::is_void_v<::sus::ops::TryOutputType<ItemT>>
sus::ops::Try<Item>
sus::iter::FromIterator<C, ::sus::ops::TryOutputType<Item>>
!std::is_void_v<::sus::ops::TryOutputType<Item>>
Fallibly transforms an iterator into a collection, short circuiting if a failure is encountered.
try_collect()
is a variation of collect()
that allows fallible
conversions during collection. Its main use case is simplifying
conversions from iterators yielding Option<T>
into
Option<Collection<T>>
, or similarly for other Try types (e.g. Result
or std::optional
).
Importantly, try_collect()
doesn’t require that the outer Try
type
also implements FromIterator; only the Try
type's Output
type must
implement it. Concretely, this means that collecting into
TryThing<Vec<i32>, _>
can be valid because Vec<i32>
implements
FromIterator, even if TryThing
doesn’t.
Also, if a failure is encountered during try_collect()
, the iterator is
still valid and may continue to be used, in which case it will continue
iterating starting after the element that triggered the failure. See the
last example below for an example of how this works.
Examples
Successfully collecting an iterator of Option<i32>
into
Option<Vec<i32>>
:
auto u = Vec<Option<i32>>(some(1), some(2), some(3));
auto v = sus::move(u).into_iter().try_collect<Vec<i32>>();
sus_check(v == some(Vec<i32>(1, 2, 3 )));
Failing to collect in the same way:
auto u = Vec<Option<i32>>(some(1), some(2), none(), some(3));
auto v = sus::move(u).into_iter().try_collect<Vec<i32>>();
sus_check(v == none());
A similar example, but with Result
:
enum Error { ERROR };
auto u = Vec<Result<i32, Error>>(ok(1), ok(2), ok(3));
auto v = sus::move(u).into_iter().try_collect<Vec<i32>>();
sus_check(v == ok(Vec<i32>(1, 2, 3)));
auto w = Vec<Result<i32, Error>>(ok(1), ok(2), err(ERROR), ok(3));
auto x = sus::move(w).into_iter().try_collect<Vec<i32>>();
sus_check(x == err(ERROR));
This function acts like fold()
but the closure returns a type that
satisfies sus::ops::Try
and which converts to the accumulator type on
success through the Try concept. If the closure ever returns failure, the
fold operation immediately stops and returns the failure
(short-circuiting).
See fold()
for more on how to use this function.
Unlike fold()
this function may be used on an iterator without fully
consuming it, since it can stop iterating early.
Also unlike fold()
the sus::ops::Try
concept limits the accumulator
value to not being a reference.
sus::fn::FnMut<F, ::sus::fn::NonVoid (ItemT)>
sus::ops::TryDefault<R>
sus::fn::FnMut<F, ::sus::fn::NonVoid (Item)>
sus::ops::TryDefault<R>
An iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error.
This can also be thought of as the fallible form of for_each()
or as the
stateless version of try_fold()
.
The closure must return a type that satisfies sus::ops::Try
Default. For
each success value returned, the iteration will continue. When a failure
is returned from the closure, iteration will stop and the failure will be
returned from for_each()
. On success, the default success value of the
TryDefault
is returned.
Unlike for_each()
this function may be used on an iterator without fully
consuming it, since it can stop iterating early.
sus::fn::FnMut<F, ::sus::fn::NonVoid (B, ItemT)>
sus::iter::DoubleEndedIterator<Iter, ItemT>
sus::ops::Try<R>
std::convertible_to<typename ::sus::ops::TryImpl<R>::Output, B>
sus::fn::FnMut<F, ::sus::fn::NonVoid (B, Item)>
sus::iter::DoubleEndedIterator<Iter, Item>
sus::ops::Try<R>
std::convertible_to<typename ::sus::ops::TryImpl<R>::Output, B>
This is the reverse version of
Iterator::try_fold()
: it
takes elements starting from the back of the iterator.
::sus::option::__private::IsTupleOfSizeTwo<ItemT>::value
sus::construct::Default<CollectionA>
sus::construct::Default<CollectionB>
sus::iter::Extend<CollectionA, ItemA>
sus::iter::Extend<CollectionB, ItemB>
::sus::option::__private::IsTupleOfSizeTwo<Item>::value
sus::construct::Default<CollectionA>
sus::construct::Default<CollectionB>
sus::iter::Extend<CollectionA, ItemA>
sus::iter::Extend<CollectionB, ItemB>
Converts an iterator of pairs into a pair of collections.
unzip()
consumes an entire iterator of pairs, producing two collections:
one from the left elements of the pairs, and one from the right elements.
This function is, in some sense, the opposite of zip()
.
"Zips up" two iterators into a single iterator of pairs.
zip()
returns a new iterator that will iterate over two other iterators,
returning a tuple where the first element comes from the first iterator,
and the second element comes from the second iterator.
In other words, it zips two iterators together, into a single one.
If either iterator returns None
, next()
from the zipped iterator will
return None
. If the zipped iterator has returned None
, further calls
to next()
will try advance both iterators, and if either returns None
the zipped iterator will continue to return None
. The zipped iterator is
not fused if both iterators are not fused, and both resume returning
values.
To "undo" the result of zipping up two iterators, see unzip.