<commit_before>//! The norm module
//!
//! This module contains implementations of various linear algebra norms.
//! The implementations are contained within the `VectorNorm` and
//! `MatrixNorm` traits. This module also contains `VectorMetric` and
//! `MatrixMetric` traits which are used to compute the metric distance.
//!
//! These traits can be used directly by importing implementors from
//! this module. In most cases it will be easier to use the `norm` and
//! `metric` functions which exist for both vectors and matrices. These
//! functions take generic arguments for the norm to be used.
//!
//! In general you should use the least generic norm that fits your purpose.
//! For example you would choose to use a `Euclidean` norm instead of an
//! `Lp(2.0)` norm - despite them being mathematically equivalent.
//!
//! # Defining your own norm
//!
//! Note that these traits enforce no requirements on the norm. It is up
//! to the user to ensure that they define a norm correctly.
//!
//! To define your own norm you need to implement the `MatrixNorm`
//! and/or the `VectorNorm` on your own struct. When you have defined
//! a norm you get the _induced metric_ for free. This means that any
//! object which implements the `VectorNorm` or `MatrixNorm` will
//! automatically implement the `VectorMetric` and `MatrixMetric` traits
//! respectively. This induced metric will compute the norm of the
//! difference between the vectors or matrices.

use matrix::BaseMatrix;
use vector::Vector;
use utils;

use std::ops::Sub;
use libnum::Float;

/// Trait for vector norms
pub trait VectorNorm<T> {
    /// Computes the vector norm.
    fn norm(&self, v: &Vector<T>) -> T;
}

/// Trait for vector metrics.
pub trait VectorMetric<T> {
    /// Computes the metric distance between two vectors.
    fn metric(&self, v1: &Vector<T>, v2: &Vector<T>) -> T;
}

/// Trait for matrix norms.
pub trait MatrixNorm<T, M: BaseMatrix<T>> {
    /// Computes the matrix norm.
    fn norm(&self, m: &M) -> T;
}

/// Trait for matrix metrics.
pub trait MatrixMetric<'a, 'b, T, M1: 'a + BaseMatrix<T>, M2: 'b + BaseMatrix<T>> {
    /// Computes the metric distance between two matrices.
    fn metric(&self, m1: &'a M1, m2: &'b M2) -> T;
}

/// The induced vector metric
///
/// Given a norm `N`, the induced vector metric `M` computes
/// the metric distance, `d`, between two vectors `v1` and `v2`
/// as follows:
///
/// `d = M(v1, v2) = N(v1 - v2)`
impl<U, T> VectorMetric<T> for U
    where U: VectorNorm<T>, T: Copy + Sub<T, Output=T> {
    fn metric(&self, v1: &Vector<T>, v2: &Vector<T>) -> T {
        self.norm(&(v1 - v2))
    }
}

/// The induced matrix metric
///
/// Given a norm `N`, the induced matrix metric `M` computes
/// the metric distance, `d`, between two matrices `m1` and `m2`
/// as follows:
///
/// `d = M(m1, m2) = N(m1 - m2)`
impl<'a, 'b, U, T, M1, M2> MatrixMetric<'a, 'b, T, M1, M2> for U
    where U: MatrixNorm<T, M1>,
    M1: 'a + BaseMatrix<T>,
    M2: 'b + BaseMatrix<T>,
    &'a M1: Sub<&'b M2, Output=M1> {

    fn metric(&self, m1: &'a M1, m2: &'b M2) -> T {
        self.norm(&(m1 - m2))
    }
}

/// The Euclidean norm
///
/// The Euclidean norm computes the square-root
/// of the sum of squares.
///
/// `||v|| = SQRT(SUM(v_i * v_i))`
#[derive(Debug)]
pub struct Euclidean;

impl<T: Float> VectorNorm<T> for Euclidean {
    fn norm(&self, v: &Vector<T>) -> T {
        utils::dot(v.data(), v.data()).sqrt()
    }
}

impl<T: Float, M: BaseMatrix<T>> MatrixNorm<T, M> for Euclidean {
    fn norm(&self, m: &M) -> T {
        let mut s = T::zero();

        for row in m.row_iter() {
            s = s + utils::dot(row.raw_slice(), row.raw_slice());
        }

        s.sqrt()
    }
}

/// The Lp norm
///
/// The
/// [Lp norm](https://en.wikipedia.org/wiki/Norm_(mathematics)#p-norm)
/// computes the `p`th root of the sum of elements
/// to the `p`th power.
///
/// The Lp norm requires `p` to be greater than
/// or equal `1`.
///
/// We use an enum for this norm to allow us to explicitly handle
/// special cases at compile time. For example, we have an `Infinity`
/// variant which handles the special case when the `Lp` norm is a
/// supremum over absolute values. The `Integer` variant gives us a
/// performance boost when `p` is an integer.
///
/// You should avoid matching directly against this enum as it is likely
/// to grow.
#[derive(Debug)]
pub enum Lp<T: Float> {
    /// The L-infinity norm (supremum)
    Infinity,
    /// The Lp norm where p is an integer
    Integer(i32),
    /// The Lp norm where p is a float
    Float(T)
}

impl<T: Float> VectorNorm<T> for Lp<T> {
    fn norm(&self, v: &Vector<T>) -> T {
        match *self {
            Lp::Infinity => {
                // Compute supremum
                let mut abs_sup = T::zero();
                for d in v.iter().map(|d| d.abs()) {
                    if d > abs_sup {
                        abs_sup = d;
                    }
                }
                abs_sup
            },
            Lp::Integer(p) => {
                assert!(p >= 1, "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in v {
                    s = s + x.abs().powi(p);
                }
                s.powf(T::from(p).expect("Could not cast i32 to float").recip())
            },
            Lp::Float(p) => {
                assert!(p >= T::one(), "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in v {
                    s = s + x.abs().powf(p);
                }
                s.powf(p.recip())
            }
        }
    }
}

impl<T: Float, M: BaseMatrix<T>> MatrixNorm<T, M> for Lp<T> {
    fn norm(&self, m: &M) -> T {
        match *self {
            Lp::Infinity => {
                // Compute supremum
                let mut abs_sup = T::zero();
                for d in m.iter().map(|d| d.abs()) {
                    if d > abs_sup {
                        abs_sup = d;
                    }
                }
                abs_sup
            },
            Lp::Integer(p) => {
                assert!(p >= 1, "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in m.iter() {
                    s = s + x.abs().powi(p);
                }
                s.powf(T::from(p).expect("Could not cast i32 to float").recip())
            },
            Lp::Float(p) => {
                assert!(p >= T::one(), "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in m.iter() {
                    s = s + x.abs().powf(p);
                }
                s.powf(p.recip())
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use libnum::Float;
    use std::f64;

    use super::*;
    use vector::Vector;
    use matrix::{Matrix, MatrixSlice};

    #[test]
    fn test_euclidean_vector_norm() {
        let v = vector![3.0, 4.0];
        assert!((VectorNorm::norm(&Euclidean, &v) - 5.0) < 1e-14);
    }

    #[test]
    fn test_euclidean_matrix_norm() {
        let m = matrix![3.0, 4.0;
                        1.0, 3.0];
        assert!((MatrixNorm::norm(&Euclidean, &m) - 35.0.sqrt()) < 1e-14);

        let slice = MatrixSlice::from_matrix(&m, [0,0], 1, 2);
        assert!((MatrixNorm::norm(&Euclidean, &slice) - 5.0) < 1e-14);
    }

    #[test]
    fn test_euclidean_vector_metric() {
        let v = vector![3.0, 4.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v)) < 1e-14);

        let v1 = vector![0.0, 0.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v1) - 5.0) < 1e-14);

