1use std::ops::RangeFull;
2
3use monoid::Monoid;
4
5#[derive(Clone, PartialEq, Eq)]
6pub struct FoldableQueue<M: Monoid> {
7 front: Vec<M::Set>,
8 front_folded: Vec<M::Set>,
9 back: Vec<M::Set>,
10 back_folded: Vec<M::Set>,
11 monoid: M,
12}
13
14impl<M: Monoid> FoldableQueue<M> {
15 pub fn new() -> Self
16 where
17 M: Default,
18 {
19 let monoid = M::default();
20 Self {
21 front: vec![],
22 front_folded: vec![monoid.id()],
23 back: vec![],
24 back_folded: vec![monoid.id()],
25 monoid,
26 }
27 }
28 pub fn push(&mut self, elt: M::Set) {
29 let tmp = self.monoid.op(self.back_folded.last().unwrap(), &elt);
30 self.back_folded.push(tmp);
31 self.back.push(elt);
32 }
33 pub fn pop(&mut self) -> Option<M::Set> {
34 self.rotate();
35 let elt = self.front.pop()?;
36 self.front_folded.pop().unwrap();
37 Some(elt)
38 }
39 pub fn fold(&self, _: RangeFull) -> M::Set {
40 self.monoid.op(
41 self.front_folded.last().unwrap(),
42 self.back_folded.last().unwrap(),
43 )
44 }
45
46 fn rotate(&mut self) {
47 if !self.front.is_empty() {
48 return;
49 }
50 while let Some(elt) = self.back.pop() {
51 self.back_folded.pop();
52 self.front_folded
53 .push(self.monoid.op(&elt, self.front_folded.last().unwrap()));
54 self.front.push(elt);
55 }
56 }
57}
58
59impl<M: Monoid> std::fmt::Debug for FoldableQueue<M>
60where
61 M::Set: std::fmt::Debug,
62{
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 f.debug_list()
65 .entries(self.front.iter().rev().chain(self.back.iter()))
66 .finish()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use concat_monoid::OpConcat;
73
74 use crate::*;
75
76 #[test]
77 fn sanity_check() {
78 let mut queue = FoldableQueue::<OpConcat<i32, Vec<_>>>::new();
79 queue.push(vec![1]);
80 assert_eq!(queue.fold(..), vec![1]);
81 assert_eq!(queue.pop(), Some(vec![1]));
82
83 queue.push(vec![1]);
84 assert_eq!(queue.fold(..), vec![1]);
85 queue.push(vec![2]);
86 assert_eq!(queue.fold(..), vec![1, 2]);
87 queue.push(vec![3]);
88 assert_eq!(queue.fold(..), vec![1, 2, 3]);
89
90 assert_eq!(queue.pop(), Some(vec![1]));
91 assert_eq!(queue.fold(..), vec![2, 3]);
92
93 queue.push(vec![4]);
94 assert_eq!(queue.fold(..), vec![2, 3, 4]);
95 assert_eq!(queue.pop(), Some(vec![2]));
96 assert_eq!(queue.fold(..), vec![3, 4]);
97 assert_eq!(queue.pop(), Some(vec![3]));
98 assert_eq!(queue.fold(..), vec![4]);
99 assert_eq!(queue.pop(), Some(vec![4]));
100 assert_eq!(queue.fold(..), vec![]);
101 assert_eq!(queue.pop(), None);
102 assert_eq!(queue.fold(..), vec![]);
103 }
104
105 #[test]
106 fn test_fmt() {
107 let mut queue = FoldableQueue::<OpConcat<_, Vec<_>>>::new();
108 assert_eq!(format!("{queue:?}"), "[]");
109 queue.push(vec![1]);
110 queue.push(vec![2]);
111 queue.push(vec![3]);
112 queue.push(vec![4]);
113 assert_eq!(format!("{queue:?}"), "[[1], [2], [3], [4]]");
114 }
115}