Skip to main content

embed_collections/
various.rs

1use crate::seg_list::SegList;
2use core::fmt;
3
4pub struct Various<T> {
5    inner: VariousInner<T>,
6}
7
8enum VariousInner<T> {
9    One(Option<T>),
10    More(SegList<T>),
11}
12
13macro_rules! match_iter {
14    ($self: expr, $iter_type: tt, $f: tt $($m: tt)*) =>{
15        match $self.inner {
16            VariousInner::One($($m)* s)=>$iter_type::One(s.$f()),
17            VariousInner::More($($m)* s)=>$iter_type::More(s.$f()),
18        }
19    }
20}
21
22macro_rules! match_call {
23    ($self: expr, $cls: tt, $call: tt) => {
24        match $self {
25            $cls::One(i) => i.$call(),
26            $cls::More(i) => i.$call(),
27        }
28    };
29}
30
31impl<T> Default for Various<T> {
32    fn default() -> Self {
33        Self::new()
34    }
35}
36
37impl<T> Various<T> {
38    #[inline]
39    pub fn new() -> Self {
40        Self { inner: VariousInner::One(None) }
41    }
42
43    #[inline]
44    pub fn from(item: T) -> Self {
45        Self { inner: VariousInner::One(Some(item)) }
46    }
47
48    #[inline]
49    pub fn is_empty(&self) -> bool {
50        match &self.inner {
51            VariousInner::One(i) => i.is_none(),
52            VariousInner::More(i) => i.is_empty(),
53        }
54    }
55
56    #[inline]
57    pub fn len(&self) -> usize {
58        match &self.inner {
59            VariousInner::One(i) => {
60                if i.is_none() {
61                    return 0;
62                } else {
63                    return 1;
64                }
65            }
66            VariousInner::More(i) => i.len(),
67        }
68    }
69
70    /// push element to the tail
71    #[inline]
72    pub fn push(&mut self, new_item: T) {
73        match self.inner {
74            VariousInner::More(ref mut s) => {
75                s.push(new_item);
76            }
77            VariousInner::One(ref mut s) => {
78                if s.is_none() {
79                    s.replace(new_item);
80                } else {
81                    let mut l = SegList::new();
82                    l.push(s.take().unwrap());
83                    l.push(new_item);
84                    self.inner = VariousInner::More(l);
85                }
86            }
87        }
88    }
89
90    /// pop element from the tail
91    #[inline]
92    pub fn pop(&mut self) -> Option<T> {
93        match self.inner {
94            VariousInner::More(ref mut s) => s.pop(),
95            VariousInner::One(ref mut s) => s.take(),
96        }
97    }
98
99    #[inline]
100    pub fn iter<'a>(&'a self) -> VariousIter<'a, T> {
101        match_iter!(self, VariousIter, iter ref)
102    }
103
104    pub fn iter_mut<'a>(&'a mut self) -> VariousIterMut<'a, T> {
105        match_iter!(self, VariousIterMut, iter_mut ref mut)
106    }
107
108    #[inline]
109    pub fn first(&self) -> Option<&T> {
110        match self.inner {
111            VariousInner::One(ref s) => s.as_ref(),
112            VariousInner::More(ref s) => s.iter().next(),
113        }
114    }
115
116    #[inline]
117    pub fn last(&self) -> Option<&T> {
118        match self.inner {
119            VariousInner::More(ref s) => s.last(),
120            VariousInner::One(ref s) => s.as_ref(),
121        }
122    }
123
124    pub fn last_mut(&mut self) -> Option<&mut T> {
125        match self.inner {
126            VariousInner::More(ref mut s) => s.last_mut(),
127            VariousInner::One(ref mut s) => s.as_mut(),
128        }
129    }
130
131    #[inline]
132    pub fn take(&mut self) -> Self {
133        use core::mem;
134        Various { inner: mem::replace(&mut self.inner, VariousInner::One(None)) }
135    }
136}
137
138impl<T> IntoIterator for Various<T> {
139    type Item = T;
140
141    type IntoIter = VariousIntoIter<T>;
142
143    fn into_iter(self) -> VariousIntoIter<T> {
144        match_iter!(self, VariousIntoIter, into_iter)
145    }
146}
147
148impl<'a, T> IntoIterator for &'a Various<T> {
149    type Item = &'a T;
150
151    type IntoIter = VariousIter<'a, T>;
152
153    fn into_iter(self) -> VariousIter<'a, T> {
154        match_iter!(self, VariousIter, iter ref)
155    }
156}
157
158pub enum VariousIter<'a, T> {
159    One(core::option::Iter<'a, T>),
160    More(crate::seg_list::SegListIter<'a, T>),
161}
162
163impl<'a, T> core::iter::Iterator for VariousIter<'a, T> {
164    type Item = &'a T;
165
166    fn next(&mut self) -> Option<Self::Item> {
167        match_call!(self, VariousIter, next)
168    }
169}
170
171pub enum VariousIterMut<'a, T> {
172    One(core::option::IterMut<'a, T>),
173    More(crate::seg_list::SegListIterMut<'a, T>),
174}
175
176impl<'a, T> core::iter::Iterator for VariousIterMut<'a, T> {
177    type Item = &'a mut T;
178
179    fn next(&mut self) -> Option<Self::Item> {
180        match_call!(self, VariousIterMut, next)
181    }
182}
183
184pub enum VariousIntoIter<T> {
185    One(core::option::IntoIter<T>),
186    More(crate::seg_list::SegListDrain<T>),
187}
188
189impl<T> core::iter::Iterator for VariousIntoIter<T> {
190    type Item = T;
191
192    fn next(&mut self) -> Option<Self::Item> {
193        match_call!(self, VariousIntoIter, next)
194    }
195}
196
197impl<T: fmt::Debug> fmt::Debug for Various<T> {
198    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
199        match &self.inner {
200            VariousInner::One(s) => s.fmt(f),
201            VariousInner::More(s) => s.fmt(f),
202        }
203    }
204}
205
206#[cfg(test)]
207mod tests {
208
209    use super::*;
210
211    #[test]
212    fn test_one() {
213        let mut s = Various::new();
214        s.push(1);
215        assert_eq!(s.len(), 1);
216        for i in &s {
217            assert_eq!(*i, 1);
218        }
219        assert_eq!(Some(1), s.pop());
220        assert_eq!(s.len(), 0);
221        if (&s).into_iter().next().is_some() {
222            unreachable!();
223        }
224    }
225
226    #[test]
227    fn test_cap_0() {
228        let mut s = Various::new();
229        s.push(1);
230        assert_eq!(s.len(), 1);
231        for i in &s {
232            assert_eq!(*i, 1);
233        }
234        s.push(2);
235        s.push(3);
236        assert_eq!(s.len(), 3);
237        let mut total = 0;
238        for i in &s {
239            total += *i;
240        }
241        assert_eq!(total, 6);
242        for i in s.iter_mut() {
243            *i += 1;
244        }
245        let mut total = 0;
246        for i in &s {
247            total += *i;
248        }
249        assert_eq!(total, 9);
250        assert_eq!(s.pop(), Some(4));
251        let mut total = 0;
252        for i in s {
253            total += i;
254        }
255        assert_eq!(total, 5);
256    }
257
258    #[test]
259    fn test_more() {
260        let mut s = Various::new();
261        s.push(1);
262        s.push(2);
263        s.push(3);
264        assert_eq!(s.len(), 3);
265        let mut total = 0;
266        for i in &s {
267            total += *i;
268        }
269        assert_eq!(total, 6);
270        for i in s.iter_mut() {
271            *i += 1;
272        }
273        let mut total = 0;
274        for i in &s {
275            total += *i;
276        }
277        assert_eq!(total, 9);
278        assert_eq!(s.pop(), Some(4));
279        let mut total = 0;
280        for i in s {
281            total += i;
282        }
283        assert_eq!(total, 5);
284    }
285}