        let v2 = vector![4.0, 3.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v2) - 2.0.sqrt()) < 1e-14);
    }

    #[test]
    #[should_panic]
    fn test_euclidean_vector_metric_bad_dim() {
        let v = vector![3.0, 4.0];
        let v2 = vector![1.0, 2.0, 3.0];

        VectorMetric::metric(&Euclidean, &v, &v2);
    }

    #[test]
    fn test_euclidean_matrix_metric() {
        let m = matrix![3.0, 4.0;
                        1.0, 3.0];
        assert!((MatrixMetric::metric(&Euclidean, &m, &m)) < 1e-14);

        let m1 = Matrix::zeros(2, 2);
        assert!((MatrixMetric::metric(&Euclidean, &m, &m1) - 35.0.sqrt()) < 1e-14);

        let m2 = matrix![2.0, 3.0;
                         2.0, 4.0];
        assert!((MatrixMetric::metric(&Euclidean, &m, &m2) - 2.0) < 1e-14);
    }

    #[test]
    #[should_panic]
    fn test_euclidean_matrix_metric_bad_dim() {
        let m = matrix![3.0, 4.0];
        let m2 = matrix![1.0, 2.0, 3.0];

        MatrixMetric::metric(&Euclidean, &m, &m2);
    }

    #[test]
    fn test_lp_vector_supremum() {
        let v = vector![-5.0, 3.0];

        let sup = VectorNorm::norm(&Lp::Infinity, &v);
        assert_eq!(sup, 5.0);
    }

    #[test]
    fn test_lp_matrix_supremum() {
        let m = matrix![0.0, -2.0;
                        3.5, 1.0];

        let sup = MatrixNorm::norm(&Lp::Infinity, &m);
        assert_eq!(sup, 3.5);
    }

    #[test]
    fn test_lp_vector_one() {
        let v = vector![1.0, 2.0, -2.0];
        assert_eq!(VectorNorm::norm(&Lp::Integer(1), &v), 5.0);
    }

    #[test]
    fn test_lp_matrix_one() {
        let m = matrix![1.0, -2.0;
                        0.5, 1.0];
        assert_eq!(MatrixNorm::norm(&Lp::Integer(1), &m), 4.5);
    }

    #[test]
    fn test_lp_vector_float() {
        let v = vector![1.0, 2.0, -2.0];
        assert_eq!(VectorNorm::norm(&Lp::Float(1.0), &v), 5.0);
    }

    #[test]
    fn test_lp_matrix_float() {
        let m = matrix![1.0, -2.0;
                        0.5, 1.0];
        assert_eq!(MatrixNorm::norm(&Lp::Float(1.0), &m), 4.5);
    }

    #[test]
    #[should_panic]
    fn test_lp_vector_bad_p() {
        let v = Vector::new(vec![]);
        VectorNorm::norm(&Lp::Float(0.5), &v);
    }

    #[test]
    #[should_panic]
    fn test_lp_matrix_bad_p() {
        let m = matrix![];
        MatrixNorm::norm(&Lp::Float(0.5), &m);
    }

    #[test]
    #[should_panic]
    fn test_lp_vector_bad_int_p() {
        let v: Vector<f64> = Vector::new(vec![]);
        VectorNorm::norm(&Lp::Integer(0), &v);
    }

    #[test]
    #[should_panic]
    fn test_lp_matrix_bad_int_p() {
        let m: Matrix<f64> = matrix![];
        MatrixNorm::norm(&Lp::Integer(0), &m);
    }
}
<commit_msg>Fix and test metric of two MatrixSlice's (#154) (#167)<commit_after>//! The norm module
//!
//! This module contains implementations of various linear algebra norms.
//! The implementations are contained within the `VectorNorm` and
//! `MatrixNorm` traits. This module also contains `VectorMetric` and
//! `MatrixMetric` traits which are used to compute the metric distance.
//!
//! These traits can be used directly by importing implementors from
//! this module. In most cases it will be easier to use the `norm` and
//! `metric` functions which exist for both vectors and matrices. These
//! functions take generic arguments for the norm to be used.
//!
//! In general you should use the least generic norm that fits your purpose.
//! For example you would choose to use a `Euclidean` norm instead of an
//! `Lp(2.0)` norm - despite them being mathematically equivalent.
//!
//! # Defining your own norm
//!
//! Note that these traits enforce no requirements on the norm. It is up
//! to the user to ensure that they define a norm correctly.
//!
//! To define your own norm you need to implement the `MatrixNorm`
//! and/or the `VectorNorm` on your own struct. When you have defined
//! a norm you get the _induced metric_ for free. This means that any
//! object which implements the `VectorNorm` or `MatrixNorm` will
//! automatically implement the `VectorMetric` and `MatrixMetric` traits
//! respectively. This induced metric will compute the norm of the
//! difference between the vectors or matrices.

use matrix::BaseMatrix;
use vector::Vector;
use utils;

use std::ops::Sub;
use libnum::Float;

/// Trait for vector norms
pub trait VectorNorm<T> {
    /// Computes the vector norm.
    fn norm(&self, v: &Vector<T>) -> T;
}

/// Trait for vector metrics.
pub trait VectorMetric<T> {
    /// Computes the metric distance between two vectors.
    fn metric(&self, v1: &Vector<T>, v2: &Vector<T>) -> T;
}

/// Trait for matrix norms.
pub trait MatrixNorm<T, M: BaseMatrix<T>> {
    /// Computes the matrix norm.
    fn norm(&self, m: &M) -> T;
}

/// Trait for matrix metrics.
pub trait MatrixMetric<'a, 'b, T, M1: 'a + BaseMatrix<T>, M2: 'b + BaseMatrix<T>> {
    /// Computes the metric distance between two matrices.
    fn metric(&self, m1: &'a M1, m2: &'b M2) -> T;
}

/// The induced vector metric
///
/// Given a norm `N`, the induced vector metric `M` computes
/// the metric distance, `d`, between two vectors `v1` and `v2`
/// as follows:
///
/// `d = M(v1, v2) = N(v1 - v2)`
impl<U, T> VectorMetric<T> for U
    where U: VectorNorm<T>, T: Copy + Sub<T, Output=T> {
    fn metric(&self, v1: &Vector<T>, v2: &Vector<T>) -> T {
        self.norm(&(v1 - v2))
    }
}

/// The induced matrix metric
///
/// Given a norm `N`, the induced matrix metric `M` computes
/// the metric distance, `d`, between two matrices `m1` and `m2`
/// as follows:
///
/// `d = M(m1, m2) = N(m1 - m2)`
impl<'a, 'b, U, T, M1, M2> MatrixMetric<'a, 'b, T, M1, M2> for U
    where U: MatrixNorm<T, ::matrix::Matrix<T>>,
    M1: 'a + BaseMatrix<T>,
    M2: 'b + BaseMatrix<T>,
    &'a M1: Sub<&'b M2, Output=::matrix::Matrix<T>> {

    fn metric(&self, m1: &'a M1, m2: &'b M2) -> T {
        self.norm(&(m1 - m2))
    }
}

/// The Euclidean norm
///
/// The Euclidean norm computes the square-root
/// of the sum of squares.
///
/// `||v|| = SQRT(SUM(v_i * v_i))`
#[derive(Debug)]
pub struct Euclidean;

impl<T: Float> VectorNorm<T> for Euclidean {
    fn norm(&self, v: &Vector<T>) -> T {
        utils::dot(v.data(), v.data()).sqrt()
    }
}

impl<T: Float, M: BaseMatrix<T>> MatrixNorm<T, M> for Euclidean {
    fn norm(&self, m: &M) -> T {
        let mut s = T::zero();

        for row in m.row_iter() {
            s = s + utils::dot(row.raw_slice(), row.raw_slice());
        }

        s.sqrt()
    }
}

/// The Lp norm
///
/// The
/// [Lp norm](https://en.wikipedia.org/wiki/Norm_(mathematics)#p-norm)
/// computes the `p`th root of the sum of elements
/// to the `p`th power.
///
/// The Lp norm requires `p` to be greater than
/// or equal `1`.
///
/// We use an enum for this norm to allow us to explicitly handle
/// special cases at compile time. For example, we have an `Infinity`
/// variant which handles the special case when the `Lp` norm is a
/// supremum over absolute values. The `Integer` variant gives us a
/// performance boost when `p` is an integer.
///
/// You should avoid matching directly against this enum as it is likely
/// to grow.
#[derive(Debug)]
pub enum Lp<T: Float> {
    /// The L-infinity norm (supremum)
    Infinity,
    /// The Lp norm where p is an integer
    Integer(i32),
    /// The Lp norm where p is a float
    Float(T)
}

impl<T: Float> VectorNorm<T> for Lp<T> {
    fn norm(&self, v: &Vector<T>) -> T {
        match *self {
            Lp::Infinity => {
                // Compute supremum
                let mut abs_sup = T::zero();
                for d in v.iter().map(|d| d.abs()) {
                    if d > abs_sup {
                        abs_sup = d;
                    }
                }
                abs_sup
            },
            Lp::Integer(p) => {
                assert!(p >= 1, "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in v {
                    s = s + x.abs().powi(p);
                }
                s.powf(T::from(p).expect("Could not cast i32 to float").recip())
            },
            Lp::Float(p) => {
                assert!(p >= T::one(), "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in v {
                    s = s + x.abs().powf(p);
                }
                s.powf(p.recip())
            }
        }
    }
}

impl<T: Float, M: BaseMatrix<T>> MatrixNorm<T, M> for Lp<T> {
    fn norm(&self, m: &M) -> T {
        match *self {
            Lp::Infinity => {
                // Compute supremum
                let mut abs_sup = T::zero();
                for d in m.iter().map(|d| d.abs()) {
                    if d > abs_sup {
                        abs_sup = d;
                    }
                }
                abs_sup
            },
            Lp::Integer(p) => {
                assert!(p >= 1, "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in m.iter() {
                    s = s + x.abs().powi(p);
                }
                s.powf(T::from(p).expect("Could not cast i32 to float").recip())
            },
            Lp::Float(p) => {
                assert!(p >= T::one(), "p value in Lp norm must be >= 1");
                // Compute standard lp norm
                let mut s = T::zero();
                for x in m.iter() {
                    s = s + x.abs().powf(p);
                }
                s.powf(p.recip())
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use libnum::Float;
    use std::f64;

    use super::*;
    use vector::Vector;
    use matrix::{Matrix, MatrixSlice};

    #[test]
    fn test_euclidean_vector_norm() {
        let v = vector![3.0, 4.0];
        assert!((VectorNorm::norm(&Euclidean, &v) - 5.0) < 1e-14);
    }

    #[test]
    fn test_euclidean_matrix_norm() {
        let m = matrix![3.0, 4.0;
                        1.0, 3.0];
        assert!((MatrixNorm::norm(&Euclidean, &m) - 35.0.sqrt()) < 1e-14);
    }

    #[test]
    fn test_euclidean_matrix_slice_norm() {
        let m = matrix![3.0, 4.0;
                        1.0, 3.0];

        let slice = MatrixSlice::from_matrix(&m, [0,0], 1, 2);
        assert!((MatrixNorm::norm(&Euclidean, &slice) - 5.0) < 1e-14);
    }

    #[test]
    fn test_euclidean_vector_metric() {
        let v = vector![3.0, 4.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v)) < 1e-14);

        let v1 = vector![0.0, 0.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v1) - 5.0) < 1e-14);

