<commit_before>
use opengl_graphics::shader_utils::{
    DynamicAttribute,
    compile_shader,
};
use opengl_graphics::{
    Gl,
};
use gl;
use gl::types::{
    GLboolean,
    GLenum,
    GLuint,
    GLsizei,
    GLsizeiptr,
};
use std::mem;
use std::ptr;

pub enum NotReady {}
pub enum Ready {}

static VERTEX_SHADER: &'static str = r"
#version 330
in vec3 position;
in vec3 fill_color;
in vec2 tex_coord;

// TEST
// uniform mat4 m_projection;
// uniform mat4 m_view;
// uniform mat4 m_model;
uniform sampler2D s_texture;

out vec2 v_tex_coord;
out vec4 v_fill_color;

void main() {
    v_tex_coord = tex_coord;
    v_fill_color = vec4(fill_color, 1.0);
    // TEST
    gl_Position = vec4(position, 1.0); // m_projection * m_view * m_model * vec4(position, 1.0);
}
";

static FRAGMENT_SHADER: &'static str = r"
#version 330
out vec4 out_color;
uniform sampler2D s_texture;

in vec2 v_tex_coord;
in vec4 v_fill_color;

void main() {
    out_color = texture(s_texture, v_tex_coord) * v_fill_color;
}
";

pub struct Shader<State> {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    position: DynamicAttribute,
    fill_color: DynamicAttribute,
    tex_coord: DynamicAttribute,
}

impl Shader<Ready> {
    pub fn position<'a>(&'a self) -> &'a DynamicAttribute { &self.position }

    pub fn fill_color<'a>(&'a self) -> &'a DynamicAttribute { &self.fill_color }

    pub fn tex_coord<'a>(&'a self) -> &'a DynamicAttribute { &self.tex_coord }
}

impl Shader<NotReady> {
    pub fn new() -> Shader<NotReady> {
        // Compile shaders.
        let vertex_shader = compile_shader(
                gl::VERTEX_SHADER,
                VERTEX_SHADER
            ).unwrap();
        let fragment_shader = compile_shader(
                gl::FRAGMENT_SHADER,
                FRAGMENT_SHADER
            ).unwrap();
        let program = gl::CreateProgram();
        gl::AttachShader(program, vertex_shader);
        gl::AttachShader(program, fragment_shader);

        unsafe {
            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
        };
        gl::LinkProgram(program);
        gl::UseProgram(program);

        let position = DynamicAttribute::xyz(program, "position").unwrap();
        let fill_color = DynamicAttribute::rgb(program, "fill_color").unwrap();
        let tex_coord = DynamicAttribute::uv(program, "tex_coord").unwrap();
        position.bind_vao(vao);
        fill_color.bind_vao(vao);
        tex_coord.bind_vao(vao);
        Shader {
            vao: vao,
            program: program,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            position: position,
            fill_color: fill_color,
            tex_coord: tex_coord,
        }
    }

    pub fn render(&self, gl: &mut Gl, f: |shader: &Shader<Ready>|) {
        gl.use_program(self.program);
        gl::BindVertexArray(self.vao);

        f(unsafe { &*(self as *_ as *Shader<Ready>) });

        gl::BindVertexArray(0);
    }
}

#[unsafe_destructor]
impl Drop for Shader<NotReady> {
    fn drop(&mut self) {
        gl::DeleteProgram(self.program);
        gl::DeleteShader(self.vertex_shader);
        gl::DeleteShader(self.fragment_shader);
    }
}

<commit_msg>Upgraded to latest opengl_graphics<commit_after>
use opengl_graphics::shader_utils::{
    DynamicAttribute,
    compile_shader,
};
use opengl_graphics::{
    Gl,
};
use gl;
use gl::types::{
    GLboolean,
    GLenum,
    GLuint,
    GLsizei,
    GLsizeiptr,
};
use std::mem;
use std::ptr;

pub enum NotReady {}
pub enum Ready {}

static VERTEX_SHADER: &'static str = r"
#version 330
in vec3 position;
in vec3 fill_color;
in vec2 tex_coord;

// TEST
// uniform mat4 m_projection;
// uniform mat4 m_view;
// uniform mat4 m_model;
uniform sampler2D s_texture;

out vec2 v_tex_coord;
out vec4 v_fill_color;

void main() {
    v_tex_coord = tex_coord;
    v_fill_color = vec4(fill_color, 1.0);
    // TEST
    gl_Position = vec4(position, 1.0); // m_projection * m_view * m_model * vec4(position, 1.0);
}
";

static FRAGMENT_SHADER: &'static str = r"
#version 330
out vec4 out_color;
uniform sampler2D s_texture;

in vec2 v_tex_coord;
in vec4 v_fill_color;

void main() {
    out_color = texture(s_texture, v_tex_coord) * v_fill_color;
}
";

pub struct Shader<State> {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    position: DynamicAttribute,
    fill_color: DynamicAttribute,
    tex_coord: DynamicAttribute,
}

impl Shader<Ready> {
    pub fn position<'a>(&'a self) -> &'a DynamicAttribute { &self.position }

    pub fn fill_color<'a>(&'a self) -> &'a DynamicAttribute { &self.fill_color }

    pub fn tex_coord<'a>(&'a self) -> &'a DynamicAttribute { &self.tex_coord }
}

impl Shader<NotReady> {
    pub fn new() -> Shader<NotReady> {
        // Compile shaders.
        let vertex_shader = compile_shader(
                gl::VERTEX_SHADER,
                VERTEX_SHADER
            ).unwrap();
        let fragment_shader = compile_shader(
                gl::FRAGMENT_SHADER,
                FRAGMENT_SHADER
            ).unwrap();
        let program = gl::CreateProgram();
        gl::AttachShader(program, vertex_shader);
        gl::AttachShader(program, fragment_shader);

        unsafe {
            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
        };
        gl::LinkProgram(program);
        gl::UseProgram(program);

        let position = DynamicAttribute::xyz(
            program, "position", vao).unwrap();
        let fill_color = DynamicAttribute::rgb(
            program, "fill_color", vao).unwrap();
        let tex_coord = DynamicAttribute::uv(
            program, "tex_coord", vao).unwrap();
        Shader {
            vao: vao,
            program: program,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            position: position,
            fill_color: fill_color,
            tex_coord: tex_coord,
        }
    }

    pub fn render(&self, gl: &mut Gl, f: |shader: &Shader<Ready>|) {
        gl.use_program(self.program);
        gl::BindVertexArray(self.vao);

        f(unsafe { &*(self as *const _ as *const Shader<Ready>) });

        gl::BindVertexArray(0);
    }
}

#[unsafe_destructor]
impl Drop for Shader<NotReady> {
    fn drop(&mut self) {
        gl::DeleteProgram(self.program);
        gl::DeleteShader(self.vertex_shader);
        gl::DeleteShader(self.fragment_shader);
    }
}

<|endoftext|>


<commit_before>extern crate rand;
extern crate timely;
extern crate timely_sort;
extern crate differential_dataflow;

use timely::dataflow::operators::*;

use rand::{Rng, SeedableRng, StdRng};

use differential_dataflow::AsCollection;
use differential_dataflow::operators::arrange::{ArrangeByKey, TraceAgent};
use differential_dataflow::operators::group::GroupArranged;
use differential_dataflow::trace::implementations::ord::OrdValSpine;
use differential_dataflow::trace::{Cursor, Trace};
// use differential_dataflow::trace::Batch;
use differential_dataflow::hashable::OrdWrapper;
use differential_dataflow::trace::TraceReader;

fn main() {

    let nodes: u32 = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: usize = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: usize = std::env::args().nth(3).unwrap().parse().unwrap();

    // define a new timely dataflow computation.
    timely::execute_from_args(std::env::args().skip(4), move |worker| {

        let index = worker.index();
        let peers = worker.peers();

    	// create a a degree counting differential dataflow
    	let (mut input, probe, mut trace) = worker.dataflow(|scope| {

            // create edge input, count a few ways.
            let (input, edges) = scope.new_input();

            // pull off source, and count.
            let arranged = edges.as_collection()
                                .arrange_by_key_hashed();

            (input, arranged.stream.probe(), arranged.trace.clone())
        });

        let seed: &[_] = &[1, 2, 3, index];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions

        // load up graph dataz
        let &time = input.time();
        for edge in 0..edges {
            if edge % peers == index {
                input.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), time, 1));
            }

            // move the data along a bit
            if edge % 10000 == 9999 {
                worker.step();
            }
        }

        let timer = ::std::time::Instant::now();

        input.advance_to(1);
        worker.step_while(|| probe.less_than(input.time()));

        if index == 0 {
            let timer = timer.elapsed();
            let nanos = timer.as_secs() * 1000000000 + timer.subsec_nanos() as u64;
            println!("Loading finished after {:?}", nanos);
        }

        // change graph, forever
        if batch > 0 {

            for edge in 0usize .. {
                let &time = input.time();
                if edge % peers == index {
                    input.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), time, 1));
                    input.send(((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)), time,-1));
                }

                if edge % batch == (batch - 1) {

                    let mut trace2 = trace.clone();
                    worker.dataflow(move |scope| {

                        TraceAgent::import(scope, trace2)
                        // trace2.create_in(scope)
                              .group_arranged(|_k, s, t| t.push((s[0].0, 1)), OrdValSpine::new())
                              .as_collection(|k: &OrdWrapper<u32>, v: &u32| (k.item.clone(),v.clone()))
                              .inspect(|x| println!("{:?}", x));
                    });

                    let timer = ::std::time::Instant::now();

                    trace.advance_by(&[input.time().clone()]);
                    trace.distinguish_since(&[input.time().clone()]);

                    let next = input.epoch() + 1;
                    input.advance_to(next);
                    worker.step_while(|| probe.less_than(input.time()));

                    if index == 0 {
                        let timer = timer.elapsed();
                        let nanos = timer.as_secs() * 1000000000 + timer.subsec_nanos() as u64;
                        println!("Round {} finished after {:?}", next - 1, nanos);

                        let mut count = 0;

                        // we can directly interrogate the trace...
                        let timer = ::std::time::Instant::now();
                        let mut cursor = trace.cursor();
                        while cursor.key_valid() {
                            while cursor.val_valid() {
                                let mut sum = 0;
                                cursor.map_times(|_,d| sum += d);
                                if sum > 0 { count += 1; }
                                cursor.step_val();
                            }

                            cursor.step_key()
                        }

                        println!("count: {} in {:?}", count, timer.elapsed());
                    }
                }
            }
        }
    }).unwrap();
}<commit_msg>minimize arrange example to demonstrate trace import and wrapping<commit_after>extern crate rand;
extern crate timely;
extern crate timely_sort;
extern crate differential_dataflow;

