1use core::cmp::Ordering;
2use std::{num::NonZeroUsize, ops::Deref};
3
4use crate::{
5 Chain, Cloned, Enumerate, Filter, FilterMap, Map, OptionTrait, SingleArgFnMut, SingleArgFnOnce, Skip, SkipWhile, StepBy, Take, TakeWhile, Zip
6};
7
8pub trait LendingIterator {
14 type Item<'a>
16 where
17 Self: 'a;
18
19 fn next(&mut self) -> Option<Self::Item<'_>>;
23
24 #[inline]
28 fn size_hint(&self) -> (usize, Option<usize>) {
29 (0, None)
30 }
31
32 #[inline]
36 fn count(self) -> usize
37 where
38 Self: Sized,
39 {
40 self.fold(0, |count, _| count + 1)
41 }
42
43 #[inline]
47 #[allow(clippy::missing_errors_doc)]
48 fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
49 for i in 0..n {
50 if self.next().is_none() {
51 return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
53 }
54 }
55 Ok(())
56 }
57
58 #[inline]
62 fn nth(&mut self, n: usize) -> Option<Self::Item<'_>> {
63 self.advance_by(n).ok()?;
64 self.next()
65 }
66
67 #[inline]
72 fn step_by(self, step: usize) -> StepBy<Self>
73 where
74 Self: Sized,
75 {
76 StepBy::new(self, step)
77 }
78
79 #[inline]
84 fn take(self, n: usize) -> Take<Self>
85 where
86 Self: Sized,
87 {
88 Take::new(self, n)
89 }
90
91 #[inline]
98 fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
99 where
100 Self: Sized,
101 P: for<'a> FnMut(&Self::Item<'a>) -> bool,
102 {
103 TakeWhile::new(self, predicate)
104 }
105
106 #[inline]
110 fn chain<I>(self, other: I) -> Chain<Self, I>
111 where
112 Self: Sized,
113 for<'a> I: LendingIterator<Item<'a> = Self::Item<'a>> + 'a,
114 {
115 Chain::new(self, other)
116 }
117
118 #[inline]
120 fn zip<I>(self, other: I) -> Zip<Self, I>
121 where
122 Self: Sized,
123 I: LendingIterator,
124 {
125 Zip::new(self, other)
126 }
127
128 #[inline]
142 fn map<F>(self, f: F) -> Map<Self, F>
143 where
144 Self: Sized,
145 F: for<'a> SingleArgFnMut<Self::Item<'a>>,
146 {
147 Map::new(self, f)
148 }
149
150 #[inline]
154 fn for_each<F>(mut self, mut f: F)
155 where
156 Self: Sized,
157 F: FnMut(Self::Item<'_>),
158 {
159 while let Some(item) = self.next() {
160 f(item);
161 }
162 }
163
164 #[inline]
169 fn filter<P>(self, predicate: P) -> Filter<Self, P>
170 where
171 Self: Sized,
172 P: for<'a> FnMut(&Self::Item<'a>) -> bool,
173 {
174 Filter::new(self, predicate)
175 }
176
177 #[inline]
181 fn filter_map<F>(self, f: F) -> FilterMap<Self, F>
182 where
183 Self: Sized,
184 F: for<'a> SingleArgFnMut<Self::Item<'a>>,
185 for<'a> <F as SingleArgFnOnce<Self::Item<'a>>>::Output: OptionTrait,
186 {
187 FilterMap::new(self, f)
188 }
189
190 #[inline]
195 fn fold<B, F>(mut self, init: B, mut f: F) -> B
196 where
197 Self: Sized,
198 F: FnMut(B, Self::Item<'_>) -> B,
199 {
200 let mut accum = init;
201 while let Some(x) = self.next() {
202 accum = f(accum, x);
203 }
204 accum
205 }
206
207 fn cloned<T>(self) -> Cloned<Self>
215 where
216 Self: Sized,
217 for<'a> Self::Item<'a>: Deref<Target = T>,
218 T: Clone,
219 {
220 Cloned::new(self)
221 }
222
223 #[inline]
225 fn enumerate(self) -> Enumerate<Self>
226 where
227 Self: Sized,
228 {
229 Enumerate::new(self)
230 }
231
232 #[inline]
234 fn skip(self, n: usize) -> Skip<Self>
235 where
236 Self: Sized,
237 {
238 Skip::new(self, n)
239 }
240
241 #[inline]
243 fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
244 where
245 Self: Sized,
246 P: for<'a> FnMut(&Self::Item<'a>) -> bool,
247 {
248 SkipWhile::new(self, predicate)
249 }
250
251 #[inline]
259 fn by_ref(&mut self) -> &mut Self
260 where
261 Self: Sized,
262 {
263 self
264 }
265
266 #[inline]
268 fn all<P>(&mut self, mut predicate: P) -> bool
269 where
270 P: FnMut(Self::Item<'_>) -> bool,
271 {
272 while let Some(item) = self.next() {
273 if !predicate(item) {
274 return false;
275 }
276 }
277 true
278 }
279
280 #[inline]
282 fn any<P>(&mut self, mut predicate: P) -> bool
283 where
284 P: FnMut(Self::Item<'_>) -> bool,
285 {
286 while let Some(item) = self.next() {
287 if predicate(item) {
288 return true;
289 }
290 }
291 false
292 }
293
294 #[inline]
297 #[allow(clippy::wrong_self_convention)]
298 fn is_partitioned<P>(mut self, mut predicate: P) -> bool
299 where
300 Self: Sized,
301 P: FnMut(Self::Item<'_>) -> bool,
302 {
303 while let Some(item) = self.next() {
304 if !predicate(item) {
305 break
306 }
307 }
308 while let Some(item) = self.next() {
309 if predicate(item) {
310 return false
311 }
312 }
313 true
314 }
315
316 #[inline]
318 fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item<'_>>
319 where
320 P: FnMut(&Self::Item<'_>) -> bool,
321 {
322 loop {
323 let self_ = unsafe { &mut *(self as *mut Self) };
325 if let Some(item) = self_.next() {
326 if (predicate)(&item) {
327 return Some(item);
328 }
329 } else {
330 return None;
331 }
332 }
333 }
334
335 #[inline]
338 fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
339 where
340 F: FnMut(Self::Item<'_>) -> Option<B>,
341 {
342 loop {
343 let self_ = unsafe { &mut *(self as *mut Self) };
345 if let Some(item) = self_.next() {
346 if let Some(result) = f(item) {
347 return Some(result);
348 }
349 } else {
350 return None;
351 }
352 }
353 }
354
355 #[inline]
357 fn position<P>(&mut self, mut predicate: P) -> Option<usize>
358 where
359 P: FnMut(Self::Item<'_>) -> bool,
360 {
361 let mut i = 0;
362 while let Some(item) = self.next() {
363 if predicate(item) {
364 return Some(i);
365 }
366 i += 1;
367 }
368 None
369 }
370
371 fn cmp<I>(mut self, mut other: I) -> Ordering
374 where
375 I: for<'a> LendingIterator<Item<'a> = Self::Item<'a>>,
376 for<'a> Self::Item<'a>: Ord,
377 Self: Sized,
378 {
379 loop {
382 match (self.next(), other.next()) {
383 (Some(x), Some(y)) => match x.cmp(&y) {
384 Ordering::Equal => continue,
385 non_eq => return non_eq,
386 },
387 (None, None) => return Ordering::Equal,
388 (None, _) => return Ordering::Less,
389 (_, None) => return Ordering::Greater,
390 }
391 }
392 }
393
394 fn cmp_by<I, F>(mut self, mut other: I, mut cmp: F) -> Ordering
397 where
398 Self: Sized,
399 I: LendingIterator,
400 F: FnMut(Self::Item<'_>, I::Item<'_>) -> Ordering,
401 {
402 loop {
403 match (self.next(), other.next()) {
404 (Some(x), Some(y)) => match cmp(x, y) {
405 Ordering::Equal => continue,
406 non_eq => return non_eq,
407 },
408 (None, None) => return Ordering::Equal,
409 (None, _) => return Ordering::Less,
410 (_, None) => return Ordering::Greater,
411 }
412 }
413 }
414
415 fn partial_cmp<I>(mut self, mut other: I) -> Option<Ordering>
420 where
421 I: LendingIterator,
422 for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
423 Self: Sized,
424 {
425 loop {
426 match (self.next(), other.next()) {
427 (Some(x), Some(y)) => match x.partial_cmp(&y) {
428 Some(Ordering::Equal) => continue,
429 non_eq => return non_eq,
430 },
431 (None, None) => return Some(Ordering::Equal),
432 (None, _) => return Some(Ordering::Less),
433 (_, None) => return Some(Ordering::Greater),
434 }
435 }
436 }
437
438 fn partial_cmp_by<I, F>(mut self, mut other: I, mut partial_cmp: F) -> Option<Ordering>
441 where
442 Self: Sized,
443 I: LendingIterator,
444 F: FnMut(Self::Item<'_>, I::Item<'_>) -> Option<Ordering>,
445 {
446 loop {
447 match (self.next(), other.next()) {
448 (Some(x), Some(y)) => match partial_cmp(x, y) {
449 Some(Ordering::Equal) => continue,
450 non_eq => return non_eq,
451 },
452 (None, None) => return Some(Ordering::Equal),
453 (None, _) => return Some(Ordering::Less),
454 (_, None) => return Some(Ordering::Greater),
455 }
456 }
457 }
458
459 fn eq<I>(mut self, mut other: I) -> bool
462 where
463 I: LendingIterator,
464 for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
465 Self: Sized,
466 {
467 loop {
468 match (self.next(), other.next()) {
469 (Some(x), Some(y)) => if x != y {
470 return false;
471 },
472 (None, None) => return true,
473 _ => return false,
474 }
475 }
476 }
477
478 fn eq_by<I, F>(mut self, mut other: I, mut eq: F) -> bool
481 where
482 Self: Sized,
483 I: LendingIterator,
484 F: FnMut(Self::Item<'_>, I::Item<'_>) -> bool,
485 {
486 loop {
487 match (self.next(), other.next()) {
488 (Some(x), Some(y)) => if !eq(x, y) {
489 return false;
490 },
491 (None, None) => return true,
492 _ => return false,
493 }
494 }
495 }
496
497 fn ne<I>(self, other: I) -> bool
500 where
501 I: LendingIterator,
502 for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
503 Self: Sized,
504 {
505 !self.eq(other)
506 }
507
508 fn lt<I>(self, other: I) -> bool
511 where
512 I: LendingIterator,
513 for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
514 Self: Sized,
515 {
516 self.partial_cmp(other) == Some(Ordering::Less)
517 }
518
519 fn le<I>(self, other: I) -> bool
522 where
523 I: LendingIterator,
524 for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
525 Self: Sized,
526 {
527 matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
528 }
529
530 fn gt<I>(self, other: I) -> bool
533 where
534 I: LendingIterator,
535 for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
536 Self: Sized,
537 {
538 self.partial_cmp(other) == Some(Ordering::Greater)
539 }
540
541 fn ge<I>(self, other: I) -> bool
544 where
545 I: LendingIterator,
546 for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
547 Self: Sized,
548 {
549 matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal))
550 }
551}
552
553impl<T: LendingIterator> LendingIterator for &mut T {
554 type Item<'a> = T::Item<'a> where Self: 'a;
555
556 #[inline]
557 fn next(&mut self) -> Option<Self::Item<'_>> {
558 (**self).next()
559 }
560
561 #[inline]
562 fn size_hint(&self) -> (usize, Option<usize>) {
563 (**self).size_hint()
564 }
565}