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> { ... }
}
Available on 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 a generic_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 that for sugar currently only blesses the stdlib Iterator 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 implement Iterator.

§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, called for<'any> LendingIteratorඞItem<'any>, which has, itself, a non-generic associated type, ::T. That way, LendingIteratorඞItem<'next>::T plays the role of LendingIterator::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 of I::Item<'_>.

    • you could technically import the Gat! macro from the ::nougat crate, and then use Gat!(I::Item<'_>) (this is how this crate manages to define Item, for instance). But it seems less convenient than a type alias.

    • within a #[gat]-annotated trait or impl, most of the …::Item<'_> mentions will automagically be amended by the macro (which is why the previous snippet works, despite its usage of Self::Item<'next>).

  • If implementing the trait yourself, you need to apply [#[gat]][crate::gat] to the impl yourself.

  • If reëxporting the trait yourself, you need to also apply [#[gat(Item)]][crate::gat] to the use statement as well, so people can implement the trait through the new path.

  • LendingIterator is not really dyn-friendly (although IIUC, with feature(generic_associated_types) it wouldn’t have been either).

    But you can use dyn LendingIteratorDyn<Item = …> + … instead, which has been designed with dyn-friendlyness in mind 🙂.

Required Methods§

source

fn next(&mut self) -> Option<Self::T>

Query the next() Item of this Self iterator.

LendingIterator counterpart of Iterator::next().

Provided Methods§

source

fn filter<F>(self, should_yield: F) -> Filter<Self, F>
where Self: Sized, F: FnMut(&Self::T) -> bool,

source

fn for_each(self, f: impl FnMut(Self::T))
where Self: Sized,

source

fn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Acc) -> Acc
where Self: Sized,

source

fn try_for_each<Err>( &mut self, f: impl FnMut(Self::T) -> Result<(), Err> ) -> Result<(), Err>

source

fn try_fold<Acc, Err>( &mut self, acc: Acc, f: impl FnMut(Acc, Self::T) -> Result<Acc, Err> ) -> Result<Acc, Err>

source

fn all(&mut self, predicate: impl FnMut(Self::T) -> bool) -> bool
where Self: Sized,

source

fn any(&mut self, predicate: impl FnMut(Self::T) -> bool) -> bool
where Self: Sized,

source

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

source

fn count(self) -> usize
where Self: Sized,

source

fn find<'find>( &'find mut self, predicate: impl FnMut(&Self::T) -> bool + 'find ) -> Option<Self::T>
where Self: Sized,

source

fn fuse(self) -> Fuse<Self>
where Self: Sized,

source

fn nth(&mut self, n: usize) -> Option<Self::T>

source

fn position<F>( &mut self, predicate: impl FnMut(Self::T) -> bool ) -> Option<usize>
where Self: Sized,

source

fn skip(self, count: usize) -> Skip<Self>
where Self: Sized,

source

fn take(self, count: usize) -> Take<Self>
where Self: Sized,

source

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| { … })
                                 👆

  1. 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-write PhantomData which does depend on '_

source

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,

Convenience method: same as .map(), but for hard-coding the HKT parameter to HKTRef<R> = HKT!(&R).

This alleviates the call-sites (no more turbofishing needed!) for such pervasive use cases 🙂

source

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,

Convenience method: same as .map(), but for hard-coding the HKT parameter to HKTRefMut<R> = HKT!(&mut R).

This alleviates the call-sites (no more turbofishing needed!) for such pervasive use cases 🙂

source

fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F>
where F: FnMut(Self::T) -> NonLendingItem, Self: Sized,

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!).

source

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.

source

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,

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.

source

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,

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.

source

fn filter_map_into_iter<F, NonLendingItem>( self, f: F ) -> FilterMapIntoIter<Self, F>
where F: FnMut(Self::T) -> Option<NonLendingItem>, Self: Sized,

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!).

source

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 '_.

source

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().

source

fn dyn_boxed_auto<BoxedDynLendingIterator, Item>( self ) -> BoxedDynLendingIterator
where Item: HKT, Self: Sized + DynCoerce<BoxedDynLendingIterator, Item>,

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§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<'r, I> LendingIterator for &'r mut I
where I: LendingIterator + ?Sized,

source§

fn next<'next>( &'next mut self ) -> Option<<&'r mut I as LendingIteratorඞItem<'next>>::T>

source§

impl<'r, I> LendingIterator for Pin<&'r mut I>
where I: LendingIterator + Unpin + ?Sized,

source§

fn next<'next>( &'next mut self ) -> Option<<Pin<&'r mut I> as LendingIteratorඞItem<'next>>::T>

source§

impl<I> LendingIterator for Box<I>
where I: LendingIterator + ?Sized,

source§

fn next<'next>( &'next mut self ) -> Option<<Box<I> as LendingIteratorඞItem<'next>>::T>

source§

impl<I> LendingIterator for Pin<Box<I>>
where I: LendingIterator + Unpin + ?Sized,

source§

fn next<'next>( &'next mut self ) -> Option<<Pin<Box<I>> as LendingIteratorඞItem<'next>>::T>

Implementors§

source§

impl<'a, F: Read + Seek> LendingIterator for Hunks<'a, F>

source§

impl<'a, F: Read + Seek> LendingIterator for MetadataEntries<'a, F>

source§

impl<'lt, T, const WINDOW_SIZE: usize> LendingIterator for WindowsMut<&'lt mut [T], WINDOW_SIZE>

source§

impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + 'usability
where Item: HKT,

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + 'usability
where Item: HKT,

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + 'usability
where Item: HKT,

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + Send + 'usability
where Item: HKT,

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<I> LendingIterator for Fuse<I>
where I: LendingIterator,

source§

impl<I> LendingIterator for Skip<I>
where I: LendingIterator,

source§

impl<I> LendingIterator for Take<I>
where I: LendingIterator,

source§

impl<I> LendingIterator for FromIter<I>
where I: Iterator + ?Sized,

source§

impl<I, F> LendingIterator for Filter<I, F>
where I: LendingIterator, F: FnMut(&<I as LendingIteratorඞItem<'_>>::T) -> bool,

source§

impl<I, NewItemType, F> LendingIterator for FilterMap<I, F, NewItemType>
where I: LendingIterator, NewItemType: HKT, F: for<'any> FnMut([&'any I; 0], <I as LendingIteratorඞItem<'any>>::T) -> Option<<NewItemType as WithLifetime<'any>>::T>,

source§

impl<I, NewItemType, F> LendingIterator for Map<I, F, NewItemType>
where I: LendingIterator, NewItemType: HKT, F: for<'any> FnMut([&'any I; 0], <I as LendingIteratorඞItem<'any>>::T) -> <NewItemType as WithLifetime<'any>>::T,

source§

impl<Item, State, Next> LendingIterator for FromFn<Item, State, Next>
where Item: HKT, Next: FnMut(&mut State) -> Option<<Item as WithLifetime<'_>>::T>,

source§

impl<State> LendingIterator for RepeatMut<State>