use timely::dataflow::operators::*;

use rand::{Rng, SeedableRng, StdRng};

use differential_dataflow::AsCollection;
use differential_dataflow::operators::arrange::ArrangeByKey;
use differential_dataflow::operators::group::{Group, GroupArranged, Count};
use differential_dataflow::operators::join::{Join, JoinArranged};
use differential_dataflow::operators::Iterate;
use differential_dataflow::trace::implementations::ord::OrdValSpine;
use differential_dataflow::trace::{Cursor, Trace};
// use differential_dataflow::trace::Batch;
use differential_dataflow::hashable::OrdWrapper;
use differential_dataflow::trace::TraceReader;

fn main() {

    let nodes: u32 = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: usize = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: usize = std::env::args().nth(3).unwrap().parse().unwrap();

    // define a new timely dataflow computation.
    timely::execute_from_args(std::env::args().skip(4), move |worker| {

        let index = worker.index();
        let peers = worker.peers();

    	// create a a degree counting differential dataflow
    	let (mut input, probe, mut trace) = worker.dataflow(|scope| {

            // create edge input, count a few ways.
            let (input, edges) = scope.new_input();
            let edges = edges.as_collection();

            // arrange, then export the arranged trace.
            let arranged = edges.arrange_by_key_hashed();

            (input, arranged.stream.probe(), arranged.trace.clone())
        });

        let (mut roots, probe2) = worker.dataflow(|scope| {

            let edges = trace.import(scope);
            let (input, roots) = scope.new_input();
            let roots = roots.as_collection();

            // repeatedly update minimal distances each node can be reached from each root
            let probe = roots.iterate(|dists| {

                let edges = edges.enter(&dists.scope());
                let roots = roots.enter(&dists.scope());

                dists.arrange_by_key_hashed()
                     .join_arranged(&edges, |_k,l,d| (*d, l+1))
                     .concat(&roots)
                     .group_u(|_, s, t| t.push((s[0].0, 1)))
            })
            .map(|(node, dist)| dist)
            .count()
            .inspect(|x| println!("distance update: {:?}", x))
            .probe();

            (input, probe)
        });

        let seed: &[_] = &[1, 2, 3, index];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions

        // load up graph dataz
        let &time = input.time();
        for edge in 0..edges {
            if edge % peers == index {
                input.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), time, 1));
            }

            // move the data along a bit
            if edge % 10000 == 9999 {
                worker.step();
            }
        }

        let timer = ::std::time::Instant::now();

        input.advance_to(1);
        roots.advance_to(1);

        worker.step_while(|| probe.less_than(input.time()));

        if index == 0 {
            let timer = timer.elapsed();
            let nanos = timer.as_secs() * 1000000000 + timer.subsec_nanos() as u64;
            println!("Loading finished after {:?}", nanos);
        }

        // change graph, forever
        if batch > 0 {

            for edge in 0usize .. {
                let &time = input.time();
                if edge % peers == index {
                    input.send(((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), time, 1));
                    input.send(((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)), time,-1));
                }

                if edge % batch == (batch - 1) {

                    roots.send(((edge as u32, 0), time, 1));

                    // let trace2 = trace.clone();
                    // worker.dataflow(move |scope| {

                    //     // TraceAgent::import(scope, trace2)
                    //     trace2.import(scope)
                    //           .group_arranged(|_k, s, t| t.push((s[0].0, 1)), OrdValSpine::new())
                    //           .as_collection(|k: &OrdWrapper<u32>, v: &u32| (k.item.clone(),v.clone()))
                    //           .inspect(|x| println!("{:?}", x));
                    // });

                    let timer = ::std::time::Instant::now();

                    // trace.advance_by(&[input.time().clone()]);
                    // trace.distinguish_since(&[input.time().clone()]);

                    let next = input.epoch() + 1;
                    input.advance_to(next);
                    roots.advance_to(next);

                    worker.step_while(|| probe.less_than(input.time()) && probe2.less_than(input.time()));

                    // if index == 0 {
                    //     let timer = timer.elapsed();
                    //     let nanos = timer.as_secs() * 1000000000 + timer.subsec_nanos() as u64;
                    //     println!("Round {} finished after {:?}", next - 1, nanos);

                    //     let mut count = 0;

                    //     // we can directly interrogate the trace...
                    //     let timer = ::std::time::Instant::now();
                    //     let mut cursor = trace.cursor();
                    //     while cursor.key_valid() {
                    //         while cursor.val_valid() {
                    //             let mut sum = 0;
                    //             cursor.map_times(|_,d| sum += d);
                    //             if sum > 0 { count += 1; }
                    //             cursor.step_val();
                    //         }

                    //         cursor.step_key()
                    //     }

                    //     println!("count: {} in {:?}", count, timer.elapsed());
                    // }
                }
            }
        }
    }).unwrap();
}<|endoftext|>


<commit_before>//! Solve Hermitian (or real symmetric) linear problems and invert Hermitian
//! (or real symmetric) matrices
//!
//! **Note that only the upper triangular portion of the matrix is used.**
//!
//! # Examples
//!
//! Solve `A * x = b`, where `A` is a Hermitian (or real symmetric) matrix:
//!
//! ```
//! #[macro_use]
//! extern crate ndarray;
//! extern crate ndarray_linalg;
//!
//! use ndarray::prelude::*;
//! use ndarray_linalg::SolveH;
//! # fn main() {
//!
//! let a: Array2<f64> = array![
//!     [3., 2., -1.],
//!     [2., -2., 4.],
//!     [-1., 4., 5.]
//! ];
//! let b: Array1<f64> = array![11., -12., 1.];
//! let x = a.solveh_into(b).unwrap();
//! assert!(x.all_close(&array![1., 3., -2.], 1e-9));
//!
//! # }
//! ```
//!
//! If you are solving multiple systems of linear equations with the same
//! Hermitian or real symmetric coefficient matrix `A`, it's faster to compute
//! the factorization once at the beginning than solving directly using `A`:
//!
//! ```
//! # extern crate ndarray;
//! # extern crate ndarray_linalg;
//! use ndarray::prelude::*;
//! use ndarray_linalg::*;
//! # fn main() {
//!
//! let a: Array2<f64> = random((3, 3));
//! let f = a.factorizeh_into().unwrap(); // Factorize A (A is consumed)
//! for _ in 0..10 {
//!     let b: Array1<f64> = random(3);
//!     let x = f.solveh_into(b).unwrap(); // Solve A * x = b using the factorization
//! }
//!
//! # }
//! ```

use ndarray::*;

use super::convert::*;
use super::error::*;
use super::layout::*;
use super::types::*;

pub use lapack_traits::{Pivot, UPLO};

/// An interface for solving systems of Hermitian (or real symmetric) linear equations.
///
/// If you plan to solve many equations with the same Hermitian (or real
/// symmetric) coefficient matrix `A` but different `b` vectors, it's faster to
/// factor the `A` matrix once using the `FactorizeH` trait, and then solve
/// using the `BKFactorized` struct.
pub trait SolveH<A: Scalar> {
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result.
    fn solveh<S: Data<Elem = A>>(&self, b: &ArrayBase<S, Ix1>) -> Result<Array1<A>> {
        let mut b = replicate(b);
        self.solveh_inplace(&mut b)?;
        Ok(b)
    }
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result.
    fn solveh_into<S: DataMut<Elem = A>>(&self, mut b: ArrayBase<S, Ix1>) -> Result<ArrayBase<S, Ix1>> {
        self.solveh_inplace(&mut b)?;
        Ok(b)
    }
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result. The value of `x` is also assigned to the
    /// argument.
    fn solveh_inplace<'a, S: DataMut<Elem = A>>(&self, &'a mut ArrayBase<S, Ix1>) -> Result<&'a mut ArrayBase<S, Ix1>>;
}

/// Represents the Bunch–Kaufman factorization of a Hermitian (or real
/// symmetric) matrix as `A = P * U * D * U^H * P^T`.
pub struct BKFactorized<S: Data> {
    pub a: ArrayBase<S, Ix2>,
    pub ipiv: Pivot,
}

impl<A, S> SolveH<A> for BKFactorized<S>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    fn solveh_inplace<'a, Sb>(&self, rhs: &'a mut ArrayBase<Sb, Ix1>) -> Result<&'a mut ArrayBase<Sb, Ix1>>
    where
        Sb: DataMut<Elem = A>,
    {
        unsafe {
            A::solveh(
                self.a.square_layout()?,
                UPLO::Upper,
                self.a.as_allocated()?,
                &self.ipiv,
                rhs.as_slice_mut().unwrap(),
            )?
        };
        Ok(rhs)
    }
}

impl<A, S> SolveH<A> for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    fn solveh_inplace<'a, Sb>(&self, mut rhs: &'a mut ArrayBase<Sb, Ix1>) -> Result<&'a mut ArrayBase<Sb, Ix1>>
    where
        Sb: DataMut<Elem = A>,
    {
        let f = self.factorizeh()?;
        f.solveh_inplace(rhs)
    }
}

/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or
/// real symmetric) matrix refs.
pub trait FactorizeH<S: Data> {
    /// Computes the Bunch–Kaufman factorization of a Hermitian (or real
    /// symmetric) matrix.
    fn factorizeh(&self) -> Result<BKFactorized<S>>;
}

/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or
/// real symmetric) matrices.
pub trait FactorizeHInto<S: Data> {
    /// Computes the Bunch–Kaufman factorization of a Hermitian (or real
    /// symmetric) matrix.
    fn factorizeh_into(self) -> Result<BKFactorized<S>>;
}

impl<A, S> FactorizeHInto<S> for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    fn factorizeh_into(mut self) -> Result<BKFactorized<S>> {
        let ipiv = unsafe { A::bk(self.layout()?, UPLO::Upper, self.as_allocated_mut()?)? };
        Ok(BKFactorized {
            a: self,
            ipiv: ipiv,
        })
    }
}