        let v2 = vector![4.0, 3.0];
        assert!((VectorMetric::metric(&Euclidean, &v, &v2) - 2.0.sqrt()) < 1e-14);
    }

    #[test]
    #[should_panic]
    fn test_euclidean_vector_metric_bad_dim() {
        let v = vector![3.0, 4.0];
        let v2 = vector![1.0, 2.0, 3.0];

        VectorMetric::metric(&Euclidean, &v, &v2);
    }

    #[test]
    fn test_euclidean_matrix_metric() {
        let m = matrix![3.0, 4.0;
                        1.0, 3.0];
        assert!((MatrixMetric::metric(&Euclidean, &m, &m)) < 1e-14);

        let m1 = Matrix::zeros(2, 2);
        assert!((MatrixMetric::metric(&Euclidean, &m, &m1) - 35.0.sqrt()) < 1e-14);

        let m2 = matrix![2.0, 3.0;
                         2.0, 4.0];
        assert!((MatrixMetric::metric(&Euclidean, &m, &m2) - 2.0) < 1e-14);
    }

    #[test]
    #[should_panic]
    fn test_euclidean_matrix_metric_bad_dim() {
        let m = matrix![3.0, 4.0];
        let m2 = matrix![1.0, 2.0, 3.0];

        MatrixMetric::metric(&Euclidean, &m, &m2);
    }

    #[test]
    fn test_euclidean_matrix_slice_metric() {
        let m = matrix![
            1.0, 1.0, 1.0;
            1.0, 1.0, 1.0;
            1.0, 1.0, 1.0
        ];

        let m2 = matrix![
            0.0, 0.0, 0.0;
            0.0, 0.0, 0.0;
            0.0, 0.0, 0.0
        ];

        let m_slice = MatrixSlice::from_matrix(
            &m, [0; 2], 1, 2
        );

        let m2_slice = MatrixSlice::from_matrix(
            &m2, [0; 2], 1, 2
        );

        assert!(MatrixMetric::metric(&Euclidean, &m_slice, &m2_slice) == 2.0.sqrt());
    }

    #[test]
    #[should_panic]
    fn test_euclidean_matrix_slice_metric_bad_dim() {
        let m = matrix![3.0, 4.0];
        let m2 = matrix![1.0, 2.0, 3.0];

        let m_slice = MatrixSlice::from_matrix(
            &m, [0; 2], 1, 1
        );

        let m2_slice = MatrixSlice::from_matrix(
            &m2, [0; 2], 1, 2
        );

        MatrixMetric::metric(&Euclidean, &m_slice, &m2_slice);
    }

    #[test]
    fn test_lp_vector_supremum() {
        let v = vector![-5.0, 3.0];

        let sup = VectorNorm::norm(&Lp::Infinity, &v);
        assert_eq!(sup, 5.0);
    }

    #[test]
    fn test_lp_matrix_supremum() {
        let m = matrix![0.0, -2.0;
                        3.5, 1.0];

        let sup = MatrixNorm::norm(&Lp::Infinity, &m);
        assert_eq!(sup, 3.5);
    }

    #[test]
    fn test_lp_vector_one() {
        let v = vector![1.0, 2.0, -2.0];
        assert_eq!(VectorNorm::norm(&Lp::Integer(1), &v), 5.0);
    }

    #[test]
    fn test_lp_matrix_one() {
        let m = matrix![1.0, -2.0;
                        0.5, 1.0];
        assert_eq!(MatrixNorm::norm(&Lp::Integer(1), &m), 4.5);
    }

    #[test]
    fn test_lp_vector_float() {
        let v = vector![1.0, 2.0, -2.0];
        assert_eq!(VectorNorm::norm(&Lp::Float(1.0), &v), 5.0);
    }

    #[test]
    fn test_lp_matrix_float() {
        let m = matrix![1.0, -2.0;
                        0.5, 1.0];
        assert_eq!(MatrixNorm::norm(&Lp::Float(1.0), &m), 4.5);
    }

    #[test]
    #[should_panic]
    fn test_lp_vector_bad_p() {
        let v = Vector::new(vec![]);
        VectorNorm::norm(&Lp::Float(0.5), &v);
    }

    #[test]
    #[should_panic]
    fn test_lp_matrix_bad_p() {
        let m = matrix![];
        MatrixNorm::norm(&Lp::Float(0.5), &m);
    }

    #[test]
    #[should_panic]
    fn test_lp_vector_bad_int_p() {
        let v: Vector<f64> = Vector::new(vec![]);
        VectorNorm::norm(&Lp::Integer(0), &v);
    }

    #[test]
    #[should_panic]
    fn test_lp_matrix_bad_int_p() {
        let m: Matrix<f64> = matrix![];
        MatrixNorm::norm(&Lp::Integer(0), &m);
    }
}
<|endoftext|>


<commit_before>//! A double-ended priority queue implemented with an interval heap.

use std::slice;
use std::default::Default;

// An interval heap is a binary tree structure with the following properties:
//
// (1) Each node (except possibly the last leaf) contains two values
//     where the first one is less than or equal to the second one.
// (2) Each node represents a closed interval.
// (3) A child node's interval is completely contained in the parent node's
//     interval.
//
// This implies that the min and max elements are always in the root node.
//
// This interval heap implementation stores its nodes in a linear array
// using a Vec. Here's an example of the layout of a tree with 13 items
// (7 nodes) where the numbers represent the *offsets* in the array:
//
//          (0 1)
//         /     \
//    (2 3)       (4 5)
//    /   \       /    \
//  (6 7)(8 9)(10 11)(12 --)
//
// Even indices are used for the "left" element of a node while odd indices
// are used for the "right" element of a node. Note: the last node may not
// have a "right" element.

// FIXME: There may be a better algorithm for turning a vector into an
// interval heap. Right now, this takes O(n log n) time, I think.

fn is_root(x: uint) -> bool { x < 2 }

/// Set LSB to zero for the "left" item index of a node.
fn left(x: uint) -> uint { x & !1u }

/// Returns index of "left" item of parent node.
fn parent_left(x: uint) -> uint {
    debug_assert!(!is_root(x));
    left((x - 2) / 2)
}

/// The first `v.len() - 1` elements are considered a valid interval heap
/// and the last element is to be inserted.
fn inteval_heap_push<T: Ord>(v: &mut [T]) {
    debug_assert!(v.len() > 0);
    // Start with the last new/modified node and work our way to
    // the root if necessary...
    let mut node_max = v.len() - 1;
    let mut node_min = left(node_max);
    // The reason for using two variables instead of one is to
    // get around the special case of the last node only containing
    // one element (node_min == node_max).
    if v[node_min] > v[node_max] { v.swap(node_min, node_max); }
    while !is_root(node_min) {
        let par_min = parent_left(node_min);
        let par_max = par_min + 1;
        if v[node_min] < v[par_min] {
            v.swap(par_min, node_min);
        } else if v[par_max] < v[node_max] {
            v.swap(par_max, node_max);
        } else {
            return; // nothing to do anymore
        }
        debug_assert!(v[node_min] <= v[node_max]);
        node_min = par_min;
        node_max = par_max;
    }
}

/// The min element in the root node of an otherwise valid interval heap
/// has been been replaced with some other value without violating rule (1)
/// for the root node. This function restores the interval heap properties.
fn update_min<T: Ord>(v: &mut [T]) {
    // Starting at the root, we go down the tree...
    debug_assert!(v[0] <= v[1]);
    let mut left = 0;
    loop {
        let c1 = left * 2 + 2; // index of 1st child's left element
        let c2 = left * 2 + 4; // index of 2nd child's left element
        if v.len() <= c1 { return; } // No children. We're done.
        // Pick child with lowest min
        let ch = if v.len() <= c2 || v[c1] < v[c2] { c1 }
                 else { c2 };
        if v[ch] < v[left] {
            v.swap(ch, left);
            left = ch;
            let right = left + 1;
            if right < v.len() {
                if v[left] > v[right] { v.swap(left, right); }
            }
        } else {
            break;
        }
    }
}

/// The max element in the root node of an otherwise valid interval heap
/// has been been replaced with some other value without violating rule (1)
/// for the root node. This function restores the interval heap properties.
fn update_max<T: Ord>(v: &mut [T]) {
    debug_assert!(v[0] <= v[1]);
    // Starting at the root, we go down the tree...
    let mut right = 1;
    loop {
        let c1 = right * 2 + 1; // index of 1st child's right element
        let c2 = right * 2 + 3; // index of 2nd child's right element
        if v.len() <= c1 { return; } // No children. We're done.
        // Pick child with greatest max
        let ch = if v.len() <= c2 || v[c1] > v[c2] { c1 }
                 else { c2 };
        if v[ch] > v[right] {
            v.swap(ch, right);
            right = ch;
            let left = right - 1; // always exists
            if v[left] > v[right] { v.swap(left, right); }
        } else {
            break;
        }
    }
}

