<commit_before>use na::{self, DVector, Real};
use std::ops::Range;

use detection::ColliderContactManifold;
use ncollide::query::TrackedContact;
use ncollide::utils::IsometryOps;
use object::BodySet;
use solver::helper;
use solver::{ConstraintSet, ContactModel, ForceDirection, ImpulseCache, IntegrationParameters,
             NonlinearUnilateralConstraint, UnilateralConstraint, UnilateralGroundConstraint};

/// A contact model generating one non-penetration constraint per contact.
///
/// This is a frictionless contact model.
pub struct SignoriniModel<N: Real> {
    impulses: ImpulseCache<N>,
    vel_ground_rng: Range<usize>,
    vel_rng: Range<usize>,
}

impl<N: Real> SignoriniModel<N> {
    /// Create a new Signorini contact model.
    pub fn new() -> Self {
        SignoriniModel {
            impulses: ImpulseCache::new(),
            vel_ground_rng: 0..0,
            vel_rng: 0..0,
        }
    }

    /// Build a non-penetration velocity-based constraint for the given contact.
    pub fn build_velocity_constraint(
        params: &IntegrationParameters<N>,
        bodies: &BodySet<N>,
        manifold: &ColliderContactManifold<N>,
        ext_vels: &DVector<N>,
        c: &TrackedContact<N>,
        impulse: N,
        impulse_id: usize,
        ground_j_id: &mut usize,
        j_id: &mut usize,
        jacobians: &mut [N],
        constraints: &mut ConstraintSet<N>,
    ) -> bool {
        let data1 = manifold.collider1.data();
        let data2 = manifold.collider2.data();

        let body1 = bodies.body(manifold.body1());
        let body2 = bodies.body(manifold.body2());
        let part1 = body1.part(manifold.body_part1(c.kinematic.feature1()));
        let part2 = body2.part(manifold.body_part2(c.kinematic.feature2()));

        let assembly_id1 = body1.companion_id();
        let assembly_id2 = body2.companion_id();

        let center1 = c.contact.world1 + c.contact.normal.unwrap() * data1.margin();
        let center2 = c.contact.world2 - c.contact.normal.unwrap() * data2.margin();
        let dir = ForceDirection::Linear(-c.contact.normal);

        let geom = helper::constraint_pair_geometry(
            body1,
            part1,
            body2,
            part2,
            &center1,
            &center2,
            &dir,
            ground_j_id,
            j_id,
            jacobians,
        );

        let mut rhs = helper::constraint_pair_velocity(
            body1,
            part1,
            body2,
            part2,
            assembly_id1,
            assembly_id2,
            &center1,
            &center2,
            &dir,
            ext_vels,
            jacobians,
            &geom,
        );

        if rhs > -params.restitution_velocity_threshold {
            let depth = c.contact.depth + data1.margin() + data2.margin();

            // No penetration, use predictive contact.
            if depth < N::zero() {
                rhs += (-depth) / params.dt;
            }
        } else {
            let rest1 = data1.material().restitution;
            let rest2 = data2.material().restitution;
            rhs += (rest1 + rest2) * na::convert(0.5) * rhs;
        }

        let warmstart = impulse * params.warmstart_coeff;
        if geom.is_ground_constraint() {
            constraints
                .velocity
                .unilateral_ground
                .push(UnilateralGroundConstraint::new(
                    geom,
                    assembly_id1,
                    assembly_id2,
                    rhs,
                    warmstart,
                    impulse_id,
                ));

            true
        } else {
            constraints
                .velocity
                .unilateral
                .push(UnilateralConstraint::new(
                    geom,
                    assembly_id1,
                    assembly_id2,
                    rhs,
                    warmstart,
                    impulse_id,
                ));

            false
        }
    }

    /// Checks if the given constraint is active.
    pub fn is_constraint_active(
        c: &TrackedContact<N>,
        manifold: &ColliderContactManifold<N>,
    ) -> bool {
        let depth = c.contact.depth + manifold.collider1.data().margin()
            + manifold.collider2.data().margin();

        // NOTE: for now we consider non-penetrating
        // constraints as inactive.
        depth >= N::zero()
    }

    /// Builds non-linear position-based non-penetration constraints for the given contact manifold.
    pub fn build_position_constraint(
        bodies: &BodySet<N>,
        manifold: &ColliderContactManifold<N>,
        c: &TrackedContact<N>,
        constraints: &mut ConstraintSet<N>,
    ) {
        let data1 = manifold.collider1.data();
        let data2 = manifold.collider2.data();

        let b1 = manifold.body_part1(c.kinematic.feature1());
        let b2 = manifold.body_part2(c.kinematic.feature2());

        let body1 = bodies.body(b1.body_handle);
        let body2 = bodies.body(b2.body_handle);
        let part1 = body1.part(b1);
        let part2 = body2.part(b2);

        // XXX: don't do this with deformable.
        let pos1 = part1.position();
        let pos2 = part2.position();
        let normal1 = pos1.inverse_transform_unit_vector(&c.contact.normal);
        let normal2 = -pos2.inverse_transform_unit_vector(&c.contact.normal);

        let mut kinematic = c.kinematic.clone();
        let total_margin1 = kinematic.dilation1() + data1.margin();
        let total_margin2 = kinematic.dilation2() + data2.margin();
        kinematic.set_dilation1(total_margin1);
        kinematic.set_dilation2(total_margin2);

//        println!("Kinematic: {:?}", kinematic);
//        println!("Original constraint: {:?}", c.contact);
//        println!("Recomputed contact : {:?}", kinematic.contact(
//            &(pos1 * data1.position_wrt_body()),
//            &**manifold.collider1.shape(),
//            None,
//            &(pos2 * data2.position_wrt_body()),
//            &**manifold.collider2.shape(),
//            None,
//            &normal1).unwrap());

        constraints
            .position
            .unilateral
            .push(NonlinearUnilateralConstraint::new(
                b1,
                manifold.collider1.handle(),
                body1.status_dependent_ndofs(),
                b2,
                manifold.collider2.handle(),
                body2.status_dependent_ndofs(),
                normal1,
                normal2,
                kinematic,
            ));
    }
}

impl<N: Real> ContactModel<N> for SignoriniModel<N> {
    fn num_velocity_constraints(&self, c: &ColliderContactManifold<N>) -> usize {
        c.manifold.len()
    }

    fn constraints(
        &mut self,
        params: &IntegrationParameters<N>,
        bodies: &BodySet<N>,
        ext_vels: &DVector<N>,
        manifolds: &[ColliderContactManifold<N>],
        ground_j_id: &mut usize,
        j_id: &mut usize,
        jacobians: &mut [N],
        constraints: &mut ConstraintSet<N>,
    ) {
        let id_vel_ground = constraints.velocity.unilateral_ground.len();
        let id_vel = constraints.velocity.unilateral.len();

        for manifold in manifolds {
            for c in manifold.contacts() {
                // if !Self::is_constraint_active(c, manifold) {
                //     continue;
                // }

                let _ = Self::build_velocity_constraint(
                    params,
                    bodies,
                    manifold,
                    ext_vels,
                    c,
                    self.impulses.get(c.id),
                    self.impulses.entry_id(c.id),
                    ground_j_id,
                    j_id,
                    jacobians,
                    constraints,
                );

                Self::build_position_constraint(bodies, manifold, c, constraints);
            }
        }

        self.vel_ground_rng = id_vel_ground..constraints.velocity.unilateral_ground.len();
        self.vel_rng = id_vel..constraints.velocity.unilateral.len();
    }

    fn cache_impulses(&mut self, constraints: &ConstraintSet<N>) {
        let ground_contacts = &constraints.velocity.unilateral_ground[self.vel_ground_rng.clone()];
        let contacts = &constraints.velocity.unilateral[self.vel_rng.clone()];

        for c in ground_contacts {
            self.impulses[c.impulse_id] = c.impulse;
        }

        for c in contacts {
            self.impulses[c.impulse_id] = c.impulse;
        }
    }
}
<commit_msg>Properly handle contact constraint activation.<commit_after>use na::{self, DVector, Real};
use std::ops::Range;

use detection::ColliderContactManifold;
use ncollide::query::TrackedContact;
use ncollide::utils::IsometryOps;
use object::BodySet;
use solver::helper;
use solver::{ConstraintSet, ContactModel, ForceDirection, ImpulseCache, IntegrationParameters,
             NonlinearUnilateralConstraint, UnilateralConstraint, UnilateralGroundConstraint};

/// A contact model generating one non-penetration constraint per contact.
///
/// This is a frictionless contact model.
pub struct SignoriniModel<N: Real> {
    impulses: ImpulseCache<N>,
    vel_ground_rng: Range<usize>,
    vel_rng: Range<usize>,
}

impl<N: Real> SignoriniModel<N> {
    /// Create a new Signorini contact model.
    pub fn new() -> Self {
        SignoriniModel {
            impulses: ImpulseCache::new(),
            vel_ground_rng: 0..0,
            vel_rng: 0..0,
        }
    }