impl<A, Si> FactorizeH<OwnedRepr<A>> for ArrayBase<Si, Ix2>
where
    A: Scalar,
    Si: Data<Elem = A>,
{
    fn factorizeh(&self) -> Result<BKFactorized<OwnedRepr<A>>> {
        let mut a: Array2<A> = replicate(self);
        let ipiv = unsafe { A::bk(a.layout()?, UPLO::Upper, a.as_allocated_mut()?)? };
        Ok(BKFactorized { a: a, ipiv: ipiv })
    }
}

/// An interface for inverting Hermitian (or real symmetric) matrix refs.
pub trait InverseH {
    type Output;
    /// Computes the inverse of the Hermitian (or real symmetric) matrix.
    ///
    /// **Warning: The inverse is stored only in the upper triangular portion
    /// of the result matrix!** If you want the lower triangular portion to be
    /// correct, you must fill it in according to the results in the upper
    /// triangular portion.
    fn invh(&self) -> Result<Self::Output>;
}

/// An interface for inverting Hermitian (or real symmetric) matrices.
pub trait InverseHInto {
    type Output;
    /// Computes the inverse of the Hermitian (or real symmetric) matrix.
    ///
    /// **Warning: The inverse is stored only in the upper triangular portion
    /// of the result matrix!** If you want the lower triangular portion to be
    /// correct, you must fill it in according to the results in the upper
    /// triangular portion.
    fn invh_into(self) -> Result<Self::Output>;
}

impl<A, S> InverseHInto for BKFactorized<S>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type Output = ArrayBase<S, Ix2>;

    fn invh_into(mut self) -> Result<ArrayBase<S, Ix2>> {
        unsafe {
            A::invh(
                self.a.square_layout()?,
                UPLO::Upper,
                self.a.as_allocated_mut()?,
                &self.ipiv,
            )?
        };
        Ok(self.a)
    }
}

impl<A, S> InverseH for BKFactorized<S>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn invh(&self) -> Result<Self::Output> {
        let f = BKFactorized {
            a: replicate(&self.a),
            ipiv: self.ipiv.clone(),
        };
        f.invh_into()
    }
}

impl<A, S> InverseHInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type Output = Self;

    fn invh_into(self) -> Result<Self::Output> {
        let f = self.factorizeh_into()?;
        f.invh_into()
    }
}

impl<A, Si> InverseH for ArrayBase<Si, Ix2>
where
    A: Scalar,
    Si: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn invh(&self) -> Result<Self::Output> {
        let f = self.factorizeh()?;
        f.invh_into()
    }
}
<commit_msg>Fill lower triangular portion of invh*() output<commit_after>//! Solve Hermitian (or real symmetric) linear problems and invert Hermitian
//! (or real symmetric) matrices
//!
//! **Note that only the upper triangular portion of the matrix is used.**
//!
//! # Examples
//!
//! Solve `A * x = b`, where `A` is a Hermitian (or real symmetric) matrix:
//!
//! ```
//! #[macro_use]
//! extern crate ndarray;
//! extern crate ndarray_linalg;
//!
//! use ndarray::prelude::*;
//! use ndarray_linalg::SolveH;
//! # fn main() {
//!
//! let a: Array2<f64> = array![
//!     [3., 2., -1.],
//!     [2., -2., 4.],
//!     [-1., 4., 5.]
//! ];
//! let b: Array1<f64> = array![11., -12., 1.];
//! let x = a.solveh_into(b).unwrap();
//! assert!(x.all_close(&array![1., 3., -2.], 1e-9));
//!
//! # }
//! ```
//!
//! If you are solving multiple systems of linear equations with the same
//! Hermitian or real symmetric coefficient matrix `A`, it's faster to compute
//! the factorization once at the beginning than solving directly using `A`:
//!
//! ```
//! # extern crate ndarray;
//! # extern crate ndarray_linalg;
//! use ndarray::prelude::*;
//! use ndarray_linalg::*;
//! # fn main() {
//!
//! let a: Array2<f64> = random((3, 3));
//! let f = a.factorizeh_into().unwrap(); // Factorize A (A is consumed)
//! for _ in 0..10 {
//!     let b: Array1<f64> = random(3);
//!     let x = f.solveh_into(b).unwrap(); // Solve A * x = b using the factorization
//! }
//!
//! # }
//! ```

use ndarray::*;

use super::convert::*;
use super::error::*;
use super::layout::*;
use super::types::*;

pub use lapack_traits::{Pivot, UPLO};

/// An interface for solving systems of Hermitian (or real symmetric) linear equations.
///
/// If you plan to solve many equations with the same Hermitian (or real
/// symmetric) coefficient matrix `A` but different `b` vectors, it's faster to
/// factor the `A` matrix once using the `FactorizeH` trait, and then solve
/// using the `BKFactorized` struct.
pub trait SolveH<A: Scalar> {
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result.
    fn solveh<S: Data<Elem = A>>(&self, b: &ArrayBase<S, Ix1>) -> Result<Array1<A>> {
        let mut b = replicate(b);
        self.solveh_inplace(&mut b)?;
        Ok(b)
    }
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result.
    fn solveh_into<S: DataMut<Elem = A>>(&self, mut b: ArrayBase<S, Ix1>) -> Result<ArrayBase<S, Ix1>> {
        self.solveh_inplace(&mut b)?;
        Ok(b)
    }
    /// Solves a system of linear equations `A * x = b` with Hermitian (or real
    /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and
    /// `x` is the successful result. The value of `x` is also assigned to the
    /// argument.
    fn solveh_inplace<'a, S: DataMut<Elem = A>>(&self, &'a mut ArrayBase<S, Ix1>) -> Result<&'a mut ArrayBase<S, Ix1>>;
}

/// Represents the Bunch–Kaufman factorization of a Hermitian (or real
/// symmetric) matrix as `A = P * U * D * U^H * P^T`.
pub struct BKFactorized<S: Data> {
    pub a: ArrayBase<S, Ix2>,
    pub ipiv: Pivot,
}

impl<A, S> SolveH<A> for BKFactorized<S>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    fn solveh_inplace<'a, Sb>(&self, rhs: &'a mut ArrayBase<Sb, Ix1>) -> Result<&'a mut ArrayBase<Sb, Ix1>>
    where
        Sb: DataMut<Elem = A>,
    {
        unsafe {
            A::solveh(
                self.a.square_layout()?,
                UPLO::Upper,
                self.a.as_allocated()?,
                &self.ipiv,
                rhs.as_slice_mut().unwrap(),
            )?
        };
        Ok(rhs)
    }
}

impl<A, S> SolveH<A> for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    fn solveh_inplace<'a, Sb>(&self, mut rhs: &'a mut ArrayBase<Sb, Ix1>) -> Result<&'a mut ArrayBase<Sb, Ix1>>
    where
        Sb: DataMut<Elem = A>,
    {
        let f = self.factorizeh()?;
        f.solveh_inplace(rhs)
    }
}

/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or
/// real symmetric) matrix refs.
pub trait FactorizeH<S: Data> {
    /// Computes the Bunch–Kaufman factorization of a Hermitian (or real
    /// symmetric) matrix.
    fn factorizeh(&self) -> Result<BKFactorized<S>>;
}

/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or
/// real symmetric) matrices.
pub trait FactorizeHInto<S: Data> {
    /// Computes the Bunch–Kaufman factorization of a Hermitian (or real
    /// symmetric) matrix.
    fn factorizeh_into(self) -> Result<BKFactorized<S>>;
}

impl<A, S> FactorizeHInto<S> for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    fn factorizeh_into(mut self) -> Result<BKFactorized<S>> {
        let ipiv = unsafe { A::bk(self.layout()?, UPLO::Upper, self.as_allocated_mut()?)? };
        Ok(BKFactorized {
            a: self,
            ipiv: ipiv,
        })
    }
}

impl<A, Si> FactorizeH<OwnedRepr<A>> for ArrayBase<Si, Ix2>
where
    A: Scalar,
    Si: Data<Elem = A>,
{
    fn factorizeh(&self) -> Result<BKFactorized<OwnedRepr<A>>> {
        let mut a: Array2<A> = replicate(self);
        let ipiv = unsafe { A::bk(a.layout()?, UPLO::Upper, a.as_allocated_mut()?)? };
        Ok(BKFactorized { a: a, ipiv: ipiv })
    }
}

/// An interface for inverting Hermitian (or real symmetric) matrix refs.
pub trait InverseH {
    type Output;
    /// Computes the inverse of the Hermitian (or real symmetric) matrix.
    fn invh(&self) -> Result<Self::Output>;
}

/// An interface for inverting Hermitian (or real symmetric) matrices.
pub trait InverseHInto {
    type Output;
    /// Computes the inverse of the Hermitian (or real symmetric) matrix.
    fn invh_into(self) -> Result<Self::Output>;
}

impl<A, S> InverseHInto for BKFactorized<S>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type Output = ArrayBase<S, Ix2>;

    fn invh_into(mut self) -> Result<ArrayBase<S, Ix2>> {
        unsafe {
            A::invh(
                self.a.square_layout()?,
                UPLO::Upper,
                self.a.as_allocated_mut()?,
                &self.ipiv,
            )?
        };
        triangular_fill_hermitian(&mut self.a, UPLO::Upper);
        Ok(self.a)
    }
}

impl<A, S> InverseH for BKFactorized<S>
where
    A: Scalar,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn invh(&self) -> Result<Self::Output> {
        let f = BKFactorized {
            a: replicate(&self.a),
            ipiv: self.ipiv.clone(),
        };
        f.invh_into()
    }
}

impl<A, S> InverseHInto for ArrayBase<S, Ix2>
where
    A: Scalar,
    S: DataMut<Elem = A>,
{
    type Output = Self;

    fn invh_into(self) -> Result<Self::Output> {
        let f = self.factorizeh_into()?;
        f.invh_into()
    }
}

impl<A, Si> InverseH for ArrayBase<Si, Ix2>
where
    A: Scalar,
    Si: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn invh(&self) -> Result<Self::Output> {
        let f = self.factorizeh()?;
        f.invh_into()
    }
}
<|endoftext|>


<commit_before>// Example of how to monitor card & card reader state changes.

extern crate pcsc;

use pcsc::*;

