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}