    /// Build a non-penetration velocity-based constraint for the given contact.
    pub fn build_velocity_constraint(
        params: &IntegrationParameters<N>,
        bodies: &BodySet<N>,
        manifold: &ColliderContactManifold<N>,
        ext_vels: &DVector<N>,
        c: &TrackedContact<N>,
        impulse: N,
        impulse_id: usize,
        ground_j_id: &mut usize,
        j_id: &mut usize,
        jacobians: &mut [N],
        constraints: &mut ConstraintSet<N>,
    ) -> bool {
        let data1 = manifold.collider1.data();
        let data2 = manifold.collider2.data();

        let body1 = bodies.body(manifold.body1());
        let body2 = bodies.body(manifold.body2());
        let part1 = body1.part(manifold.body_part1(c.kinematic.feature1()));
        let part2 = body2.part(manifold.body_part2(c.kinematic.feature2()));

        let assembly_id1 = body1.companion_id();
        let assembly_id2 = body2.companion_id();

        let center1 = c.contact.world1 + c.contact.normal.unwrap() * data1.margin();
        let center2 = c.contact.world2 - c.contact.normal.unwrap() * data2.margin();
        let dir = ForceDirection::Linear(-c.contact.normal);

        let geom = helper::constraint_pair_geometry(
            body1,
            part1,
            body2,
            part2,
            &center1,
            &center2,
            &dir,
            ground_j_id,
            j_id,
            jacobians,
        );

        let mut rhs = helper::constraint_pair_velocity(
            body1,
            part1,
            body2,
            part2,
            assembly_id1,
            assembly_id2,
            &center1,
            &center2,
            &dir,
            ext_vels,
            jacobians,
            &geom,
        );

        /*if true { // rhs > -params.restitution_velocity_threshold {
            let depth = c.contact.depth + data1.margin() + data2.margin();

            // No penetration, use predictive contact.
            if depth < N::zero() {
                rhs += (-depth) / params.dt;
            }
        } else {
            let rest1 = data1.material().restitution;
            let rest2 = data2.material().restitution;
            rhs += (rest1 + rest2) * na::convert(0.5) * rhs;
        }*/

        // Handle restitution.
        if rhs <= -params.restitution_velocity_threshold {
            let rest1 = data1.material().restitution;
            let rest2 = data2.material().restitution;
            rhs += (rest1 + rest2) * na::convert(0.5) * rhs;
        }

        // Handle predictive contact if no penetration.
        let depth = c.contact.depth + data1.margin() + data2.margin();
        if depth < N::zero() {
            rhs += (-depth) / params.dt;
        }

        // FIXME: would it be more efficient to consider the contact active iff. the rhs
        // is still negative at this point?

        let warmstart = impulse * params.warmstart_coeff;
        if geom.is_ground_constraint() {
            constraints
                .velocity
                .unilateral_ground
                .push(UnilateralGroundConstraint::new(
                    geom,
                    assembly_id1,
                    assembly_id2,
                    rhs,
                    warmstart,
                    impulse_id,
                ));

            true
        } else {
            constraints
                .velocity
                .unilateral
                .push(UnilateralConstraint::new(
                    geom,
                    assembly_id1,
                    assembly_id2,
                    rhs,
                    warmstart,
                    impulse_id,
                ));

            false
        }
    }

    /// Checks if the given constraint is active.
    pub fn is_constraint_active(
        c: &TrackedContact<N>,
        manifold: &ColliderContactManifold<N>,
    ) -> bool {
        let depth = c.contact.depth + manifold.collider1.data().margin()
            + manifold.collider2.data().margin();

        // NOTE: for now we consider non-penetrating
        // constraints as inactive.
        depth >= N::zero()
    }

    /// Builds non-linear position-based non-penetration constraints for the given contact manifold.
    pub fn build_position_constraint(
        bodies: &BodySet<N>,
        manifold: &ColliderContactManifold<N>,
        c: &TrackedContact<N>,
        constraints: &mut ConstraintSet<N>,
    ) {
        let data1 = manifold.collider1.data();
        let data2 = manifold.collider2.data();

        let b1 = manifold.body_part1(c.kinematic.feature1());
        let b2 = manifold.body_part2(c.kinematic.feature2());

        let body1 = bodies.body(b1.body_handle);
        let body2 = bodies.body(b2.body_handle);
        let part1 = body1.part(b1);
        let part2 = body2.part(b2);

        // XXX: don't do this with deformable.
        let pos1 = part1.position();
        let pos2 = part2.position();
        let normal1 = pos1.inverse_transform_unit_vector(&c.contact.normal);
        let normal2 = -pos2.inverse_transform_unit_vector(&c.contact.normal);

        let mut kinematic = c.kinematic.clone();
        let total_margin1 = kinematic.dilation1() + data1.margin();
        let total_margin2 = kinematic.dilation2() + data2.margin();
        kinematic.set_dilation1(total_margin1);
        kinematic.set_dilation2(total_margin2);

//        println!("Kinematic: {:?}", kinematic);
//        println!("Original constraint: {:?}", c.contact);
//        println!("Recomputed contact : {:?}", kinematic.contact(
//            &(pos1 * data1.position_wrt_body()),
//            &**manifold.collider1.shape(),
//            None,
//            &(pos2 * data2.position_wrt_body()),
//            &**manifold.collider2.shape(),
//            None,
//            &normal1).unwrap());

        constraints
            .position
            .unilateral
            .push(NonlinearUnilateralConstraint::new(
                b1,
                manifold.collider1.handle(),
                body1.status_dependent_ndofs(),
                b2,
                manifold.collider2.handle(),
                body2.status_dependent_ndofs(),
                normal1,
                normal2,
                kinematic,
            ));
    }
}

impl<N: Real> ContactModel<N> for SignoriniModel<N> {
    fn num_velocity_constraints(&self, c: &ColliderContactManifold<N>) -> usize {
        c.manifold.len()
    }

    fn constraints(
        &mut self,
        params: &IntegrationParameters<N>,
        bodies: &BodySet<N>,
        ext_vels: &DVector<N>,
        manifolds: &[ColliderContactManifold<N>],
        ground_j_id: &mut usize,
        j_id: &mut usize,
        jacobians: &mut [N],
        constraints: &mut ConstraintSet<N>,
    ) {
        let id_vel_ground = constraints.velocity.unilateral_ground.len();
        let id_vel = constraints.velocity.unilateral.len();

        for manifold in manifolds {
            for c in manifold.contacts() {
                 if !Self::is_constraint_active(c, manifold) {
                     continue;
                 }

                let _ = Self::build_velocity_constraint(
                    params,
                    bodies,
                    manifold,
                    ext_vels,
                    c,
                    self.impulses.get(c.id),
                    self.impulses.entry_id(c.id),
                    ground_j_id,
                    j_id,
                    jacobians,
                    constraints,
                );

                Self::build_position_constraint(bodies, manifold, c, constraints);
            }
        }

        self.vel_ground_rng = id_vel_ground..constraints.velocity.unilateral_ground.len();
        self.vel_rng = id_vel..constraints.velocity.unilateral.len();
    }

    fn cache_impulses(&mut self, constraints: &ConstraintSet<N>) {
        let ground_contacts = &constraints.velocity.unilateral_ground[self.vel_ground_rng.clone()];
        let contacts = &constraints.velocity.unilateral[self.vel_rng.clone()];

        for c in ground_contacts {
            self.impulses[c.impulse_id] = c.impulse;
        }

        for c in contacts {
            self.impulses[c.impulse_id] = c.impulse;
        }
    }
}
<|endoftext|>


<commit_before>use CL::*;
use hl::*;
use error::check;

// These are basically types that can be safely memcpyed.
pub trait VectorType {}

impl int: VectorType;
impl i32: VectorType;
impl uint: VectorType;
impl u32: VectorType;
impl float: VectorType;
impl f64: VectorType;
impl f32: VectorType;

pub struct Vector<T: VectorType> {
    cl_buffer: cl_mem,
    size: uint,
    context: @ComputeContext,

    drop {
        clReleaseMemObject(self.cl_buffer);
    }
}

pub impl<T: VectorType> Vector<T> {
    static pub fn from_vec(ctx: @ComputeContext, v: &[const T]) -> Vector<T> {
        do vec::as_const_buf(v) |p, len| {
            let mut status = 0;
            let byte_size = len * sys::size_of::<T>() as libc::size_t;

            let buf = clCreateBuffer(ctx.ctx.ctx,
                                     CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
                                     byte_size,
                                     p as *libc::c_void,
                                     ptr::addr_of(&status));
            check(status, "Could not allocate buffer");

            //let status = clEnqueueWriteBuffer(
            //    ctx.q, buf, CL_TRUE, 0, byte_size, p as *libc::c_void,
            //    0, ptr::null(), ptr::null());

            Vector {
                cl_buffer: buf,
                size: len,
                context: ctx,
            }
        }
    }

    pub fn to_vec(self) -> ~[T] unsafe {
        let mut result = ~[];
        vec::reserve(&mut result, self.size);
        vec::raw::set_len(&mut result, self.size);
        do vec::as_imm_buf(result) |p, len| {
            clEnqueueReadBuffer(
                self.context.q.cqueue, self.cl_buffer, CL_TRUE, 0,
                len * sys::size_of::<T>() as libc::size_t,
                p as *libc::c_void, 0, ptr::null(), ptr::null());

        }
        move result
    }
}

impl<T: VectorType> Vector<T>: ::hl::KernelArg {
    pure fn get_value(&self) -> (libc::size_t, *libc::c_void) {
        (sys::size_of::<cl_mem>() as libc::size_t,
         ptr::addr_of(&self.cl_buffer) as *libc::c_void)
    }
}

pub struct Unique<T: VectorType> {
    cl_buffer: cl_mem,
    size: uint,
    context: @ComputeContext,

    drop {
        clReleaseMemObject(self.cl_buffer);
    }
}

pub impl<T: VectorType> Unique<T> {
    static pub fn from_vec(ctx: @ComputeContext, v: ~[const T]) -> Unique<T>
        unsafe
    {
        let byte_size
            = 6 * sys::size_of::<uint>()
            + v.len() * sys::size_of::<T>();
        let byte_size = byte_size as libc::size_t;

        let len = v.len();

        let addr: *libc::c_void = cast::reinterpret_cast(&v);

        let mut status = 0;
        let buf = clCreateBuffer(ctx.ctx.ctx,
                                 CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
                                 byte_size,
                                 addr,
                                 ptr::addr_of(&status));
        check(status, "Could not allocate buffer");

        Unique {
            cl_buffer: buf,
            size: len,
            context: ctx,
        }
    }

    pub fn to_vec(self) -> ~[T] unsafe {
        let mut result = ~[];
        vec::reserve(&mut result, self.size);
        vec::raw::set_len(&mut result, self.size);
        do vec::as_imm_buf(result) |p, len| {
            clEnqueueReadBuffer(
                self.context.q.cqueue, self.cl_buffer, CL_TRUE,
                // Skip the header, we have a new one here.
                (6 * sys::size_of::<uint>()) as libc::size_t,
                len * sys::size_of::<T>() as libc::size_t,
                p as *libc::c_void, 0, ptr::null(), ptr::null());

        }
        move result
    }
}

impl<T: VectorType> Unique<T>: ::hl::KernelArg {
    pure fn get_value(&self) -> (libc::size_t, *libc::c_void) {
        (sys::size_of::<cl_mem>() as libc::size_t,
         ptr::addr_of(&self.cl_buffer) as *libc::c_void)
    }
}

#[cfg(test)]
mod test {
    use hl::*;
    use vector::*;

    macro_rules! expect (
        ($test: expr, $expected: expr) => ({
            let test = $test;
            let expected = $expected;
            if test != expected {
                fail fmt!("Test failure in %s: expected %?, got %?",
                          stringify!($test),
                          expected, test)
            }
        })
    )