fn main() {
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    let mut readers_buf = [0; 2048];
    let mut reader_states = vec![
        // Listen for reader insertions/removals.
        ReaderState::new(PNP_NOTIFICATION(), STATE_UNAWARE),
    ];
    loop {
        // Remove dead readers.
        fn is_dead(rs: &ReaderState) -> bool {
            rs.event_state().intersects(STATE_UNKNOWN | STATE_IGNORE)
        }
        for rs in &reader_states {
            if is_dead(rs) {
                println!("Removing {:?}", rs.name());
            }
        }
        reader_states.retain(|ref rs| !is_dead(rs));

        // Add new readers.
        let names = ctx.list_readers(&mut readers_buf).expect("failed to list readers");
        for name in names {
            if !reader_states[1..].iter().any(|rs| rs.name() == name) {
                println!("Adding {:?}", name);
                reader_states.push(ReaderState::new(name, STATE_UNAWARE));
            }
        }

        // Update the view of the state to wait on.
        for rs in &mut reader_states {
            rs.sync_current_state();
        }

        // Wait until the state changes.
        ctx.get_status_change(None, &mut reader_states).expect("failed to get status change");

        // Print current state.
        println!();
        for rs in &reader_states[1..] {
            println!("{:?} {:?}", rs.name(), rs.event_state());
        }
    }
}
<commit_msg>examples/monitor: remove reference to a reference<commit_after>// Example of how to monitor card & card reader state changes.

extern crate pcsc;

use pcsc::*;

fn main() {
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    let mut readers_buf = [0; 2048];
    let mut reader_states = vec![
        // Listen for reader insertions/removals.
        ReaderState::new(PNP_NOTIFICATION(), STATE_UNAWARE),
    ];
    loop {
        // Remove dead readers.
        fn is_dead(rs: &ReaderState) -> bool {
            rs.event_state().intersects(STATE_UNKNOWN | STATE_IGNORE)
        }
        for rs in &reader_states {
            if is_dead(rs) {
                println!("Removing {:?}", rs.name());
            }
        }
        reader_states.retain(|rs| !is_dead(rs));

        // Add new readers.
        let names = ctx.list_readers(&mut readers_buf).expect("failed to list readers");
        for name in names {
            if !reader_states[1..].iter().any(|rs| rs.name() == name) {
                println!("Adding {:?}", name);
                reader_states.push(ReaderState::new(name, STATE_UNAWARE));
            }
        }

        // Update the view of the state to wait on.
        for rs in &mut reader_states {
            rs.sync_current_state();
        }

        // Wait until the state changes.
        ctx.get_status_change(None, &mut reader_states).expect("failed to get status change");

        // Print current state.
        println!();
        for rs in &reader_states[1..] {
            println!("{:?} {:?}", rs.name(), rs.event_state());
        }
    }
}
<|endoftext|>


<commit_before>use super::{Executor, Enter, SpawnError};

use futures::Future;

use std::cell::Cell;

#[cfg(feature = "unstable-futures")]
use futures2;

/// Executes futures on the default executor for the current execution context.
///
/// `DefaultExecutor` implements `Executor` and can be used to spawn futures
/// without referencing a specific executor.
///
/// When an executor starts, it sets the `DefaultExecutor` handle to point to an
/// executor (usually itself) that is used to spawn new tasks.
///
/// The current `DefaultExecutor` reference is tracked using a thread-local
/// variable and is set using `tokio_executor::with_default`
#[derive(Debug, Clone)]
pub struct DefaultExecutor {
    _dummy: (),
}

impl DefaultExecutor {
    /// Returns a handle to the default executor for the current context.
    ///
    /// Futures may be spawned onto the default executor using this handle.
    ///
    /// The returned handle will reference whichever executor is configured as
    /// the default **at the time `spawn` is called**. This enables
    /// `DefaultExecutor::current()` to be called before an execution context is
    /// setup, then passed **into** an execution context before it is used.
    ///
    /// This is also true for sending the handle across threads, so calling
    /// `DefaultExecutor::current()` on thread A and then sending the result to
    /// thread B will _not_ reference the default executor that was set on thread A.
    pub fn current() -> DefaultExecutor {
        DefaultExecutor {
            _dummy: (),
        }
    }
}

/// Thread-local tracking the current executor
thread_local!(static EXECUTOR: Cell<Option<*mut Executor>> = Cell::new(None));

// ===== impl DefaultExecutor =====

impl super::Executor for DefaultExecutor {
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
        -> Result<(), SpawnError>
    {
        EXECUTOR.with(|current_executor| {
            match current_executor.get() {
                Some(executor) => {
                    let executor = unsafe { &mut *executor };
                    executor.spawn(future)
                }
                None => {
                    Err(SpawnError::shutdown())
                }
            }
        })
    }

    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
             -> Result<(), futures2::executor::SpawnError>
    {
        EXECUTOR.with(|current_executor| {
            match current_executor.get() {
                Some(executor) => {
                    let executor = unsafe { &mut *executor };
                    executor.spawn2(future)
                }
                None => {
                    Err(futures2::executor::SpawnError::shutdown())
                }
            }
        })
    }

    fn status(&self) -> Result<(), SpawnError> {
        EXECUTOR.with(|current_executor| {
            match current_executor.get() {
                Some(executor) => {
                    let executor = unsafe { &*executor };
                    executor.status()
                }
                None => {
                    Err(SpawnError::shutdown())
                }
            }
        })
    }
}

// ===== global spawn fns =====

/// Submits a future for execution on the default executor -- usually a
/// threadpool.
///
/// Futures are lazy constructs. When they are defined, no work happens. In
/// order for the logic defined by the future to be run, the future must be
/// spawned on an executor. This function is the easiest way to do so.
///
/// This function must be called from an execution context, i.e. from a future
/// that has been already spawned onto an executor.
///
/// Once spawned, the future will execute. The details of how that happens is
/// left up to the executor instance. If the executor is a thread pool, the
/// future will be pushed onto a queue that a worker thread polls from. If the
/// executor is a "current thread" executor, the future might be polled
/// immediately from within the call to `spawn` or it might be pushed onto an
/// internal queue.
///
/// # Panics
///
/// This function will panic if the default executor is not set or if spawning
/// onto the default executor returns an error. To avoid the panic, use the
/// `DefaultExecutor` handle directly.
///
/// # Examples
///
/// ```rust
/// # extern crate futures;
/// # extern crate tokio_executor;
/// # use tokio_executor::spawn;
/// # pub fn dox() {
/// use futures::future::lazy;
///
/// spawn(lazy(|| {
///     println!("running on the default executor");
///     Ok(())
/// }));
/// # }
/// # pub fn main() {}
/// ```
pub fn spawn<T>(future: T)
    where T: Future<Item = (), Error = ()> + Send + 'static,
{
    DefaultExecutor::current().spawn(Box::new(future))
        .unwrap()
}

/// Like `spawn` but compatible with futures 0.2
#[cfg(feature = "unstable-futures")]
pub fn spawn2<T>(future: T)
    where T: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
{
    DefaultExecutor::current().spawn2(Box::new(future))
        .unwrap()
}

/// Set the default executor for the duration of the closure
///
/// # Panics
///
/// This function panics if there already is a default executor set.
pub fn with_default<T, F, R>(executor: &mut T, enter: &mut Enter, f: F) -> R
where T: Executor,
      F: FnOnce(&mut Enter) -> R
{
    EXECUTOR.with(|cell| {
        assert!(cell.get().is_none(), "default executor already set for execution context");

        // Ensure that the executor is removed from the thread-local context
        // when leaving the scope. This handles cases that involve panicking.
        struct Reset<'a>(&'a Cell<Option<*mut Executor>>);

        impl<'a> Drop for Reset<'a> {
            fn drop(&mut self) {
                self.0.set(None);
            }
        }

        let _reset = Reset(cell);

        // While scary, this is safe. The function takes a
        // `&mut Executor`, which guarantees that the reference lives for the
        // duration of `with_default`.
        //
        // Because we are always clearing the TLS value at the end of the
        // function, we can cast the reference to 'static which thread-local
        // cells require.
        let executor = unsafe { hide_lt(executor as &mut _ as *mut _) };

        cell.set(Some(executor));

        f(enter)
    })
}

unsafe fn hide_lt<'a>(p: *mut (Executor + 'a)) -> *mut (Executor + 'static) {
    use std::mem;
    mem::transmute(p)
}

#[cfg(test)]
mod tests {
    use super::DefaultExecutor;

