incremental/kind/
array_fold.rs1use 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}