    #[test]
    fn gpu_vector() {
        let ctx = create_compute_context();

        let x = ~[1, 2, 3, 4, 5];
        let gx = Vector::from_vec(ctx, x);
        let y = gx.to_vec();
        expect!(y, x);
    }

    #[test]
    fn unique_vector() {
        let ctx = create_compute_context();

        let x = ~[1, 2, 3, 4, 5];
        let gx = Unique::from_vec(ctx, copy x);
        let y = gx.to_vec();
        expect!(y, x);
    }
}
<commit_msg>Use clEnqueueWriteBuffer instead of copying the buffer as part of clCreateBuffer. This seems to improve performance drammatically.<commit_after>use CL::*;
use hl::*;
use error::check;

// These are basically types that can be safely memcpyed.
pub trait VectorType {}

impl int: VectorType;
impl i32: VectorType;
impl uint: VectorType;
impl u32: VectorType;
impl float: VectorType;
impl f64: VectorType;
impl f32: VectorType;

pub struct Vector<T: VectorType> {
    cl_buffer: cl_mem,
    size: uint,
    context: @ComputeContext,

    drop {
        clReleaseMemObject(self.cl_buffer);
    }
}

pub impl<T: VectorType> Vector<T> {
    static pub fn from_vec(ctx: @ComputeContext, v: &[const T]) -> Vector<T> {
        do vec::as_const_buf(v) |p, len| {
            let mut status = 0;
            let byte_size = len * sys::size_of::<T>() as libc::size_t;

            let buf = clCreateBuffer(ctx.ctx.ctx,
                                     CL_MEM_READ_WRITE,
                                     byte_size,
                                     p as *libc::c_void,
                                     ptr::addr_of(&status));
            check(status, "Could not allocate buffer");

            let status = clEnqueueWriteBuffer(
                ctx.q.cqueue, buf, CL_TRUE,
                0, byte_size, p as *libc::c_void,
                0, ptr::null(), ptr::null());
            check(status, "Error copying buffer data");

            Vector {
                cl_buffer: buf,
                size: len,
                context: ctx,
            }
        }
    }

    pub fn to_vec(self) -> ~[T] unsafe {
        let mut result = ~[];
        vec::reserve(&mut result, self.size);
        vec::raw::set_len(&mut result, self.size);
        do vec::as_imm_buf(result) |p, len| {
            clEnqueueReadBuffer(
                self.context.q.cqueue, self.cl_buffer, CL_TRUE, 0,
                len * sys::size_of::<T>() as libc::size_t,
                p as *libc::c_void, 0, ptr::null(), ptr::null());

        }
        move result
    }
}

impl<T: VectorType> Vector<T>: ::hl::KernelArg {
    pure fn get_value(&self) -> (libc::size_t, *libc::c_void) {
        (sys::size_of::<cl_mem>() as libc::size_t,
         ptr::addr_of(&self.cl_buffer) as *libc::c_void)
    }
}

pub struct Unique<T: VectorType> {
    cl_buffer: cl_mem,
    size: uint,
    context: @ComputeContext,

    drop {
        clReleaseMemObject(self.cl_buffer);
    }
}

pub impl<T: VectorType> Unique<T> {
    static pub fn from_vec(ctx: @ComputeContext, v: ~[const T]) -> Unique<T>
        unsafe
    {
        let byte_size
            = 6 * sys::size_of::<uint>()
            + v.len() * sys::size_of::<T>();
        let byte_size = byte_size as libc::size_t;

        let len = v.len();

        let addr: *libc::c_void = cast::reinterpret_cast(&v);

        let mut status = 0;
        let buf = clCreateBuffer(ctx.ctx.ctx,
                                 CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
                                 byte_size,
                                 addr,
                                 ptr::addr_of(&status));
        check(status, "Could not allocate buffer");

        Unique {
            cl_buffer: buf,
            size: len,
            context: ctx,
        }
    }

    pub fn to_vec(self) -> ~[T] unsafe {
        let mut result = ~[];
        vec::reserve(&mut result, self.size);
        vec::raw::set_len(&mut result, self.size);
        do vec::as_imm_buf(result) |p, len| {
            clEnqueueReadBuffer(
                self.context.q.cqueue, self.cl_buffer, CL_TRUE,
                // Skip the header, we have a new one here.
                (6 * sys::size_of::<uint>()) as libc::size_t,
                len * sys::size_of::<T>() as libc::size_t,
                p as *libc::c_void, 0, ptr::null(), ptr::null());

        }
        move result
    }
}

impl<T: VectorType> Unique<T>: ::hl::KernelArg {
    pure fn get_value(&self) -> (libc::size_t, *libc::c_void) {
        (sys::size_of::<cl_mem>() as libc::size_t,
         ptr::addr_of(&self.cl_buffer) as *libc::c_void)
    }
}

#[cfg(test)]
mod test {
    use hl::*;
    use vector::*;

    macro_rules! expect (
        ($test: expr, $expected: expr) => ({
            let test = $test;
            let expected = $expected;
            if test != expected {
                fail fmt!("Test failure in %s: expected %?, got %?",
                          stringify!($test),
                          expected, test)
            }
        })
    )

    #[test]
    fn gpu_vector() {
        let ctx = create_compute_context();

        let x = ~[1, 2, 3, 4, 5];
        let gx = Vector::from_vec(ctx, x);
        let y = gx.to_vec();
        expect!(y, x);
    }

    #[test]
    fn unique_vector() {
        let ctx = create_compute_context();

        let x = ~[1, 2, 3, 4, 5];
        let gx = Unique::from_vec(ctx, copy x);
        let y = gx.to_vec();
        expect!(y, x);
    }
}
<|endoftext|>


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

//! A wrapper around any Reader to treat it as an RNG.

use Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use rand::{reader, Rng};
/// use std::io::MemReader;
///
/// let mut rng = reader::ReaderRng::new(MemReader::new(vec!(1,2,3,4,5,6,7,8)));
/// println!("{:x}", rng.gen::<uint>());
/// ```
pub struct ReaderRng<R> {
    reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        if cfg!(target_endian="little") {
            self.reader.read_le_u32().unwrap()
        } else {
            self.reader.read_be_u32().unwrap()
        }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        if cfg!(target_endian="little") {
            self.reader.read_le_u64().unwrap()
        } else {
            self.reader.read_be_u64().unwrap()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.fill(v) {
            Ok(()) => {}
            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
        }
    }
}

#[cfg(test)]
#[allow(deprecated_owned_vector)]
mod test {
    use super::ReaderRng;
    use std::io::MemReader;
    use std::mem;
    use Rng;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = box [1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {mem::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = box [1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {mem::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(Vec::from_slice(v)));
        rng.fill_bytes(w);

        assert!(v == w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(vec!()));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<commit_msg>io: Add .read_at_least() to Reader<commit_after>// Copyright 2013 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.

//! A wrapper around any Reader to treat it as an RNG.

use Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use rand::{reader, Rng};
/// use std::io::MemReader;
///
/// let mut rng = reader::ReaderRng::new(MemReader::new(vec!(1,2,3,4,5,6,7,8)));
/// println!("{:x}", rng.gen::<uint>());
/// ```
pub struct ReaderRng<R> {
    reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        if cfg!(target_endian="little") {
            self.reader.read_le_u32().unwrap()
        } else {
            self.reader.read_be_u32().unwrap()
        }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        if cfg!(target_endian="little") {
            self.reader.read_le_u64().unwrap()
        } else {
            self.reader.read_be_u64().unwrap()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.read_at_least(v.len(), v) {
            Ok(_) => {}
            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
        }
    }
}

#[cfg(test)]
#[allow(deprecated_owned_vector)]
mod test {
    use super::ReaderRng;
    use std::io::MemReader;
    use std::mem;
    use Rng;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = box [1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {mem::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = box [1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {mem::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes.move_iter().collect()));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(Vec::from_slice(v)));
        rng.fill_bytes(w);

        assert!(v == w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(vec!()));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<|endoftext|>


<commit_before>use crate::clean;
use crate::core::DocContext;
use crate::html::item_type::ItemType;
use crate::fold::{self, DocFolder};
use crate::passes::Pass;

use syntax::attr;

use std::collections::BTreeMap;
use std::fmt;
use std::ops;

pub const CALCULATE_DOC_COVERAGE: Pass = Pass {
    name: "calculate-doc-coverage",
    pass: calculate_doc_coverage,
    description: "counts the number of items with and without documentation",
};

fn calculate_doc_coverage(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
    let mut calc = CoverageCalculator::default();
    let krate = calc.fold_crate(krate);

    calc.print_results();

    krate
}

#[derive(Default, Copy, Clone)]
struct ItemCount {
    total: u64,
    with_docs: u64,
}

impl ItemCount {
    fn count_item(&mut self, has_docs: bool) {
        self.total += 1;

        if has_docs {
            self.with_docs += 1;
        }
    }

    fn percentage(&self) -> Option<f64> {
        if self.total > 0 {
            Some((self.with_docs as f64 * 100.0) / self.total as f64)
        } else {
            None
        }
    }
}

impl ops::Sub for ItemCount {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        ItemCount {
            total: self.total - rhs.total,
            with_docs: self.with_docs - rhs.with_docs,
        }
    }
}

impl ops::AddAssign for ItemCount {
    fn add_assign(&mut self, rhs: Self) {
        self.total += rhs.total;
        self.with_docs += rhs.with_docs;
    }
}

impl fmt::Display for ItemCount {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}/{}", self.with_docs, self.total)
    }
}

#[derive(Default)]
struct CoverageCalculator {
    items: BTreeMap<ItemType, ItemCount>,
}

impl CoverageCalculator {
    fn print_results(&self) {
        use crate::html::item_type::ItemType::*;

        let mut total = ItemCount::default();

        let main_types = [
            Module, Function,
            Struct, StructField,
            Enum, Variant,
            Union,
            Method,
            Trait, TyMethod,
            AssociatedType, AssociatedConst,
            Macro,
            Static, Constant,
            ForeignType, Existential,
            Typedef, TraitAlias,
            Primitive, Keyword,
        ];

        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
        println!("| {:<25} | {:>10} | {:>10} | {:>10} |",
                 "Item Type", "Documented", "Total", "Percentage");
        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

        for item_type in &main_types {
            let count = self.items.get(item_type).cloned().unwrap_or_default();

            if let Some(percentage) = count.percentage() {
                println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                         table_name(item_type), count.with_docs, count.total, percentage);

                total += count;
            }
        }

        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

        if let Some(count) = self.items.get(&Impl) {
            if let Some(percentage) = count.percentage() {
                if let Some(percentage) = total.percentage() {
                    println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                             "Total (non trait impls)", total.with_docs, total.total, percentage);
                }

                println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

                println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                         table_name(&Impl), count.with_docs, count.total, percentage);

                println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

                total += *count;
            }
        }

        println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                 "Total", total.with_docs, total.total, total.percentage().unwrap_or(0.0));
        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
    }
}