    #[test]
    fn default_executor_is_send_and_sync() {
        fn assert_send_sync<T: Send + Sync>() {}

        assert_send_sync::<DefaultExecutor>();
    }
}
<commit_msg>detect and handle recursive calls to DefaultExecutor (#473)<commit_after>use super::{Executor, Enter, SpawnError};

use futures::Future;

use std::cell::Cell;

#[cfg(feature = "unstable-futures")]
use futures2;

/// Executes futures on the default executor for the current execution context.
///
/// `DefaultExecutor` implements `Executor` and can be used to spawn futures
/// without referencing a specific executor.
///
/// When an executor starts, it sets the `DefaultExecutor` handle to point to an
/// executor (usually itself) that is used to spawn new tasks.
///
/// The current `DefaultExecutor` reference is tracked using a thread-local
/// variable and is set using `tokio_executor::with_default`
#[derive(Debug, Clone)]
pub struct DefaultExecutor {
    _dummy: (),
}

impl DefaultExecutor {
    /// Returns a handle to the default executor for the current context.
    ///
    /// Futures may be spawned onto the default executor using this handle.
    ///
    /// The returned handle will reference whichever executor is configured as
    /// the default **at the time `spawn` is called**. This enables
    /// `DefaultExecutor::current()` to be called before an execution context is
    /// setup, then passed **into** an execution context before it is used.
    ///
    /// This is also true for sending the handle across threads, so calling
    /// `DefaultExecutor::current()` on thread A and then sending the result to
    /// thread B will _not_ reference the default executor that was set on thread A.
    pub fn current() -> DefaultExecutor {
        DefaultExecutor {
            _dummy: (),
        }
    }

    #[inline]
    fn with_current<F: FnOnce(&mut Executor) -> R, R>(f: F) -> Option<R> {
        EXECUTOR.with(|current_executor| {
            match current_executor.replace(State::Active) {
                State::Ready(executor_ptr) => {
                    let executor = unsafe { &mut *executor_ptr };
                    let result = f(executor);
                    current_executor.set(State::Ready(executor_ptr));
                    Some(result)
                },
                State::Empty | State::Active => None,
            }
        })
    }
}

#[derive(Clone, Copy)]
enum State {
    // default executor not defined
    Empty,
    // default executor is defined and ready to be used
    Ready(*mut Executor),
    // default executor is currently active (used to detect recursive calls)
    Active
}

/// Thread-local tracking the current executor
thread_local!(static EXECUTOR: Cell<State> = Cell::new(State::Empty));

// ===== impl DefaultExecutor =====

impl super::Executor for DefaultExecutor {
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
        -> Result<(), SpawnError>
    {
        DefaultExecutor::with_current(|executor| executor.spawn(future))
            .unwrap_or_else(|| Err(SpawnError::shutdown()))
    }

    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
             -> Result<(), futures2::executor::SpawnError>
    {
        DefaultExecutor::with_current(|executor| executor.spawn2(future))
            .unwrap_or_else(|| Err(futures2::executor::SpawnError::shutdown()))
    }

    fn status(&self) -> Result<(), SpawnError> {
        DefaultExecutor::with_current(|executor| executor.status())
            .unwrap_or_else(|| Err(SpawnError::shutdown()))
    }
}

// ===== global spawn fns =====

/// Submits a future for execution on the default executor -- usually a
/// threadpool.
///
/// Futures are lazy constructs. When they are defined, no work happens. In
/// order for the logic defined by the future to be run, the future must be
/// spawned on an executor. This function is the easiest way to do so.
///
/// This function must be called from an execution context, i.e. from a future
/// that has been already spawned onto an executor.
///
/// Once spawned, the future will execute. The details of how that happens is
/// left up to the executor instance. If the executor is a thread pool, the
/// future will be pushed onto a queue that a worker thread polls from. If the
/// executor is a "current thread" executor, the future might be polled
/// immediately from within the call to `spawn` or it might be pushed onto an
/// internal queue.
///
/// # Panics
///
/// This function will panic if the default executor is not set or if spawning
/// onto the default executor returns an error. To avoid the panic, use the
/// `DefaultExecutor` handle directly.
///
/// # Examples
///
/// ```rust
/// # extern crate futures;
/// # extern crate tokio_executor;
/// # use tokio_executor::spawn;
/// # pub fn dox() {
/// use futures::future::lazy;
///
/// spawn(lazy(|| {
///     println!("running on the default executor");
///     Ok(())
/// }));
/// # }
/// # pub fn main() {}
/// ```
pub fn spawn<T>(future: T)
    where T: Future<Item = (), Error = ()> + Send + 'static,
{
    DefaultExecutor::current().spawn(Box::new(future))
        .unwrap()
}

/// Like `spawn` but compatible with futures 0.2
#[cfg(feature = "unstable-futures")]
pub fn spawn2<T>(future: T)
    where T: futures2::Future<Item = (), Error = futures2::Never> + Send + 'static,
{
    DefaultExecutor::current().spawn2(Box::new(future))
        .unwrap()
}

/// Set the default executor for the duration of the closure
///
/// # Panics
///
/// This function panics if there already is a default executor set.
pub fn with_default<T, F, R>(executor: &mut T, enter: &mut Enter, f: F) -> R
where T: Executor,
      F: FnOnce(&mut Enter) -> R
{
    EXECUTOR.with(|cell| {
        match cell.get() {
            State::Ready(_) | State::Active =>
                panic!("default executor already set for execution context"),
            _ => {}
        }

        // Ensure that the executor is removed from the thread-local context
        // when leaving the scope. This handles cases that involve panicking.
        struct Reset<'a>(&'a Cell<State>);

        impl<'a> Drop for Reset<'a> {
            fn drop(&mut self) {
                self.0.set(State::Empty);
            }
        }

        let _reset = Reset(cell);

        // While scary, this is safe. The function takes a
        // `&mut Executor`, which guarantees that the reference lives for the
        // duration of `with_default`.
        //
        // Because we are always clearing the TLS value at the end of the
        // function, we can cast the reference to 'static which thread-local
        // cells require.
        let executor = unsafe { hide_lt(executor as &mut _ as *mut _) };

        cell.set(State::Ready(executor));

        f(enter)
    })
}

unsafe fn hide_lt<'a>(p: *mut (Executor + 'a)) -> *mut (Executor + 'static) {
    use std::mem;
    mem::transmute(p)
}

#[cfg(test)]
mod tests {
    use super::{Executor, DefaultExecutor, with_default};

    #[test]
    fn default_executor_is_send_and_sync() {
        fn assert_send_sync<T: Send + Sync>() {}

        assert_send_sync::<DefaultExecutor>();
    }

    #[test]
    fn nested_default_executor_status() {
        let mut enter = super::super::enter().unwrap();
        let mut executor = DefaultExecutor::current();

        let result = with_default(&mut executor, &mut enter, |_| {
            DefaultExecutor::current().status()
        });

        assert!(result.err().unwrap().is_shutdown())
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::path::{PathBuf, Path};
use std::fs::File;
use std::cmp::{Ordering, PartialEq, Ord};
use std::collections::HashMap;
use object::File as OFile;
use memmap::{Mmap, Protection};
use gimli::*;
use rustc_demangle::demangle;
use cargo::core::Workspace;

use config::Config;
use source_analysis::*;

/// Describes a function as `low_pc`, `high_pc` and bool representing `is_test`.
type FuncDesc = (u64, u64, FunctionType);

#[derive(Clone, Copy, PartialEq)]
enum FunctionType {
    Generated,
    Test,
    Standard
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
pub enum LineType {
    /// Generated test main. Shouldn't be traced.
    TestMain,
    /// Entry of function known to be a test
    TestEntry(u64),
    /// Entry of function. May or may not be test
    FunctionEntry(u64),
    /// Standard statement
    Statement,
    /// Condition
    Condition,
    /// Unknown type
    Unknown,
    /// Unused meta-code
    UnusedGeneric,
}

#[derive(Debug, Clone, Eq, PartialOrd)]
pub struct TracerData {
    pub path: PathBuf,
    pub line: u64,
    pub address: Option<u64>,
    pub trace_type: LineType,
    pub hits: u64,
}

impl PartialEq for TracerData {
    fn eq(&self, other: &TracerData) -> bool {
        (self.path == other.path) && (self.line == other.line)
    }
}

impl Ord for TracerData {

    fn cmp(&self, other: &TracerData) -> Ordering {
        if self == other {
            Ordering::Equal
        } else if self.path == other.path {
            if self.line > other.line {
                Ordering::Greater
            } else {
                Ordering::Less
            }
        } else if self.path > other.path {
            Ordering::Greater
        } else {
            Ordering::Less
        }
    }
}

fn generate_func_desc<R, Offset>(die: &DebuggingInformationEntry<R, Offset>,
                                 debug_str: &DebugStr<R>) -> Result<FuncDesc>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut func_type = FunctionType::Standard;
    let low = die.attr_value(DW_AT_low_pc)?;
    let high = die.attr_value(DW_AT_high_pc)?;
    let linkage = die.attr_value(DW_AT_linkage_name)?;

    // Low is a program counter address so stored in an Addr
    let low = match low {
        Some(AttributeValue::Addr(x)) => x,
        _ => 0u64,
    };
    // High is an offset from the base pc, therefore is u64 data.
    let high = match high {
        Some(AttributeValue::Udata(x)) => x,
        _ => 0u64,
    };
    if let Some(AttributeValue::DebugStrRef(offset)) = linkage {
        let name = debug_str.get_str(offset)
            .and_then(|r| r.to_string().map(|s| s.to_string()))
            .unwrap_or("".into());
        let name = demangle(name.as_ref()).to_string();
        // Simplest test is whether it's in tests namespace.
        // Rust guidelines recommend all tests are in a tests module.
        func_type = if name.contains("tests::") {
            FunctionType::Test
        } else if name.contains("__test::main") {
            FunctionType::Generated
        } else {
            FunctionType::Standard
        };
    }
    Ok((low, high, func_type))
}

/// Finds all function entry points and returns a vector
/// This will identify definite tests, but may be prone to false negatives.
/// TODO Potential to trace all function calls from `__test::main` and find addresses of interest
fn get_entry_points<R, Offset>(debug_info: &CompilationUnitHeader<R, Offset>,
                               debug_abbrev: &Abbreviations,
                               debug_str: &DebugStr<R>) -> Vec<FuncDesc>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut result:Vec<FuncDesc> = Vec::new();
    let mut cursor = debug_info.entries(debug_abbrev);
    // skip compilation unit root.
    let _ = cursor.next_entry();
    while let Ok(Some((_, node))) = cursor.next_dfs() {
        // Function DIE
        if node.tag() == DW_TAG_subprogram {

            if let Ok(fd) = generate_func_desc(node, debug_str) {
                result.push(fd);
            }
        }
    }
    result
}

fn get_addresses_from_program<R, Offset>(prog: IncompleteLineNumberProgram<R>,
                                         entries: &[(u64, LineType)],
                                         project: &Path) -> Result<Vec<TracerData>>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut result: Vec<TracerData> = Vec::new();
    let ( cprog, seq) = prog.sequences()?;
    for s in seq {
        let mut temp_store : Vec<TracerData> = Vec::new();
        let mut sm = cprog.resume_from(&s);
         while let Ok(Some((header, &ln_row))) = sm.next_row() {
            if let Some(file) = ln_row.file(header) {
                let mut path = PathBuf::new();

                if let Some(dir) = file.directory(header) {
                    if let Ok(temp) = dir.to_string() {
                        path.push(temp.as_ref());
                    }
                }
                // Fix relative paths and determine if in target directory
                // Source in target directory shouldn't be covered as it's either
                // autogenerated or resulting from the projects Cargo.lock
                let is_target = if path.is_relative() {
                    let res = path.starts_with("target");
                    if !res {
                        if let Ok(p) = path.canonicalize() {
                            path = p;
                        }
                    }
                    res
                } else {
                    path.starts_with(project.join("target"))
                };
                // Source is part of project so we cover it.
                if !is_target && path.starts_with(project) {
                    let force_test = path.starts_with(project.join("tests"));
                    if let Some(file) = ln_row.file(header) {
                        // If we can't map to line, we can't trace it.
                        let line = match ln_row.line() {
                            Some(l) => l,
                            None => continue,
                        };

                        let file = file.path_name();

                        if let Ok(file) = file.to_string() {
                            path.push(file.as_ref());
                            if !path.is_file() {
                                // Not really a source file!
                                continue;
                            }
                            let address = ln_row.address();

                            let desc = entries.iter()
                                              .filter(|&&(addr, _)| addr == address )
                                              .map(|&(_, t)| t)
                                              .nth(0)
                                              .unwrap_or(LineType::Unknown);
                            // TODO HACK: If in tests/ directory force it to a TestEntry
                            let desc = match desc {
                                LineType::FunctionEntry(e) if force_test => LineType::TestEntry(e),
                                x => x
                            };
                            temp_store.push( TracerData {
                                path: path,
                                line: line,
                                address: Some(address),
                                trace_type: desc,
                                hits: 0u64
                            });
                        }
                    }
                }
            }
        }
        if !temp_store.is_empty() {
            temp_store.sort();
            temp_store.dedup();
            result.append(&mut temp_store);
        }
    }
    Ok(result)
}

