incremental_map/
lib.rs

1// We have some really complicated types. Most of them can't be typedef'd to be any shorter.
2#![allow(clippy::type_complexity)]
3
4use std::marker::PhantomData;
5
6use incremental::incrsan::NotObserver;
7use incremental::{Incr, Value};
8
9pub mod btree_map;
10#[cfg(feature = "im")]
11pub mod im_rc;
12pub mod symmetric_fold;
13
14pub use self::symmetric_fold::{DiffElement, MergeElement};
15
16pub mod prelude {
17    pub use super::btree_map::IncrBTreeMap;
18    #[cfg(feature = "im")]
19    pub use super::im_rc::Either;
20    #[cfg(feature = "im")]
21    pub use super::im_rc::IncrOrdMap;
22    pub use super::symmetric_fold::DiffElement;
23    pub use super::symmetric_fold::GenericMap;
24    pub use super::symmetric_fold::MergeElement;
25    pub use super::symmetric_fold::MutableMap;
26    pub use super::symmetric_fold::SymmetricFoldMap;
27    pub use super::symmetric_fold::SymmetricMapMap;
28    pub use super::ClosureFold;
29    pub use super::IncrMap;
30    pub use super::UnorderedFold;
31}
32
33use symmetric_fold::{GenericMap, MutableMap, SymmetricFoldMap, SymmetricMapMap};
34
35trait Operator<K, V, V2> {
36    type Output;
37    type Function;
38    fn as_opt(output: &Self::Output) -> Option<&V2>;
39    fn call_fn(&mut self, key: &K, input: Incr<V>) -> Incr<Self::Output>;
40}
41
42struct MapOperator<K, V, V2, F>(F, PhantomData<(K, V, V2)>)
43where
44    F: FnMut(&K, Incr<V>) -> Incr<V2> + NotObserver;
45
46impl<K, V, V2, F> Operator<K, V, V2> for MapOperator<K, V, V2, F>
47where
48    F: FnMut(&K, Incr<V>) -> Incr<V2> + NotObserver,
49{
50    type Output = V2;
51    type Function = F;
52    #[inline]
53    fn as_opt(output: &Self::Output) -> Option<&V2> {
54        Some(output)
55    }
56    #[inline]
57    fn call_fn(&mut self, key: &K, input: Incr<V>) -> Incr<Self::Output> {
58        (self.0)(key, input)
59    }
60}
61
62struct FilterMapOperator<K, V, V2, F>(F, PhantomData<(K, V, V2)>)
63where
64    F: FnMut(&K, Incr<V>) -> Incr<Option<V2>> + NotObserver;
65
66impl<K, V, V2, F> Operator<K, V, V2> for FilterMapOperator<K, V, V2, F>
67where
68    F: FnMut(&K, Incr<V>) -> Incr<Option<V2>> + NotObserver,
69{
70    type Output = Option<V2>;
71    type Function = F;
72    #[inline]
73    fn as_opt(output: &Self::Output) -> Option<&V2> {
74        output.as_ref()
75    }
76    #[inline]
77    fn call_fn(&mut self, key: &K, input: Incr<V>) -> Incr<Self::Output> {
78        (self.0)(key, input)
79    }
80}
81
82/// Internal -- variations on map_with_old
83pub(crate) trait WithOldIO<T> {
84    fn with_old_input_output<R, F>(&self, f: F) -> Incr<R>
85    where
86        R: Value,
87        F: FnMut(Option<(T, R)>, &T) -> (R, bool) + 'static + NotObserver;
88
89    fn with_old_input_output2<R, T2, F>(&self, other: &Incr<T2>, f: F) -> Incr<R>
90    where
91        R: Value,
92        T2: Value,
93        F: FnMut(Option<(T, T2, R)>, &T, &T2) -> (R, bool) + 'static + NotObserver;
94}
95
96impl<T: Value> WithOldIO<T> for Incr<T> {
97    fn with_old_input_output<R, F>(&self, mut f: F) -> Incr<R>
98    where
99        R: Value,
100        F: FnMut(Option<(T, R)>, &T) -> (R, bool) + 'static + NotObserver,
101    {
102        let mut old_input: Option<T> = None;
103        self.map_with_old(move |old_opt, a| {
104            let oi = &mut old_input;
105            let (b, didchange) = f(old_opt.and_then(|x| oi.take().map(|oi| (oi, x))), a);
106            *oi = Some(a.clone());
107            (b, didchange)
108        })
109    }
110
111    fn with_old_input_output2<R, T2, F>(&self, other: &Incr<T2>, mut f: F) -> Incr<R>
112    where
113        R: Value,
114        T2: Value,
115        F: FnMut(Option<(T, T2, R)>, &T, &T2) -> (R, bool) + 'static + NotObserver,
116    {
117        let mut old_input: Option<(T, T2)> = None;
118        // TODO: too much cloning
119        self.zip(other).map_with_old(move |old_opt, (a, b)| {
120            let oi = &mut old_input;
121            let (r, didchange) = f(
122                old_opt.and_then(|x| oi.take().map(|(oia, oib)| (oia, oib, x))),
123                a,
124                b,
125            );
126            *oi = Some((a.clone(), b.clone()));
127            (r, didchange)
128        })
129    }
130}
131/// Incremental maps, filter maps and folds on incremental key-value containers (maps).
132///
133/// Common functions available on `Incr<BTreeMap>` etc, with blanket
134/// implementation covering `M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>`.
135///
136/// So to get a lot of functionality for a new map type, you don't have to
137/// implement much. Just those two traits, and then you get all these methods
138/// for free.
139///
140/// **NOTE**: there are additional methods available on [crate::prelude::IncrBTreeMap] and
141/// [crate::prelude::IncrOrdMap] (with the `im` feature).
142///
143pub trait IncrMap<M> {
144    fn incr_map<F, K, V, V2>(&self, f: F) -> Incr<M::OutputMap<V2>>
145    where
146        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
147        K: Value + Ord,
148        V: Value,
149        V2: Value,
150        F: FnMut(&V) -> V2 + 'static + NotObserver,
151        M::OutputMap<V2>: Value;
152
153    fn incr_filter_map<F, K, V, V2>(&self, f: F) -> Incr<M::OutputMap<V2>>
154    where
155        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
156        K: Value + Ord,
157        V: Value,
158        V2: Value,
159        F: FnMut(&V) -> Option<V2> + 'static + NotObserver,
160        M::OutputMap<V2>: Value;
161
162    fn incr_mapi<F, K, V, V2>(&self, f: F) -> Incr<M::OutputMap<V2>>
163    where
164        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
165        K: Value + Ord,
166        V: Value,
167        V2: Value,
168        F: FnMut(&K, &V) -> V2 + 'static + NotObserver,
169        M::OutputMap<V2>: Value;
170
171    fn incr_filter_mapi<F, K, V, V2>(&self, f: F) -> Incr<M::OutputMap<V2>>
172    where
173        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
174        K: Value + Ord,
175        V: Value,
176        V2: Value,
177        F: FnMut(&K, &V) -> Option<V2> + 'static + NotObserver,
178        M::OutputMap<V2>: Value;
179
180    fn incr_unordered_fold_with<K, V, R, F>(&self, init: R, fold: F) -> Incr<R>
181    where
182        M: SymmetricFoldMap<K, V>,
183        K: Value + Ord,
184        V: Value,
185        R: Value,
186        F: UnorderedFold<M, K, V, R> + 'static + NotObserver;
187
188    fn incr_unordered_fold<FAdd, FRemove, K, V, R>(
189        &self,
190        init: R,
191        add: FAdd,
192        remove: FRemove,
193        revert_to_init_when_empty: bool,
194    ) -> Incr<R>
195    where
196        M: SymmetricFoldMap<K, V>,
197        K: Value + Ord,
198        V: Value,
199        R: Value,
200        FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
201        FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver;
202
203    fn incr_unordered_fold_update<FAdd, FRemove, FUpdate, K, V, R>(
204        &self,
205        init: R,
206        add: FAdd,
207        remove: FRemove,
208        update: FUpdate,
209        revert_to_init_when_empty: bool,
210    ) -> Incr<R>
211    where
212        M: SymmetricFoldMap<K, V>,
213        K: Value + Ord,
214        V: Value,
215        R: Value,
216        FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
217        FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver,
218        FUpdate: FnMut(R, &K, &V, &V) -> R + 'static + NotObserver;
219}
220
221impl<M: Value> IncrMap<M> for Incr<M> {
222    #[inline]
223    fn incr_map<F, K, V, V2>(&self, mut f: F) -> Incr<M::OutputMap<V2>>
224    where
225        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
226        K: Value + Ord,
227        V: Value,
228        V2: Value,
229        F: FnMut(&V) -> V2 + 'static + NotObserver,
230        M::OutputMap<V2>: Value,
231    {
232        let i = self.incr_filter_mapi(move |_k, v| Some(f(v)));
233        #[cfg(debug_assertions)]
234        i.set_graphviz_user_data(Box::new(format!(
235            "incr_map -> {}",
236            std::any::type_name::<M::OutputMap<V2>>()
237        )));
238        i
239    }
240
241    #[inline]
242    fn incr_filter_map<F, K, V, V2>(&self, mut f: F) -> Incr<M::OutputMap<V2>>
243    where
244        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
245        K: Value + Ord,
246        V: Value,
247        V2: Value,
248        F: FnMut(&V) -> Option<V2> + 'static + NotObserver,
249        M::OutputMap<V2>: Value,
250    {
251        let i = self.incr_filter_mapi(move |_k, v| f(v));
252        #[cfg(debug_assertions)]
253        i.set_graphviz_user_data(Box::new(format!(
254            "incr_filter_map -> {}",
255            std::any::type_name::<M::OutputMap<V2>>()
256        )));
257        i
258    }
259
260    #[inline]
261    fn incr_mapi<F, K, V, V2>(&self, mut f: F) -> Incr<M::OutputMap<V2>>
262    where
263        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
264        K: Value + Ord,
265        V: Value,
266        V2: Value,
267        F: FnMut(&K, &V) -> V2 + 'static + NotObserver,
268        M::OutputMap<V2>: Value,
269    {
270        let i = self.incr_filter_mapi(move |k, v| Some(f(k, v)));
271        #[cfg(debug_assertions)]
272        i.set_graphviz_user_data(Box::new(format!(
273            "incr_mapi -> {}",
274            std::any::type_name::<M::OutputMap<V2>>()
275        )));
276        i
277    }
278
279    fn incr_filter_mapi<F, K, V, V2>(&self, mut f: F) -> Incr<M::OutputMap<V2>>
280    where
281        M: SymmetricFoldMap<K, V> + SymmetricMapMap<K, V>,
282        K: Value + Ord,
283        V: Value,
284        V2: Value,
285        F: FnMut(&K, &V) -> Option<V2> + 'static + NotObserver,
286        M::OutputMap<V2>: Value,
287    {
288        let i = self.with_old_input_output(move |old, input| match (old, input.len()) {
289            (_, 0) | (None, _) => (input.filter_map_collect(&mut f), true),
290            (Some((old_in, mut old_out)), _) => {
291                let mut did_change = false;
292                let old_out_mut = old_out.make_mut();
293                let _: &mut <M::OutputMap<V2> as MutableMap<K, V2>>::UnderlyingMap = old_in
294                    .symmetric_fold(input, old_out_mut, |out, (key, change)| {
295                        did_change = true;
296                        match change {
297                            DiffElement::Left(_) => {
298                                out.remove(key);
299                            }
300                            DiffElement::Right(newval) => {
301                                if let Some(v2) = f(key, newval) {
302                                    out.insert(key.clone(), v2);
303                                } else {
304                                    out.remove(key);
305                                }
306                            }
307                            DiffElement::Unequal(_, newval) => {
308                                if let Some(v2) = f(key, newval) {
309                                    out.insert(key.clone(), v2);
310                                } else {
311                                    out.remove(key);
312                                }
313                            }
314                        }
315                        out
316                    });
317                (old_out, did_change)
318            }
319        });
320        #[cfg(debug_assertions)]
321        i.set_graphviz_user_data(Box::new(format!(
322            "incr_filter_mapi -> {}",
323            std::any::type_name::<M::OutputMap<V2>>()
324        )));
325        i
326    }
327
328    fn incr_unordered_fold<FAdd, FRemove, K, V, R>(
329        &self,
330        init: R,
331        add: FAdd,
332        remove: FRemove,
333        revert_to_init_when_empty: bool,
334    ) -> Incr<R>
335    where
336        M: SymmetricFoldMap<K, V>,
337        K: Value + Ord,
338        V: Value,
339        R: Value,
340        FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
341        FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver,
342    {
343        self.incr_unordered_fold_with(
344            init,
345            PlainUnorderedFold {
346                add,
347                remove,
348                revert_to_init_when_empty,
349                phantom: PhantomData,
350            },
351        )
352    }
353
354    fn incr_unordered_fold_update<FAdd, FRemove, FUpdate, K, V, R>(
355        &self,
356        init: R,
357        add: FAdd,
358        remove: FRemove,
359        update: FUpdate,
360        revert_to_init_when_empty: bool,
361    ) -> Incr<R>
362    where
363        M: SymmetricFoldMap<K, V>,
364        K: Value + Ord,
365        V: Value,
366        R: Value,
367        FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
368        FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver,
369        FUpdate: FnMut(R, &K, &V, &V) -> R + 'static + NotObserver,
370    {
371        let i = self.incr_unordered_fold_with(
372            init,
373            UpdateUnorderedFold {
374                add,
375                remove,
376                update,
377                revert_to_init_when_empty,
378                phantom: PhantomData,
379            },
380        );
381        #[cfg(debug_assertions)]
382        i.set_graphviz_user_data(Box::new(format!(
383            "incr_unordered_fold_update -> {}",
384            std::any::type_name::<R>()
385        )));
386        i
387    }
388
389    fn incr_unordered_fold_with<K, V, R, F>(&self, init: R, mut fold: F) -> Incr<R>
390    where
391        M: SymmetricFoldMap<K, V>,
392        K: Value + Ord,
393        V: Value,
394        R: Value,
395        F: UnorderedFold<M, K, V, R> + 'static + NotObserver,
396    {
397        let i = self.with_old_input_output(move |old, new_in| match old {
398            None => {
399                let newmap = fold.initial_fold(init.clone(), new_in);
400                (newmap, true)
401            }
402            Some((old_in, old_out)) => {
403                if fold.revert_to_init_when_empty() && new_in.is_empty() {
404                    return (init.clone(), !old_in.is_empty());
405                }
406                let mut did_change = false;
407                let folded: R = old_in.symmetric_fold(new_in, old_out, |acc, (key, difference)| {
408                    did_change = true;
409                    match difference {
410                        DiffElement::Left(value) => fold.remove(acc, key, value),
411                        DiffElement::Right(value) => fold.add(acc, key, value),
412                        DiffElement::Unequal(lv, rv) => fold.update(acc, key, lv, rv),
413                    }
414                });
415                (folded, did_change)
416            }
417        });
418        #[cfg(debug_assertions)]
419        i.set_graphviz_user_data(Box::new(format!(
420            "incr_unordered_fold_with -> {}",
421            std::any::type_name::<R>()
422        )));
423        i
424    }
425}
426
427/// Defines an unordered fold for a given map, key, value and output type.
428///
429/// Used with [IncrMap::incr_unordered_fold_with].
430///
431/// Implementations get &mut access to self. So you can store things in
432/// the type that implements this.
433pub trait UnorderedFold<M, K, V, R>
434where
435    M: SymmetricFoldMap<K, V>,
436    K: Value + Ord,
437    V: Value,
438{
439    /// How to add a key/value pair to the fold value
440    ///
441    /// E.g. `|acc, _, value| acc + value` for a signed integer.
442    fn add(&mut self, acc: R, key: &K, value: &V) -> R;
443
444    /// How to remove a key/value pair from the fold value
445    ///
446    /// E.g. `|acc, _, value| acc - value` for a signed integer.
447    fn remove(&mut self, acc: R, key: &K, value: &V) -> R;
448
449    /// Default implementation is `self.add(self.remove(acc, key, old), key, new)`
450    fn update(&mut self, mut acc: R, key: &K, old: &V, new: &V) -> R {
451        acc = self.remove(acc, key, old);
452        self.add(acc, key, new)
453    }
454
455    /// If we have emptied the map, can we just reset to the initial value?
456    /// Or do we have to call remove() on everything that was removed?
457    fn revert_to_init_when_empty(&self) -> bool;
458
459    /// Optimize the initial fold
460    fn initial_fold(&mut self, acc: R, input: &M) -> R {
461        input.nonincremental_fold(acc, |acc, (k, v)| self.add(acc, k, v))
462    }
463}
464
465struct PlainUnorderedFold<M, K, V, R, FAdd, FRemove> {
466    add: FAdd,
467    remove: FRemove,
468    revert_to_init_when_empty: bool,
469    phantom: PhantomData<(M, K, V, R)>,
470}
471
472impl<M, K: Value + Ord, V: Value, R: Value, FAdd, FRemove> UnorderedFold<M, K, V, R>
473    for PlainUnorderedFold<M, K, V, R, FAdd, FRemove>
474where
475    M: SymmetricFoldMap<K, V>,
476    FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
477    FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver,
478{
479    fn add(&mut self, acc: R, key: &K, value: &V) -> R {
480        (self.add)(acc, key, value)
481    }
482    fn remove(&mut self, acc: R, key: &K, value: &V) -> R {
483        (self.remove)(acc, key, value)
484    }
485    fn revert_to_init_when_empty(&self) -> bool {
486        self.revert_to_init_when_empty
487    }
488}
489
490struct UpdateUnorderedFold<M, K, V, R, FAdd, FRemove, FUpdate> {
491    add: FAdd,
492    remove: FRemove,
493    update: FUpdate,
494    revert_to_init_when_empty: bool,
495    phantom: PhantomData<(M, K, V, R)>,
496}
497
498impl<M, K: Value + Ord, V: Value, R: Value, FAdd, FRemove, FUpdate> UnorderedFold<M, K, V, R>
499    for UpdateUnorderedFold<M, K, V, R, FAdd, FRemove, FUpdate>
500where
501    M: SymmetricFoldMap<K, V>,
502    FAdd: FnMut(R, &K, &V) -> R + 'static + NotObserver,
503    FUpdate: FnMut(R, &K, &V, &V) -> R + 'static + NotObserver,
504    FRemove: FnMut(R, &K, &V) -> R + 'static + NotObserver,
505{
506    fn add(&mut self, acc: R, key: &K, value: &V) -> R {
507        (self.add)(acc, key, value)
508    }
509    fn remove(&mut self, acc: R, key: &K, value: &V) -> R {
510        (self.remove)(acc, key, value)
511    }
512    fn update(&mut self, acc: R, key: &K, old: &V, new: &V) -> R {
513        (self.update)(acc, key, old, new)
514    }
515    fn revert_to_init_when_empty(&self) -> bool {
516        self.revert_to_init_when_empty
517    }
518}
519
520/// An implementation of [UnorderedFold] using a builder pattern and closures.
521pub struct ClosureFold<M, K, V, R, FAdd, FRemove, FUpdate, FInitial> {
522    add: FAdd,
523    remove: FRemove,
524    update: Option<FUpdate>,
525    initial: Option<FInitial>,
526    revert_to_init_when_empty: bool,
527    phantom: PhantomData<(M, K, V, R)>,
528}
529
530impl ClosureFold<(), (), (), (), (), (), (), ()> {
531    pub fn new<M, K, V, R>(
532    ) -> ClosureFold<M, K, V, R, (), (), fn(R, &K, &V, &V) -> R, fn(R, &M) -> R>
533where {
534        ClosureFold::<M, K, V, R, _, _, _, _> {
535            add: (),
536            remove: (),
537            update: None,
538            initial: None,
539            revert_to_init_when_empty: false,
540            phantom: PhantomData,
541        }
542    }
543
544    pub fn new_add_remove<M, K, V, R, FAdd, FRemove>(
545        add: FAdd,
546        remove: FRemove,
547    ) -> ClosureFold<M, K, V, R, FAdd, FRemove, fn(R, &K, &V, &V) -> R, fn(R, &M) -> R>
548    where
549        FAdd: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
550        FRemove: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
551    {
552        ClosureFold {
553            add,
554            remove,
555            update: None,
556            initial: None,
557            revert_to_init_when_empty: false,
558            phantom: PhantomData,
559        }
560    }
561}
562
563impl<M, K, V, R, FAdd_, FRemove_, FUpdate_, FInitial_>
564    ClosureFold<M, K, V, R, FAdd_, FRemove_, FUpdate_, FInitial_>
565{
566    pub fn add<FAdd>(
567        self,
568        add: FAdd,
569    ) -> ClosureFold<M, K, V, R, FAdd, FRemove_, FUpdate_, FInitial_>
570    where
571        FAdd: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
572    {
573        ClosureFold {
574            add,
575            remove: self.remove,
576            update: None,
577            initial: None,
578            revert_to_init_when_empty: false,
579            phantom: PhantomData,
580        }
581    }
582    pub fn remove<FRemove>(
583        self,
584        remove: FRemove,
585    ) -> ClosureFold<M, K, V, R, FAdd_, FRemove, FUpdate_, FInitial_>
586    where
587        FRemove: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
588    {
589        ClosureFold {
590            add: self.add,
591            remove,
592            update: None,
593            initial: None,
594            revert_to_init_when_empty: false,
595            phantom: PhantomData,
596        }
597    }
598    pub fn update<FUpdate>(
599        self,
600        update: FUpdate,
601    ) -> ClosureFold<M, K, V, R, FAdd_, FRemove_, FUpdate, FInitial_>
602    where
603        FUpdate: for<'a> FnMut(R, &'a K, &'a V, &'a V) -> R + 'static + NotObserver,
604    {
605        ClosureFold {
606            add: self.add,
607            remove: self.remove,
608            update: Some(update),
609            initial: self.initial,
610            revert_to_init_when_empty: self.revert_to_init_when_empty,
611            phantom: self.phantom,
612        }
613    }
614
615    pub fn initial<FInitial>(
616        self,
617        initial: FInitial,
618    ) -> ClosureFold<M, K, V, R, FAdd_, FRemove_, FUpdate_, FInitial>
619    where
620        FInitial: for<'a> FnMut(R, &'a M) -> R + 'static + NotObserver,
621    {
622        ClosureFold {
623            add: self.add,
624            remove: self.remove,
625            update: self.update,
626            initial: Some(initial),
627            revert_to_init_when_empty: self.revert_to_init_when_empty,
628            phantom: self.phantom,
629        }
630    }
631    pub fn revert_to_init_when_empty(
632        self,
633        revert_to_init_when_empty: bool,
634    ) -> ClosureFold<M, K, V, R, FAdd_, FRemove_, FUpdate_, FInitial_> {
635        ClosureFold {
636            add: self.add,
637            remove: self.remove,
638            update: self.update,
639            initial: self.initial,
640            revert_to_init_when_empty,
641            phantom: self.phantom,
642        }
643    }
644}
645
646impl<M, K, V, R, FAdd, FRemove, FUpdate, FInitial> UnorderedFold<M, K, V, R>
647    for ClosureFold<M, K, V, R, FAdd, FRemove, FUpdate, FInitial>
648where
649    M: SymmetricFoldMap<K, V>,
650    K: Value + Ord,
651    V: Value,
652    R: Value,
653    FAdd: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
654    FRemove: for<'a> FnMut(R, &'a K, &'a V) -> R + 'static + NotObserver,
655    FUpdate: for<'a> FnMut(R, &'a K, &'a V, &'a V) -> R + 'static + NotObserver,
656    FInitial: for<'a> FnMut(R, &'a M) -> R + 'static + NotObserver,
657{
658    fn add(&mut self, acc: R, key: &K, value: &V) -> R {
659        (self.add)(acc, key, value)
660    }
661
662    fn remove(&mut self, acc: R, key: &K, value: &V) -> R {
663        (self.remove)(acc, key, value)
664    }
665
666    fn update(&mut self, acc: R, key: &K, old: &V, new: &V) -> R {
667        if let Some(closure) = &mut self.update {
668            closure(acc, key, old, new)
669        } else {
670            let r = self.remove(acc, key, old);
671            let r = self.add(r, key, new);
672            r
673        }
674    }
675
676    fn revert_to_init_when_empty(&self) -> bool {
677        self.revert_to_init_when_empty
678    }
679
680    fn initial_fold(&mut self, init: R, input: &M) -> R {
681        if let Some(closure) = &mut self.initial {
682            closure(init, input)
683        } else {
684            input.nonincremental_fold(init, |acc, (k, v)| self.add(acc, k, v))
685        }
686    }
687}