1use std::{
2 fmt::Display,
3 iter::Sum,
4 ops::AddAssign,
5 ops::{Add, Sub},
6};
7
8use crate::{GCounter, NodeId};
9
10pub struct PnCounter<V>
11where
12 V: Display
13 + AddAssign
14 + Clone
15 + Copy
16 + for<'v> Sum<&'v V>
17 + Ord
18 + Add<Output = V>
19 + Sub<Output = V>
20 + Default,
21{
22 pub id: NodeId,
23 pub pos_counter: GCounter<V>,
24 pub neg_counter: GCounter<V>,
25 pub default_value: V,
26}
27
28impl<V> PnCounter<V>
29where
30 V: Display
31 + AddAssign
32 + Clone
33 + Copy
34 + for<'v> Sum<&'v V>
35 + Ord
36 + Add<Output = V>
37 + Sub<Output = V>
38 + Default,
39{
40 pub fn new(id: NodeId) -> Self {
41 PnCounter {
42 id: id.clone(),
43 pos_counter: GCounter::new(id.clone()),
44 neg_counter: GCounter::new(id.clone()),
45 default_value: Default::default(),
46 }
47 }
48
49 pub fn inc(&mut self, to_sum: Option<V>) {
50 self.pos_counter.inc(to_sum);
51 }
52
53 pub fn dec(&mut self, to_sub: Option<V>) {
54 self.neg_counter.inc(to_sub);
55 }
56
57 pub fn local(&self) -> V {
58 self.pos_counter.local().clone() - self.neg_counter.local().clone()
59 }
60
61 pub fn read(&self) -> V {
62 self.pos_counter.read() - self.neg_counter.read()
63 }
64
65 pub fn join(&mut self, pncounter: &PnCounter<V>) {
66 self.pos_counter.join(&pncounter.pos_counter);
67 self.neg_counter.join(&pncounter.neg_counter);
68 }
69}