fn get_line_addresses(endian: RunTimeEndian,
                      project: &Path,
                      obj: &OFile,
                      analysis: &HashMap<PathBuf, LineAnalysis>,
                      config: &Config) -> Result<Vec<TracerData>>  {
    let mut result: Vec<TracerData> = Vec::new();
    let debug_info = obj.get_section(".debug_info").unwrap_or(&[]);
    let debug_info = DebugInfo::new(debug_info, endian);
    let debug_abbrev = obj.get_section(".debug_abbrev").unwrap_or(&[]);
    let debug_abbrev = DebugAbbrev::new(debug_abbrev, endian);
    let debug_strings = obj.get_section(".debug_str").unwrap_or(&[]);
    let debug_strings = DebugStr::new(debug_strings, endian);

    let mut iter = debug_info.units();
    while let Ok(Some(cu)) = iter.next() {
        let addr_size = cu.address_size();
        let abbr = match cu.abbreviations(&debug_abbrev) {
            Ok(a) => a,
            _ => continue,
        };
        let entries = get_entry_points(&cu, &abbr, &debug_strings)
            .iter()
            .map(|&(a, b, c)| {
                match c {
                    FunctionType::Test => (a, LineType::TestEntry(b)),
                    FunctionType::Standard => (a, LineType::FunctionEntry(b)),
                    FunctionType::Generated => (a, LineType::TestMain),
                }
            }).collect::<Vec<_>>();
        if let Ok(Some((_, root))) = cu.entries(&abbr).next_dfs() {
            let offset = match root.attr_value(DW_AT_stmt_list) {
                Ok(Some(AttributeValue::DebugLineRef(o))) => o,
                _ => continue,
            };
            let debug_line = obj.get_section(".debug_line").unwrap_or(&[]);
            let debug_line = DebugLine::new(debug_line, endian);

            let prog = debug_line.program(offset, addr_size, None, None)?;
            if let Ok(mut addresses) = get_addresses_from_program(prog, &entries, project) {
                result.append(&mut addresses);
            }
        }
    }
    // Due to rust being a higher level language multiple instructions may map
    // to the same line. This prunes these to just the first instruction address
    let mut result = result.iter()
                           .filter(|x| !(config.ignore_tests && x.path.starts_with(project.join("tests"))))
                           .filter(|x| !analysis.should_ignore(x.path.as_ref(), &(x.line as usize)))
                           .filter(|x| x.trace_type != LineType::TestMain)
                           .cloned()
                           .collect::<Vec<TracerData>>();

    let addresses = result.iter()
                          .map(|x| x.address.unwrap())
                          .collect::<Vec<_>>();
    // TODO Probably a more idiomatic way to do this.
    {
        let test_entries = result.iter_mut()
                                 .filter(|x| match x.trace_type {
                                     LineType::TestEntry(_) => true,
                                     _ => false,
                                 });

        for test_entry in test_entries {
            let endpoint = match test_entry.trace_type {
                LineType::TestEntry(x) => x,
                _ => continue,
            };
            let addr = test_entry.address.unwrap();
            let max_address = addresses.iter()
                                       .fold(0, |acc, x| {
                                           if x > &(addr + acc) && (x-addr) <= endpoint {
                                               *x - addr
                                           } else {
                                               acc
                                           }
                                       });
            test_entry.trace_type = LineType::TestEntry(max_address);
        }
    }
    for (file, ref line_analysis) in analysis.iter() {
        for line in &line_analysis.cover {
            let line64 = *line as u64;
            let contain = result.iter().any(|ref x| &x.path == file && line64 == x.line);
            if !contain && !line_analysis.should_ignore(line) {
                result.push(TracerData {
                    line: line64,
                    path: file.to_path_buf(),
                    address: None,
                    hits: 0,
                    trace_type: LineType::UnusedGeneric,
                });
            }
        }
    }
    Ok(result)
}

/// Generates a list of lines we want to trace the coverage of. Used to instrument the
/// traces into the test executable
pub fn generate_tracer_data(project: &Workspace, test: &Path, config: &Config) -> io::Result<Vec<TracerData>> {
    let manifest = project.root();
    let file = File::open(test)?;
    let file = Mmap::open(&file, Protection::Read)?;
    if let Ok(obj) = OFile::parse(unsafe {file.as_slice() }) {
        let analysis = get_line_analysis(project, config);
        let endian = if obj.is_little_endian() {
            RunTimeEndian::Little
        } else {
            RunTimeEndian::Big
        };
        get_line_addresses(endian,
                           manifest,
                           &obj,
                           &analysis,
                           config.ignore_tests)
            .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Error while parsing"))
    } else {
        Err(io::Error::new(io::ErrorKind::InvalidData, "Unable to parse binary."))
    }
}

<commit_msg>File exclusion works<commit_after>use std::io;
use std::path::{PathBuf, Path};
use std::fs::File;
use std::cmp::{Ordering, PartialEq, Ord};
use std::collections::HashMap;
use object::File as OFile;
use memmap::{Mmap, Protection};
use gimli::*;
use rustc_demangle::demangle;
use cargo::core::Workspace;

use config::Config;
use source_analysis::*;

/// Describes a function as `low_pc`, `high_pc` and bool representing `is_test`.
type FuncDesc = (u64, u64, FunctionType);

#[derive(Clone, Copy, PartialEq)]
enum FunctionType {
    Generated,
    Test,
    Standard
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
pub enum LineType {
    /// Generated test main. Shouldn't be traced.
    TestMain,
    /// Entry of function known to be a test
    TestEntry(u64),
    /// Entry of function. May or may not be test
    FunctionEntry(u64),
    /// Standard statement
    Statement,
    /// Condition
    Condition,
    /// Unknown type
    Unknown,
    /// Unused meta-code
    UnusedGeneric,
}

#[derive(Debug, Clone, Eq, PartialOrd)]
pub struct TracerData {
    pub path: PathBuf,
    pub line: u64,
    pub address: Option<u64>,
    pub trace_type: LineType,
    pub hits: u64,
}

impl PartialEq for TracerData {
    fn eq(&self, other: &TracerData) -> bool {
        (self.path == other.path) && (self.line == other.line)
    }
}

impl Ord for TracerData {

    fn cmp(&self, other: &TracerData) -> Ordering {
        if self == other {
            Ordering::Equal
        } else if self.path == other.path {
            if self.line > other.line {
                Ordering::Greater
            } else {
                Ordering::Less
            }
        } else if self.path > other.path {
            Ordering::Greater
        } else {
            Ordering::Less
        }
    }
}

fn generate_func_desc<R, Offset>(die: &DebuggingInformationEntry<R, Offset>,
                                 debug_str: &DebugStr<R>) -> Result<FuncDesc>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut func_type = FunctionType::Standard;
    let low = die.attr_value(DW_AT_low_pc)?;
    let high = die.attr_value(DW_AT_high_pc)?;
    let linkage = die.attr_value(DW_AT_linkage_name)?;

    // Low is a program counter address so stored in an Addr
    let low = match low {
        Some(AttributeValue::Addr(x)) => x,
        _ => 0u64,
    };
    // High is an offset from the base pc, therefore is u64 data.
    let high = match high {
        Some(AttributeValue::Udata(x)) => x,
        _ => 0u64,
    };
    if let Some(AttributeValue::DebugStrRef(offset)) = linkage {
        let name = debug_str.get_str(offset)
            .and_then(|r| r.to_string().map(|s| s.to_string()))
            .unwrap_or("".into());
        let name = demangle(name.as_ref()).to_string();
        // Simplest test is whether it's in tests namespace.
        // Rust guidelines recommend all tests are in a tests module.
        func_type = if name.contains("tests::") {
            FunctionType::Test
        } else if name.contains("__test::main") {
            FunctionType::Generated
        } else {
            FunctionType::Standard
        };
    }
    Ok((low, high, func_type))
}

/// Finds all function entry points and returns a vector
/// This will identify definite tests, but may be prone to false negatives.
/// TODO Potential to trace all function calls from `__test::main` and find addresses of interest
fn get_entry_points<R, Offset>(debug_info: &CompilationUnitHeader<R, Offset>,
                               debug_abbrev: &Abbreviations,
                               debug_str: &DebugStr<R>) -> Vec<FuncDesc>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut result:Vec<FuncDesc> = Vec::new();
    let mut cursor = debug_info.entries(debug_abbrev);
    // skip compilation unit root.
    let _ = cursor.next_entry();
    while let Ok(Some((_, node))) = cursor.next_dfs() {
        // Function DIE
        if node.tag() == DW_TAG_subprogram {

            if let Ok(fd) = generate_func_desc(node, debug_str) {
                result.push(fd);
            }
        }
    }
    result
}

