soa_derive 0.12.0

Automatic Struct of Array generation
Documentation
#![allow(clippy::float_cmp)]

use soa_derive::soa_zip;
mod particles;
use self::particles::{Particle, ParticleVec, ParticleSlice, ParticleSliceMut};

#[test]
fn vec() {
    let mut particles = ParticleVec::new();
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));

    for name in soa_zip!(&particles, [name]) {
        assert_eq!(name, "Na");
    }

    for &mass in soa_zip!(&particles, [mass]) {
        assert_eq!(mass, 56.0);
    }

    for (name, &mass) in soa_zip!(&particles, [name, mass]) {
        assert_eq!(name, "Na");
        assert_eq!(mass, 56.0);
    }

    for (_, mass) in soa_zip!(&mut particles, [name, mut mass]) {
        *mass = 42.0;
    }

    for (name, _) in soa_zip!(&mut particles, [mut name, mut mass]) {
        *name = "Fe".into();
    }

    for (name, &mass) in soa_zip!(&particles, [name, mass]) {
        assert_eq!(name, "Fe");
        assert_eq!(mass, 42.0);
    }
}

#[test]
fn slice() {
    let mut particles = ParticleVec::new();
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));

    let particles = particles.as_slice();

    for name in soa_zip!(&particles, [name]) {
        assert_eq!(name, "Na");
    }

    for &mass in soa_zip!(&particles, [mass]) {
        assert_eq!(mass, 56.0);
    }

    for (name, &mass) in soa_zip!(&particles, [name, mass]) {
        assert_eq!(name, "Na");
        assert_eq!(mass, 56.0);
    }
}

#[test]
fn slice_mut() {
    let mut particles = ParticleVec::new();
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));

    let mut particles = particles.as_mut_slice();

    for name in soa_zip!(&particles, [name]) {
        assert_eq!(name, "Na");
    }

    for &mass in soa_zip!(&particles, [mass]) {
        assert_eq!(mass, 56.0);
    }

    for (name, &mass) in soa_zip!(&particles, [name, mass]) {
        assert_eq!(name, "Na");
        assert_eq!(mass, 56.0);
    }

    for (_, mass) in soa_zip!(&mut particles, [name, mut mass]) {
        *mass = 42.0;
    }

    for (name, _) in soa_zip!(&mut particles, [mut name, mut mass]) {
        *name = "Fe".into();
    }

    for (name, &mass) in soa_zip!(&particles, [name, mass]) {
        assert_eq!(name, "Fe");
        assert_eq!(mass, 42.0);
    }
}

#[test]
fn external() {
    let mut particles = ParticleVec::new();
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));

    let bar = vec![42.0; 4];
    for (mass, &bar) in soa_zip!(&mut particles, [mut mass], &bar) {
        *mass = bar;
    }

    for &mass in &particles.mass {
        assert_eq!(mass, 42.0);
    }
}

struct Wrapper {
    particles: ParticleVec
}

impl Wrapper {
    fn new(particles: ParticleVec) -> Wrapper {
        Wrapper {
            particles,
        }
    }

    fn particles(&self) -> ParticleSlice {
        self.particles.as_slice()
    }

    fn particles_mut(&mut self) -> ParticleSliceMut {
        self.particles.as_mut_slice()
    }
}

#[test]
fn access_particles_through_function() {
    let mut particles = ParticleVec::new();
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));
    particles.push(Particle::new(String::from("Na"), 56.0));

    let mut wrapper = Wrapper::new(particles);

    for name in soa_zip!(wrapper.particles(), [name]) {
        assert_eq!(name, "Na");
    }

    for &mass in soa_zip!(wrapper.particles(), [mass]) {
        assert_eq!(mass, 56.0);
    }

    for (name, &mass) in soa_zip!(wrapper.particles(), [name, mass]) {
        assert_eq!(name, "Na");
        assert_eq!(mass, 56.0);
    }

    for (_, mass) in soa_zip!(wrapper.particles_mut(), [name, mut mass]) {
        *mass = 42.0;
    }

    for (name, _) in soa_zip!(wrapper.particles_mut(), [mut name, mut mass]) {
        *name = "Fe".into();
    }

    for (name, &mass) in soa_zip!(wrapper.particles(), [name, mass]) {
        assert_eq!(name, "Fe");
        assert_eq!(mass, 42.0);
    }
}