use std::time::Instant;
use slicefire::*;
/// Sequentially write `value` into `slice` with the given `indices`, discarding
/// the writes for any out of bound indexes
pub fn writes_discard<T: Copy>(vs: &mut [T], val: T, indices: &[usize]) {
    for i in indices {
        if *i < vs.len() {
            vs[*i] = val;
        }
    }
}
#[derive(Debug, Copy, Clone)]
#[allow(unused)]
struct Foo {
    x: i32,
    y: i64,
}
impl From<i32> for Foo {
    fn from(x: i32) -> Self {
        Self { x, y: x as i64 * 2 }
    }
}
fn indices(size: usize) -> (Vec<usize>, Vec<Foo>) {
    let indices = (0..(size)).map(|i| i % (size - 2)).collect::<Vec<usize>>();
    let vs = (0..size).map(|v| (v as i32).into()).collect::<Vec<Foo>>();
    (indices, vs)
}
fn main() {
    let args = std::env::args().collect::<Vec<_>>();
    if args.len() <= 2 {
        eprintln!("usage: example nelements value_to_write");
        std::process::exit(1);
    }
    let nelements = args[1].parse::<usize>().expect("given an integer length");
    let value = Foo::from(args[2].parse::<i32>().expect("given an integer value"));
    let serial = args.len() == 4;
    let (indices, mut vs) = indices(nelements);
    let t = Instant::now();
    if serial {
        writes_discard(&mut vs, value, &indices);
    } else {
        writes_par_shard_discard(&mut vs, value, &indices);
    }
    println!("Writing {} value took {:?}", nelements, t.elapsed());
}