// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! External iterators for generic mathematics
//!
//! ## Compatibility
//!
//! The `num-iter` crate is tested for rustc 1.8 and greater.

#![doc(html_root_url = "https://docs.rs/num-iter/0.1")]

#![no_std]
#[cfg(feature = "std")]
extern crate std;

extern crate num_traits as traits;
extern crate num_integer as integer;

use integer::Integer;
use traits::{Zero, One, CheckedAdd, ToPrimitive};
use core::ops::{Add, Sub};
use core::usize;

/// An iterator over the range [start, stop)
#[derive(Clone)]
pub struct Range<A> {
    state: A,
    stop: A,
    one: A
}

/// Returns an iterator over the given range [start, stop) (that is, starting
/// at start (inclusive), and ending at stop (exclusive)).
///
/// # Example
///
/// ```rust
/// let array = [0, 1, 2, 3, 4];
///
/// for i in num_iter::range(0, 5) {
///     println!("{}", i);
///     assert_eq!(i,  array[i]);
/// }
/// ```
#[inline]
pub fn range<A>(start: A, stop: A) -> Range<A>
    where A: Add<A, Output = A> + PartialOrd + Clone + One
{
    Range{state: start, stop: stop, one: One::one()}
}

#[inline]
#[cfg(has_i128)]
fn unsigned<T: ToPrimitive>(x: &T) -> Option<u128> {
    match x.to_u128() {
        None => match x.to_i128() {
            Some(i) => Some(i as u128),
            None => None,
        },
        Some(u) => Some(u),
    }
}

#[inline]
#[cfg(not(has_i128))]
fn unsigned<T: ToPrimitive>(x: &T) -> Option<u64> {
    match x.to_u64() {
        None => match x.to_i64() {
            Some(i) => Some(i as u64),
            None => None,
        },
        Some(u) => Some(u),
    }
}

// FIXME: rust-lang/rust#10414: Unfortunate type bound
impl<A> Iterator for Range<A>
    where A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive
{
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.state < self.stop {
            let result = self.state.clone();
            self.state = self.state.clone() + self.one.clone();
            Some(result)
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        // Check for empty ranges first.
        if self.state >= self.stop {
            return (0, Some(0));
        }

        // Try to cast both ends to the largest unsigned primitive.
        // Note that negative values will wrap to a large positive.
        if let Some(a) = unsigned(&self.state) {
            if let Some(b) = unsigned(&self.stop) {
                // We've lost signs, but we already know state < stop, so
                // a `wrapping_sub` will give the correct unsigned delta.
                return match b.wrapping_sub(a).to_usize() {
                    Some(len) => (len, Some(len)),
                    None => (usize::MAX, None),
                }
            }
        }

        // Standard fallback for unbounded/unrepresentable bounds
        (0, None)
    }
}

/// `Integer` is required to ensure the range will be the same regardless of
/// the direction it is consumed.
impl<A> DoubleEndedIterator for Range<A>
    where A: Integer + Clone + ToPrimitive
{
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.stop > self.state {
            self.stop = self.stop.clone() - self.one.clone();
            Some(self.stop.clone())
        } else {
            None
        }
    }
}

/// An iterator over the range [start, stop]
#[derive(Clone)]
pub struct RangeInclusive<A> {
    range: Range<A>,
    done: bool,
}

/// Return an iterator over the range [start, stop]
#[inline]
pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
    where A: Add<A, Output = A> + PartialOrd + Clone + One
{
    RangeInclusive{range: range(start, stop), done: false}
}

impl<A> Iterator for RangeInclusive<A>
    where A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive
{
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        match self.range.next() {
            Some(x) => Some(x),
            None => {
                if !self.done && self.range.state == self.range.stop {
                    self.done = true;
                    Some(self.range.stop.clone())
                } else {
                    None
                }
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (lo, hi) = self.range.size_hint();
        if self.done {
            (lo, hi)
        } else {
            let lo = lo.saturating_add(1);
            let hi = match hi {
                Some(x) => x.checked_add(1),
                None => None
            };
            (lo, hi)
        }
    }
}

impl<A> DoubleEndedIterator for RangeInclusive<A>
    where A: Sub<A, Output = A> + Integer + Clone + ToPrimitive
{
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.range.stop > self.range.state {
            let result = self.range.stop.clone();
            self.range.stop = self.range.stop.clone() - self.range.one.clone();
            Some(result)
        } else if !self.done && self.range.state == self.range.stop {
            self.done = true;
            Some(self.range.stop.clone())
        } else {
            None
        }
    }
}

/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
#[derive(Clone)]
pub struct RangeStep<A> {
    state: A,
    stop: A,
    step: A,
    rev: bool,
}

/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
#[inline]
pub fn range_step<A>(start: A, stop: A, step: A) -> RangeStep<A>
    where A: CheckedAdd + PartialOrd + Clone + Zero
{
    let rev = step < Zero::zero();
    RangeStep{state: start, stop: stop, step: step, rev: rev}
}

