Trait chd::iter::LendingIterator
source · pub trait LendingIterator: for<'next> LendingIteratorඞItem<'next> {
Show 27 methods
// Required method
fn next(&mut self) -> Option<Self::T>;
// Provided methods
fn filter<F>(self, should_yield: F) -> Filter<Self, F>
where Self: Sized,
F: FnMut(&Self::T) -> bool { ... }
fn for_each(self, f: impl FnMut(Self::T))
where Self: Sized { ... }
fn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Acc) -> Acc
where Self: Sized { ... }
fn try_for_each<Err>(
&mut self,
f: impl FnMut(Self::T) -> Result<(), Err>
) -> Result<(), Err> { ... }
fn try_fold<Acc, Err>(
&mut self,
acc: Acc,
f: impl FnMut(Acc, Self::T) -> Result<Acc, Err>
) -> Result<Acc, Err> { ... }
fn all(&mut self, predicate: impl FnMut(Self::T) -> bool) -> bool
where Self: Sized { ... }
fn any(&mut self, predicate: impl FnMut(Self::T) -> bool) -> bool
where Self: Sized { ... }
fn by_ref(&mut self) -> &mut Self
where Self: Sized { ... }
fn count(self) -> usize
where Self: Sized { ... }
fn find<'find>(
&'find mut self,
predicate: impl FnMut(&Self::T) -> bool + 'find
) -> Option<Self::T>
where Self: Sized { ... }
fn fuse(self) -> Fuse<Self>
where Self: Sized { ... }
fn nth(&mut self, n: usize) -> Option<Self::T> { ... }
fn position<F>(
&mut self,
predicate: impl FnMut(Self::T) -> bool
) -> Option<usize>
where Self: Sized { ... }
fn skip(self, count: usize) -> Skip<Self>
where Self: Sized { ... }
fn take(self, count: usize) -> Take<Self>
where Self: Sized { ... }
fn map<NewItemType, F>(self, f: F) -> Map<Self, F, NewItemType>
where NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> <NewItemType as WithLifetime<'next>>::T,
Self: Sized { ... }
fn map_to_ref<R, F>(
self,
f: F
) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
where F: for<'any> FnMut([&'any Self; 0], Self::T) -> &'any R,
Self: Sized,
R: ?Sized { ... }
fn map_to_mut<R, F>(
self,
f: F
) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
where F: for<'any> FnMut([&'any Self; 0], Self::T) -> &'any mut R,
Self: Sized,
R: ?Sized { ... }
fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F>
where F: FnMut(Self::T) -> NonLendingItem,
Self: Sized { ... }
fn filter_map<NewItemType, F>(self, f: F) -> FilterMap<Self, F, NewItemType>
where NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> Option<<NewItemType as WithLifetime<'next>>::T>,
Self: Sized { ... }
fn filter_map_to_ref<R, F>(
self,
f: F
) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
where F: for<'any> FnMut([&'any Self; 0], Self::T) -> Option<&'any R>,
Self: Sized,
R: ?Sized { ... }
fn filter_map_to_mut<R, F>(
self,
f: F
) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
where F: for<'any> FnMut([&'any Self; 0], Self::T) -> Option<&'any mut R>,
Self: Sized,
R: ?Sized { ... }
fn filter_map_into_iter<F, NonLendingItem>(
self,
f: F
) -> FilterMapIntoIter<Self, F>
where F: FnMut(Self::T) -> Option<NonLendingItem>,
Self: Sized { ... }
fn into_iter<Item>(self) -> IntoIter<Self>
where Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized { ... }
fn dyn_boxed<'usability>(
self
) -> Box<dyn LendingIteratorDyn<Item = HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = Self::T>>> + 'usability>
where Self: 'usability + Sized { ... }
fn dyn_boxed_auto<BoxedDynLendingIterator, Item>(
self
) -> BoxedDynLendingIterator
where Item: HKT,
Self: Sized + DynCoerce<BoxedDynLendingIterator, Item> { ... }
}
unstable_lending_iterators
only.Expand description
A LendingIterator
definition re-exported from the lending-iterator
crate. Provides an lending iterator interface with various adapters
that map to those from Iterator
.
This crate defined LendingIterator
will be replaced once a stabilized trait lands in std
, and should
not be considered stable.
The meat of the crate. Trait similar to Iterator
but for the return
type of the fn next(&'_ mut self)
method being allowed to depend on that
'_
.
Click to hide
-
That type is called the
Item<'_>
type, and is ageneric_associated_type
. -
That difference is crucial both in terms of signature complexity (as this crate’s API ought to prove 😅) and borrowing semantics.
Mainly, when yielded, such Item<'_>
is still &mut
borrowing *self
, so
it won’t be possible to further advance the iterator (or anything else,
for that matter), until the current item is no longer used.
That is: the Item<'_>
s yielded by a LendingIterator
cannot
coëxist!
-
this will thus impose serious usability limitations on it (e.g, no
.collect()
ing whatsoever, since collecting items, by definition, expects them to coëxist (within the collection)).-
For instance, there won’t be a
for item in iter {
sugar on these things, since thatfor
sugar currently only blesses the stdlibIterator
trait.That being said,
while let Some(item) = iter.next() {
works just as well, to be honest.
-
-
but the dual / other side of that API restriction is that it is way simpler / less constraining, for implementors, to implement this trait.
The canonical example illustrating this difference is
windows_mut()
, which is both an intuitive “iterator” we can think of, and yet something for which it is impossible to implementIterator
.
§A Generic Associated Type
The core definition of this trait is thus:
-
ⓘ
#![feature(generic_associated_types)] trait LendingIterator { type Item<'next> where Self : 'next, ; fn next<'next> ( self: &'next mut Self, // <- `Self : 'next` indeed! ) -> Option<Self::Item<'next>> ; }
As you can see, it involves that more complex type Item
definition, which
is called a generic associated type (GAT for short), and, it currently
requires the nightly
-only feature(generic_associated_types)
.
–Then how come this crate can work on stable?— you may ask.
The answer is that (lifetime)-GATs can actually be emulated in stable Rust through some extra slightly convoluted hoops.
That’s why this crate uses those techniques (and the crate featuring them,
::nougat
), to achieve Stable Rust support:
-
#[::nougat::gat] // 👈 Add this and now It Just Works™ on stable. trait LendingIterator { type Item<'next> where Self : 'next, ; fn next<'next> ( self: &'next mut Self, ) -> Option<Self::Item<'next>> ; }
It does come with a few caveats, though: the LendingIterator::Item
item
is no longer really nameable, at least not directly.
-
The current implementation of
::nougat
uses a helper higher-order super-trait, calledfor<'any> LendingIteratorඞItem<'any>
, which has, itself, a non-generic associated type,::T
. That way,LendingIteratorඞItem<'next>::T
plays the role ofLendingIterator::Item<'next>
.BUT THIS MAY change within semver-compatible changes of
nougat
That’s why that path should never be used, directly, by downstream code.
The only reason I am even talking about it and not having it
#[doc(hidden)]
is that exposing it makes understanding the signatures of the adapters multiple order of magnitude easier.
Hence the following “rules”:
-
Use
Item<'_, I>
instead ofI::Item<'_>
.-
you could technically import the
Gat!
macro from the::nougat
crate, and then useGat!(I::Item<'_>)
(this is how this crate manages to defineItem
, for instance). But it seems less convenient than a type alias. -
within a
#[gat]
-annotatedtrait
orimpl
, most of the…::Item<'_>
mentions will automagically be amended by the macro (which is why the previous snippet works, despite its usage ofSelf::Item<'next>
).
-
-
If implementing the trait yourself, you need to apply
[#[gat]][crate::gat]
to theimpl
yourself. -
If reëxporting the trait yourself, you need to also apply
[#[gat(Item)]][crate::gat]
to theuse
statement as well, so people can implement the trait through the new path. -
LendingIterator
is not reallydyn
-friendly (although IIUC, withfeature(generic_associated_types)
it wouldn’t have been either).But you can use
dyn LendingIteratorDyn<Item = …> + …
instead, which has been designed withdyn
-friendlyness in mind 🙂.
Required Methods§
sourcefn next(&mut self) -> Option<Self::T>
fn next(&mut self) -> Option<Self::T>
Query the next()
Item
of this Self
iterator.
LendingIterator
counterpart of Iterator::next()
.
Provided Methods§
sourcefn filter<F>(self, should_yield: F) -> Filter<Self, F>
fn filter<F>(self, should_yield: F) -> Filter<Self, F>
LendingIterator
counterpart of Iterator::filter()
.
sourcefn for_each(self, f: impl FnMut(Self::T))where
Self: Sized,
fn for_each(self, f: impl FnMut(Self::T))where
Self: Sized,
LendingIterator
counterpart of Iterator::for_each()
.
sourcefn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Acc) -> Accwhere
Self: Sized,
fn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Acc) -> Accwhere
Self: Sized,
LendingIterator
counterpart of Iterator::fold()
.
sourcefn try_for_each<Err>(
&mut self,
f: impl FnMut(Self::T) -> Result<(), Err>
) -> Result<(), Err>
fn try_for_each<Err>( &mut self, f: impl FnMut(Self::T) -> Result<(), Err> ) -> Result<(), Err>
LendingIterator
counterpart of Iterator::try_for_each()
.
sourcefn try_fold<Acc, Err>(
&mut self,
acc: Acc,
f: impl FnMut(Acc, Self::T) -> Result<Acc, Err>
) -> Result<Acc, Err>
fn try_fold<Acc, Err>( &mut self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Result<Acc, Err> ) -> Result<Acc, Err>
LendingIterator
counterpart of Iterator::try_fold()
.
sourcefn all(&mut self, predicate: impl FnMut(Self::T) -> bool) -> boolwhere
Self: Sized,
fn all(&mut self, predicate: impl FnMut(Self::T) -> bool) -> boolwhere
Self: Sized,
LendingIterator
counterpart of Iterator::all()
.
sourcefn any(&mut self, predicate: impl FnMut(Self::T) -> bool) -> boolwhere
Self: Sized,
fn any(&mut self, predicate: impl FnMut(Self::T) -> bool) -> boolwhere
Self: Sized,
LendingIterator
counterpart of Iterator::any()
.
sourcefn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
LendingIterator
counterpart of Iterator::by_ref()
.
sourcefn count(self) -> usizewhere
Self: Sized,
fn count(self) -> usizewhere
Self: Sized,
LendingIterator
counterpart of Iterator::count()
.
sourcefn find<'find>(
&'find mut self,
predicate: impl FnMut(&Self::T) -> bool + 'find
) -> Option<Self::T>where
Self: Sized,
fn find<'find>(
&'find mut self,
predicate: impl FnMut(&Self::T) -> bool + 'find
) -> Option<Self::T>where
Self: Sized,
LendingIterator
counterpart of Iterator::find()
.
sourcefn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
LendingIterator
counterpart of Iterator::fuse()
.
sourcefn nth(&mut self, n: usize) -> Option<Self::T>
fn nth(&mut self, n: usize) -> Option<Self::T>
LendingIterator
counterpart of Iterator::nth()
.
sourcefn position<F>(
&mut self,
predicate: impl FnMut(Self::T) -> bool
) -> Option<usize>where
Self: Sized,
fn position<F>(
&mut self,
predicate: impl FnMut(Self::T) -> bool
) -> Option<usize>where
Self: Sized,
LendingIterator
counterpart of Iterator::position()
.
sourcefn skip(self, count: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, count: usize) -> Skip<Self>where
Self: Sized,
LendingIterator
counterpart of Iterator::skip()
.
sourcefn take(self, count: usize) -> Take<Self>where
Self: Sized,
fn take(self, count: usize) -> Take<Self>where
Self: Sized,
LendingIterator
counterpart of Iterator::take()
.
sourcefn map<NewItemType, F>(self, f: F) -> Map<Self, F, NewItemType>where
NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> <NewItemType as WithLifetime<'next>>::T,
Self: Sized,
fn map<NewItemType, F>(self, f: F) -> Map<Self, F, NewItemType>where
NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> <NewItemType as WithLifetime<'next>>::T,
Self: Sized,
LendingIterator
counterpart of Iterator::map()
.
-
Turbofishing the
NewItemType
is mandatory, otherwise you’ll run into issues with non-higher-order closures.See the module-level documentation of
crate::higher_kinded_types
for more info.But the TL,DR is that you’d use it as:
lending_iter.map::<HKT!(ReturnType<'_>), _>(
-
the second idiosyncracy is that, for technical reasons1 related to the maximally generic aspect of this API, the closure itself cannot just be a
Self::Item<'_> -> Feed<'_, NewItemType>
closure, and instead, requires that an extra[]
dummy parameter be part of the signature:lending_iter.map::<HKT…, _>(|[], item| { … }) 👆
In the case where
Self::Item<'_>
does not depend on'_
, the return type then technically can’t depend on it either, so Rust complains about this (in a rather obtuse fashion). We solve this by requiring that extra[]
parameter which acts as a convenient-to-writePhantomData
which does depend on'_
. ↩
sourcefn map_to_ref<R, F>(
self,
f: F
) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
fn map_to_ref<R, F>( self, f: F ) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
sourcefn map_to_mut<R, F>(
self,
f: F
) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
fn map_to_mut<R, F>( self, f: F ) -> Map<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
sourcefn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F>
fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F>
Convenience shorthand for
.map…(…).into_iter()
.
When the return type of the .map()
closure is not lending
/ borrowing from *self
, it becomes possible to call
.into_iter() on it right away.
Moreover, it makes the [],
closure arg hack no longer necessary.
This convenience function encompasses both things, thence returning
an Iterator
(not a LendingIterator
!).
sourcefn filter_map<NewItemType, F>(self, f: F) -> FilterMap<Self, F, NewItemType>where
NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> Option<<NewItemType as WithLifetime<'next>>::T>,
Self: Sized,
fn filter_map<NewItemType, F>(self, f: F) -> FilterMap<Self, F, NewItemType>where
NewItemType: HKT,
F: for<'next> FnMut([&'next Self; 0], Self::T) -> Option<<NewItemType as WithLifetime<'next>>::T>,
Self: Sized,
LendingIterator
counterpart of Iterator::filter_map()
.
All the caveats and remarks of .map()
apply, go check
them up.
sourcefn filter_map_to_ref<R, F>(
self,
f: F
) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
fn filter_map_to_ref<R, F>( self, f: F ) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ R>>>
Convenience method: same as
.filter_map()
, but for hard-coding the
HKT
parameter to HKTRef<R> = HKT!(&R)
.
All the caveats and remarks of
.map_to_ref()
apply, go check them up.
sourcefn filter_map_to_mut<R, F>(
self,
f: F
) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
fn filter_map_to_mut<R, F>( self, f: F ) -> FilterMap<Self, F, HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = &'ඞ mut R>>>
Convenience method: same as
.filter_map()
, but for hard-coding the
HKT
parameter to HKTRefMut<R> = HKT!(&mut R)
.
All the caveats and remarks of
.map_to_mut()
apply, go check them up.
sourcefn filter_map_into_iter<F, NonLendingItem>(
self,
f: F
) -> FilterMapIntoIter<Self, F>
fn filter_map_into_iter<F, NonLendingItem>( self, f: F ) -> FilterMapIntoIter<Self, F>
Convenience shorthand for
.filter_map…(…).into_iter()
.
When the return type of the .filter_map()
closure is not lending
/ borrowing from *self
, it becomes possible to call
.into_iter() on it right away.
Moreover, it makes the [],
closure arg hack no longer necessary.
This convenience function encompasses both things, thence returning
an Iterator
(not a LendingIterator
!).
sourcefn into_iter<Item>(self) -> IntoIter<Self>where
Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized,
fn into_iter<Item>(self) -> IntoIter<Self>where
Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized,
Convert a Self : LendingIterator
into an Iterator
,
provided Self::Item<'_>
does not depend on '_
.
sourcefn dyn_boxed<'usability>(
self
) -> Box<dyn LendingIteratorDyn<Item = HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = Self::T>>> + 'usability>where
Self: 'usability + Sized,
fn dyn_boxed<'usability>(
self
) -> Box<dyn LendingIteratorDyn<Item = HKT<dyn for<'ඞ> WithLifetime<'ඞ, T = Self::T>>> + 'usability>where
Self: 'usability + Sized,
Converts this LendingIterator
into a
Box<dyn LendingIteratorDyn…>
.
Note that the return dyn Trait
will not be Send
or implement any
other auto-traits. For a more general albeit harder-on-type-inference
alternative, see .dyn_boxed_auto()
.
sourcefn dyn_boxed_auto<BoxedDynLendingIterator, Item>(
self
) -> BoxedDynLendingIterator
fn dyn_boxed_auto<BoxedDynLendingIterator, Item>( self ) -> BoxedDynLendingIterator
Converts this LendingIterator
into a
Box<dyn LendingIteratorDyn…>
.
In order for it to work, the Item
parameter has to be provided
(probably funneled through a CanonicalHKT
), as well as an explicit
“landing type” (inference will probably fail to figure it out!).
That is, BoxedDynLendingIterator
is expected to be of the form:
Box<dyn 'lt [+ Send] [+ Sync] + LendingIteratorDyn<Item = CanonicalHKT<…>>>
Object Safety§
Implementations on Foreign Types§
source§impl<'r, I> LendingIterator for &'r mut Iwhere
I: LendingIterator + ?Sized,
impl<'r, I> LendingIterator for &'r mut Iwhere
I: LendingIterator + ?Sized,
source§impl<'r, I> LendingIterator for Pin<&'r mut I>
impl<'r, I> LendingIterator for Pin<&'r mut I>
source§impl<I> LendingIterator for Box<I>where
I: LendingIterator + ?Sized,
impl<I> LendingIterator for Box<I>where
I: LendingIterator + ?Sized,
source§impl<I> LendingIterator for Pin<Box<I>>
impl<I> LendingIterator for Pin<Box<I>>
Implementors§
impl<'a, F: Read + Seek> LendingIterator for Hunks<'a, F>
impl<'a, F: Read + Seek> LendingIterator for MetadataEntries<'a, F>
impl<'lt, T, const WINDOW_SIZE: usize> LendingIterator for WindowsMut<&'lt mut [T], WINDOW_SIZE>
impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + 'usabilitywhere
Item: HKT,
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + 'usabilitywhere
Item: HKT,
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + 'usabilitywhere
Item: HKT,
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + Send + 'usabilitywhere
Item: HKT,
dyn LendingIteratorDyn + … : LendingIterator