impl fold::DocFolder for CoverageCalculator {
    fn fold_item(&mut self, mut i: clean::Item) -> Option<clean::Item> {
        let has_docs = !i.attrs.doc_strings.is_empty();

        match i.inner {
            _ if !i.def_id.is_local() => {
                // non-local items are skipped because they can be out of the users control,
                // especially in the case of trait impls, which rustdoc eagerly inlines
                return Some(i);
            }
            clean::StrippedItem(..) => {
                // don't count items in stripped modules
                return Some(i);
            }
            clean::ImportItem(..) | clean::ExternCrateItem(..) => {
                // docs on `use` and `extern crate` statements are not displayed, so they're not
                // worth counting
                return Some(i);
            }
            clean::ImplItem(ref impl_)
                if attr::contains_name(&i.attrs.other_attrs, "automatically_derived")
                    || impl_.synthetic || impl_.blanket_impl.is_some() =>
            {
                // built-in derives get the `#[automatically_derived]` attribute, and
                // synthetic/blanket impls are made up by rustdoc and can't be documented
                // FIXME(misdreavus): need to also find items that came out of a derive macro
                return Some(i);
            }
            clean::ImplItem(ref impl_) => {
                if let Some(ref tr) = impl_.trait_ {
                    debug!("counting impl {:#} for {:#}", tr, impl_.for_);

                    // trait impls inherit their docs from the trait definition, so documenting
                    // them can be considered optional
                    self.items.entry(ItemType::Impl).or_default().count_item(has_docs);

                    for it in &impl_.items {
                        let has_docs = !it.attrs.doc_strings.is_empty();
                        self.items.entry(ItemType::Impl).or_default().count_item(has_docs);
                    }

                    // now skip recursing, so that we don't double-count this impl's items
                    return Some(i);
                } else {
                    // inherent impls *can* be documented, and those docs show up, but in most
                    // cases it doesn't make sense, as all methods on a type are in one single
                    // impl block
                    debug!("not counting impl {:#}", impl_.for_);
                }
            }
            clean::MacroItem(..) | clean::ProcMacroItem(..) => {
                // combine `macro_rules!` macros and proc-macros in the same count
                debug!("counting macro {:?}", i.name);
                self.items.entry(ItemType::Macro).or_default().count_item(has_docs);
            }
            clean::TraitItem(ref mut trait_) => {
                // because both trait methods with a default impl and struct methods are
                // ItemType::Method, we need to properly tag trait methods as TyMethod instead
                debug!("counting trait {:?}", i.name);
                self.items.entry(ItemType::Trait).or_default().count_item(has_docs);

                // since we're not going on to document the crate, it doesn't matter if we discard
                // the item after counting it
                trait_.items.retain(|it| {
                    if it.type_() == ItemType::Method {
                        let has_docs = !it.attrs.doc_strings.is_empty();
                        self.items.entry(ItemType::TyMethod).or_default().count_item(has_docs);
                        false
                    } else {
                        true
                    }
                });
            }
            _ => {
                debug!("counting {} {:?}", i.type_(), i.name);
                self.items.entry(i.type_()).or_default().count_item(has_docs);
            }
        }

        self.fold_item_recur(i)
    }
}

fn table_name(type_: &ItemType) -> &'static str {
        match *type_ {
            ItemType::Module          => "Modules",
            ItemType::Struct          => "Structs",
            ItemType::Union           => "Unions",
            ItemType::Enum            => "Enums",
            ItemType::Function        => "Functions",
            ItemType::Typedef         => "Type Aliases",
            ItemType::Static          => "Statics",
            ItemType::Trait           => "Traits",
            // inherent impls aren't counted, and trait impls get all their items thrown into this
            // counter
            ItemType::Impl            => "Trait Impl Items",
            // even though trait methods with a default impl get cleaned as Method, we convert them
            // to TyMethod when counting
            ItemType::TyMethod        => "Trait Methods",
            ItemType::Method          => "Methods",
            ItemType::StructField     => "Struct Fields",
            ItemType::Variant         => "Enum Variants",
            ItemType::Macro           => "Macros",
            ItemType::Primitive       => "Primitives",
            ItemType::AssociatedType  => "Associated Types",
            ItemType::Constant        => "Constants",
            ItemType::AssociatedConst => "Associated Constants",
            ItemType::ForeignType     => "Foreign Types",
            ItemType::Keyword         => "Keywords",
            ItemType::Existential     => "Existential Types",
            ItemType::TraitAlias      => "Trait Aliases",
            _                         => panic!("unanticipated ItemType: {}", type_),
        }
}
<commit_msg>tweak wording of extern types<commit_after>use crate::clean;
use crate::core::DocContext;
use crate::html::item_type::ItemType;
use crate::fold::{self, DocFolder};
use crate::passes::Pass;

use syntax::attr;

use std::collections::BTreeMap;
use std::fmt;
use std::ops;

pub const CALCULATE_DOC_COVERAGE: Pass = Pass {
    name: "calculate-doc-coverage",
    pass: calculate_doc_coverage,
    description: "counts the number of items with and without documentation",
};

fn calculate_doc_coverage(krate: clean::Crate, _: &DocContext<'_, '_, '_>) -> clean::Crate {
    let mut calc = CoverageCalculator::default();
    let krate = calc.fold_crate(krate);

    calc.print_results();

    krate
}

#[derive(Default, Copy, Clone)]
struct ItemCount {
    total: u64,
    with_docs: u64,
}

impl ItemCount {
    fn count_item(&mut self, has_docs: bool) {
        self.total += 1;

        if has_docs {
            self.with_docs += 1;
        }
    }

    fn percentage(&self) -> Option<f64> {
        if self.total > 0 {
            Some((self.with_docs as f64 * 100.0) / self.total as f64)
        } else {
            None
        }
    }
}

impl ops::Sub for ItemCount {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        ItemCount {
            total: self.total - rhs.total,
            with_docs: self.with_docs - rhs.with_docs,
        }
    }
}

impl ops::AddAssign for ItemCount {
    fn add_assign(&mut self, rhs: Self) {
        self.total += rhs.total;
        self.with_docs += rhs.with_docs;
    }
}

impl fmt::Display for ItemCount {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}/{}", self.with_docs, self.total)
    }
}

#[derive(Default)]
struct CoverageCalculator {
    items: BTreeMap<ItemType, ItemCount>,
}

impl CoverageCalculator {
    fn print_results(&self) {
        use crate::html::item_type::ItemType::*;

        let mut total = ItemCount::default();

        let main_types = [
            Module, Function,
            Struct, StructField,
            Enum, Variant,
            Union,
            Method,
            Trait, TyMethod,
            AssociatedType, AssociatedConst,
            Macro,
            Static, Constant,
            ForeignType, Existential,
            Typedef, TraitAlias,
            Primitive, Keyword,
        ];

        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
        println!("| {:<25} | {:>10} | {:>10} | {:>10} |",
                 "Item Type", "Documented", "Total", "Percentage");
        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

        for item_type in &main_types {
            let count = self.items.get(item_type).cloned().unwrap_or_default();

            if let Some(percentage) = count.percentage() {
                println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                         table_name(item_type), count.with_docs, count.total, percentage);

                total += count;
            }
        }

        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

        if let Some(count) = self.items.get(&Impl) {
            if let Some(percentage) = count.percentage() {
                if let Some(percentage) = total.percentage() {
                    println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                             "Total (non trait impls)", total.with_docs, total.total, percentage);
                }

                println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

                println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                         table_name(&Impl), count.with_docs, count.total, percentage);

                println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");

                total += *count;
            }
        }

        println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
                 "Total", total.with_docs, total.total, total.percentage().unwrap_or(0.0));
        println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
    }
}

impl fold::DocFolder for CoverageCalculator {
    fn fold_item(&mut self, mut i: clean::Item) -> Option<clean::Item> {
        let has_docs = !i.attrs.doc_strings.is_empty();

        match i.inner {
            _ if !i.def_id.is_local() => {
                // non-local items are skipped because they can be out of the users control,
                // especially in the case of trait impls, which rustdoc eagerly inlines
                return Some(i);
            }
            clean::StrippedItem(..) => {
                // don't count items in stripped modules
                return Some(i);
            }
            clean::ImportItem(..) | clean::ExternCrateItem(..) => {
                // docs on `use` and `extern crate` statements are not displayed, so they're not
                // worth counting
                return Some(i);
            }
            clean::ImplItem(ref impl_)
                if attr::contains_name(&i.attrs.other_attrs, "automatically_derived")
                    || impl_.synthetic || impl_.blanket_impl.is_some() =>
            {
                // built-in derives get the `#[automatically_derived]` attribute, and
                // synthetic/blanket impls are made up by rustdoc and can't be documented
                // FIXME(misdreavus): need to also find items that came out of a derive macro
                return Some(i);
            }
            clean::ImplItem(ref impl_) => {
                if let Some(ref tr) = impl_.trait_ {
                    debug!("counting impl {:#} for {:#}", tr, impl_.for_);

                    // trait impls inherit their docs from the trait definition, so documenting
                    // them can be considered optional
                    self.items.entry(ItemType::Impl).or_default().count_item(has_docs);

                    for it in &impl_.items {
                        let has_docs = !it.attrs.doc_strings.is_empty();
                        self.items.entry(ItemType::Impl).or_default().count_item(has_docs);
                    }

                    // now skip recursing, so that we don't double-count this impl's items
                    return Some(i);
                } else {
                    // inherent impls *can* be documented, and those docs show up, but in most
                    // cases it doesn't make sense, as all methods on a type are in one single
                    // impl block
                    debug!("not counting impl {:#}", impl_.for_);
                }
            }
            clean::MacroItem(..) | clean::ProcMacroItem(..) => {
                // combine `macro_rules!` macros and proc-macros in the same count
                debug!("counting macro {:?}", i.name);
                self.items.entry(ItemType::Macro).or_default().count_item(has_docs);
            }
            clean::TraitItem(ref mut trait_) => {
                // because both trait methods with a default impl and struct methods are
                // ItemType::Method, we need to properly tag trait methods as TyMethod instead
                debug!("counting trait {:?}", i.name);
                self.items.entry(ItemType::Trait).or_default().count_item(has_docs);

                // since we're not going on to document the crate, it doesn't matter if we discard
                // the item after counting it
                trait_.items.retain(|it| {
                    if it.type_() == ItemType::Method {
                        let has_docs = !it.attrs.doc_strings.is_empty();
                        self.items.entry(ItemType::TyMethod).or_default().count_item(has_docs);
                        false
                    } else {
                        true
                    }
                });
            }
            _ => {
                debug!("counting {} {:?}", i.type_(), i.name);
                self.items.entry(i.type_()).or_default().count_item(has_docs);
            }
        }

        self.fold_item_recur(i)
    }
}