/// An `IntervalHeap` is an implementation of a double-ended priority queue.
/// As such, it supports the following operations: `push`, `get_min`,
/// `get_max`, `pop_min`, `pop_max` where insertion takes amortized O(log n)
/// time, removal takes O(log n) time and accessing minimum and maximum can
/// be done in constant time. Also, other convenient functions are provided
/// that handle conversion from and into vectors and allow iteration etc.
#[deriving(Clone)]
pub struct IntervalHeap<T> {
    data: Vec<T>
}

impl<T: Ord> Default for IntervalHeap<T> {
    /// Creates an empty `IntervalHeap`.
    #[inline]
    fn default() -> IntervalHeap<T> { IntervalHeap::new() }
}

/// `IntervalHeap` iterator.
pub type Items<'a, T> = slice::Iter<'a, T>;

impl<T: Ord> IntervalHeap<T> {
    /// Creates an empty `IntervalHeap`.
    pub fn new() -> IntervalHeap<T> {
        IntervalHeap { data: Vec::new() }
    }

    /// Creates an empty `IntervalHeap` with a specific capacity. This
    /// preallocates enough memory for capacity elements, so that the
    /// `IntervalHeap` does not have to be reallocated until it contains at
    /// least that many values.
    pub fn with_capacity(c: uint) -> IntervalHeap<T> {
        IntervalHeap { data: Vec::with_capacity(c) }
    }

    /// Creates an `IntervalHeap` from a vector.
    pub fn from_vec(mut v: Vec<T>) -> IntervalHeap<T> {
        for to in range(2, v.len()) {
            inteval_heap_push(v.slice_to_mut(to));
        }
        IntervalHeap { data: v }
    }

    /// An iterator visiting all values in underlying vector,
    /// in arbitrary order.
    pub fn iter(&self) -> Items<T> {
        self.data.iter()
    }

    /// Returns a reference to the smallest item or None (if empty).
    pub fn get_min(&self) -> Option<&T> {
        match self.data.len() {
            0 => None,
            _ => Some(&self.data[0])
        }
    }

    /// Returns a reference to the greatest item or None (if empty).
    pub fn get_max(&self) -> Option<&T> {
        match self.data.len() {
            0 => None,
            1 => Some(&self.data[0]),
            _ => Some(&self.data[1])
        }
    }

    /// Returns references to the smallest and greatest item or None (if empty).
    pub fn get_min_max(&self) -> Option<(&T, &T)> {
        match self.data.len() {
            0 => None,
            1 => Some((&self.data[0],&self.data[0])),
            _ => Some((&self.data[0],&self.data[1]))
        }
    }

    /// Returns the number of items the interval heap could hold
    /// without reallocation.
    pub fn capacity(&self) -> uint {
        self.data.capacity()
    }

    /// Reserves the minimum capacity for exactly `additional` more elements
    /// to be inserted in the given `IntervalHeap`. Does nothing if the capacity
    /// is already sufficient.
    ///
    /// Note that the allocator may give the collection more space than it
    /// requests. Therefore capacity can not be relied upon to be precisely
    /// minimal. Prefer `reserve` if future insertions are expected.
    pub fn reserve_exact(&mut self, additional: uint) {
        self.data.reserve_exact(additional);
    }

    /// Reserves capacity for at least `additional` more elements to be inserted
    /// in the `IntervalHeap`. The collection may reserve more space to avoid
    /// frequent reallocations.
    pub fn reserve(&mut self, additional: uint) {
        self.data.reserve(additional);
    }

    /// Discards as much additional capacity as possible.
    pub fn shrink_to_fit(&mut self) {
        self.data.shrink_to_fit()
    }

    /// Removes the smallest item and returns it, or None if is empty.
    pub fn pop_min(&mut self) -> Option<T> {
        match self.data.len() {
            0 => None,
            1...2 => self.data.swap_remove(0),
            _ => {
                let res = self.data.swap_remove(0);
                update_min(self.data.as_mut_slice());
                res
            }
        }
    }

    /// Removes the greatest item and returns it, or None if is empty.
    pub fn pop_max(&mut self) -> Option<T> {
        match self.data.len() {
            0...2 => self.data.pop(),
            _ => {
                let res = self.data.swap_remove(1);
                update_max(self.data.as_mut_slice());
                res
            }
        }
    }

    /// Pushes an item onto the queue.
    pub fn push(&mut self, x: T) {
        self.data.push(x);
        inteval_heap_push(self.data.as_mut_slice());
    }

    /// Consumes the `IntervalHeap` and returns the underlying vector
    /// in arbitrary order.
    pub fn into_vec(self) -> Vec<T> { self.data }

    /// Consumes the `IntervalHeap` and returns a vector in sorted
    /// (ascending) order.
    pub fn into_sorted_vec(self) -> Vec<T> {
        let mut vec = self.data;
        for hsize in range(2, vec.len()).rev() {
            vec.swap(1, hsize);
            update_max(vec.slice_to_mut(hsize));
        }
        vec
    }

    /// Returns the number of items in the interval heap
    pub fn len(&self) -> uint {
        self.data.len()
    }

    /// Returns true if the queue contains no items.
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Drops all items from the queue.
    pub fn clear(&mut self) {
        self.data.clear();
    }
}

impl<T: Ord> FromIterator<T> for IntervalHeap<T> {
    /// Creates an interval heap with all the items from an iterator
    fn from_iter<Iter: Iterator<T>>(iter: Iter) -> IntervalHeap<T> {
        let vec: Vec<T> = iter.collect();
        IntervalHeap::from_vec(vec)
    }
}

impl<T: Ord> Extend<T> for IntervalHeap<T> {
    /// Extends the interval heap by a new chunk of items given by
    /// an iterator.
    fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
        let (lower, _) = iter.size_hint();
        self.reserve(lower);
        for elem in iter {
            self.push(elem);
        }
    }
}

#[cfg(test)]
pub fn as_slice<T>(x: &IntervalHeap<T>) -> &[T] {
    x.data.as_slice()
}

#[cfg(test)]
mod test {
    use std::rand::{ task_rng, Rng };
    use super::{ IntervalHeap, as_slice };

    fn is_interval_heap<T: Ord>(x: &[T]) -> bool {
        if x.len() < 2 { return true; }
        if x[1] < x[0] { return false; }
        let mut ofs = 2;
        while ofs < x.len() {
            let ofz = ofs + (ofs + 1 < x.len()) as uint;
            if x[ofz] < x[ofs] { return false; }
            let parent = (ofs / 2 - 1) & !1u;
            if x[ofs] < x[parent] { return false; }
            if x[parent+1] < x[ofz] { return false; }
            ofs += 2;
        }
        true
    }

    #[test]
    fn fuzz_push_into_sorted_vec() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
                assert!(is_interval_heap(as_slice(&ih)));
            }
            tmp = ih.into_sorted_vec();
            for pair in tmp.windows(2) {
                assert!(pair[0] <= pair[1]);
            }
        }
    }

    #[test]
    fn fuzz_pop_min() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
            }
            let mut tmpx: Option<u32> = None;
            loop {
                let tmpy = ih.pop_min();
                assert!(is_interval_heap(as_slice(&ih)));
                match (tmpx, tmpy) {
                    (_, None) => break,
                    (Some(x), Some(y)) => assert!(x <= y),
                    _ => ()
                }
                tmpx = tmpy;
            }
            tmp = ih.into_vec();
        }
    }

    #[test]
    fn fuzz_pop_max() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
            }
            let mut tmpx: Option<u32> = None;
            loop {
                let tmpy = ih.pop_max();
                assert!(is_interval_heap(as_slice(&ih)));
                match (tmpx, tmpy) {
                    (_, None) => break,
                    (Some(x), Some(y)) => assert!(x >= y),
                    _ => ()
                }
                tmpx = tmpy;
            }
            tmp = ih.into_vec();
        }
    }

} // mod test

<commit_msg>correct `IntervalHeap::from_vec`<commit_after>//! A double-ended priority queue implemented with an interval heap.

use std::slice;
use std::default::Default;

// An interval heap is a binary tree structure with the following properties:
//
// (1) Each node (except possibly the last leaf) contains two values
//     where the first one is less than or equal to the second one.
// (2) Each node represents a closed interval.
// (3) A child node's interval is completely contained in the parent node's
//     interval.
//
// This implies that the min and max elements are always in the root node.
//
// This interval heap implementation stores its nodes in a linear array
// using a Vec. Here's an example of the layout of a tree with 13 items
// (7 nodes) where the numbers represent the *offsets* in the array:
//
//          (0 1)
//         /     \
//    (2 3)       (4 5)
//    /   \       /    \
//  (6 7)(8 9)(10 11)(12 --)
//
// Even indices are used for the "left" element of a node while odd indices
// are used for the "right" element of a node. Note: the last node may not
// have a "right" element.

// FIXME: There may be a better algorithm for turning a vector into an
// interval heap. Right now, this takes O(n log n) time, I think.

fn is_root(x: uint) -> bool { x < 2 }

/// Set LSB to zero for the "left" item index of a node.
fn left(x: uint) -> uint { x & !1u }

/// Returns index of "left" item of parent node.
fn parent_left(x: uint) -> uint {
    debug_assert!(!is_root(x));
    left((x - 2) / 2)
}