fn get_addresses_from_program<R, Offset>(prog: IncompleteLineNumberProgram<R>,
                                         entries: &[(u64, LineType)],
                                         project: &Path) -> Result<Vec<TracerData>>
    where R: Reader<Offset = Offset>,
          Offset: ReaderOffset
{
    let mut result: Vec<TracerData> = Vec::new();
    let ( cprog, seq) = prog.sequences()?;
    for s in seq {
        let mut temp_store : Vec<TracerData> = Vec::new();
        let mut sm = cprog.resume_from(&s);
         while let Ok(Some((header, &ln_row))) = sm.next_row() {
            if let Some(file) = ln_row.file(header) {
                let mut path = PathBuf::new();

                if let Some(dir) = file.directory(header) {
                    if let Ok(temp) = dir.to_string() {
                        path.push(temp.as_ref());
                    }
                }
                // Fix relative paths and determine if in target directory
                // Source in target directory shouldn't be covered as it's either
                // autogenerated or resulting from the projects Cargo.lock
                let is_target = if path.is_relative() {
                    let res = path.starts_with("target");
                    if !res {
                        if let Ok(p) = path.canonicalize() {
                            path = p;
                        }
                    }
                    res
                } else {
                    path.starts_with(project.join("target"))
                };
                // Source is part of project so we cover it.
                if !is_target && path.starts_with(project) {
                    let force_test = path.starts_with(project.join("tests"));
                    if let Some(file) = ln_row.file(header) {
                        // If we can't map to line, we can't trace it.
                        let line = match ln_row.line() {
                            Some(l) => l,
                            None => continue,
                        };

                        let file = file.path_name();

                        if let Ok(file) = file.to_string() {
                            path.push(file.as_ref());
                            if !path.is_file() {
                                // Not really a source file!
                                continue;
                            }
                            let address = ln_row.address();

                            let desc = entries.iter()
                                              .filter(|&&(addr, _)| addr == address )
                                              .map(|&(_, t)| t)
                                              .nth(0)
                                              .unwrap_or(LineType::Unknown);
                            // TODO HACK: If in tests/ directory force it to a TestEntry
                            let desc = match desc {
                                LineType::FunctionEntry(e) if force_test => LineType::TestEntry(e),
                                x => x
                            };
                            temp_store.push( TracerData {
                                path: path,
                                line: line,
                                address: Some(address),
                                trace_type: desc,
                                hits: 0u64
                            });
                        }
                    }
                }
            }
        }
        if !temp_store.is_empty() {
            temp_store.sort();
            temp_store.dedup();
            result.append(&mut temp_store);
        }
    }
    Ok(result)
}

fn get_line_addresses(endian: RunTimeEndian,
                      project: &Path,
                      obj: &OFile,
                      analysis: &HashMap<PathBuf, LineAnalysis>,
                      config: &Config) -> Result<Vec<TracerData>>  {
    let mut result: Vec<TracerData> = Vec::new();
    let debug_info = obj.get_section(".debug_info").unwrap_or(&[]);
    let debug_info = DebugInfo::new(debug_info, endian);
    let debug_abbrev = obj.get_section(".debug_abbrev").unwrap_or(&[]);
    let debug_abbrev = DebugAbbrev::new(debug_abbrev, endian);
    let debug_strings = obj.get_section(".debug_str").unwrap_or(&[]);
    let debug_strings = DebugStr::new(debug_strings, endian);

    let mut iter = debug_info.units();
    while let Ok(Some(cu)) = iter.next() {
        let addr_size = cu.address_size();
        let abbr = match cu.abbreviations(&debug_abbrev) {
            Ok(a) => a,
            _ => continue,
        };
        let entries = get_entry_points(&cu, &abbr, &debug_strings)
            .iter()
            .map(|&(a, b, c)| {
                match c {
                    FunctionType::Test => (a, LineType::TestEntry(b)),
                    FunctionType::Standard => (a, LineType::FunctionEntry(b)),
                    FunctionType::Generated => (a, LineType::TestMain),
                }
            }).collect::<Vec<_>>();
        if let Ok(Some((_, root))) = cu.entries(&abbr).next_dfs() {
            let offset = match root.attr_value(DW_AT_stmt_list) {
                Ok(Some(AttributeValue::DebugLineRef(o))) => o,
                _ => continue,
            };
            let debug_line = obj.get_section(".debug_line").unwrap_or(&[]);
            let debug_line = DebugLine::new(debug_line, endian);

            let prog = debug_line.program(offset, addr_size, None, None)?;
            if let Ok(mut addresses) = get_addresses_from_program(prog, &entries, project) {
                result.append(&mut addresses);
            }
        }
    }
    // Due to rust being a higher level language multiple instructions may map
    // to the same line. This prunes these to just the first instruction address
    let mut result = result.iter()
                           .filter(|x| !(config.ignore_tests && x.path.starts_with(project.join("tests"))))
                           .filter(|x| !(config.excluded_files.iter().any(|y| x.path.ends_with(y))))
                           .filter(|x| !analysis.should_ignore(x.path.as_ref(), &(x.line as usize)))
                           .filter(|x| x.trace_type != LineType::TestMain)
                           .cloned()
                           .collect::<Vec<TracerData>>();

    let addresses = result.iter()
                          .map(|x| x.address.unwrap())
                          .collect::<Vec<_>>();
    // TODO Probably a more idiomatic way to do this.
    {
        let test_entries = result.iter_mut()
                                 .filter(|x| match x.trace_type {
                                     LineType::TestEntry(_) => true,
                                     _ => false,
                                 });

        for test_entry in test_entries {
            let endpoint = match test_entry.trace_type {
                LineType::TestEntry(x) => x,
                _ => continue,
            };
            let addr = test_entry.address.unwrap();
            let max_address = addresses.iter()
                                       .fold(0, |acc, x| {
                                           if x > &(addr + acc) && (x-addr) <= endpoint {
                                               *x - addr
                                           } else {
                                               acc
                                           }
                                       });
            test_entry.trace_type = LineType::TestEntry(max_address);
        }
    }
    for (file, ref line_analysis) in analysis.iter() {
        for line in &line_analysis.cover {
            let line64 = *line as u64;
            let contain = result.iter().any(|ref x| &x.path == file && line64 == x.line);
            if !contain && !line_analysis.should_ignore(line) {
                result.push(TracerData {
                    line: line64,
                    path: file.to_path_buf(),
                    address: None,
                    hits: 0,
                    trace_type: LineType::UnusedGeneric,
                });
            }
        }
    }
    Ok(result)
}

/// Generates a list of lines we want to trace the coverage of. Used to instrument the
/// traces into the test executable
pub fn generate_tracer_data(project: &Workspace, test: &Path, config: &Config) -> io::Result<Vec<TracerData>> {
    let manifest = project.root();
    let file = File::open(test)?;
    let file = Mmap::open(&file, Protection::Read)?;
    if let Ok(obj) = OFile::parse(unsafe {file.as_slice() }) {
        let analysis = get_line_analysis(project, config);
        let endian = if obj.is_little_endian() {
            RunTimeEndian::Little
        } else {
            RunTimeEndian::Big
        };
        get_line_addresses(endian,
                           manifest,
                           &obj,
                           &analysis,
                           config)
            .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Error while parsing"))
    } else {
        Err(io::Error::new(io::ErrorKind::InvalidData, "Unable to parse binary."))
    }
}

<|endoftext|>


<commit_before>use serde::{Deserialize, Serialize};

/// Trait represents global state of the
/// entire simulation which can updated
/// independently from any particular cell.
/// Consider to store there as much as you can
/// because this data will be created only once
/// and will not be copied.
pub trait EvolutionState {
    /// Method is called once between cells' updates.
    fn update(&mut self);
}

pub trait Cell: Serialize + Deserialize {
    type Coord: Coord;
    type State: EvolutionState;

    fn update<'a, I>(&'a mut self, old: &'a Self, neighbors: I, &Self::State)
        where I: Iterator<Item = Option<&'a Self>>;

    fn with_coord<C: Coord>(C) -> Self;
    fn coord(&self) -> &Self::Coord;
    fn set_coord<C: Coord>(&mut self, &C);
}

pub trait Nhood {
    type Coord: Coord;

    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;
    fn neighbors_count(&self) -> usize;
}

/// Basic coordinate with three components.
/// This crate is used for creating automata
/// on 2D grids for now, so `z` has default impl.
pub trait Coord: Clone + Serialize + Deserialize {
    /// Build coord from any other representation of coord.
    fn from_2d(x: i32, y: i32) -> Self;

    /// Returns `x` component.
    fn x(&self) -> i32;
    /// Returns `y` component.
    fn y(&self) -> i32;
    /// Returns `z` component.
    fn z(&self) -> i32 { 0 }
}

pub trait Grid {
    type Cell: Cell;
    type Coord: Coord;

    fn update(&mut self);

    fn state(&self) -> &<<Self as Grid>::Cell as Cell>::State;
    fn cells(&self) -> &Vec<Self::Cell>;
    fn dimensions(&self) -> Self::Coord;

    fn set_cells(&mut self, Vec<Self::Cell>);
}

/// Interface to the outer world.
pub trait Consumer {
    /// Cells supported by this consumer. Helps
    /// to use cells from grid directly if grid
    /// has the same cell in it.
    type Cell: Cell;

    /// Called once when all cells has been updated.
    fn consume<G>(&mut self, &mut G)
        where G: Grid<Cell = Self::Cell>;
}

/// Interlayer between grid and consumer(s).
pub trait Engine {
    /// Runs evolution fixed number of times.
    fn run_times(&mut self, i64);
}
<commit_msg>Note about Nhood.<commit_after>use serde::{Deserialize, Serialize};

/// Trait represents global state of the
/// entire simulation which can updated
/// independently from any particular cell.
/// Consider to store there as much as you can
/// because this data will be created only once
/// and will not be copied.
pub trait EvolutionState {
    /// Method is called once between cells' updates.
    fn update(&mut self);
}

pub trait Cell: Serialize + Deserialize {
    type Coord: Coord;
    type State: EvolutionState;

    fn update<'a, I>(&'a mut self, old: &'a Self, neighbors: I, &Self::State)
        where I: Iterator<Item = Option<&'a Self>>;

    fn with_coord<C: Coord>(C) -> Self;
    fn coord(&self) -> &Self::Coord;
    fn set_coord<C: Coord>(&mut self, &C);
}

/// Represents neighborhood for automata.
pub trait Nhood {
    /// Coords this nhood supports.
    type Coord: Coord;

    /// Method returns for any given coord
    /// coordinates of surrounding neighbors.
    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;
    /// Hint for grid.
    fn neighbors_count(&self) -> usize;
}

/// Basic coordinate with three components.
/// This crate is used for creating automata
/// on 2D grids for now, so `z` has default impl.
pub trait Coord: Clone + Serialize + Deserialize {
    /// Build coord from any other representation of coord.
    fn from_2d(x: i32, y: i32) -> Self;

    /// Returns `x` component.
    fn x(&self) -> i32;
    /// Returns `y` component.
    fn y(&self) -> i32;
    /// Returns `z` component.
    fn z(&self) -> i32 { 0 }
}