fn table_name(type_: &ItemType) -> &'static str {
        match *type_ {
            ItemType::Module          => "Modules",
            ItemType::Struct          => "Structs",
            ItemType::Union           => "Unions",
            ItemType::Enum            => "Enums",
            ItemType::Function        => "Functions",
            ItemType::Typedef         => "Type Aliases",
            ItemType::Static          => "Statics",
            ItemType::Trait           => "Traits",
            // inherent impls aren't counted, and trait impls get all their items thrown into this
            // counter
            ItemType::Impl            => "Trait Impl Items",
            // even though trait methods with a default impl get cleaned as Method, we convert them
            // to TyMethod when counting
            ItemType::TyMethod        => "Trait Methods",
            ItemType::Method          => "Methods",
            ItemType::StructField     => "Struct Fields",
            ItemType::Variant         => "Enum Variants",
            ItemType::Macro           => "Macros",
            ItemType::Primitive       => "Primitives",
            ItemType::AssociatedType  => "Associated Types",
            ItemType::Constant        => "Constants",
            ItemType::AssociatedConst => "Associated Constants",
            ItemType::ForeignType     => "Extern Types",
            ItemType::Keyword         => "Keywords",
            ItemType::Existential     => "Existential Types",
            ItemType::TraitAlias      => "Trait Aliases",
            _                         => panic!("unanticipated ItemType: {}", type_),
        }
}
<|endoftext|>


<commit_before>#![deny(unsafe_code)]

#[cfg(feature = "open")]
pub mod open;

#[cfg(feature = "plugins")]
pub mod plugins;

#[cfg(feature = "upgrade")]
pub mod upgrade;

#[cfg(feature = "config")]
pub mod config;

#[cfg(feature = "inspect")]
pub mod inspect;

#[cfg(feature = "request")]
pub mod request;

#[cfg(feature = "serve")]
pub mod serve;

#[cfg(any(feature = "request", feature = "serve"))]
pub mod delegate;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod jwt;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod methods;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod protocols;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod rpc;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod urls;

// Methods

pub mod read;
pub mod write;

pub mod decode;
pub mod encode;

pub mod export;
pub mod import;

pub mod convert;

pub mod validate;

pub mod execute;

// Utilities

pub mod util {
    pub mod dirs;
    pub mod params;
}
pub mod logging;
pub mod nodes;

// Re-export packages (mainly for use by stencila-* language packages in this workspace)

pub use anyhow;
pub use regex;
pub use serde_json;
pub use strum;
pub use tokio;
pub use tracing;
<commit_msg>feat(Rust): Re-export serde<commit_after>#![deny(unsafe_code)]

#[cfg(feature = "open")]
pub mod open;

#[cfg(feature = "plugins")]
pub mod plugins;

#[cfg(feature = "upgrade")]
pub mod upgrade;

#[cfg(feature = "config")]
pub mod config;

#[cfg(feature = "inspect")]
pub mod inspect;

#[cfg(feature = "request")]
pub mod request;

#[cfg(feature = "serve")]
pub mod serve;

#[cfg(any(feature = "request", feature = "serve"))]
pub mod delegate;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod jwt;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod methods;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod protocols;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod rpc;
#[cfg(any(feature = "request", feature = "serve"))]
pub mod urls;

// Methods

pub mod read;
pub mod write;

pub mod decode;
pub mod encode;

pub mod export;
pub mod import;

pub mod convert;

pub mod validate;

pub mod execute;

// Utilities

pub mod util {
    pub mod dirs;
    pub mod params;
}
pub mod logging;
pub mod nodes;

// Re-export packages (mainly for use by stencila-* language packages in this workspace)

pub use anyhow;
pub use regex;
pub use serde;
pub use serde_json;
pub use strum;
pub use tokio;
pub use tracing;
<|endoftext|>


<commit_before>import std::cmp::FuzzyEq;
import num::Num;

pure fn Matrix4<T:copy FuzzyEq Num>(m11: T, m12: T, m13: T, m14: T,
                                    m21: T, m22: T, m23: T, m24: T,
                                    m31: T, m32: T, m33: T, m34: T,
                                    m41: T, m42: T, m43: T, m44: T)
                                 -> Matrix4<T> {

    Matrix4 {
        m11: m11, m12: m12, m13: m13, m14: m14,
        m21: m21, m22: m22, m23: m23, m24: m24,
        m31: m31, m32: m32, m33: m33, m34: m34,
        m41: m41, m42: m42, m43: m43, m44: m44
    }
}

struct Matrix4<T:copy FuzzyEq Num> {
    let m11: T; let m12: T; let m13: T; let m14: T;
    let m21: T; let m22: T; let m23: T; let m24: T;
    let m31: T; let m32: T; let m33: T; let m34: T;
    let m41: T; let m42: T; let m43: T; let m44: T;

    pure fn fuzzy_eq(&&other: Matrix4<T>) -> bool {
        self.m11.fuzzy_eq(other.m11) && self.m12.fuzzy_eq(other.m12) &&
        self.m13.fuzzy_eq(other.m13) && self.m14.fuzzy_eq(other.m14) &&
        self.m21.fuzzy_eq(other.m21) && self.m22.fuzzy_eq(other.m22) &&
        self.m23.fuzzy_eq(other.m23) && self.m24.fuzzy_eq(other.m24) &&
        self.m31.fuzzy_eq(other.m31) && self.m32.fuzzy_eq(other.m32) &&
        self.m33.fuzzy_eq(other.m33) && self.m34.fuzzy_eq(other.m34) &&
        self.m41.fuzzy_eq(other.m41) && self.m42.fuzzy_eq(other.m42) &&
        self.m43.fuzzy_eq(other.m43) && self.m44.fuzzy_eq(other.m44)
    }

    pure fn mul(&&m: Matrix4<T>) -> Matrix4<T> {
        return Matrix4(m.m11.mul(self.m11).add(m.m12.mul(self.m21))
                                          .add(m.m13.mul(self.m31))
                                          .add(m.m14.mul(self.m41)),
                       m.m11.mul(self.m12).add(m.m12.mul(self.m22))
                                          .add(m.m13.mul(self.m32))
                                          .add(m.m14.mul(self.m42)),
                       m.m11.mul(self.m13).add(m.m12.mul(self.m23))
                                          .add(m.m13.mul(self.m33))
                                          .add(m.m14.mul(self.m43)),
                       m.m11.mul(self.m14).add(m.m12.mul(self.m24))
                                          .add(m.m13.mul(self.m34))
                                          .add(m.m14.mul(self.m44)),
                       m.m21.mul(self.m11).add(m.m22.mul(self.m21))
                                          .add(m.m23.mul(self.m31))
                                          .add(m.m24.mul(self.m41)),
                       m.m21.mul(self.m12).add(m.m22.mul(self.m22))
                                          .add(m.m23.mul(self.m32))
                                          .add(m.m24.mul(self.m42)),
                       m.m21.mul(self.m13).add(m.m22.mul(self.m23))
                                          .add(m.m23.mul(self.m33))
                                          .add(m.m24.mul(self.m43)),
                       m.m21.mul(self.m14).add(m.m22.mul(self.m24))
                                          .add(m.m23.mul(self.m34))
                                          .add(m.m24.mul(self.m44)),
                       m.m31.mul(self.m11).add(m.m32.mul(self.m21))
                                          .add(m.m33.mul(self.m31))
                                          .add(m.m34.mul(self.m41)),
                       m.m31.mul(self.m12).add(m.m32.mul(self.m22))
                                          .add(m.m33.mul(self.m32))
                                          .add(m.m34.mul(self.m42)),
                       m.m31.mul(self.m13).add(m.m32.mul(self.m23))
                                          .add(m.m33.mul(self.m33))
                                          .add(m.m34.mul(self.m43)),
                       m.m31.mul(self.m14).add(m.m32.mul(self.m24))
                                          .add(m.m33.mul(self.m34))
                                          .add(m.m34.mul(self.m44)),
                       m.m41.mul(self.m11).add(m.m42.mul(self.m21))
                                          .add(m.m43.mul(self.m31))
                                          .add(m.m44.mul(self.m41)),
                       m.m41.mul(self.m12).add(m.m42.mul(self.m22))
                                          .add(m.m43.mul(self.m32))
                                          .add(m.m44.mul(self.m42)),
                       m.m41.mul(self.m13).add(m.m42.mul(self.m23))
                                          .add(m.m43.mul(self.m33))
                                          .add(m.m44.mul(self.m43)),
                       m.m41.mul(self.m14).add(m.m42.mul(self.m24))
                                          .add(m.m43.mul(self.m34))
                                          .add(m.m44.mul(self.m44)));
    }

    pure fn mul_s(&&x: T) -> Matrix4<T> {
        return Matrix4(self.m11.mul(x), self.m12.mul(x), self.m13.mul(x), self.m14.mul(x),
                       self.m21.mul(x), self.m22.mul(x), self.m23.mul(x), self.m24.mul(x),
                       self.m31.mul(x), self.m32.mul(x), self.m33.mul(x), self.m34.mul(x),
                       self.m41.mul(x), self.m42.mul(x), self.m43.mul(x), self.m44.mul(x));
    }

    pure fn scale(&&x: T, &&y: T, &&z: T) -> Matrix4<T> {
        return Matrix4(self.m11.mul(x), self.m12,        self.m13,        self.m14,
                       self.m21,        self.m22.mul(y), self.m23,        self.m24,
                       self.m31,        self.m32,        self.m33.mul(z), self.m34,
                       self.m41,        self.m42,        self.m43,        self.m44);
    }