/// The first `v.len() - 1` elements are considered a valid interval heap
/// and the last element is to be inserted.
fn inteval_heap_push<T: Ord>(v: &mut [T]) {
    debug_assert!(v.len() > 0);
    // Start with the last new/modified node and work our way to
    // the root if necessary...
    let mut node_max = v.len() - 1;
    let mut node_min = left(node_max);
    // The reason for using two variables instead of one is to
    // get around the special case of the last node only containing
    // one element (node_min == node_max).
    if v[node_min] > v[node_max] { v.swap(node_min, node_max); }
    while !is_root(node_min) {
        let par_min = parent_left(node_min);
        let par_max = par_min + 1;
        if v[node_min] < v[par_min] {
            v.swap(par_min, node_min);
        } else if v[par_max] < v[node_max] {
            v.swap(par_max, node_max);
        } else {
            return; // nothing to do anymore
        }
        debug_assert!(v[node_min] <= v[node_max]);
        node_min = par_min;
        node_max = par_max;
    }
}

/// The min element in the root node of an otherwise valid interval heap
/// has been been replaced with some other value without violating rule (1)
/// for the root node. This function restores the interval heap properties.
fn update_min<T: Ord>(v: &mut [T]) {
    // Starting at the root, we go down the tree...
    debug_assert!(v[0] <= v[1]);
    let mut left = 0;
    loop {
        let c1 = left * 2 + 2; // index of 1st child's left element
        let c2 = left * 2 + 4; // index of 2nd child's left element
        if v.len() <= c1 { return; } // No children. We're done.
        // Pick child with lowest min
        let ch = if v.len() <= c2 || v[c1] < v[c2] { c1 }
                 else { c2 };
        if v[ch] < v[left] {
            v.swap(ch, left);
            left = ch;
            let right = left + 1;
            if right < v.len() {
                if v[left] > v[right] { v.swap(left, right); }
            }
        } else {
            break;
        }
    }
}

/// The max element in the root node of an otherwise valid interval heap
/// has been been replaced with some other value without violating rule (1)
/// for the root node. This function restores the interval heap properties.
fn update_max<T: Ord>(v: &mut [T]) {
    debug_assert!(v[0] <= v[1]);
    // Starting at the root, we go down the tree...
    let mut right = 1;
    loop {
        let c1 = right * 2 + 1; // index of 1st child's right element
        let c2 = right * 2 + 3; // index of 2nd child's right element
        if v.len() <= c1 { return; } // No children. We're done.
        // Pick child with greatest max
        let ch = if v.len() <= c2 || v[c1] > v[c2] { c1 }
                 else { c2 };
        if v[ch] > v[right] {
            v.swap(ch, right);
            right = ch;
            let left = right - 1; // always exists
            if v[left] > v[right] { v.swap(left, right); }
        } else {
            break;
        }
    }
}

/// An `IntervalHeap` is an implementation of a double-ended priority queue.
/// As such, it supports the following operations: `push`, `get_min`,
/// `get_max`, `pop_min`, `pop_max` where insertion takes amortized O(log n)
/// time, removal takes O(log n) time and accessing minimum and maximum can
/// be done in constant time. Also, other convenient functions are provided
/// that handle conversion from and into vectors and allow iteration etc.
#[deriving(Clone)]
pub struct IntervalHeap<T> {
    data: Vec<T>
}

impl<T: Ord> Default for IntervalHeap<T> {
    /// Creates an empty `IntervalHeap`.
    #[inline]
    fn default() -> IntervalHeap<T> { IntervalHeap::new() }
}

/// `IntervalHeap` iterator.
pub type Items<'a, T> = slice::Iter<'a, T>;

impl<T: Ord> IntervalHeap<T> {
    /// Creates an empty `IntervalHeap`.
    pub fn new() -> IntervalHeap<T> {
        IntervalHeap { data: Vec::new() }
    }

    /// Creates an empty `IntervalHeap` with a specific capacity. This
    /// preallocates enough memory for capacity elements, so that the
    /// `IntervalHeap` does not have to be reallocated until it contains at
    /// least that many values.
    pub fn with_capacity(c: uint) -> IntervalHeap<T> {
        IntervalHeap { data: Vec::with_capacity(c) }
    }

    /// Creates an `IntervalHeap` from a vector.
    pub fn from_vec(mut v: Vec<T>) -> IntervalHeap<T> {
        for to in 2 .. v.len() + 1 {
            inteval_heap_push(v.slice_to_mut(to));
        }
        IntervalHeap { data: v }
    }

    /// An iterator visiting all values in underlying vector,
    /// in arbitrary order.
    pub fn iter(&self) -> Items<T> {
        self.data.iter()
    }

    /// Returns a reference to the smallest item or None (if empty).
    pub fn get_min(&self) -> Option<&T> {
        match self.data.len() {
            0 => None,
            _ => Some(&self.data[0])
        }
    }

    /// Returns a reference to the greatest item or None (if empty).
    pub fn get_max(&self) -> Option<&T> {
        match self.data.len() {
            0 => None,
            1 => Some(&self.data[0]),
            _ => Some(&self.data[1])
        }
    }

    /// Returns references to the smallest and greatest item or None (if empty).
    pub fn get_min_max(&self) -> Option<(&T, &T)> {
        match self.data.len() {
            0 => None,
            1 => Some((&self.data[0],&self.data[0])),
            _ => Some((&self.data[0],&self.data[1]))
        }
    }

    /// Returns the number of items the interval heap could hold
    /// without reallocation.
    pub fn capacity(&self) -> uint {
        self.data.capacity()
    }

    /// Reserves the minimum capacity for exactly `additional` more elements
    /// to be inserted in the given `IntervalHeap`. Does nothing if the capacity
    /// is already sufficient.
    ///
    /// Note that the allocator may give the collection more space than it
    /// requests. Therefore capacity can not be relied upon to be precisely
    /// minimal. Prefer `reserve` if future insertions are expected.
    pub fn reserve_exact(&mut self, additional: uint) {
        self.data.reserve_exact(additional);
    }

    /// Reserves capacity for at least `additional` more elements to be inserted
    /// in the `IntervalHeap`. The collection may reserve more space to avoid
    /// frequent reallocations.
    pub fn reserve(&mut self, additional: uint) {
        self.data.reserve(additional);
    }

    /// Discards as much additional capacity as possible.
    pub fn shrink_to_fit(&mut self) {
        self.data.shrink_to_fit()
    }

    /// Removes the smallest item and returns it, or None if is empty.
    pub fn pop_min(&mut self) -> Option<T> {
        match self.data.len() {
            0 => None,
            1...2 => self.data.swap_remove(0),
            _ => {
                let res = self.data.swap_remove(0);
                update_min(self.data.as_mut_slice());
                res
            }
        }
    }

    /// Removes the greatest item and returns it, or None if is empty.
    pub fn pop_max(&mut self) -> Option<T> {
        match self.data.len() {
            0...2 => self.data.pop(),
            _ => {
                let res = self.data.swap_remove(1);
                update_max(self.data.as_mut_slice());
                res
            }
        }
    }

    /// Pushes an item onto the queue.
    pub fn push(&mut self, x: T) {
        self.data.push(x);
        inteval_heap_push(self.data.as_mut_slice());
    }

    /// Consumes the `IntervalHeap` and returns the underlying vector
    /// in arbitrary order.
    pub fn into_vec(self) -> Vec<T> { self.data }

    /// Consumes the `IntervalHeap` and returns a vector in sorted
    /// (ascending) order.
    pub fn into_sorted_vec(self) -> Vec<T> {
        let mut vec = self.data;
        for hsize in range(2, vec.len()).rev() {
            vec.swap(1, hsize);
            update_max(vec.slice_to_mut(hsize));
        }
        vec
    }

    /// Returns the number of items in the interval heap
    pub fn len(&self) -> uint {
        self.data.len()
    }

    /// Returns true if the queue contains no items.
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Drops all items from the queue.
    pub fn clear(&mut self) {
        self.data.clear();
    }
}

impl<T: Ord> FromIterator<T> for IntervalHeap<T> {
    /// Creates an interval heap with all the items from an iterator
    fn from_iter<Iter: Iterator<T>>(iter: Iter) -> IntervalHeap<T> {
        let vec: Vec<T> = iter.collect();
        IntervalHeap::from_vec(vec)
    }
}

impl<T: Ord> Extend<T> for IntervalHeap<T> {
    /// Extends the interval heap by a new chunk of items given by
    /// an iterator.
    fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
        let (lower, _) = iter.size_hint();
        self.reserve(lower);
        for elem in iter {
            self.push(elem);
        }
    }
}

#[cfg(test)]
pub fn as_slice<T>(x: &IntervalHeap<T>) -> &[T] {
    x.data.as_slice()
}

#[cfg(test)]
mod test {
    use std::rand::{ task_rng, Rng };
    use super::{ IntervalHeap, as_slice };

    fn is_interval_heap<T: Ord>(x: &[T]) -> bool {
        if x.len() < 2 { return true; }
        if x[1] < x[0] { return false; }
        let mut ofs = 2;
        while ofs < x.len() {
            let ofz = ofs + (ofs + 1 < x.len()) as uint;
            if x[ofz] < x[ofs] { return false; }
            let parent = (ofs / 2 - 1) & !1u;
            if x[ofs] < x[parent] { return false; }
            if x[parent+1] < x[ofz] { return false; }
            ofs += 2;
        }
        true
    }

