gat_lending_iterator/traits/
lending_iterator.rs

1use core::cmp::Ordering;
2use std::{num::NonZeroUsize, ops::Deref};
3
4use crate::{
5    Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse, Inspect, Map, MapWhile,
6    OptionTrait, Scan, SingleArgFnMut, SingleArgFnOnce, Skip, SkipWhile, StepBy, Take, TakeWhile,
7    Zip,
8};
9
10/// Like [`Iterator`], but items may borrow from `&mut self`.
11///
12/// This means that the compiler will check that you finish using an item
13/// before requesting the next item, as it's not allowed for two `&mut self` to exist
14/// at the same time.
15pub trait LendingIterator {
16    /// The type of the elements being iterated over.
17    type Item<'a>
18    where
19        Self: 'a;
20
21    /// Advances the lending iterator and returns the next value.
22    ///
23    /// See [`Iterator::next`].
24    fn next(&mut self) -> Option<Self::Item<'_>>;
25
26    /// Returns the bounds on the remaining length of the iterator.
27    ///
28    /// See [`Iterator::size_hint`].
29    #[inline]
30    fn size_hint(&self) -> (usize, Option<usize>) {
31        (0, None)
32    }
33
34    /// Returns the number of items in the lending iterator.
35    ///
36    /// See [`Iterator::count`].
37    #[inline]
38    fn count(self) -> usize
39    where
40        Self: Sized,
41    {
42        self.fold(0, |count, _| count + 1)
43    }
44
45    /// Advances the lending iterator by `n` elements.
46    ///
47    /// See [`Iterator::advance_by`].
48    #[inline]
49    #[allow(clippy::missing_errors_doc)]
50    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
51        for i in 0..n {
52            if self.next().is_none() {
53                // SAFETY: `i` is always less than `n`.
54                return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
55            }
56        }
57        Ok(())
58    }
59
60    /// Returns the `n`th element of the lending iterator.
61    ///
62    /// See [`Iterator::nth`].
63    #[inline]
64    fn nth(&mut self, n: usize) -> Option<Self::Item<'_>> {
65        self.advance_by(n).ok()?;
66        self.next()
67    }
68
69    /// Creates a lending iterator starting at the same point, but stepping by
70    /// the given amount at each iteration.
71    ///
72    /// See [`Iterator::step_by`].
73    #[inline]
74    fn step_by(self, step: usize) -> StepBy<Self>
75    where
76        Self: Sized,
77    {
78        StepBy::new(self, step)
79    }
80
81    /// Creates a lending iterator that lends the first `n` elements, or fewer
82    /// if the underlying iterator ends sooner.
83    ///
84    /// See [`Iterator::take`].
85    #[inline]
86    fn take(self, n: usize) -> Take<Self>
87    where
88        Self: Sized,
89    {
90        Take::new(self, n)
91    }
92
93    /// Creates a lending iterator that lends items matching a predicate.
94    ///
95    /// The predicate is called once for every item.
96    /// Once it returns false once, `None` is returned for all subsequent calls to [`next`].
97    ///
98    /// [`next`]: Self::next
99    #[inline]
100    fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
101    where
102        Self: Sized,
103        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
104    {
105        TakeWhile::new(self, predicate)
106    }
107
108    /// Takes two lending iterators and creates a new lending iterator over both in sequence.
109    ///
110    /// See [`Iterator::chain`].
111    #[inline]
112    fn chain<I>(self, other: I) -> Chain<Self, I>
113    where
114        Self: Sized,
115        for<'a> I: LendingIterator<Item<'a> = Self::Item<'a>> + 'a,
116    {
117        Chain::new(self, other)
118    }
119
120    /// 'Zips up' two lending iterators into a single lending iterator of pairs.
121    #[inline]
122    fn zip<I>(self, other: I) -> Zip<Self, I>
123    where
124        Self: Sized,
125        I: LendingIterator,
126    {
127        Zip::new(self, other)
128    }
129
130    /// Takes a closure and creates a lending iterator which calls that closure on each
131    /// element.
132    ///
133    /// As of writing, in stable rust it's not possible to create a closure
134    /// where the lifetime of its output is tied to its input.
135    /// If you're on nightly, you can use the unstable
136    /// `closure_lifetime_binder` feature. If you're on stable, try using
137    /// a function.
138    ///
139    /// In the case that the closure's return type doesn't borrow from its input,
140    /// the resulting `LendingIterator` will implement [`IntoIterator`].
141    ///
142    /// See [`Iterator::map`].
143    #[inline]
144    fn map<F>(self, f: F) -> Map<Self, F>
145    where
146        Self: Sized,
147        F: for<'a> SingleArgFnMut<Self::Item<'a>>,
148    {
149        Map::new(self, f)
150    }
151
152    /// Calls a closure on each element of the lending iterator.
153    ///
154    /// See [`Iterator::for_each`].
155    #[inline]
156    fn for_each<F>(mut self, mut f: F)
157    where
158        Self: Sized,
159        F: FnMut(Self::Item<'_>),
160    {
161        while let Some(item) = self.next() {
162            f(item);
163        }
164    }
165
166    /// Creates a lending iterator which uses a closure to determine if an element
167    /// should be yielded.
168    ///
169    /// See [`Iterator::filter`].
170    #[inline]
171    fn filter<P>(self, predicate: P) -> Filter<Self, P>
172    where
173        Self: Sized,
174        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
175    {
176        Filter::new(self, predicate)
177    }
178
179    /// Creates a lending iterator that both filters and maps.
180    ///
181    /// See [`Iterator::filter_map`].
182    #[inline]
183    fn filter_map<F>(self, f: F) -> FilterMap<Self, F>
184    where
185        Self: Sized,
186        F: for<'a> SingleArgFnMut<Self::Item<'a>>,
187        for<'a> <F as SingleArgFnOnce<Self::Item<'a>>>::Output: OptionTrait,
188    {
189        FilterMap::new(self, f)
190    }
191
192    /// Folds every element into an accumulator by applying an operation,
193    /// returning the final result.
194    ///
195    /// See [`Iterator::fold`].
196    #[inline]
197    fn fold<B, F>(mut self, init: B, mut f: F) -> B
198    where
199        Self: Sized,
200        F: FnMut(B, Self::Item<'_>) -> B,
201    {
202        let mut accum = init;
203        while let Some(x) = self.next() {
204            accum = f(accum, x);
205        }
206        accum
207    }
208
209    /// Creates a lending iterator which [`clone`]s all of its elements.
210    ///
211    /// The resulting lending iterator implements [`IntoIterator`].
212    ///
213    /// See [`Iterator::cloned`].
214    ///
215    /// [`clone`]: Clone::clone
216    fn cloned<T>(self) -> Cloned<Self>
217    where
218        Self: Sized,
219        for<'a> Self::Item<'a>: Deref<Target = T>,
220        T: Clone,
221    {
222        Cloned::new(self)
223    }
224
225    /// Creates a lending iterator which copies all of its elements.
226    ///
227    /// The resulting lending iterator implements [`IntoIterator`].
228    ///
229    /// See [`Iterator::copied`].
230    #[inline]
231    fn copied<T>(self) -> Copied<Self>
232    where
233        Self: Sized,
234        for<'a> Self::Item<'a>: Deref<Target = T>,
235        T: Copy,
236    {
237        Copied::new(self)
238    }
239
240    /// Creates a lending iterator which gives the current iteration count as well as the next value.
241    #[inline]
242    fn enumerate(self) -> Enumerate<Self>
243    where
244        Self: Sized,
245    {
246        Enumerate::new(self)
247    }
248
249    /// Creates a lending iterator that skips over the first `n` elements of self.
250    #[inline]
251    fn skip(self, n: usize) -> Skip<Self>
252    where
253        Self: Sized,
254    {
255        Skip::new(self, n)
256    }
257
258    /// Creates a lending iterator that rejects elements while `predicate` returns `true`.
259    #[inline]
260    fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
261    where
262        Self: Sized,
263        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
264    {
265        SkipWhile::new(self, predicate)
266    }
267
268    /// Creates a lending iterator that yields the current element unchanged,
269    /// while calling a provided function with a reference to that element.
270    ///
271    /// See [`Iterator::inspect`].
272    #[inline]
273    fn inspect<F>(self, f: F) -> Inspect<Self, F>
274    where
275        Self: Sized,
276        F: for<'a> FnMut(&Self::Item<'a>),
277    {
278        Inspect::new(self, f)
279    }
280
281    /// Creates a lending iterator that yields elements transformed by a stateful closure.
282    ///
283    /// See [`Iterator::scan`].
284    #[inline]
285    fn scan<St, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
286    where
287        Self: Sized,
288    {
289        Scan::new(self, initial_state, f)
290    }
291
292    /// Creates a lending iterator that yields elements while the predicate returns `Some`.
293    ///
294    /// See [`Iterator::map_while`].
295    #[inline]
296    fn map_while<F>(self, f: F) -> MapWhile<Self, F>
297    where
298        Self: Sized,
299        F: for<'a> SingleArgFnMut<Self::Item<'a>>,
300        for<'a> <F as SingleArgFnOnce<Self::Item<'a>>>::Output: OptionTrait,
301    {
302        MapWhile::new(self, f)
303    }
304
305    /// Creates a lending iterator that yields `None` forever after the
306    /// underlying iterator yields `None` once.
307    ///
308    /// See [`Iterator::fuse`].
309    #[inline]
310    fn fuse(self) -> Fuse<Self>
311    where
312        Self: Sized,
313    {
314        Fuse::new(self)
315    }
316
317    /// Creates a lending iterator that repeats elements endlessly by cloning the iterator.
318    ///
319    /// See [`Iterator::cycle`].
320    #[inline]
321    fn cycle(self) -> Cycle<Self>
322    where
323        Self: Sized + Clone,
324    {
325        Cycle::new(self)
326    }
327
328    /// Borrows the lending iterator.
329    ///
330    /// This is useful to allow applying iterator adapters while still
331    /// retaining ownership of the original iterator.
332    ///
333    /// Unfortunately adapters that take in a closure are currently
334    /// incompatible with this, due to limitations in the borrow checker.
335    #[inline]
336    fn by_ref(&mut self) -> &mut Self
337    where
338        Self: Sized,
339    {
340        self
341    }
342
343    /// Tests if every element of the iterator matches a predicate.
344    #[inline]
345    fn all<P>(&mut self, mut predicate: P) -> bool
346    where
347        P: FnMut(Self::Item<'_>) -> bool,
348    {
349        while let Some(item) = self.next() {
350            if !predicate(item) {
351                return false;
352            }
353        }
354        true
355    }
356
357    /// Tests if any element of the iterator matches a predicate.
358    #[inline]
359    fn any<P>(&mut self, mut predicate: P) -> bool
360    where
361        P: FnMut(Self::Item<'_>) -> bool,
362    {
363        while let Some(item) = self.next() {
364            if predicate(item) {
365                return true;
366            }
367        }
368        false
369    }
370
371    /// Checks if the elements of this iterator are partitioned according to the given predicate,
372    /// such that all those that return `true` precede all those that return `false`.
373    #[inline]
374    #[allow(clippy::wrong_self_convention)]
375    fn is_partitioned<P>(mut self, mut predicate: P) -> bool
376    where
377        Self: Sized,
378        P: FnMut(Self::Item<'_>) -> bool,
379    {
380        while let Some(item) = self.next() {
381            if !predicate(item) {
382                break;
383            }
384        }
385        while let Some(item) = self.next() {
386            if predicate(item) {
387                return false;
388            }
389        }
390        true
391    }
392
393    /// Searches for an element of an iterator that satisfies a predicate.
394    #[inline]
395    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item<'_>>
396    where
397        P: FnMut(&Self::Item<'_>) -> bool,
398    {
399        loop {
400            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
401            let self_ = unsafe { &mut *(self as *mut Self) };
402            if let Some(item) = self_.next() {
403                if (predicate)(&item) {
404                    return Some(item);
405                }
406            } else {
407                return None;
408            }
409        }
410    }
411
412    /// Applies function to the elements of iterator and returns
413    /// the first non-none result.
414    #[inline]
415    fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
416    where
417        F: FnMut(Self::Item<'_>) -> Option<B>,
418    {
419        loop {
420            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
421            let self_ = unsafe { &mut *(self as *mut Self) };
422            if let Some(item) = self_.next() {
423                if let Some(result) = f(item) {
424                    return Some(result);
425                }
426            } else {
427                return None;
428            }
429        }
430    }
431
432    /// Searches for an element in an iterator, returning its index.
433    #[inline]
434    fn position<P>(&mut self, mut predicate: P) -> Option<usize>
435    where
436        P: FnMut(Self::Item<'_>) -> bool,
437    {
438        let mut i = 0;
439        while let Some(item) = self.next() {
440            if predicate(item) {
441                return Some(i);
442            }
443            i += 1;
444        }
445        None
446    }
447
448    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
449    /// of another.
450    fn cmp<I>(mut self, mut other: I) -> Ordering
451    where
452        I: for<'a> LendingIterator<Item<'a> = Self::Item<'a>>,
453        for<'a> Self::Item<'a>: Ord,
454        Self: Sized,
455    {
456        // TODO: this could be implemented as `self.cmp_by(other, |x, y| x.cmp(y))`
457        // except that doesn't type check due to lifetime issues.
458        loop {
459            match (self.next(), other.next()) {
460                (Some(x), Some(y)) => match x.cmp(&y) {
461                    Ordering::Equal => {}
462                    non_eq => return non_eq,
463                },
464                (None, None) => return Ordering::Equal,
465                (None, _) => return Ordering::Less,
466                (_, None) => return Ordering::Greater,
467            }
468        }
469    }
470
471    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
472    /// of another with respect to the specified comparison function.
473    fn cmp_by<I, F>(mut self, mut other: I, mut cmp: F) -> Ordering
474    where
475        Self: Sized,
476        I: LendingIterator,
477        F: FnMut(Self::Item<'_>, I::Item<'_>) -> Ordering,
478    {
479        loop {
480            match (self.next(), other.next()) {
481                (Some(x), Some(y)) => match cmp(x, y) {
482                    Ordering::Equal => {}
483                    non_eq => return non_eq,
484                },
485                (None, None) => return Ordering::Equal,
486                (None, _) => return Ordering::Less,
487                (_, None) => return Ordering::Greater,
488            }
489        }
490    }
491
492    /// [Lexicographically](Ord#lexicographical-comparison) compares the [`PartialOrd`] elements of
493    /// this [`Iterator`] with those of another. The comparison works like short-circuit
494    /// evaluation, returning a result without comparing the remaining elements.
495    /// As soon as an order can be determined, the evaluation stops and a result is returned.
496    fn partial_cmp<I>(mut self, mut other: I) -> Option<Ordering>
497    where
498        I: LendingIterator,
499        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
500        Self: Sized,
501    {
502        loop {
503            match (self.next(), other.next()) {
504                (Some(x), Some(y)) => match x.partial_cmp(&y) {
505                    Some(Ordering::Equal) => {}
506                    non_eq => return non_eq,
507                },
508                (None, None) => return Some(Ordering::Equal),
509                (None, _) => return Some(Ordering::Less),
510                (_, None) => return Some(Ordering::Greater),
511            }
512        }
513    }
514
515    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
516    /// of another with respect to the specified comparison function.
517    fn partial_cmp_by<I, F>(mut self, mut other: I, mut partial_cmp: F) -> Option<Ordering>
518    where
519        Self: Sized,
520        I: LendingIterator,
521        F: FnMut(Self::Item<'_>, I::Item<'_>) -> Option<Ordering>,
522    {
523        loop {
524            match (self.next(), other.next()) {
525                (Some(x), Some(y)) => match partial_cmp(x, y) {
526                    Some(Ordering::Equal) => {}
527                    non_eq => return non_eq,
528                },
529                (None, None) => return Some(Ordering::Equal),
530                (None, _) => return Some(Ordering::Less),
531                (_, None) => return Some(Ordering::Greater),
532            }
533        }
534    }
535
536    /// Determines if the elements of this [`Iterator`] are equal to those of
537    /// another.
538    fn eq<I>(mut self, mut other: I) -> bool
539    where
540        I: LendingIterator,
541        for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
542        Self: Sized,
543    {
544        loop {
545            match (self.next(), other.next()) {
546                (Some(x), Some(y)) => {
547                    if x != y {
548                        return false;
549                    }
550                }
551                (None, None) => return true,
552                _ => return false,
553            }
554        }
555    }
556
557    /// Determines if the elements of this [`Iterator`] are equal to those of
558    /// another with respect to the specified equality function.
559    fn eq_by<I, F>(mut self, mut other: I, mut eq: F) -> bool
560    where
561        Self: Sized,
562        I: LendingIterator,
563        F: FnMut(Self::Item<'_>, I::Item<'_>) -> bool,
564    {
565        loop {
566            match (self.next(), other.next()) {
567                (Some(x), Some(y)) => {
568                    if !eq(x, y) {
569                        return false;
570                    }
571                }
572                (None, None) => return true,
573                _ => return false,
574            }
575        }
576    }
577
578    /// Determines if the elements of this [`Iterator`] are not equal to those of
579    /// another.
580    fn ne<I>(self, other: I) -> bool
581    where
582        I: LendingIterator,
583        for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
584        Self: Sized,
585    {
586        !self.eq(other)
587    }
588
589    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
590    /// less than those of another.
591    fn lt<I>(self, other: I) -> bool
592    where
593        I: LendingIterator,
594        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
595        Self: Sized,
596    {
597        self.partial_cmp(other) == Some(Ordering::Less)
598    }
599
600    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
601    /// less or equal to those of another.
602    fn le<I>(self, other: I) -> bool
603    where
604        I: LendingIterator,
605        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
606        Self: Sized,
607    {
608        matches!(
609            self.partial_cmp(other),
610            Some(Ordering::Less | Ordering::Equal)
611        )
612    }
613
614    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
615    /// greater than those of another.
616    fn gt<I>(self, other: I) -> bool
617    where
618        I: LendingIterator,
619        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
620        Self: Sized,
621    {
622        self.partial_cmp(other) == Some(Ordering::Greater)
623    }
624
625    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
626    /// greater or equal to those of another.
627    fn ge<I>(self, other: I) -> bool
628    where
629        I: LendingIterator,
630        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
631        Self: Sized,
632    {
633        matches!(
634            self.partial_cmp(other),
635            Some(Ordering::Greater | Ordering::Equal)
636        )
637    }
638
639    /// Reduces the elements to a single one, by repeatedly applying a reducing
640    /// operation.
641    ///
642    /// If the iterator is empty, returns [`None`]; otherwise, returns the
643    /// result of the reduction.
644    ///
645    /// The reducing function takes an accumulator and an element and returns a new accumulator.
646    /// For lending iterators, since items borrow from `&mut self`, the accumulator must be
647    /// an owned type that doesn't borrow from the iterator.
648    ///
649    /// See [`Iterator::reduce`].
650    #[inline]
651    fn reduce<B, F>(mut self, f: F) -> Option<B>
652    where
653        Self: Sized,
654        F: FnMut(B, Self::Item<'_>) -> B,
655        B: for<'a> From<Self::Item<'a>>,
656    {
657        let first = B::from(self.next()?);
658        Some(self.fold(first, f))
659    }
660
661    /// An iterator method that applies a fallible function to each item in the
662    /// iterator, stopping at the first error and returning that error.
663    ///
664    /// After an error is returned, the iterator may be in an unspecified state.
665    ///
666    /// # Errors
667    ///
668    /// Returns the first error produced by the closure `f`.
669    ///
670    /// See [`Iterator::try_fold`].
671    #[inline]
672    fn try_fold<B, F, E>(&mut self, init: B, mut f: F) -> Result<B, E>
673    where
674        Self: Sized,
675        F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
676    {
677        let mut accum = init;
678        while let Some(x) = self.next() {
679            accum = f(accum, x)?;
680        }
681        Ok(accum)
682    }
683
684    /// An iterator method that applies a fallible function to each item in the
685    /// iterator, stopping at the first error and returning that error.
686    ///
687    /// # Errors
688    ///
689    /// Returns the first error produced by the closure `f`.
690    ///
691    /// See [`Iterator::try_for_each`].
692    #[inline]
693    fn try_for_each<F, E>(&mut self, mut f: F) -> Result<(), E>
694    where
695        Self: Sized,
696        F: FnMut(Self::Item<'_>) -> Result<(), E>,
697    {
698        while let Some(x) = self.next() {
699            f(x)?;
700        }
701        Ok(())
702    }
703
704    /// Applies function to the elements of iterator and returns
705    /// the first true result or the first error.
706    ///
707    /// # Errors
708    ///
709    /// Returns the first error produced by the predicate `f`.
710    ///
711    /// See [`Iterator::try_find`].
712    #[inline]
713    fn try_find<F, R>(&mut self, mut f: F) -> Result<Option<Self::Item<'_>>, R>
714    where
715        Self: Sized,
716        F: FnMut(&Self::Item<'_>) -> Result<bool, R>,
717    {
718        loop {
719            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
720            let self_ = unsafe { &mut *(self as *mut Self) };
721            if let Some(item) = self_.next() {
722                match f(&item) {
723                    Ok(true) => return Ok(Some(item)),
724                    Ok(false) => continue,
725                    Err(e) => return Err(e),
726                }
727            }
728            return Ok(None);
729        }
730    }
731
732    /// Reduces the elements to a single one by repeatedly applying a reducing operation.
733    /// If the closure returns a failure, the failure is propagated back to the caller immediately.
734    ///
735    /// For lending iterators, the accumulator must be an owned type since items borrow from `&mut self`.
736    ///
737    /// # Errors
738    ///
739    /// Returns the first error produced by the reducing closure `f`.
740    ///
741    /// See [`Iterator::try_reduce`].
742    #[inline]
743    fn try_reduce<B, F, E>(mut self, f: F) -> Result<Option<B>, E>
744    where
745        Self: Sized,
746        F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
747        B: for<'a> From<Self::Item<'a>>,
748    {
749        let first = B::from(match self.next() {
750            Some(i) => i,
751            None => return Ok(None),
752        });
753        self.try_fold(first, f).map(Some)
754    }
755
756    /// Returns the maximum element of an iterator.
757    ///
758    /// For lending iterators, items are compared in their borrowed form and only
759    /// converted to the owned type `T` when they become the new maximum, minimizing
760    /// conversions.
761    ///
762    /// See [`Iterator::max`].
763    #[inline]
764    fn max<T>(mut self) -> Option<T>
765    where
766        Self: Sized,
767        T: for<'a> From<Self::Item<'a>>,
768        for<'a> T: PartialOrd<Self::Item<'a>>,
769    {
770        let first = T::from(self.next()?);
771        Some(self.fold(first, |max, x| if max < x { T::from(x) } else { max }))
772    }
773
774    /// Returns the minimum element of an iterator.
775    ///
776    /// For lending iterators, items are compared in their borrowed form and only
777    /// converted to the owned type `T` when they become the new minimum, minimizing
778    /// conversions.
779    ///
780    /// See [`Iterator::min`].
781    #[inline]
782    fn min<T>(mut self) -> Option<T>
783    where
784        Self: Sized,
785        T: for<'a> From<Self::Item<'a>>,
786        for<'a> T: PartialOrd<Self::Item<'a>>,
787    {
788        let first = T::from(self.next()?);
789        Some(self.fold(first, |min, x| if min > x { T::from(x) } else { min }))
790    }
791
792    /// Returns the element that gives the maximum value from the specified function.
793    ///
794    /// For lending iterators, the comparison function operates on borrowed items and owned
795    /// values. Items are only converted to `T` when they become the new maximum.
796    ///
797    /// See [`Iterator::max_by`].
798    #[inline]
799    fn max_by<T, F>(mut self, mut compare: F) -> Option<T>
800    where
801        Self: Sized,
802        F: for<'a> FnMut(&T, &Self::Item<'a>) -> Ordering,
803        T: for<'a> From<Self::Item<'a>>,
804    {
805        let first = T::from(self.next()?);
806        Some(self.fold(first, |max, x| match compare(&max, &x) {
807            Ordering::Less => T::from(x),
808            _ => max,
809        }))
810    }
811
812    /// Returns the element that gives the minimum value from the specified function.
813    ///
814    /// For lending iterators, the comparison function operates on borrowed items and owned
815    /// values. Items are only converted to `T` when they become the new minimum.
816    ///
817    /// See [`Iterator::min_by`].
818    #[inline]
819    fn min_by<T, F>(mut self, mut compare: F) -> Option<T>
820    where
821        Self: Sized,
822        F: for<'a> FnMut(&T, &Self::Item<'a>) -> Ordering,
823        T: for<'a> From<Self::Item<'a>>,
824    {
825        let first = T::from(self.next()?);
826        Some(self.fold(first, |min, x| match compare(&min, &x) {
827            Ordering::Greater => T::from(x),
828            _ => min,
829        }))
830    }
831
832    /// Returns the element that gives the maximum value with respect to the
833    /// specified key function.
834    ///
835    /// For lending iterators, the key function operates on borrowed items. Items are
836    /// only converted to `T` when they produce a new maximum key.
837    ///
838    /// See [`Iterator::max_by_key`].
839    #[inline]
840    fn max_by_key<T, B, F>(mut self, mut f: F) -> Option<T>
841    where
842        Self: Sized,
843        B: Ord,
844        F: for<'a> FnMut(&Self::Item<'a>) -> B,
845        T: for<'a> From<Self::Item<'a>>,
846    {
847        let first_item = self.next()?;
848        let first_key = f(&first_item);
849        let first = T::from(first_item);
850        Some(
851            self.fold((first, first_key), |(max, max_key), x| {
852                let x_key = f(&x);
853                if x_key > max_key {
854                    (T::from(x), x_key)
855                } else {
856                    (max, max_key)
857                }
858            })
859            .0,
860        )
861    }
862
863    /// Returns the element that gives the minimum value with respect to the
864    /// specified key function.
865    ///
866    /// For lending iterators, the key function operates on borrowed items. Items are
867    /// only converted to `T` when they produce a new minimum key.
868    ///
869    /// See [`Iterator::min_by_key`].
870    #[inline]
871    fn min_by_key<T, B, F>(mut self, mut f: F) -> Option<T>
872    where
873        Self: Sized,
874        B: Ord,
875        F: for<'a> FnMut(&Self::Item<'a>) -> B,
876        T: for<'a> From<Self::Item<'a>>,
877    {
878        let first_item = self.next()?;
879        let first_key = f(&first_item);
880        let first = T::from(first_item);
881        Some(
882            self.fold((first, first_key), |(min, min_key), x| {
883                let x_key = f(&x);
884                if x_key < min_key {
885                    (T::from(x), x_key)
886                } else {
887                    (min, min_key)
888                }
889            })
890            .0,
891        )
892    }
893
894    /// Sums the elements of an iterator.
895    ///
896    /// Takes each element, converts it to the sum type, and adds them together.
897    ///
898    /// An empty iterator returns the zero value of the type.
899    ///
900    /// For lending iterators, items must be convertible to the sum type.
901    ///
902    /// See [`Iterator::sum`].
903    #[inline]
904    fn sum<S>(self) -> S
905    where
906        Self: Sized,
907        for<'a> S: std::ops::AddAssign<Self::Item<'a>> + Default,
908    {
909        let mut sum = S::default();
910        self.for_each(|item| sum += item);
911        sum
912    }
913
914    /// Iterates over the entire iterator, multiplying all the elements
915    ///
916    /// An empty iterator returns the multiplicative identity (1).
917    ///
918    /// Unlike [`Iterator::product`], this works directly with borrowed items by requiring
919    /// the product type to implement `MulAssign` for the borrowed item type.
920    ///
921    /// Note: Requires `From<u8>` to create the identity value (1). This works for all
922    /// standard numeric types. For types without this conversion, consider using
923    /// [`fold`](Self::fold) or [`reduce`](Self::reduce) instead.
924    ///
925    /// See [`Iterator::product`].
926    #[inline]
927    fn product<P>(self) -> P
928    where
929        Self: Sized,
930        for<'a> P: std::ops::MulAssign<Self::Item<'a>>,
931        P: From<u8>,
932    {
933        let mut product = P::from(1u8);
934        self.for_each(|item| product *= item);
935        product
936    }
937}
938
939impl<T: LendingIterator> LendingIterator for &mut T {
940    type Item<'a>
941        = T::Item<'a>
942    where
943        Self: 'a;
944
945    #[inline]
946    fn next(&mut self) -> Option<Self::Item<'_>> {
947        (**self).next()
948    }
949
950    #[inline]
951    fn size_hint(&self) -> (usize, Option<usize>) {
952        (**self).size_hint()
953    }
954}