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