    #[test]
    fn fuzz_push_into_sorted_vec() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
                assert!(is_interval_heap(as_slice(&ih)));
            }
            tmp = ih.into_sorted_vec();
            for pair in tmp.windows(2) {
                assert!(pair[0] <= pair[1]);
            }
        }
    }

    #[test]
    fn fuzz_pop_min() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
            }
            let mut tmpx: Option<u32> = None;
            loop {
                let tmpy = ih.pop_min();
                assert!(is_interval_heap(as_slice(&ih)));
                match (tmpx, tmpy) {
                    (_, None) => break,
                    (Some(x), Some(y)) => assert!(x <= y),
                    _ => ()
                }
                tmpx = tmpy;
            }
            tmp = ih.into_vec();
        }
    }

    #[test]
    fn fuzz_pop_max() {
        let mut rng = task_rng();
        let mut tmp = Vec::with_capacity(100);
        for _ in range(0, 100u) {
            tmp.clear();
            let mut ih: IntervalHeap<u32> = IntervalHeap::from_vec(tmp);
            for _ in range(0, 100u) {
                ih.push(rng.next_u32());
            }
            let mut tmpx: Option<u32> = None;
            loop {
                let tmpy = ih.pop_max();
                assert!(is_interval_heap(as_slice(&ih)));
                match (tmpx, tmpy) {
                    (_, None) => break,
                    (Some(x), Some(y)) => assert!(x >= y),
                    _ => ()
                }
                tmpx = tmpy;
            }
            tmp = ih.into_vec();
        }
    }

    #[test]
    fn test_from_vec() {
        let heap = IntervalHeap::<uint>::from_vec(vec![]);
        assert_eq!(heap.get_min_max(), None);

        let heap = IntervalHeap::from_vec(vec![2u]);
        assert_eq!(heap.get_min_max(), Some((&2, &2)));

        let heap = IntervalHeap::from_vec(vec![2u, 1]);
        assert_eq!(heap.get_min_max(), Some((&1, &2)));

        let heap = IntervalHeap::from_vec(vec![2u, 1, 3]);
        assert_eq!(heap.get_min_max(), Some((&1, &3)));
    }
} // mod test

<|endoftext|>


<commit_before>use alloc::arc::Arc;
use alloc::boxed::FnBox;
use alloc::heap;
use arch::cpu;
use arch::thread;
use collections::vec_deque::VecDeque;
use core::mem;
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use libc::{self,jmp_buf};
use mutex::{Mutex,MutexGuard};
use prelude::*;
use process::Process;
use singleton::Singleton;

static SCHEDULER: Singleton<Mutex<SchedulerState>> = Singleton::new();

fn setjmp() -> Option<jmp_buf> {
    unsafe {
        let mut jmp_buf = mem::uninitialized();
        if libc::setjmp(&mut jmp_buf) == 0 {
            Some(jmp_buf)
        } else {
            None
        }
    }
}

fn drop_write_guard<'a, T>(guard: MutexGuard<'a, T>) {
    mem::drop(guard);
}

fn forget_write_guard<'a, T>(guard: MutexGuard<'a, T>) {
    mem::forget(guard);
}

fn assert_no_lock() {
    assert!(cpu::interrupts_enabled());
}

struct Thread {
    id: usize,
    stack: &'static mut [u8],
    process: Arc<Process>
}

impl Thread {
    pub fn new(process: Arc<Process>, stack: &'static mut [u8]) -> Thread {
        static NEXT_THREAD_ID: AtomicUsize = ATOMIC_USIZE_INIT;
        Thread {
            id: NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed),
            stack: stack,
            process: process
        }
    }
}

struct DeferredState<A> {
    result: Option<A>,
    waiters: VecDeque<(jmp_buf, Thread)>
}

struct SchedulerState {
    current: Thread,
    threads: VecDeque<(jmp_buf, Thread)>,
    garbage_stacks: Vec<&'static mut [u8]>
}

impl Drop for SchedulerState {
    fn drop(&mut self) {
        let garbage_stacks = mem::replace(&mut self.garbage_stacks, Vec::new());

        for stack in garbage_stacks {
            unsafe { heap::deallocate(stack.as_mut_ptr(), stack.len(), 16) };
        }
    }
}

pub struct Deferred<A> {
    state: Arc<Mutex<DeferredState<A>>>
}

pub fn with_scheduler<F: FnOnce()>(idle_process: Arc<Process>, f: F) {
    let state = SchedulerState {
        current: Thread::new(idle_process, &mut []),
        threads: VecDeque::new(),
        garbage_stacks: Vec::new()
    };

    let _d = SCHEDULER.register(Mutex::new(state));
    f()
}

fn current_sched() -> &'static Mutex<SchedulerState> {
    SCHEDULER.get().expect("no Scheduler registered")
}

macro_rules! lock_sched {
    () => (lock!(current_sched()))
}

pub fn schedule() {
    assert_no_lock();

    let mut state = lock_sched!();
    match state.threads.pop_front() {
        Some((new_jmp_buf, new_current)) => {
            let old_current = mem::replace(&mut state.current, new_current);

            match setjmp() {
                Some(old_jmp_buf) => {
                    state.threads.push_back((old_jmp_buf, old_current));
                    drop_write_guard(state);

                    unsafe {
                        libc::longjmp(&new_jmp_buf, 1);
                    }
                },

                None => {
                    forget_write_guard(state);
                }
            }
        },

        None => { }
    };
}

pub fn exit() -> ! {
    assert_no_lock();

    let mut state = lock_sched!();
    let (new_jmp_buf, new_current) =
        match state.threads.pop_front() {
            Some(front) => front,
            None => panic!("exit({}): no more threads", state.current.id)
        };

    let old_current = mem::replace(&mut state.current, new_current);
    state.garbage_stacks.push(old_current.stack);
    drop_write_guard(state);

    unsafe {
        libc::longjmp(&new_jmp_buf, 1);
    }
}

fn spawn_inner<'a>(process: Arc<Process>, start: Box<FnBox() + 'a>) {
    let stack_len = 4096;
    let stack_base_ptr = unsafe { heap::allocate(stack_len, 16) };
    let b: Box<FnBox() + 'a> = Box::new(start);
    let jmp_buf = thread::new_jmp_buf(b, unsafe { stack_base_ptr.offset(stack_len as isize) });
    let thread = Thread::new(process, unsafe { slice::from_raw_parts_mut(stack_base_ptr, stack_len) });

    {
        let mut state = lock_sched!();
        state.threads.push_back((jmp_buf, thread));
    }
}

pub fn spawn_user_mode(pc: *const u8, stack: &mut [u8]) {
    let stack_ptr = stack.as_mut_ptr();
    let stack_len = stack.len();

    let start = move || {
        unsafe {
            thread::jmp_user_mode(pc, stack_ptr.offset(stack_len as isize))
        }
        // TODO: free stack
    };

    let process = lock_sched!().current.process.clone();
    spawn_inner(process, Box::new(start))
}

pub fn spawn_remote<T, A>(process: Arc<Process>, start: T) -> Deferred<A> where T : FnOnce() -> A {
    let d = Deferred::new();

    let start = {
        let d = d.clone();
        move || {
            let result = start();
            d.resolve(result);
            exit();
        }
    };

    spawn_inner(process, Box::new(start));
    d
}

pub fn spawn<T, A>(start: T) -> Deferred<A> where T : FnOnce() -> A {
    let process = lock_sched!().current.process.clone();
    spawn_remote(process, start)
}

impl<A> Clone for Deferred<A> {
    fn clone(&self) -> Self {
        Deferred { state: self.state.clone() }
    }
}

impl<A> Deferred<A> {
    pub fn new() -> Self {
        let dstate = Arc::new(Mutex::new(DeferredState {
            result: None,
            waiters: VecDeque::new()
        }));

        Deferred { state: dstate }
    }

    pub fn resolve(&self, result: A) {
        let mut dstate = lock!(self.state);
        match dstate.result {
            Some(_) => panic!("promise is already resolved"),
            None => { }
        }

        dstate.result = Some(result);

        let mut waiters = mem::replace(&mut dstate.waiters, VecDeque::new());
        if waiters.len() > 0 {
            let mut state = lock_sched!();
            state.threads.append(&mut waiters);
        }
    }

    pub fn get(self) -> A {
        loop {
            assert_no_lock();

            let mut dstate = lock!(self.state);
            match mem::replace(&mut dstate.result, None) {
                Some(result) => { return result; },
                None => { }
            }

            let mut state = lock_sched!();
            let (new_jmp_buf, new_current) =
                match state.threads.pop_front() {
                    Some(front) => front,
                    None => panic!("block({}): no more threads", state.current.id)
                };

            let old_current = mem::replace(&mut state.current, new_current);

            match setjmp() {
                Some(old_jmp_buf) => {
                    dstate.waiters.push_back((old_jmp_buf, old_current));
                    drop_write_guard(state);
                    drop_write_guard(dstate);

                    unsafe {
                        libc::longjmp(&new_jmp_buf, 1);
                    }
                },

                None => {
                    forget_write_guard(state);
                    forget_write_guard(dstate);
                }
            }
        }
    }

    pub fn try_get(self) -> Result<A, Self> {
        let opt = {
            let mut state = lock!(self.state);
            mem::replace(&mut state.result, None)
        };

        opt.ok_or(self)
    }
}

#[cfg(feature = "test")]
pub mod test {
    use alloc::arc::Arc;
    use phys_mem::PhysicalBitmap;
    use prelude::*;
    use process::Process;
    use super::*;
    use virt_mem::VirtualTree;