    pure fn to_array() -> ~[T] {
        return ~[
            self.m11, self.m12, self.m13, self.m14,
            self.m21, self.m22, self.m23, self.m24,
            self.m31, self.m32, self.m33, self.m34,
            self.m41, self.m42, self.m43, self.m44
        ];
    }

    pure fn translate(&&x: T, &&y: T, &&z: T) -> Matrix4<T> {
        let _0 = x.from_int(0);
        let _1 = x.from_int(1);
        let matrix = Matrix4(_1, _0, _0, _0,
                             _0, _1, _0, _0,
                             _0, _0, _1, _0,
                              x,  y,  z, _1);

        return self.mul(matrix);
    }
}

fn ortho<T:copy FuzzyEq Num>(+left: T, +right: T, +bottom: T, +top: T, +near: T, +far: T)
                          -> Matrix4<T> {

    let two = left.from_int(2);
    let one = left.from_int(1);
    let zero = left.from_int(0);
    let minus_two = left.from_int(-2);

    let tx = right.add(left).div(right.sub(left)).neg();
    let ty = top.add(bottom).div(top.sub(bottom)).neg();
    let tz = far.add(near).div(far.sub(near)).neg();

    return Matrix4(two.div(right.sub(left)), zero, zero, zero,
                   zero, two.div(top.sub(bottom)), zero, zero,
                   zero, zero, minus_two.div(far.sub(near)), zero,
                   tx, ty, tz, one);
}

fn identity<T:copy FuzzyEq Num>(_0: T) -> Matrix4<T> {
    let _1 = _0.from_int(1);
    return Matrix4(_1, _0, _0, _0,
                   _0, _1, _0, _0,
                   _0, _0, _1, _0,
                   _0, _0, _0, _1);
}

#[test]
fn test_ortho() {
    let (left, right, bottom, top) = (0.0, 1.0, 0.1, 1.0);
    let (near, far) = (-1.0, 1.0);
    let result = ortho(left, right, bottom, top, near, far);
    let expected = Matrix4(2.0,  0.0,         0.0,  0.0,
                           0.0,  2.22222222,  0.0,  0.0,
                           0.0,  0.0,         -1.0, 0.0,
                           -1.0, -1.22222222, -0.0, 1.0);
    #debug("result=%? expected=%?", result, expected);
    assert result.fuzzy_eq(expected);
}

<commit_msg>Fix for language changes related to static methods<commit_after>import std::cmp::FuzzyEq;
import num::Num;

pure fn Matrix4<T:copy FuzzyEq Num>(m11: T, m12: T, m13: T, m14: T,
                                    m21: T, m22: T, m23: T, m24: T,
                                    m31: T, m32: T, m33: T, m34: T,
                                    m41: T, m42: T, m43: T, m44: T)
                                 -> Matrix4<T> {

    Matrix4 {
        m11: m11, m12: m12, m13: m13, m14: m14,
        m21: m21, m22: m22, m23: m23, m24: m24,
        m31: m31, m32: m32, m33: m33, m34: m34,
        m41: m41, m42: m42, m43: m43, m44: m44
    }
}

struct Matrix4<T:copy FuzzyEq Num> {
    let m11: T; let m12: T; let m13: T; let m14: T;
    let m21: T; let m22: T; let m23: T; let m24: T;
    let m31: T; let m32: T; let m33: T; let m34: T;
    let m41: T; let m42: T; let m43: T; let m44: T;

    pure fn fuzzy_eq(&&other: Matrix4<T>) -> bool {
        self.m11.fuzzy_eq(other.m11) && self.m12.fuzzy_eq(other.m12) &&
        self.m13.fuzzy_eq(other.m13) && self.m14.fuzzy_eq(other.m14) &&
        self.m21.fuzzy_eq(other.m21) && self.m22.fuzzy_eq(other.m22) &&
        self.m23.fuzzy_eq(other.m23) && self.m24.fuzzy_eq(other.m24) &&
        self.m31.fuzzy_eq(other.m31) && self.m32.fuzzy_eq(other.m32) &&
        self.m33.fuzzy_eq(other.m33) && self.m34.fuzzy_eq(other.m34) &&
        self.m41.fuzzy_eq(other.m41) && self.m42.fuzzy_eq(other.m42) &&
        self.m43.fuzzy_eq(other.m43) && self.m44.fuzzy_eq(other.m44)
    }

    pure fn mul(&&m: Matrix4<T>) -> Matrix4<T> {
        return Matrix4(m.m11.mul(self.m11).add(m.m12.mul(self.m21))
                                          .add(m.m13.mul(self.m31))
                                          .add(m.m14.mul(self.m41)),
                       m.m11.mul(self.m12).add(m.m12.mul(self.m22))
                                          .add(m.m13.mul(self.m32))
                                          .add(m.m14.mul(self.m42)),
                       m.m11.mul(self.m13).add(m.m12.mul(self.m23))
                                          .add(m.m13.mul(self.m33))
                                          .add(m.m14.mul(self.m43)),
                       m.m11.mul(self.m14).add(m.m12.mul(self.m24))
                                          .add(m.m13.mul(self.m34))
                                          .add(m.m14.mul(self.m44)),
                       m.m21.mul(self.m11).add(m.m22.mul(self.m21))
                                          .add(m.m23.mul(self.m31))
                                          .add(m.m24.mul(self.m41)),
                       m.m21.mul(self.m12).add(m.m22.mul(self.m22))
                                          .add(m.m23.mul(self.m32))
                                          .add(m.m24.mul(self.m42)),
                       m.m21.mul(self.m13).add(m.m22.mul(self.m23))
                                          .add(m.m23.mul(self.m33))
                                          .add(m.m24.mul(self.m43)),
                       m.m21.mul(self.m14).add(m.m22.mul(self.m24))
                                          .add(m.m23.mul(self.m34))
                                          .add(m.m24.mul(self.m44)),
                       m.m31.mul(self.m11).add(m.m32.mul(self.m21))
                                          .add(m.m33.mul(self.m31))
                                          .add(m.m34.mul(self.m41)),
                       m.m31.mul(self.m12).add(m.m32.mul(self.m22))
                                          .add(m.m33.mul(self.m32))
                                          .add(m.m34.mul(self.m42)),
                       m.m31.mul(self.m13).add(m.m32.mul(self.m23))
                                          .add(m.m33.mul(self.m33))
                                          .add(m.m34.mul(self.m43)),
                       m.m31.mul(self.m14).add(m.m32.mul(self.m24))
                                          .add(m.m33.mul(self.m34))
                                          .add(m.m34.mul(self.m44)),
                       m.m41.mul(self.m11).add(m.m42.mul(self.m21))
                                          .add(m.m43.mul(self.m31))
                                          .add(m.m44.mul(self.m41)),
                       m.m41.mul(self.m12).add(m.m42.mul(self.m22))
                                          .add(m.m43.mul(self.m32))
                                          .add(m.m44.mul(self.m42)),
                       m.m41.mul(self.m13).add(m.m42.mul(self.m23))
                                          .add(m.m43.mul(self.m33))
                                          .add(m.m44.mul(self.m43)),
                       m.m41.mul(self.m14).add(m.m42.mul(self.m24))
                                          .add(m.m43.mul(self.m34))
                                          .add(m.m44.mul(self.m44)));
    }

    pure fn mul_s(&&x: T) -> Matrix4<T> {
        return Matrix4(self.m11.mul(x), self.m12.mul(x), self.m13.mul(x), self.m14.mul(x),
                       self.m21.mul(x), self.m22.mul(x), self.m23.mul(x), self.m24.mul(x),
                       self.m31.mul(x), self.m32.mul(x), self.m33.mul(x), self.m34.mul(x),
                       self.m41.mul(x), self.m42.mul(x), self.m43.mul(x), self.m44.mul(x));
    }

    pure fn scale(&&x: T, &&y: T, &&z: T) -> Matrix4<T> {
        return Matrix4(self.m11.mul(x), self.m12,        self.m13,        self.m14,
                       self.m21,        self.m22.mul(y), self.m23,        self.m24,
                       self.m31,        self.m32,        self.m33.mul(z), self.m34,
                       self.m41,        self.m42,        self.m43,        self.m44);
    }

    pure fn to_array() -> ~[T] {
        return ~[
            self.m11, self.m12, self.m13, self.m14,
            self.m21, self.m22, self.m23, self.m24,
            self.m31, self.m32, self.m33, self.m34,
            self.m41, self.m42, self.m43, self.m44
        ];
    }

    pure fn translate(&&x: T, &&y: T, &&z: T) -> Matrix4<T> {
        let _0 = num::from_int(0);
        let _1 = num::from_int(1);
        let matrix = Matrix4(_1, _0, _0, _0,
                             _0, _1, _0, _0,
                             _0, _0, _1, _0,
                              x,  y,  z, _1);

        return self.mul(matrix);
    }
}

fn ortho<T:copy FuzzyEq Num>(+left: T, +right: T, +bottom: T, +top: T, +near: T, +far: T)
                          -> Matrix4<T> {

    let two: T = num::from_int(2);
    let one: T = num::from_int(1);
    let zero: T = num::from_int(0);
    let minus_two: T = num::from_int(-2);

    let tx = right.add(left).div(right.sub(left)).neg();
    let ty = top.add(bottom).div(top.sub(bottom)).neg();
    let tz = far.add(near).div(far.sub(near)).neg();

    return Matrix4(two.div(right.sub(left)), zero, zero, zero,
                   zero, two.div(top.sub(bottom)), zero, zero,
                   zero, zero, minus_two.div(far.sub(near)), zero,
                   tx, ty, tz, one);
}

fn identity<T:copy FuzzyEq Num>(_0: T) -> Matrix4<T> {
    let _1 = num::from_int(1);
    return Matrix4(_1, _0, _0, _0,
                   _0, _1, _0, _0,
                   _0, _0, _1, _0,
                   _0, _0, _0, _1);
}

#[test]
fn test_ortho() {
    let (left, right, bottom, top) = (0.0, 1.0, 0.1, 1.0);
    let (near, far) = (-1.0, 1.0);
    let result = ortho(left, right, bottom, top, near, far);
    let expected = Matrix4(2.0,  0.0,         0.0,  0.0,
                           0.0,  2.22222222,  0.0,  0.0,
                           0.0,  0.0,         -1.0, 0.0,
                           -1.0, -1.22222222, -0.0, 1.0);
    #debug("result=%? expected=%?", result, expected);
    assert result.fuzzy_eq(expected);
}

<|endoftext|>


