incremental/kind/
array_fold.rs

1use std::cell::RefCell;
2use std::fmt::{self, Debug};
3
4use super::{Incr, Value};
5use crate::boxes::{new_unsized, SmallBox};
6use crate::incrsan::NotObserver;
7use crate::kind::KindTrait;
8use crate::{NodeRef, ValueInternal};
9
10pub(crate) struct ArrayFold<F, I, R> {
11    pub(crate) init: R,
12    pub(crate) fold: RefCell<F>,
13    pub(crate) children: Vec<Incr<I>>,
14}
15
16impl<F, I, R> KindTrait for ArrayFold<F, I, R>
17where
18    F: FnMut(R, &I) -> R + 'static + NotObserver,
19    I: Value,
20    R: Value,
21{
22    fn compute(&self) -> SmallBox<dyn ValueInternal> {
23        let mut acc = self.init.clone();
24        let mut f = self.fold.borrow_mut();
25        acc = self.children.iter().fold(acc, |acc, x| {
26            let v = x.node.value_as_ref().unwrap();
27            f(acc, &v)
28        });
29        new_unsized!(acc)
30    }
31    fn children_len(&self) -> usize {
32        self.children.len()
33    }
34    fn iter_children_packed(&self) -> Box<dyn Iterator<Item = NodeRef> + '_> {
35        Box::new(self.children.iter().map(|x| x.node.packed()))
36    }
37    fn slow_get_child(&self, index: usize) -> NodeRef {
38        self.children[index].node.packed()
39    }
40    fn debug_ty(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        write!(
42            f,
43            "ArrayFold<[{}] -> {}>",
44            std::any::type_name::<I>(),
45            std::any::type_name::<R>()
46        )
47    }
48}
49
50impl<F, I, R> Debug for ArrayFold<F, I, R>
51where
52    R: Debug,
53{
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        f.debug_struct("ArrayFold")
56            .field("len", &self.children.len())
57            .finish()
58    }
59}