    test! {
        fn can_spawn_exit_thread() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let d = spawn(|| 123);
                assert_eq!(123, d.get());
            });
        }

        fn can_spawn_exit_two_threads() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let d1 = spawn(|| 456);
                let d2 = spawn(|| 789);
                assert_eq!(456, d1.get());
                assert_eq!(789, d2.get());
            });
        }

        fn can_closure() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let s = String::from("hello");
                let d = spawn(move || s + &" world");
                assert_eq!("hello world", d.get());
            });
        }

        fn threads_can_spawn_more_threads() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let thread2_fn = || 1234;

                let thread1_fn = {
                    || {
                        let d = spawn(thread2_fn);
                        d.get() * 2
                    }
                };

                let d = spawn(thread1_fn);
                assert_eq!(1234 * 2, d.get());
            });
        }
    }
}
<commit_msg>Exit threads cleanly<commit_after>use alloc::arc::Arc;
use alloc::boxed::FnBox;
use alloc::heap;
use arch::cpu;
use arch::thread;
use collections::vec_deque::VecDeque;
use core::mem;
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use libc::{self,jmp_buf};
use mutex::{Mutex,MutexGuard};
use prelude::*;
use process::Process;
use singleton::Singleton;

static SCHEDULER: Singleton<Mutex<SchedulerState>> = Singleton::new();

fn setjmp() -> Option<jmp_buf> {
    unsafe {
        let mut jmp_buf = mem::uninitialized();
        if libc::setjmp(&mut jmp_buf) == 0 {
            Some(jmp_buf)
        } else {
            None
        }
    }
}

fn drop_write_guard<'a, T>(guard: MutexGuard<'a, T>) {
    mem::drop(guard);
}

fn forget_write_guard<'a, T>(guard: MutexGuard<'a, T>) {
    mem::forget(guard);
}

fn assert_no_lock() {
    assert!(cpu::interrupts_enabled());
}

struct Thread {
    id: usize,
    stack: &'static mut [u8],
    process: Arc<Process>
}

impl Thread {
    pub fn new(process: Arc<Process>, stack: &'static mut [u8]) -> Thread {
        static NEXT_THREAD_ID: AtomicUsize = ATOMIC_USIZE_INIT;
        Thread {
            id: NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed),
            stack: stack,
            process: process
        }
    }
}

struct DeferredState<A> {
    result: Option<A>,
    waiters: VecDeque<(jmp_buf, Thread)>
}

struct SchedulerState {
    current: Thread,
    threads: VecDeque<(jmp_buf, Thread)>,
    garbage_stacks: Vec<&'static mut [u8]>
}

impl Drop for SchedulerState {
    fn drop(&mut self) {
        let garbage_stacks = mem::replace(&mut self.garbage_stacks, Vec::new());

        for stack in garbage_stacks {
            unsafe { heap::deallocate(stack.as_mut_ptr(), stack.len(), 16) };
        }
    }
}

pub struct Deferred<A> {
    state: Arc<Mutex<DeferredState<A>>>
}

#[inline(never)] // hmm?
pub fn with_scheduler<F: FnOnce()>(idle_process: Arc<Process>, f: F) {
    let state = SchedulerState {
        current: Thread::new(idle_process, &mut []),
        threads: VecDeque::new(),
        garbage_stacks: Vec::new()
    };

    let _d = SCHEDULER.register(Mutex::new(state));
    f()
}

fn current_sched() -> &'static Mutex<SchedulerState> {
    SCHEDULER.get().expect("no Scheduler registered")
}

macro_rules! lock_sched {
    () => (lock!(current_sched()))
}

pub fn schedule() {
    assert_no_lock();

    let mut state = lock_sched!();
    match state.threads.pop_front() {
        Some((new_jmp_buf, new_current)) => {
            let old_current = mem::replace(&mut state.current, new_current);

            match setjmp() {
                Some(old_jmp_buf) => {
                    state.threads.push_back((old_jmp_buf, old_current));
                    drop_write_guard(state);

                    unsafe {
                        libc::longjmp(&new_jmp_buf, 1);
                    }
                },

                None => {
                    forget_write_guard(state);
                }
            }
        },

        None => { }
    };
}

pub fn exit() -> ! {
    assert_no_lock();

    let new_jmp_buf = {
        let mut state = lock_sched!();
        let (new_jmp_buf, new_current) =
            match state.threads.pop_front() {
                Some(front) => front,
                None => panic!("exit({}): no more threads", state.current.id)
            };

        let old_current = mem::replace(&mut state.current, new_current);
        state.garbage_stacks.push(old_current.stack);
        new_jmp_buf
    };

    unsafe {
        libc::longjmp(&new_jmp_buf, 1);
    }
}

fn spawn_inner<'a>(process: Arc<Process>, start: Box<FnBox() + 'a>) {
    let stack_len = 4096;
    let stack_base_ptr = unsafe { heap::allocate(stack_len, 16) };
    let b: Box<FnBox() + 'a> = Box::new(start);
    let jmp_buf = thread::new_jmp_buf(b, unsafe { stack_base_ptr.offset(stack_len as isize) });
    let thread = Thread::new(process, unsafe { slice::from_raw_parts_mut(stack_base_ptr, stack_len) });

    {
        let mut state = lock_sched!();
        state.threads.push_back((jmp_buf, thread));
    }
}

pub fn spawn_user_mode(pc: *const u8, stack: &mut [u8]) {
    let stack_ptr = stack.as_mut_ptr();
    let stack_len = stack.len();

    let start = move || {
        unsafe {
            thread::jmp_user_mode(pc, stack_ptr.offset(stack_len as isize))
        }
        // TODO: free stack
    };

    let process = lock_sched!().current.process.clone();
    spawn_inner(process, Box::new(start))
}

pub fn spawn_remote<T, A>(process: Arc<Process>, start: T) -> Deferred<A> where T : FnOnce() -> A {
    let d = Deferred::new();

    let start = {
        let d = d.clone();
        move || {
            let result = start();
            d.resolve(result);
            exit();
        }
    };

    spawn_inner(process, Box::new(start));
    d
}

pub fn spawn<T, A>(start: T) -> Deferred<A> where T : FnOnce() -> A {
    let process = lock_sched!().current.process.clone();
    spawn_remote(process, start)
}

impl<A> Clone for Deferred<A> {
    fn clone(&self) -> Self {
        Deferred { state: self.state.clone() }
    }
}

impl<A> Deferred<A> {
    pub fn new() -> Self {
        let dstate = Arc::new(Mutex::new(DeferredState {
            result: None,
            waiters: VecDeque::new()
        }));

        Deferred { state: dstate }
    }

    pub fn resolve(&self, result: A) {
        let mut dstate = lock!(self.state);
        match dstate.result {
            Some(_) => panic!("promise is already resolved"),
            None => { }
        }

        dstate.result = Some(result);

        let mut waiters = mem::replace(&mut dstate.waiters, VecDeque::new());
        if waiters.len() > 0 {
            let mut state = lock_sched!();
            state.threads.append(&mut waiters);
        }
    }

    pub fn get(self) -> A {
        loop {
            assert_no_lock();

            let mut dstate = lock!(self.state);
            match mem::replace(&mut dstate.result, None) {
                Some(result) => { return result; },
                None => { }
            }

            let mut state = lock_sched!();
            let (new_jmp_buf, new_current) =
                match state.threads.pop_front() {
                    Some(front) => front,
                    None => panic!("block({}): no more threads", state.current.id)
                };

            let old_current = mem::replace(&mut state.current, new_current);

            match setjmp() {
                Some(old_jmp_buf) => {
                    dstate.waiters.push_back((old_jmp_buf, old_current));
                    drop_write_guard(state);
                    drop_write_guard(dstate);

                    unsafe {
                        libc::longjmp(&new_jmp_buf, 1);
                    }
                },

                None => {
                    forget_write_guard(state);
                    forget_write_guard(dstate);
                }
            }
        }
    }

    pub fn try_get(self) -> Result<A, Self> {
        let opt = {
            let mut state = lock!(self.state);
            mem::replace(&mut state.result, None)
        };

        opt.ok_or(self)
    }
}

#[cfg(feature = "test")]
pub mod test {
    use alloc::arc::Arc;
    use phys_mem::PhysicalBitmap;
    use prelude::*;
    use process::Process;
    use super::*;
    use virt_mem::VirtualTree;

    test! {
        fn can_spawn_exit_thread() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let d = spawn(|| 123);
                assert_eq!(123, d.get());
            });
        }

        fn can_spawn_exit_two_threads() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let d1 = spawn(|| 456);
                let d2 = spawn(|| 789);
                assert_eq!(456, d1.get());
                assert_eq!(789, d2.get());
            });
        }

        fn can_closure() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let s = String::from("hello");
                let d = spawn(move || s + &" world");
                assert_eq!("hello world", d.get());
            });
        }

        fn threads_can_spawn_more_threads() {
            let phys = Arc::new(PhysicalBitmap::parse_multiboot());
            let kernel_virt = Arc::new(VirtualTree::new());
            let p = Arc::new(Process::new(phys, kernel_virt).unwrap());
            with_scheduler(p, || {
                let thread2_fn = || 1234;

                let thread1_fn = {
                    || {
                        let d = spawn(thread2_fn);
                        d.get() * 2
                    }
                };

                let d = spawn(thread1_fn);
                assert_eq!(1234 * 2, d.get());
            });
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 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.

//! Implementations of things like `Eq` for fixed-length arrays
//! up to a certain length. Eventually we should able to generalize
//! to all lengths.
//!
//! *[See also the array primitive type](../primitive.array.html).*

#![unstable(feature = "fixed_size_array",
            reason = "traits and impls are better expressed through generic \
                      integer constants",
            issue = "27778")]