<commit_before>#[derive(Debug)]
struct ListNode {
    val: i32,
    next: Option<Box<ListNode>>,
}

impl Clone for ListNode {
    fn clone(&self) -> ListNode {
        let mut result = ListNode::new(self.val);
        result.next = self.next.clone();
        return result;
    }
}

impl ListNode {
    fn new(v: i32) -> Self {
        ListNode { val: v, next: None }
    }

    fn check_ten(&mut self, flag: i32) {
        let mut inner_flag = flag;
        self.val += flag;
        if self.val >= 10 {
            self.val -= 10;
            inner_flag = 1;
        } else {
            inner_flag = 0;
        }

        match self.next {
            Some(ref mut n) => n.check_ten(inner_flag),
            None => if inner_flag == 1 {
                self.next = Some(Box::new(ListNode::new(inner_flag)));
            },
        }
    }
}

fn add_two_numbers(a: ListNode, b: ListNode, flag: i32) -> ListNode {
    let mut inner_flag = flag;
    let mut result = ListNode::new(a.val + b.val);

    let mut inner_a = a;
    let mut inner_b = b;

    if inner_a.next.is_some() && inner_b.next.is_some() {
        result.val += inner_flag;
        if result.val >= 10 {
            result.val -= 10;
            inner_flag = 1;
        } else {
            inner_flag = 0;
        }

        inner_a = Box::leak(inner_a.next.unwrap()).clone();
        inner_b = Box::leak(inner_b.next.unwrap()).clone();
        result.next = Some(Box::new(add_two_numbers(inner_a, inner_b, inner_flag)))
    } else if inner_a.next.is_none() && inner_b.next.is_some() {
        let temp = Box::leak(inner_b.next.unwrap()).clone();
        result.next = Some(Box::new(temp));
        result.check_ten(inner_flag)
    } else if inner_b.next.is_none() && inner_a.next.is_some() {
        let temp = Box::leak(inner_a.next.unwrap()).clone();
        result.next = Some(Box::new(temp));
        result.check_ten(inner_flag)
    } else if inner_a.next.is_none() && inner_b.next.is_none() {
        result.check_ten(inner_flag);
    }

    return result;
}

fn main() {
    let a = ListNode::new(1);
    let mut b = ListNode::new(9);
    b.next = Some(Box::new(ListNode::new(2)));

    println!("{:?}", add_two_numbers(a, b, 0));

    let c = ListNode::new(2);
    let mut d = ListNode::new(8);
    let mut d1 = ListNode::new(9);
    let mut d2 = ListNode::new(9);
    d1.next = Some(Box::new(d2));
    d.next = Some(Box::new(d1));

    println!("{:?}", add_two_numbers(c, d, 0));
}
<commit_msg>a bit<commit_after>#[derive(Debug)]
struct ListNode {
    val: i32,
    next: Option<Box<ListNode>>,
}

impl Clone for ListNode {
    fn clone(&self) -> ListNode {
        let mut result = ListNode::new(self.val);
        result.next = self.next.clone();
        return result;
    }
}

impl ListNode {
    fn new(v: i32) -> Self {
        ListNode { val: v, next: None }
    }

    fn check_ten(&mut self, flag: i32) {
        let mut inner_flag = flag;
        self.val += flag;
        if self.val >= 10 {
            self.val -= 10;
            inner_flag = 1;
        } else {
            inner_flag = 0;
        }

        match self.next {
            Some(ref mut n) => n.check_ten(inner_flag),
            None => if inner_flag == 1 {
                self.next = Some(Box::new(ListNode::new(inner_flag)));
            },
        }
    }
}

fn add_two_numbers(a: ListNode, b: ListNode, flag: i32) -> ListNode {
    let mut inner_flag = flag;
    let mut result = ListNode::new(a.val + b.val);

    if a.next.is_some() && b.next.is_some() {
        result.val += inner_flag;
        if result.val >= 10 {
            result.val -= 10;
            inner_flag = 1;
        } else {
            inner_flag = 0;
        }

        let inner_a = Box::leak(a.next.unwrap()).clone();
        let inner_b = Box::leak(b.next.unwrap()).clone();
        result.next = Some(Box::new(add_two_numbers(inner_a, inner_b, inner_flag)))
    } else if a.next.is_none() && b.next.is_some() {
        let temp = Box::leak(b.next.unwrap()).clone();
        result.next = Some(Box::new(temp));
        result.check_ten(inner_flag)
    } else if b.next.is_none() && a.next.is_some() {
        let temp = Box::leak(a.next.unwrap()).clone();
        result.next = Some(Box::new(temp));
        result.check_ten(inner_flag)
    } else if a.next.is_none() && b.next.is_none() {
        result.check_ten(inner_flag);
    }

    return result;
}

fn main() {
    let a = ListNode::new(1);
    let mut b = ListNode::new(9);
    b.next = Some(Box::new(ListNode::new(2)));

    println!("{:?}", add_two_numbers(a, b, 0));

    let c = ListNode::new(2);
    let mut d = ListNode::new(8);
    let mut d1 = ListNode::new(9);
    let mut d2 = ListNode::new(9);
    d1.next = Some(Box::new(d2));
    d.next = Some(Box::new(d1));

    println!("{:?}", add_two_numbers(c, d, 0));
}
<|endoftext|>


<commit_before>extern crate csv;
extern crate rustc_serialize;

#[macro_use]
extern crate text_io;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

struct IndexedDB(HashMap<String, HashMap<String, f32>>, HashMap<String, HashMap<String, f32>>);

fn load_db(path: &str) -> IndexedDB {
    let mut rdr = csv::Reader::from_file(path).unwrap().has_headers(false);
    let mut ratings: HashMap<String, HashMap<String, f32>> = HashMap::new();
    let mut features: HashMap<String, HashMap<String, f32>> = HashMap::new();

    for record in rdr.decode() {
        let (user_id, feat_id, rating): (String, String, f32) = record.unwrap();
        let (user_id2, feat_id2, rating2) = (user_id.clone(), feat_id.clone(), rating);

        match ratings.entry(user_id) {
            Vacant(entry) => {
                let mut user_ratings = HashMap::new();
                user_ratings.insert(feat_id, rating);
                entry.insert(user_ratings);
            }
            Occupied(entry) => {
                entry.into_mut().insert(feat_id, rating);
            }
        }

        match features.entry(feat_id2) {
            Vacant(entry) => {
                let mut movie_ratings = HashMap::new();
                movie_ratings.insert(user_id2, rating2);
                entry.insert(movie_ratings);
            }
            Occupied(entry) => {
                entry.into_mut().insert(user_id2, rating2);
            }
        }
    }

    IndexedDB(ratings, features)
}

fn deviation(db: &IndexedDB, feat_1: &str, feat_2: &str) -> (f32, usize) {
    let mut vec_a: Vec<f32> = Vec::new();
    let mut vec_b: Vec<f32> = Vec::new();

    if let Some(ref ratings_f1) = db.1.get(&String::from(feat_1)) {
        for (user_id, &rating_f1) in ratings_f1.iter() {
            if let Some(ratings_f2) = db.1.get(&String::from(feat_2)) {
                if let Some(&rating_f2) = ratings_f2.get(user_id) {
                    vec_a.push(rating_f1);
                    vec_b.push(rating_f2);
                }
            } else {
                panic!("1: feat_2 is not found!");
            }
        }
    } else {
        panic!("1: feat_1 is not found!");
    }

    let length = vec_a.len();
    let mut deviation = 0.0;
    for i in 0..length {
        deviation += (vec_a[i] - vec_b[i]) / length as f32;
    }

    (deviation, length)
}

fn weighted_slope_one(db: &IndexedDB, user: &str, feat: &str) -> f32 {
    let mut num = 0.0;
    let mut den = 0.0;
    if let Some(ref ratings) = db.0.get(&String::from(user)) {
        for (feat_id, &rating) in ratings.iter() {
            let (dev, card) = deviation(&db, feat, feat_id);
            num += (dev + rating) * card as f32;
            den += card as f32;
        }
    } else {
        panic!("user is not found!");
    }

    num / den
}

// fn item_based_prediction_input(db: &mut IndexedDB,
//                                sim_fun: fn(&MovieDB, String, String) -> f32)
//                                -> f32 {
//     let user_id: String;
//     let movie_id: String;
//     println!("Enter user_id y movie_id:");
//     scan!("{} {}", user_id, movie_id);

//     match db.0.entry(user_id) {
//         Vacant(entry) => {
//             let mut ratings: HashMap<u32, f32> = HashMap::new();
//             let mut movie: u32;
//             let mut rating: f32;
//             for i in 0..10 {
//                 println!("Enter movie_id:");
//                 scan!("{}", movie);
//                 println!("Enter rating:");
//                 scan!("{}", rating);
//                 ratings.insert(movie, rating);
//                 match db.1.entry(user_id) {
//                     Vacant(usr_map) => {
//                         let mut user_rtngs: HashMap<u32, f32> = HashMap::new();
//                         user_rtngs.insert(user_id, rating);
//                         usr_map.insert(user_rtngs);
//                     }
//                     Occupied(usr_map) => {
//                         usr_map.into_mut().insert(user_id, rating);
//                     }
//                 }
//             }
//             entry.insert(ratings);
//         }
//         Occupied(_) => {}
//     }

//     sim_fun(&db, user_id, movie_id)
// }

fn main() {
    println!("Loading database, please wait...");
    let mut db = load_db("./data/db2.csv");
    // let mut db = load_db("../report01/data/BX-Dump/BX-Book-Ratings.csv");
    println!("Database ready!\n---------------------------------------------");

    // println!("{}", deviation(&db, "Taylor Swift", "PSY"));
    // println!("{}", deviation(&db, "PSY", "Whitney Houston"));
    // println!("{}", deviation(&db, "Taylor Swift", "Whitney Houston"));
    println!("{}", weighted_slope_one(&db, "Ben", "Whitney Houston"));

    // let mut ender: u32;
    // loop {
    //     println!("Press 1 to make a query with Slope One.\n\
    //               Press 2 to make a query with Adjusted Cosine.\n\
    //               Press 0 to exit: ");
    //     scan!("{}", ender);
    //     match ender {
    //         1 => {
    //             println!("Slope One");
    //         }
    //         2 => {
    //             println!("Item similarity");
    //         }
    //         0 => {
    //             break;
    //         }
    //         _ => {
    //             println!("Try again");
    //         }
    //     }
    //     println!("\n______________________________________________________");
    // }
    // println!("\nBye bytes...");
}
<commit_msg>Finished with adjusted cosine<commit_after>extern crate csv;
extern crate rustc_serialize;

