use std::cell::UnsafeCell;
use ffi::mask;
use crate::{cu::Single, Cu};
pub struct Mask {
pub(crate) _c_: UnsafeCell<mask>,
}
impl Mask {
pub fn nel(&self) -> usize {
unsafe { &*self._c_.get() }.nel as usize
}
pub fn nnz(&self) -> usize {
unsafe { &*self._c_.get() }.nnz as usize
}
pub fn iter(&self) -> impl Iterator<Item = bool> {
let mut d_f = Cu::<Single>::vector(self.nel());
d_f.from_ptr(unsafe { &mut *self._c_.get() }.f);
Vec::<f32>::from(d_f).into_iter().map(|f| f > 0.0)
}
pub fn to_vec(&self) -> Vec<bool> {
self.iter().collect()
}
}
pub trait MaskFilter {
fn filter<'a, T: 'a + ?Sized>(
self,
data: impl Iterator<Item = &'a T>,
) -> impl Iterator<Item = &'a T>;
}
impl MaskFilter for &Mask {
fn filter<'a, T: 'a + ?Sized>(
self,
data: impl Iterator<Item = &'a T>,
) -> impl Iterator<Item = &'a T> {
data.zip(self.iter())
.filter(|(_, m)| *m)
.map(|(data, _)| data)
}
}
impl MaskFilter for (&Mask, &Mask) {
fn filter<'a, T: 'a + ?Sized>(
self,
data: impl Iterator<Item = &'a T>,
) -> impl Iterator<Item = &'a T> {
data.zip(self.0.iter().zip(self.1.iter()))
.filter(|(_, (m, mo))| *m && *mo)
.map(|(data, _)| data)
}
}