use borrow::{Borrow, BorrowMut};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use convert::{AsRef, AsMut};
use default::Default;
use fmt;
use hash::{Hash, self};
use iter::IntoIterator;
use marker::{Copy, Sized, Unsize};
use option::Option;
use slice::{Iter, IterMut, SliceExt};

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
pub trait FixedSizeArray<T> {
    /// Converts the array to immutable slice
    fn as_slice(&self) -> &[T];
    /// Converts the array to mutable slice
    fn as_mut_slice(&mut self) -> &mut [T];
}

impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
    #[inline]
    fn as_slice(&self) -> &[T] {
        self
    }
    #[inline]
    fn as_mut_slice(&mut self) -> &mut [T] {
        self
    }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            impl<T> AsRef<[T]> for [T; $N] {
                #[inline]
                fn as_ref(&self) -> &[T] {
                    &self[..]
                }
            }

            impl<T> AsMut<[T]> for [T; $N] {
                #[inline]
                fn as_mut(&mut self) -> &mut [T] {
                    &mut self[..]
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> Borrow<[T]> for [T; $N] {
                fn borrow(&self) -> &[T] {
                    self
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> BorrowMut<[T]> for [T; $N] {
                fn borrow_mut(&mut self) -> &mut [T] {
                    self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Copy> Clone for [T; $N] {
                fn clone(&self) -> [T; $N] {
                    *self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: Hash> Hash for [T; $N] {
                fn hash<H: hash::Hasher>(&self, state: &mut H) {
                    Hash::hash(&self[..], state)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: fmt::Debug> fmt::Debug for [T; $N] {
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    fmt::Debug::fmt(&&self[..], f)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a [T; $N] {
                type Item = &'a T;
                type IntoIter = Iter<'a, T>;

                fn into_iter(self) -> Iter<'a, T> {
                    self.iter()
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a mut [T; $N] {
                type Item = &'a mut T;
                type IntoIter = IterMut<'a, T>;

                fn into_iter(self) -> IterMut<'a, T> {
                    self.iter_mut()
                }
            }

            // NOTE: some less important impls are omitted to reduce code bloat
            __impl_slice_eq1! { [A; $N], [B; $N] }
            __impl_slice_eq2! { [A; $N], [B] }
            __impl_slice_eq2! { [A; $N], &'b [B] }
            __impl_slice_eq2! { [A; $N], &'b mut [B] }
            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Eq> Eq for [T; $N] { }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:PartialOrd> PartialOrd for [T; $N] {
                #[inline]
                fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                }
                #[inline]
                fn lt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::lt(&&self[..], &&other[..])
                }
                #[inline]
                fn le(&self, other: &[T; $N]) -> bool {
                    PartialOrd::le(&&self[..], &&other[..])
                }
                #[inline]
                fn ge(&self, other: &[T; $N]) -> bool {
                    PartialOrd::ge(&&self[..], &&other[..])
                }
                #[inline]
                fn gt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::gt(&&self[..], &&other[..])
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Ord> Ord for [T; $N] {
                #[inline]
                fn cmp(&self, other: &[T; $N]) -> Ordering {
                    Ord::cmp(&&self[..], &&other[..])
                }
            }
        )+
    }
}

array_impls! {
     0  1  2  3  4  5  6  7  8  9
    10 11 12 13 14 15 16 17 18 19
    20 21 22 23 24 25 26 27 28 29
    30 31 32
}

// The Default impls cannot be generated using the array_impls! macro because
// they require array literals.

macro_rules! array_impl_default {
    {$n:expr, $t:ident $($ts:ident)*} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] where T: Default {
            fn default() -> [T; $n] {
                [$t::default(), $($ts::default()),*]
            }
        }
        array_impl_default!{($n - 1), $($ts)*}
    };
    {$n:expr,} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] {
            fn default() -> [T; $n] { [] }
        }
    };
}

array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
<commit_msg>Make FixedSizeArray an unsafe trait<commit_after>// Copyright 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.

//! Implementations of things like `Eq` for fixed-length arrays
//! up to a certain length. Eventually we should able to generalize
//! to all lengths.
//!
//! *[See also the array primitive type](../primitive.array.html).*

#![unstable(feature = "fixed_size_array",
            reason = "traits and impls are better expressed through generic \
                      integer constants",
            issue = "27778")]

use borrow::{Borrow, BorrowMut};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use convert::{AsRef, AsMut};
use default::Default;
use fmt;
use hash::{Hash, self};
use iter::IntoIterator;
use marker::{Copy, Sized, Unsize};
use option::Option;
use slice::{Iter, IterMut, SliceExt};

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
pub unsafe trait FixedSizeArray<T> {
    /// Converts the array to immutable slice
    fn as_slice(&self) -> &[T];
    /// Converts the array to mutable slice
    fn as_mut_slice(&mut self) -> &mut [T];
}

unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
    #[inline]
    fn as_slice(&self) -> &[T] {
        self
    }
    #[inline]
    fn as_mut_slice(&mut self) -> &mut [T] {
        self
    }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            impl<T> AsRef<[T]> for [T; $N] {
                #[inline]
                fn as_ref(&self) -> &[T] {
                    &self[..]
                }
            }

            impl<T> AsMut<[T]> for [T; $N] {
                #[inline]
                fn as_mut(&mut self) -> &mut [T] {
                    &mut self[..]
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> Borrow<[T]> for [T; $N] {
                fn borrow(&self) -> &[T] {
                    self
                }
            }

            #[stable(feature = "array_borrow", since = "1.4.0")]
            impl<T> BorrowMut<[T]> for [T; $N] {
                fn borrow_mut(&mut self) -> &mut [T] {
                    self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Copy> Clone for [T; $N] {
                fn clone(&self) -> [T; $N] {
                    *self
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: Hash> Hash for [T; $N] {
                fn hash<H: hash::Hasher>(&self, state: &mut H) {
                    Hash::hash(&self[..], state)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T: fmt::Debug> fmt::Debug for [T; $N] {
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                    fmt::Debug::fmt(&&self[..], f)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a [T; $N] {
                type Item = &'a T;
                type IntoIter = Iter<'a, T>;

                fn into_iter(self) -> Iter<'a, T> {
                    self.iter()
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<'a, T> IntoIterator for &'a mut [T; $N] {
                type Item = &'a mut T;
                type IntoIter = IterMut<'a, T>;

                fn into_iter(self) -> IterMut<'a, T> {
                    self.iter_mut()
                }
            }

            // NOTE: some less important impls are omitted to reduce code bloat
            __impl_slice_eq1! { [A; $N], [B; $N] }
            __impl_slice_eq2! { [A; $N], [B] }
            __impl_slice_eq2! { [A; $N], &'b [B] }
            __impl_slice_eq2! { [A; $N], &'b mut [B] }
            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Eq> Eq for [T; $N] { }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:PartialOrd> PartialOrd for [T; $N] {
                #[inline]
                fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                }
                #[inline]
                fn lt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::lt(&&self[..], &&other[..])
                }
                #[inline]
                fn le(&self, other: &[T; $N]) -> bool {
                    PartialOrd::le(&&self[..], &&other[..])
                }
                #[inline]
                fn ge(&self, other: &[T; $N]) -> bool {
                    PartialOrd::ge(&&self[..], &&other[..])
                }
                #[inline]
                fn gt(&self, other: &[T; $N]) -> bool {
                    PartialOrd::gt(&&self[..], &&other[..])
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<T:Ord> Ord for [T; $N] {
                #[inline]
                fn cmp(&self, other: &[T; $N]) -> Ordering {
                    Ord::cmp(&&self[..], &&other[..])
                }
            }
        )+
    }
}

array_impls! {
     0  1  2  3  4  5  6  7  8  9
    10 11 12 13 14 15 16 17 18 19
    20 21 22 23 24 25 26 27 28 29
    30 31 32
}

// The Default impls cannot be generated using the array_impls! macro because
// they require array literals.

macro_rules! array_impl_default {
    {$n:expr, $t:ident $($ts:ident)*} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] where T: Default {
            fn default() -> [T; $n] {
                [$t::default(), $($ts::default()),*]
            }
        }
        array_impl_default!{($n - 1), $($ts)*}
    };
    {$n:expr,} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] {
            fn default() -> [T; $n] { [] }
        }
    };
}

array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
<|endoftext|>


<commit_before>extern crate dotenv;
extern crate diesel;

use self::dotenv::dotenv;
use std::env;
use self::diesel::prelude::*;
use self::diesel::pg::PgConnection;

pub fn establish_connection() -> PgConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}
<commit_msg>Add DAO functionality to add category<commit_after>extern crate dotenv;
extern crate diesel;

use self::dotenv::dotenv;
use std::env;
use self::diesel::prelude::*;
use self::diesel::pg::PgConnection;
use super::model::*;

type Result<T> = self::diesel::QueryResult<T>;

pub struct Dao {
    conn: PgConnection,
}

impl Dao {
    pub fn new() -> Self {
        Dao { conn: establish_connection() }
    }

    pub fn create_category(&self, text: &str) -> Result<Category> {
        use super::schema::category;
        let new_category = NewCategory { text };
        diesel::insert(&new_category)
            .into(category::table)
            .get_result(&self.conn)
    }
}

fn establish_connection() -> PgConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}
<|endoftext|>