impl<A> Iterator for RangeStep<A>
    where A: CheckedAdd + PartialOrd + Clone
{
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
            let result = self.state.clone();
            match self.state.checked_add(&self.step) {
                Some(x) => self.state = x,
                None => self.state = self.stop.clone()
            }
            Some(result)
        } else {
            None
        }
    }
}

/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
#[derive(Clone)]
pub struct RangeStepInclusive<A> {
    state: A,
    stop: A,
    step: A,
    rev: bool,
    done: bool,
}

/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
#[inline]
pub fn range_step_inclusive<A>(start: A, stop: A, step: A) -> RangeStepInclusive<A>
    where A: CheckedAdd + PartialOrd + Clone + Zero
{
    let rev = step < Zero::zero();
    RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false}
}

impl<A> Iterator for RangeStepInclusive<A>
    where A: CheckedAdd + PartialOrd + Clone + PartialEq
{
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if !self.done && ((self.rev && self.state >= self.stop) ||
                          (!self.rev && self.state <= self.stop)) {
            let result = self.state.clone();
            match self.state.checked_add(&self.step) {
                Some(x) => self.state = x,
                None => self.done = true
            }
            Some(result)
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use core::{isize, usize};
    use core::ops::{Add, Mul};
    use core::cmp::Ordering;
    use core::iter;
    use traits::{One, ToPrimitive};

    #[test]
    fn test_range() {
        /// A mock type to check Range when ToPrimitive returns None
        struct Foo;

        impl ToPrimitive for Foo {
            fn to_i64(&self) -> Option<i64> { None }
            fn to_u64(&self) -> Option<u64> { None }
        }

        impl Add<Foo> for Foo {
            type Output = Foo;

            fn add(self, _: Foo) -> Foo {
                Foo
            }
        }

        impl PartialEq for Foo {
            fn eq(&self, _: &Foo) -> bool {
                true
            }
        }

        impl PartialOrd for Foo {
            fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
                None
            }
        }

        impl Clone for Foo {
            fn clone(&self) -> Foo {
                Foo
            }
        }

        impl Mul<Foo> for Foo {
            type Output = Foo;

            fn mul(self, _: Foo) -> Foo {
                Foo
            }
        }

        impl One for Foo {
            fn one() -> Foo {
                Foo
            }
        }

        assert!(super::range(0, 5)
                .eq([0, 1, 2, 3, 4].iter().cloned()));
        assert!(super::range(-10, -1)
                .eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned()));
        assert!(super::range(0, 5).rev()
                .eq([4, 3, 2, 1, 0].iter().cloned()));
        assert_eq!(super::range(200, -5).count(), 0);
        assert_eq!(super::range(200, -5).rev().count(), 0);
        assert_eq!(super::range(200, 200).count(), 0);
        assert_eq!(super::range(200, 200).rev().count(), 0);

        assert_eq!(super::range(0, 100).size_hint(), (100, Some(100)));
        // this test is only meaningful when sizeof usize < sizeof u64
        assert_eq!(super::range(usize::MAX - 1, usize::MAX).size_hint(), (1, Some(1)));
        assert_eq!(super::range(-10, -1).size_hint(), (9, Some(9)));
        assert_eq!(super::range(isize::MIN, isize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
    }

    #[test]
    #[cfg(has_i128)]
    fn test_range_128() {
        use core::{i128, u128};

        assert!(super::range(0i128, 5)
                .eq([0, 1, 2, 3, 4].iter().cloned()));
        assert!(super::range(-10i128, -1)
                .eq([-10, -9, -8, -7, -6, -5, -4, -3, -2].iter().cloned()));
        assert!(super::range(0u128, 5).rev()
                .eq([4, 3, 2, 1, 0].iter().cloned()));

        assert_eq!(super::range(i128::MIN, i128::MIN+1).size_hint(), (1, Some(1)));
        assert_eq!(super::range(i128::MAX - 1, i128::MAX).size_hint(), (1, Some(1)));
        assert_eq!(super::range(i128::MIN, i128::MAX).size_hint(), (usize::MAX, None));

        assert_eq!(super::range(u128::MAX - 1, u128::MAX).size_hint(), (1, Some(1)));
        assert_eq!(super::range(0, usize::MAX as u128).size_hint(), (usize::MAX, Some(usize::MAX)));
        assert_eq!(super::range(0, usize::MAX as u128 + 1).size_hint(), (usize::MAX, None));
        assert_eq!(super::range(0, i128::MAX).size_hint(), (usize::MAX, None));
    }

    #[test]
    fn test_range_inclusive() {
        assert!(super::range_inclusive(0, 5)
                .eq([0, 1, 2, 3, 4, 5].iter().cloned()));
        assert!(super::range_inclusive(0, 5).rev()
                .eq([5, 4, 3, 2, 1, 0].iter().cloned()));
        assert_eq!(super::range_inclusive(200, -5).count(), 0);
        assert_eq!(super::range_inclusive(200, -5).rev().count(), 0);
        assert!(super::range_inclusive(200, 200)
                .eq(iter::once(200)));
        assert!(super::range_inclusive(200, 200).rev()
                .eq(iter::once(200)));
        assert_eq!(super::range_inclusive(isize::MIN, isize::MAX - 1).size_hint(),
                   (usize::MAX, Some(usize::MAX)));
        assert_eq!(super::range_inclusive(isize::MIN, isize::MAX).size_hint(),
                   (usize::MAX, None));
    }

    #[test]
    #[cfg(has_i128)]
    fn test_range_inclusive_128() {
        use core::i128;

        assert!(super::range_inclusive(0u128, 5)
                .eq([0, 1, 2, 3, 4, 5].iter().cloned()));
        assert!(super::range_inclusive(0u128, 5).rev()
                .eq([5, 4, 3, 2, 1, 0].iter().cloned()));
        assert_eq!(super::range_inclusive(200i128, -5).count(), 0);
        assert_eq!(super::range_inclusive(200i128, -5).rev().count(), 0);
        assert!(super::range_inclusive(200u128, 200)
                .eq(iter::once(200)));
        assert!(super::range_inclusive(200u128, 200).rev()
                .eq(iter::once(200)));
        assert_eq!(super::range_inclusive(isize::MIN as i128, isize::MAX as i128 - 1).size_hint(),
                   (usize::MAX, Some(usize::MAX)));
        assert_eq!(super::range_inclusive(isize::MIN as i128, isize::MAX as i128).size_hint(),
                   (usize::MAX, None));
        assert_eq!(super::range_inclusive(isize::MIN as i128, isize::MAX as i128 + 1).size_hint(),
                   (usize::MAX, None));
        assert_eq!(super::range_inclusive(i128::MIN, i128::MAX).size_hint(),
                   (usize::MAX, None));
    }

    #[test]
    fn test_range_step() {
        assert!(super::range_step(0, 20, 5)
                .eq([0, 5, 10, 15].iter().cloned()));
        assert!(super::range_step(20, 0, -5)
                .eq([20, 15, 10, 5].iter().cloned()));
        assert!(super::range_step(20, 0, -6)
                .eq([20, 14, 8, 2].iter().cloned()));
        assert!(super::range_step(200u8, 255, 50)
                .eq([200u8, 250].iter().cloned()));
        assert!(super::range_step(200, -5, 1)
                .eq(iter::empty()));
        assert!(super::range_step(200, 200, 1)
                .eq(iter::empty()));
    }

    #[test]
    #[cfg(has_i128)]
    fn test_range_step_128() {
        use core::u128::MAX as UMAX;

        assert!(super::range_step(0u128, 20, 5)
                .eq([0, 5, 10, 15].iter().cloned()));
        assert!(super::range_step(20i128, 0, -5)
                .eq([20, 15, 10, 5].iter().cloned()));
        assert!(super::range_step(20i128, 0, -6)
                .eq([20, 14, 8, 2].iter().cloned()));
        assert!(super::range_step(UMAX - 55, UMAX, 50)
                .eq([UMAX - 55, UMAX - 5].iter().cloned()));
        assert!(super::range_step(200i128, -5, 1)
                .eq(iter::empty()));
        assert!(super::range_step(200i128, 200, 1)
                .eq(iter::empty()));
    }

    #[test]
    fn test_range_step_inclusive() {
        assert!(super::range_step_inclusive(0, 20, 5)
                .eq([0, 5, 10, 15, 20].iter().cloned()));
        assert!(super::range_step_inclusive(20, 0, -5)
                .eq([20, 15, 10, 5, 0].iter().cloned()));
        assert!(super::range_step_inclusive(20, 0, -6)
                .eq([20, 14, 8, 2].iter().cloned()));
        assert!(super::range_step_inclusive(200u8, 255, 50)
                .eq([200u8, 250].iter().cloned()));
        assert!(super::range_step_inclusive(200, -5, 1)
                .eq(iter::empty()));
        assert!(super::range_step_inclusive(200, 200, 1)
                .eq(iter::once(200)));
    }

    #[test]
    #[cfg(has_i128)]
    fn test_range_step_inclusive_128() {
        use core::u128::MAX as UMAX;

        assert!(super::range_step_inclusive(0u128, 20, 5)
                .eq([0, 5, 10, 15, 20].iter().cloned()));
        assert!(super::range_step_inclusive(20i128, 0, -5)
                .eq([20, 15, 10, 5, 0].iter().cloned()));
        assert!(super::range_step_inclusive(20i128, 0, -6)
                .eq([20, 14, 8, 2].iter().cloned()));
        assert!(super::range_step_inclusive(UMAX - 55, UMAX, 50)
                .eq([UMAX - 55, UMAX - 5].iter().cloned()));
        assert!(super::range_step_inclusive(200i128, -5, 1)
                .eq(iter::empty()));
        assert!(super::range_step_inclusive(200i128, 200, 1)
                .eq(iter::once(200)));
    }
}
