synthphonia/forward/data/
size.rs

1use std::cell::UnsafeCell;
2
3use itertools::Itertools;
4
5use crate::{
6    expr::{cfg::Cfg, Expr},
7    utils::UnsafeCellExt,
8    value::Value,
9};
10
11pub type EV = (&'static Expr, Value);
12pub type VecEv = Vec<EV>;
13type SizeVec = Vec<VecEv>;
14
15/// Term Dispatcher for a specific size of expression
16pub struct Data(UnsafeCell<SizeVec>);
17
18impl std::fmt::Debug for Data {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        write!(f, "Enum Size: {}, {:?}", self.len(), self.unsafe_inner().iter().map(|x| x.len()).collect_vec())
21    }
22}
23
24impl Data {
25    fn unsafe_inner(&self) -> &mut SizeVec { unsafe { self.0.as_mut() } }
26    pub fn new(cfg: &Cfg) -> Self { Self(vec![vec![]].into()) }
27    pub fn len(&self) -> usize { self.unsafe_inner().len() }
28    pub fn get_all(&self, size: usize) -> &[EV] { self.unsafe_inner()[size].as_slice() }
29    #[inline(always)]
30    pub fn get_all_under(&self, size: usize) -> impl Iterator<Item = (usize, &EV)> + '_ {
31        (1..size).flat_map(move |i| self.unsafe_inner()[i].iter().map(move |x| (i, x)))
32    }
33    #[inline(always)]
34    pub fn add(&self, size: usize, vec: VecEv) {
35        assert!(self.len() == size, "{size}, {}", self.len());
36        self.unsafe_inner().push(vec);
37    }
38}