rs_isl 0.2.0

2-dimensional generic Iterative Stencil Loops
Documentation
use std::{mem::swap, sync::Arc};

use parking_lot::RwLock;

use crate::withcall::WithCall;

#[derive(Clone)]
pub struct Cell<T> {
    pub value: Arc<RwLock<T>>,
    pub neighbours: Vec<Option<Arc<RwLock<T>>>>,
    pub next_val: T,
}

impl<T> Cell<T>
where
    T: Clone,
{
    pub fn run<F>(&mut self, op: &WithCall<F, T>)
    where
        F: Fn(&T, Vec<Option<&T>>) -> T,
    {
        let mut locks = vec![];
        let mut nbs = vec![];

        let own_lock = self.value.read();
        let own_ref = &*own_lock;

        self.neighbours.iter().for_each(|f| {
            if f.is_none() {
                locks.push(None);
            } else {
                let n = f.as_ref().unwrap();
                let n_val = n.read();
                locks.push(Option::from(n_val));
            }
        });

        for lock in &locks {
            let inner = lock.as_deref();
            nbs.push(inner);
        }

        self.next_val = op.run(own_ref, nbs);
    }

    pub fn write(&mut self) {
        let mut lt = self.value.write();
        swap(&mut *lt, &mut self.next_val);
    }
}