1#![doc(html_root_url = "https://docs.rs/num-iter/0.1")]
18#![no_std]
19
20use core::ops::{Add, Bound, RangeBounds, Sub};
21use core::usize;
22use num_integer::Integer;
23use num_traits::{CheckedAdd, One, ToPrimitive, Zero};
24
25#[derive(Clone)]
27pub struct Range<A> {
28 state: A,
29 stop: A,
30 one: A,
31}
32
33#[inline]
47pub fn range<A>(start: A, stop: A) -> Range<A>
48where
49 A: Add<A, Output = A> + PartialOrd + Clone + One,
50{
51 Range {
52 state: start,
53 stop,
54 one: One::one(),
55 }
56}
57
58#[inline]
59fn unsigned<T: ToPrimitive>(x: &T) -> Option<u128> {
60 match x.to_u128() {
61 Some(u) => Some(u),
62 None => Some(x.to_i128()? as u128),
63 }
64}
65
66impl<A> RangeBounds<A> for Range<A> {
67 fn start_bound(&self) -> Bound<&A> {
68 Bound::Included(&self.state)
69 }
70
71 fn end_bound(&self) -> Bound<&A> {
72 Bound::Excluded(&self.stop)
73 }
74}
75
76impl<A> Iterator for Range<A>
78where
79 A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive,
80{
81 type Item = A;
82
83 #[inline]
84 fn next(&mut self) -> Option<A> {
85 if self.state < self.stop {
86 let result = self.state.clone();
87 self.state = self.state.clone() + self.one.clone();
88 Some(result)
89 } else {
90 None
91 }
92 }
93
94 #[inline]
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 if self.state >= self.stop {
98 return (0, Some(0));
99 }
100
101 if let Some(a) = unsigned(&self.state) {
104 if let Some(b) = unsigned(&self.stop) {
105 return match b.wrapping_sub(a).to_usize() {
108 Some(len) => (len, Some(len)),
109 None => (usize::MAX, None),
110 };
111 }
112 }
113
114 (0, None)
116 }
117}
118
119impl<A> DoubleEndedIterator for Range<A>
122where
123 A: Integer + Clone + ToPrimitive,
124{
125 #[inline]
126 fn next_back(&mut self) -> Option<A> {
127 if self.stop > self.state {
128 self.stop.dec();
129 Some(self.stop.clone())
130 } else {
131 None
132 }
133 }
134}
135
136#[derive(Clone)]
138pub struct RangeInclusive<A> {
139 range: Range<A>,
140 done: bool,
141}
142
143#[inline]
145pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
146where
147 A: Add<A, Output = A> + PartialOrd + Clone + One,
148{
149 RangeInclusive {
150 range: range(start, stop),
151 done: false,
152 }
153}
154
155impl<A> RangeBounds<A> for RangeInclusive<A> {
156 fn start_bound(&self) -> Bound<&A> {
157 Bound::Included(&self.range.state)
158 }
159
160 fn end_bound(&self) -> Bound<&A> {
161 Bound::Included(&self.range.stop)
162 }
163}
164
165impl<A> Iterator for RangeInclusive<A>
166where
167 A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive,
168{
169 type Item = A;
170
171 #[inline]
172 fn next(&mut self) -> Option<A> {
173 match self.range.next() {
174 Some(x) => Some(x),
175 None => {
176 if !self.done && self.range.state == self.range.stop {
177 self.done = true;
178 Some(self.range.stop.clone())
179 } else {
180 None
181 }
182 }
183 }
184 }
185
186 #[inline]
187 fn size_hint(&self) -> (usize, Option<usize>) {
188 let (lo, hi) = self.range.size_hint();
189 if self.done {
190 (lo, hi)
191 } else {
192 let lo = lo.saturating_add(1);
193 let hi = match hi {
194 Some(x) => x.checked_add(1),
195 None => None,
196 };
197 (lo, hi)
198 }
199 }
200}
201
202impl<A> DoubleEndedIterator for RangeInclusive<A>
203where
204 A: Sub<A, Output = A> + Integer + Clone + ToPrimitive,
205{
206 #[inline]
207 fn next_back(&mut self) -> Option<A> {
208 if self.range.stop > self.range.state {
209 let result = self.range.stop.clone();
210 self.range.stop.dec();
211 Some(result)
212 } else if !self.done && self.range.state == self.range.stop {
213 self.done = true;
214 Some(self.range.stop.clone())
215 } else {
216 None
217 }
218 }
219}
220
221#[derive(Clone)]
223pub struct RangeStep<A> {
224 state: A,
225 stop: A,
226 step: A,
227 rev: bool,
228}
229
230#[inline]
232pub fn range_step<A>(start: A, stop: A, step: A) -> RangeStep<A>
233where
234 A: CheckedAdd + PartialOrd + Clone + Zero,
235{
236 let rev = step < Zero::zero();
237 RangeStep {
238 state: start,
239 stop,
240 step,
241 rev,
242 }
243}
244
245impl<A> Iterator for RangeStep<A>
246where
247 A: CheckedAdd + PartialOrd + Clone,
248{
249 type Item = A;
250
251 #[inline]
252 fn next(&mut self) -> Option<A> {
253 if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
254 let result = self.state.clone();
255 match self.state.checked_add(&self.step) {
256 Some(x) => self.state = x,
257 None => self.state = self.stop.clone(),
258 }
259 Some(result)
260 } else {
261 None
262 }
263 }
264}
265
266#[derive(Clone)]
268pub struct RangeStepInclusive<A> {
269 state: A,
270 stop: A,
271 step: A,
272 rev: bool,
273 done: bool,
274}
275
276#[inline]
278pub fn range_step_inclusive<A>(start: A, stop: A, step: A) -> RangeStepInclusive<A>
279where
280 A: CheckedAdd + PartialOrd + Clone + Zero,
281{
282 let rev = step < Zero::zero();
283 RangeStepInclusive {
284 state: start,
285 stop,
286 step,
287 rev,
288 done: false,
289 }
290}
291
292impl<A> Iterator for RangeStepInclusive<A>
293where
294 A: CheckedAdd + PartialOrd + Clone + PartialEq,
295{
296 type Item = A;
297
298 #[inline]
299 fn next(&mut self) -> Option<A> {
300 if !self.done
301 && ((self.rev && self.state >= self.stop) || (!self.rev && self.state <= self.stop))
302 {
303 let result = self.state.clone();
304 match self.state.checked_add(&self.step) {
305 Some(x) => self.state = x,
306 None => self.done = true,
307 }
308 Some(result)
309 } else {
310 None
311 }
312 }
313}
314
315#[derive(Clone)]
317pub struct RangeFrom<A> {
318 state: A,
319 one: A,
320}
321
322#[inline]
329pub fn range_from<A>(start: A) -> RangeFrom<A>
330where
331 A: Add<A, Output = A> + Clone + One,
332{
333 RangeFrom {
334 state: start,
335 one: One::one(),
336 }
337}
338
339impl<A> RangeBounds<A> for RangeFrom<A> {
340 fn start_bound(&self) -> Bound<&A> {
341 Bound::Included(&self.state)
342 }
343
344 fn end_bound(&self) -> Bound<&A> {
345 Bound::Unbounded
346 }
347}
348
349impl<A> Iterator for RangeFrom<A>
350where
351 A: Add<A, Output = A> + Clone,
352{
353 type Item = A;
354
355 #[inline]
356 fn next(&mut self) -> Option<A> {
357 let result = self.state.clone();
358 self.state = self.state.clone() + self.one.clone();
359 Some(result)
360 }
361
362 #[inline]
363 fn size_hint(&self) -> (usize, Option<usize>) {
364 (usize::MAX, None)
365 }
366}
367
368#[derive(Clone)]
370pub struct RangeStepFrom<A> {
371 state: A,
372 step: A,
373}
374
375#[inline]
382pub fn range_step_from<A>(start: A, step: A) -> RangeStepFrom<A>
383where
384 A: Add<A, Output = A> + Clone,
385{
386 RangeStepFrom { state: start, step }
387}
388
389impl<A> Iterator for RangeStepFrom<A>
390where
391 A: Add<A, Output = A> + Clone,
392{
393 type Item = A;
394
395 #[inline]
396 fn next(&mut self) -> Option<A> {
397 let result = self.state.clone();
398 self.state = self.state.clone() + self.step.clone();
399 Some(result)
400 }
401
402 #[inline]
403 fn size_hint(&self) -> (usize, Option<usize>) {
404 (usize::MAX, None)
405 }
406}
407
408#[cfg(test)]
409mod tests {
410 use core::cmp::Ordering;
411 use core::iter;
412 use core::ops::{Add, Mul};
413 use core::{isize, usize};
414 use num_traits::{One, ToPrimitive};
415
416 #[test]
417 fn test_range() {
418 struct Foo;
420
421 impl ToPrimitive for Foo {
422 fn to_i64(&self) -> Option<i64> {
423 None
424 }
425 fn to_u64(&self) -> Option<u64> {
426 None
427 }
428 }
429
430 impl Add<Foo> for Foo {
431 type Output = Foo;
432
433 fn add(self, _: Foo) -> Foo {
434 Foo
435 }
436 }
437
438 impl PartialEq for Foo {
439 fn eq(&self, _: &Foo) -> bool {
440 true
441 }
442 }
443
444 impl PartialOrd for Foo {
445 fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
446 None
447 }
448 }
449
450 impl Clone for Foo {
451 fn clone(&self) -> Foo {
452 Foo
453 }
454 }
455
456 impl Mul<Foo> for Foo {
457 type Output = Foo;
458
459 fn mul(self, _: Foo) -> Foo {
460 Foo
461 }
462 }
463
464 impl One for Foo {
465 fn one() -> Foo {
466 Foo
467 }
468 }
469
470 assert!(super::range(0, 5).eq([0, 1, 2, 3, 4].iter().cloned()));
471 assert!(super::range(-10, -1).eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned()));
472 assert!(super::range(0, 5).rev().eq([4, 3, 2, 1, 0].iter().cloned()));
473 assert_eq!(super::range(200, -5).count(), 0);
474 assert_eq!(super::range(200, -5).rev().count(), 0);
475 assert_eq!(super::range(200, 200).count(), 0);
476 assert_eq!(super::range(200, 200).rev().count(), 0);
477
478 assert_eq!(super::range(0, 100).size_hint(), (100, Some(100)));
479 assert_eq!(
481 super::range(usize::MAX - 1, usize::MAX).size_hint(),
482 (1, Some(1))
483 );
484 assert_eq!(super::range(-10, -1).size_hint(), (9, Some(9)));
485 assert_eq!(
486 super::range(isize::MIN, isize::MAX).size_hint(),
487 (usize::MAX, Some(usize::MAX))
488 );
489 }
490
491 #[test]
492 fn test_range_128() {
493 use core::{i128, u128};
494
495 assert!(super::range(0i128, 5).eq([0, 1, 2, 3, 4].iter().cloned()));
496 assert!(super::range(-10i128, -1).eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned()));
497 assert!(super::range(0u128, 5)
498 .rev()
499 .eq([4, 3, 2, 1, 0].iter().cloned()));
500
501 assert_eq!(
502 super::range(i128::MIN, i128::MIN + 1).size_hint(),
503 (1, Some(1))
504 );
505 assert_eq!(
506 super::range(i128::MAX - 1, i128::MAX).size_hint(),
507 (1, Some(1))
508 );
509 assert_eq!(
510 super::range(i128::MIN, i128::MAX).size_hint(),
511 (usize::MAX, None)
512 );
513
514 assert_eq!(
515 super::range(u128::MAX - 1, u128::MAX).size_hint(),
516 (1, Some(1))
517 );
518 assert_eq!(
519 super::range(0, usize::MAX as u128).size_hint(),
520 (usize::MAX, Some(usize::MAX))
521 );
522 assert_eq!(
523 super::range(0, usize::MAX as u128 + 1).size_hint(),
524 (usize::MAX, None)
525 );
526 assert_eq!(super::range(0, i128::MAX).size_hint(), (usize::MAX, None));
527 }
528
529 #[test]
530 fn test_range_inclusive() {
531 assert!(super::range_inclusive(0, 5).eq([0, 1, 2, 3, 4, 5].iter().cloned()));
532 assert!(super::range_inclusive(0, 5)
533 .rev()
534 .eq([5, 4, 3, 2, 1, 0].iter().cloned()));
535 assert_eq!(super::range_inclusive(200, -5).count(), 0);
536 assert_eq!(super::range_inclusive(200, -5).rev().count(), 0);
537 assert!(super::range_inclusive(200, 200).eq(iter::once(200)));
538 assert!(super::range_inclusive(200, 200).rev().eq(iter::once(200)));
539 assert_eq!(
540 super::range_inclusive(isize::MIN, isize::MAX - 1).size_hint(),
541 (usize::MAX, Some(usize::MAX))
542 );
543 assert_eq!(
544 super::range_inclusive(isize::MIN, isize::MAX).size_hint(),
545 (usize::MAX, None)
546 );
547 }
548
549 #[test]
550 fn test_range_inclusive_128() {
551 use core::i128;
552
553 assert!(super::range_inclusive(0u128, 5).eq([0, 1, 2, 3, 4, 5].iter().cloned()));
554 assert!(super::range_inclusive(0u128, 5)
555 .rev()
556 .eq([5, 4, 3, 2, 1, 0].iter().cloned()));
557 assert_eq!(super::range_inclusive(200i128, -5).count(), 0);
558 assert_eq!(super::range_inclusive(200i128, -5).rev().count(), 0);
559 assert!(super::range_inclusive(200u128, 200).eq(iter::once(200)));
560 assert!(super::range_inclusive(200u128, 200)
561 .rev()
562 .eq(iter::once(200)));
563 assert_eq!(
564 super::range_inclusive(isize::MIN as i128, isize::MAX as i128 - 1).size_hint(),
565 (usize::MAX, Some(usize::MAX))
566 );
567 assert_eq!(
568 super::range_inclusive(isize::MIN as i128, isize::MAX as i128).size_hint(),
569 (usize::MAX, None)
570 );
571 assert_eq!(
572 super::range_inclusive(isize::MIN as i128, isize::MAX as i128 + 1).size_hint(),
573 (usize::MAX, None)
574 );
575 assert_eq!(
576 super::range_inclusive(i128::MIN, i128::MAX).size_hint(),
577 (usize::MAX, None)
578 );
579 }
580
581 #[test]
582 fn test_range_step() {
583 assert!(super::range_step(0, 20, 5).eq([0, 5, 10, 15].iter().cloned()));
584 assert!(super::range_step(20, 0, -5).eq([20, 15, 10, 5].iter().cloned()));
585 assert!(super::range_step(20, 0, -6).eq([20, 14, 8, 2].iter().cloned()));
586 assert!(super::range_step(200u8, 255, 50).eq([200u8, 250].iter().cloned()));
587 assert!(super::range_step(200, -5, 1).eq(iter::empty()));
588 assert!(super::range_step(200, 200, 1).eq(iter::empty()));
589 }
590
591 #[test]
592 fn test_range_step_128() {
593 use core::u128::MAX as UMAX;
594
595 assert!(super::range_step(0u128, 20, 5).eq([0, 5, 10, 15].iter().cloned()));
596 assert!(super::range_step(20i128, 0, -5).eq([20, 15, 10, 5].iter().cloned()));
597 assert!(super::range_step(20i128, 0, -6).eq([20, 14, 8, 2].iter().cloned()));
598 assert!(super::range_step(UMAX - 55, UMAX, 50).eq([UMAX - 55, UMAX - 5].iter().cloned()));
599 assert!(super::range_step(200i128, -5, 1).eq(iter::empty()));
600 assert!(super::range_step(200i128, 200, 1).eq(iter::empty()));
601 }
602
603 #[test]
604 fn test_range_step_inclusive() {
605 assert!(super::range_step_inclusive(0, 20, 5).eq([0, 5, 10, 15, 20].iter().cloned()));
606 assert!(super::range_step_inclusive(20, 0, -5).eq([20, 15, 10, 5, 0].iter().cloned()));
607 assert!(super::range_step_inclusive(20, 0, -6).eq([20, 14, 8, 2].iter().cloned()));
608 assert!(super::range_step_inclusive(200u8, 255, 50).eq([200u8, 250].iter().cloned()));
609 assert!(super::range_step_inclusive(200, -5, 1).eq(iter::empty()));
610 assert!(super::range_step_inclusive(200, 200, 1).eq(iter::once(200)));
611 }
612
613 #[test]
614 fn test_range_step_inclusive_128() {
615 use core::u128::MAX as UMAX;
616
617 assert!(super::range_step_inclusive(0u128, 20, 5).eq([0, 5, 10, 15, 20].iter().cloned()));
618 assert!(super::range_step_inclusive(20i128, 0, -5).eq([20, 15, 10, 5, 0].iter().cloned()));
619 assert!(super::range_step_inclusive(20i128, 0, -6).eq([20, 14, 8, 2].iter().cloned()));
620 assert!(super::range_step_inclusive(UMAX - 55, UMAX, 50)
621 .eq([UMAX - 55, UMAX - 5].iter().cloned()));
622 assert!(super::range_step_inclusive(200i128, -5, 1).eq(iter::empty()));
623 assert!(super::range_step_inclusive(200i128, 200, 1).eq(iter::once(200)));
624 }
625
626 #[test]
627 fn test_range_from() {
628 assert!(super::range_from(10u8)
629 .take(5)
630 .eq([10, 11, 12, 13, 14].iter().cloned()));
631 assert_eq!(super::range_from(10u8).size_hint(), (usize::MAX, None));
632 }
633
634 #[test]
635 fn test_range_step_from() {
636 assert!(super::range_step_from(10u8, 2u8)
637 .take(5)
638 .eq([10, 12, 14, 16, 18].iter().cloned()));
639 assert_eq!(
640 super::range_step_from(10u8, 2u8).size_hint(),
641 (usize::MAX, None)
642 );
643
644 assert!(super::range_step_from(10u8, 1u8)
645 .take(5)
646 .eq([10, 11, 12, 13, 14].iter().cloned()));
647 assert_eq!(
648 super::range_step_from(10u8, 1u8).size_hint(),
649 (usize::MAX, None)
650 );
651
652 assert!(super::range_step_from(10u8, 0u8)
653 .take(5)
654 .eq([10, 10, 10, 10, 10].iter().cloned()));
655 assert_eq!(
656 super::range_step_from(10u8, 0u8).size_hint(),
657 (usize::MAX, None)
658 );
659
660 assert!(super::range_step_from(10i8, 2i8)
661 .take(5)
662 .eq([10, 12, 14, 16, 18].iter().cloned()));
663 assert_eq!(
664 super::range_step_from(10i8, 2i8).size_hint(),
665 (usize::MAX, None)
666 );
667
668 assert!(super::range_step_from(10i8, 1i8)
669 .take(5)
670 .eq([10, 11, 12, 13, 14].iter().cloned()));
671 assert_eq!(
672 super::range_step_from(10i8, 1i8).size_hint(),
673 (usize::MAX, None)
674 );
675
676 assert!(super::range_step_from(10i8, 0i8)
677 .take(5)
678 .eq([10, 10, 10, 10, 10].iter().cloned()));
679 assert_eq!(
680 super::range_step_from(10i8, 0i8).size_hint(),
681 (usize::MAX, None)
682 );
683
684 assert!(super::range_step_from(10i8, -1i8)
685 .take(5)
686 .eq([10, 9, 8, 7, 6].iter().cloned()));
687 assert_eq!(
688 super::range_step_from(10i8, -1i8).size_hint(),
689 (usize::MAX, None)
690 );
691
692 assert!(super::range_step_from(10i8, -2i8)
693 .take(5)
694 .eq([10, 8, 6, 4, 2].iter().cloned()));
695 assert_eq!(
696 super::range_step_from(10i8, -2i8).size_hint(),
697 (usize::MAX, None)
698 );
699 }
700}