evobench_tools/utillib/
micro_vec.rs1#[derive(Debug, PartialEq, Eq)]
10pub enum MicroVec<T> {
11 None,
12 One(T),
13 More(Box<Vec<T>>),
14}
15
16impl<T> Default for MicroVec<T> {
17 #[inline]
18 fn default() -> Self {
19 MicroVec::new()
20 }
21}
22
23impl<T, const N: usize> From<[T; N]> for MicroVec<T> {
24 fn from(values: [T; N]) -> Self {
25 let mut vec = MicroVec::new();
26 for v in values {
27 vec.push(v);
28 }
29 vec
30 }
31}
32
33impl<T: Clone> From<&[T]> for MicroVec<T> {
34 fn from(values: &[T]) -> Self {
35 let mut vec = MicroVec::new();
36 for v in values {
37 vec.push(v.clone());
38 }
39 vec
40 }
41}
42
43impl<T> MicroVec<T> {
44 #[inline]
45 pub fn new() -> Self {
46 Self::None
47 }
48
49 pub fn len(&self) -> usize {
50 match self {
51 MicroVec::None => 0,
52 MicroVec::One(_) => 1,
53 MicroVec::More(items) => items.len(),
54 }
55 }
56
57 pub fn push(&mut self, val: T) {
58 match self {
59 MicroVec::None => {
60 *self = MicroVec::One(val);
61 }
62 MicroVec::One(_) => {
63 let mut removed = MicroVec::None;
64 std::mem::swap(self, &mut removed);
65 match removed {
66 MicroVec::One(v0) => {
67 *self = MicroVec::More(vec![v0, val].into());
68 }
69 _ => unreachable!(),
70 }
71 }
72 MicroVec::More(items) => {
73 items.push(val);
74 }
75 }
76 }
77}
78
79#[macro_export]
82macro_rules! microvec {
83 [] => {
84 $crate::utillib::micro_vec::MicroVec::None
85 };
86 [ $v:expr ] => {
87 $crate::utillib::micro_vec::MicroVec::One($v)
88 };
89 [ $($e:tt)* ] => {
90 {
91 let mut vec = $crate::utillib::micro_vec::MicroVec::None;
92 for v in [$($e)*] {
93 vec.push(v);
94 }
95 vec
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn t_1() {
106 let mut vec: MicroVec<u32> = Default::default();
107
108 assert_eq!(size_of_val(&vec), 16);
110
111 assert_eq!(vec.len(), 0);
112 assert_eq!(µvec![], &vec);
113
114 vec.push(123);
115 assert_eq!(vec.len(), 1);
116 assert_eq!(µvec![123], &vec);
117
118 vec.push(124);
119 assert_eq!(vec.len(), 2);
120
121 assert_eq!(µvec![123, 124], &vec);
122 }
123}