pub trait Grid {
    type Cell: Cell;
    type Coord: Coord;

    fn update(&mut self);

    fn state(&self) -> &<<Self as Grid>::Cell as Cell>::State;
    fn cells(&self) -> &Vec<Self::Cell>;
    fn dimensions(&self) -> Self::Coord;

    fn set_cells(&mut self, Vec<Self::Cell>);
}

/// Interface to the outer world.
pub trait Consumer {
    /// Cells supported by this consumer. Helps
    /// to use cells from grid directly if grid
    /// has the same cell in it.
    type Cell: Cell;

    /// Called once when all cells has been updated.
    fn consume<G>(&mut self, &mut G)
        where G: Grid<Cell = Self::Cell>;
}

/// Interlayer between grid and consumer(s).
pub trait Engine {
    /// Runs evolution fixed number of times.
    fn run_times(&mut self, i64);
}
<|endoftext|>


<commit_before>use std::env;

use screen::{Screen, Pen};
use speed::Speed;
use point::Point;
use ideoutput::IDEOutput;
use angle::Direction;

pub use angle::Angle;

/// This type represents any distance value
pub type Distance = f64;

/// A turtle with a pen attached to its tail
pub struct Turtle {
    screen: Box<Screen>,
    speed: Speed,
    position: Point,
    direction: Direction,
    pen: Pen,
}

impl Turtle {
    /// Initialize a new Turtle instance
    pub fn new() -> Turtle {
        let screen: Box<Screen> = match env::args().any(|a| a == "--turtle-ide-print-mode") {
            false => unimplemented!(),
            true => Box::new(IDEOutput::new()),
        };
        Turtle {
            // Attempt to automatically detect if this is running within the Turtle IDE
            screen: screen,
            speed: "normal".into(),
            position: Point::origin(),
            direction: Direction::zero_degrees(),
            pen: Pen::default(),
        }
    }

    /// Returns the current speed of the turtle
    pub fn speed(&self) -> Speed {
        self.speed
    }

    /// Return the turtle's current location (x, y)
    pub fn position(&self) -> Point {
        self.position
    }

    /// Return the turtle's current heading
    pub fn heading(&self) -> Angle {
        self.direction.raw_angle()
    }

    /// Set the turtle's speed to the given setting.
    ///
    /// Usually this method is used as shown below:
    ///
    /// ```rust,no_run
    /// # extern crate turtleide;
    /// # fn main() {
    /// # let mut turtle = turtleide::Turtle::new();
    /// turtle.set_speed("normal".into());
    /// turtle.set_speed("fast".into());
    /// turtle.set_speed(2.into());
    /// turtle.set_speed(10.into());
    /// # }
    /// ```
    ///
    /// If input is a number greater than 10 or smaller than 1,
    /// speed is set to 0 (Speed::Instant). Strings are converted as follows:
    ///
    /// * "slowest" => Speed::One
    /// * "slow" => Speed::Three
    /// * "normal" => Speed::Six
    /// * "fast" => Speed::Ten
    /// * "fastest" => Speed::Instant
    /// * anything else will cause the program to `panic!` at runtime
    ///
    /// Speeds from 1 to 10 enforce increasingly faster animation of
    /// line drawing and turtle turning.
    ///
    /// Note: speed = 0 means that no animation takes place. forward/back
    /// makes turtle jump and likewise left/right make the turtle turn instantly.
    ///
    /// Using this type is an excellent way to learn about conversion
    /// traits `From` and `Into`. Rather than instantiating `Speed`
    /// directly using `Speed::Six`, you usually use `6.into()`. This is the
    /// same as using `Speed::from(6)` but much more compact. This works because
    /// any type that implements the `From` trait gets a matching implementation
    /// of the `Into` trait.
    pub fn set_speed(&mut self, speed: Speed) {
        self.speed = speed;
    }

    /// Change the angle unit to degrees.
    pub fn use_degrees(&mut self) {
        self.direction = self.direction.into_degrees();
    }

    /// Change the angle unit to radians.
    pub fn use_radians(&mut self) {
        self.direction = self.direction.into_radians();
    }

    /// Move the turtle forward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move backward
    /// using this method.
    pub fn forward(&mut self, distance: Distance) {
        let start = self.position;
        self.position = self.position.translate(self.direction, distance);
        self.screen.draw_line(start, self.position, self.speed, self.pen);
    }

    /// Move the turtle backward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move forwards
    /// using this method.
    pub fn backward(&mut self, distance: Distance) {
        self.forward(-distance);
    }

    /// Rotate the turtle right by the given angle.
    ///
    /// Units are by default degrees, but can be set using the methods
    /// [`Turtle::use_degrees`](struct.Turtle.html#method.use_degrees) or
    /// [`Turtle::use_radians`](struct.Turtle.html#method.use_radians).
    pub fn right(&mut self, angle: Angle) {
        self.direction.rotate_clockwise(angle);
    }

    /// Rotate the turtle left by the given angle.
    ///
    /// Units are by default degrees, but can be set using the methods
    /// [`Turtle::use_degrees`](struct.Turtle.html#method.use_degrees) or
    /// [`Turtle::use_radians`](struct.Turtle.html#method.use_radians).
    pub fn left(&mut self, angle: Angle) {
        self.direction.rotate_counterclockwise(angle);
    }
}
<commit_msg>Implemented pen_down/pen_up<commit_after>use std::env;

use screen::{Screen, Pen};
use speed::Speed;
use point::Point;
use ideoutput::IDEOutput;
use angle::Direction;

pub use angle::Angle;

/// This type represents any distance value
pub type Distance = f64;

/// A turtle with a pen attached to its tail
pub struct Turtle {
    /// The current screen being drawn to
    screen: Box<Screen>,
    /// How fast the turtle will move during animation
    speed: Speed,
    /// Current position of the turtle
    position: Point,
    /// Direction of travel
    direction: Direction,
    /// Pen settings
    pen: Pen,
    /// Whether the pen is down or not
    drawing_enabled: bool,
}

impl Turtle {
    /// Initialize a new Turtle instance
    pub fn new() -> Turtle {
        let screen: Box<Screen> = match env::args().any(|a| a == "--turtle-ide-print-mode") {
            false => unimplemented!(),
            true => Box::new(IDEOutput::new()),
        };
        Turtle {
            // Attempt to automatically detect if this is running within the Turtle IDE
            screen: screen,
            speed: "normal".into(),
            position: Point::origin(),
            direction: Direction::zero_degrees(),
            pen: Pen::default(),
            drawing_enabled: true,
        }
    }

    /// Returns the current speed of the turtle
    pub fn speed(&self) -> Speed {
        self.speed
    }

    /// Return the turtle's current location (x, y)
    pub fn position(&self) -> Point {
        self.position
    }

    /// Return the turtle's current heading
    pub fn heading(&self) -> Angle {
        self.direction.raw_angle()
    }

    /// Pull the pen down so that the turtle draws while moving
    pub fn pen_down(&mut self) {
        self.drawing_enabled = true;
    }

    /// Pick the pen up so that the turtle does not draw while moving
    pub fn pen_up(&mut self) {
        self.drawing_enabled = false;
    }

    /// Set the turtle's speed to the given setting.
    ///
    /// Usually this method is used as shown below:
    ///
    /// ```rust,no_run
    /// # extern crate turtleide;
    /// # fn main() {
    /// # let mut turtle = turtleide::Turtle::new();
    /// turtle.set_speed("normal".into());
    /// turtle.set_speed("fast".into());
    /// turtle.set_speed(2.into());
    /// turtle.set_speed(10.into());
    /// # }
    /// ```
    ///
    /// If input is a number greater than 10 or smaller than 1,
    /// speed is set to 0 (Speed::Instant). Strings are converted as follows:
    ///
    /// * "slowest" => Speed::One
    /// * "slow" => Speed::Three
    /// * "normal" => Speed::Six
    /// * "fast" => Speed::Ten
    /// * "fastest" => Speed::Instant
    /// * anything else will cause the program to `panic!` at runtime
    ///
    /// Speeds from 1 to 10 enforce increasingly faster animation of
    /// line drawing and turtle turning.
    ///
    /// Note: speed = 0 means that no animation takes place. forward/back
    /// makes turtle jump and likewise left/right make the turtle turn instantly.
    ///
    /// Using this type is an excellent way to learn about conversion
    /// traits `From` and `Into`. Rather than instantiating `Speed`
    /// directly using `Speed::Six`, you usually use `6.into()`. This is the
    /// same as using `Speed::from(6)` but much more compact. This works because
    /// any type that implements the `From` trait gets a matching implementation
    /// of the `Into` trait.
    pub fn set_speed(&mut self, speed: Speed) {
        self.speed = speed;
    }

    /// Change the angle unit to degrees.
    pub fn use_degrees(&mut self) {
        self.direction = self.direction.into_degrees();
    }

    /// Change the angle unit to radians.
    pub fn use_radians(&mut self) {
        self.direction = self.direction.into_radians();
    }

    /// Move the turtle forward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move backward
    /// using this method.
    pub fn forward(&mut self, distance: Distance) {
        let start = self.position;
        self.position = self.position.translate(self.direction, distance);
        if self.drawing_enabled {
            self.screen.draw_line(start, self.position, self.speed, self.pen);
        }
    }

    /// Move the turtle backward by the given amount of `distance`.
    ///
    /// `distance` is given in "pixels" which are like really small turtle steps.
    /// `distance` can be negative in which case the turtle can move forwards
    /// using this method.
    pub fn backward(&mut self, distance: Distance) {
        self.forward(-distance);
    }

    /// Rotate the turtle right by the given angle.
    ///
    /// Units are by default degrees, but can be set using the methods
    /// [`Turtle::use_degrees`](struct.Turtle.html#method.use_degrees) or
    /// [`Turtle::use_radians`](struct.Turtle.html#method.use_radians).
    pub fn right(&mut self, angle: Angle) {
        self.direction.rotate_clockwise(angle);
    }

    /// Rotate the turtle left by the given angle.
    ///
    /// Units are by default degrees, but can be set using the methods
    /// [`Turtle::use_degrees`](struct.Turtle.html#method.use_degrees) or
    /// [`Turtle::use_radians`](struct.Turtle.html#method.use_radians).
    pub fn left(&mut self, angle: Angle) {
        self.direction.rotate_counterclockwise(angle);
    }
}
<|endoftext|>