#[macro_use]
extern crate text_io;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

struct IndexedDB(HashMap<String, HashMap<String, f32>>, HashMap<String, HashMap<String, f32>>);

fn load_db(path: &str) -> IndexedDB {
    let mut rdr = csv::Reader::from_file(path).unwrap().has_headers(false);
    let mut ratings: HashMap<String, HashMap<String, f32>> = HashMap::new();
    let mut features: HashMap<String, HashMap<String, f32>> = HashMap::new();

    for record in rdr.decode() {
        let (user_id, feat_id, rating): (String, String, f32) = record.unwrap();
        let (user_id2, feat_id2, rating2) = (user_id.clone(), feat_id.clone(), rating);

        match ratings.entry(user_id) {
            Vacant(entry) => {
                let mut user_ratings = HashMap::new();
                user_ratings.insert(feat_id, rating);
                entry.insert(user_ratings);
            }
            Occupied(entry) => {
                entry.into_mut().insert(feat_id, rating);
            }
        }

        match features.entry(feat_id2) {
            Vacant(entry) => {
                let mut movie_ratings = HashMap::new();
                movie_ratings.insert(user_id2, rating2);
                entry.insert(movie_ratings);
            }
            Occupied(entry) => {
                entry.into_mut().insert(user_id2, rating2);
            }
        }
    }

    IndexedDB(ratings, features)
}

fn deviation(db: &IndexedDB, feat_1: &str, feat_2: &str) -> (f32, usize) {
    let mut vec_a: Vec<f32> = Vec::new();
    let mut vec_b: Vec<f32> = Vec::new();

    if let Some(ref ratings_f1) = db.1.get(&String::from(feat_1)) {
        for (user_id, &rating_f1) in ratings_f1.iter() {
            if let Some(ratings_f2) = db.1.get(&String::from(feat_2)) {
                if let Some(&rating_f2) = ratings_f2.get(user_id) {
                    vec_a.push(rating_f1);
                    vec_b.push(rating_f2);
                }
            } else {
                panic!("feat_2 is not found!");
            }
        }
    } else {
        panic!("feat_1 is not found!");
    }

    let length = vec_a.len();
    let mut deviation = 0.0;
    for i in 0..length {
        deviation += (vec_a[i] - vec_b[i]) / length as f32;
    }

    (deviation, length)
}

fn weighted_slope_one(db: &IndexedDB, user: &str, feat: &str) -> f32 {
    let mut num = 0.0;
    let mut den = 0.0;
    if let Some(ref ratings) = db.0.get(&String::from(user)) {
        for (feat_id, &rating) in ratings.iter() {
            let (dev, card) = deviation(&db, feat, feat_id);
            num += (dev + rating) * card as f32;
            den += card as f32;
        }
    } else {
        panic!("user is not found!");
    }

    num / den
}

fn adjusted_cosine(vec_feat_1: &Vec<f32>, vec_feat_2: &Vec<f32>, vec_avg: &Vec<f32>) -> f32 {
    if vec_feat_1.len() != vec_feat_2.len() || vec_feat_1.len() != vec_avg.len() {
        panic!("Should compare vectors of same size");
    }

    let n_users = vec_feat_1.len();

    let mut usr_pref = 0.0;
    let mut feat_1_sqr = 0.0;
    let mut feat_2_sqr = 0.0;

    for i in 0..n_users {
        if vec_feat_1[i] > 0.0 && vec_feat_2[i] > 0.0 {
            let feat_1_inf = vec_feat_1[i] - vec_avg[i];
            let feat_2_inf = vec_feat_2[i] - vec_avg[i];
            usr_pref += feat_1_inf * feat_2_inf;
            feat_1_sqr += feat_1_inf.powf(2.0);
            feat_2_sqr += feat_2_inf.powf(2.0);
        }
    }

    usr_pref / (feat_1_sqr.sqrt() * feat_2_sqr.sqrt())
}

fn computer_user_avg(db: &IndexedDB, user: &str) -> f32 {
    let mut avg: f32 = 0.0;
    if let Some(ref ratings) = db.0.get(&String::from(user)) {
        for (_, &rating) in ratings.iter() {
            avg += rating;
        }
        avg /= ratings.len() as f32
    }
    avg
}

fn adjusted_cosine_features(db: &IndexedDB, feat_1: &str, feat_2: &str) -> f32 {
    let mut vec_a: Vec<f32> = Vec::new();
    let mut vec_b: Vec<f32> = Vec::new();
    let mut vec_avg: Vec<f32> = Vec::new();

    if let Some(ref ratings_f1) = db.1.get(&String::from(feat_1)) {
        for (user_id, &rating_f1) in ratings_f1.iter() {
            vec_avg.push(computer_user_avg(&db, user_id));
            if let Some(ratings_f2) = db.1.get(&String::from(feat_2)) {
                if let Some(&rating_f2) = ratings_f2.get(user_id) {
                    vec_a.push(rating_f1);
                    vec_b.push(rating_f2);
                } else {
                    vec_a.push(rating_f1);
                    vec_b.push(0.0);
                }
            } else {
                panic!("1: feat_2 is not found!");
            }
        }
    } else {
        panic!("1: feat_1 is not found!");
    }

    if let Some(ref ratings_f2) = db.1.get(&String::from(feat_2)) {
        for (user_id, &rating_f2) in ratings_f2.iter() {
            if let Some(ratings_f1) = db.1.get(&String::from(feat_1)) {
                if let Some(_) = ratings_f1.get(user_id) {
                } else {
                    vec_a.push(0.0);
                    vec_b.push(rating_f2);
                    vec_avg.push(computer_user_avg(&db, user_id));
                }
            } else {
                panic!("2: feat_1 is not found!");
            }
        }
    } else {
        panic!("2: feat_2 is not found!");
    }

    adjusted_cosine(&vec_a, &vec_b, &vec_avg)
}

fn prediction(sim_vec: Vec<f32>, normd_vec: Vec<f32>) -> f32 {
    let mut num = 0.0;
    let mut den = 0.0;
    let inv_i = sim_vec.len();
    for i in 0..inv_i {
        num += sim_vec[i] * normd_vec[i];
        den += sim_vec[i].abs();
    }

    num / den
}

fn normalize(vect: &Vec<f32>) -> (Vec<f32>, f32, f32) {
    let mut normd_vec = Vec::with_capacity(vect.len());

    let mut max = vect[0];
    let mut min = vect[0];

    for rating in vect.iter() {
        if *rating > max {
            max = *rating;
        }
        if *rating != 0.0 && *rating < min || min == 0.0 {
            min = *rating;
        }
    }

    for rating in vect.iter() {
        if *rating > 0.0 {
            let norm = (2.0 * (rating - min) - (max - min)) / (max - min);
            normd_vec.push(norm);
        }
    }

    (normd_vec, max, min)
}

fn unnormalize(norm_val: f32, max: f32, min: f32) -> f32 {
    0.5 * (norm_val + 1.0) * (max - min) + min
}

fn adjusted_cosine_prediction(db: &IndexedDB, user: &str, feature: &str) -> f32 {
    let mut sim_vec: Vec<f32> = Vec::new();
    let mut usr_vec: Vec<f32> = Vec::new();

    match db.0.get(&String::from(user)) {
        Some(a_ratings) => {
            for (movie_id, &rating) in a_ratings.iter() {
                sim_vec.push(adjusted_cosine_features(db, &feature, movie_id));
                usr_vec.push(rating);
            }
        }
        None => {}
    }

    let normd_usr_vec = normalize(&usr_vec);
    let normd_pred = prediction(sim_vec, normd_usr_vec.0);
    println!("Normalized prediction: {}", normd_pred);
    unnormalize(normd_pred, normd_usr_vec.1, normd_usr_vec.2)
}

// fn item_based_prediction_input(db: &mut IndexedDB,
//                                sim_fun: fn(&IndexedDB, String, String) -> f32)
//                                -> f32 {
//     let user_id: String;
//     let movie_id: String;
//     println!("Enter user_id y movie_id:");
//     scan!("{} {}", user_id, movie_id);

//     match db.0.entry(user_id) {
//         Vacant(entry) => {
//             let mut ratings: HashMap<u32, f32> = HashMap::new();
//             let mut movie: u32;
//             let mut rating: f32;
//             for i in 0..10 {
//                 println!("Enter movie_id:");
//                 scan!("{}", movie);
//                 println!("Enter rating:");
//                 scan!("{}", rating);
//                 ratings.insert(movie, rating);
//                 match db.1.entry(user_id) {
//                     Vacant(usr_map) => {
//                         let mut user_rtngs: HashMap<u32, f32> = HashMap::new();
//                         user_rtngs.insert(user_id, rating);
//                         usr_map.insert(user_rtngs);
//                     }
//                     Occupied(usr_map) => {
//                         usr_map.into_mut().insert(user_id, rating);
//                     }
//                 }
//             }
//             entry.insert(ratings);
//         }
//         Occupied(_) => {}
//     }

//     sim_fun(&db, user_id, movie_id)
// }

fn main() {
    println!("Loading database, please wait...");
    let mut db = load_db("./data/db2.csv");
    // let mut db = load_db("../report01/data/BX-Dump/BX-Book-Ratings.csv");
    println!("Database ready!\n---------------------------------------------");

    // println!("{}", deviation(&db, "Taylor Swift", "PSY"));
    // println!("{}", deviation(&db, "PSY", "Whitney Houston"));
    // println!("{}", deviation(&db, "Taylor Swift", "Whitney Houston"));
    println!("{}", weighted_slope_one(&db, "Ben", "Whitney Houston"));
    println!("{}",
             adjusted_cosine_prediction(&db, "Ben", "Whitney Houston"));

    // let mut ender: u32;
    // loop {
    //     println!("Press 1 to make a query with Slope One.\n\
    //               Press 2 to make a query with Adjusted Cosine.\n\
    //               Press 0 to exit: ");
    //     scan!("{}", ender);
    //     match ender {
    //         1 => {
    //             println!("Slope One");
    //         }
    //         2 => {
    //             println!("Item similarity");
    //         }
    //         0 => {
    //             break;
    //         }
    //         _ => {
    //             println!("Try again");
    //         }
    //     }
    //     println!("\n______________________________________________________");
    // }
    // println!("\nBye bytes...");
}
<|endoftext|>