oxihuman_core/
compact_vec.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
7#[derive(Debug, Clone)]
8pub struct CompactVec<T: Clone + Default> {
9 inline: [T; 4],
10 inline_len: usize,
11 overflow: Vec<T>,
12}
13
14#[allow(dead_code)]
15impl<T: Clone + Default + PartialEq> CompactVec<T> {
16 pub fn new() -> Self {
17 Self {
18 inline: Default::default(),
19 inline_len: 0,
20 overflow: Vec::new(),
21 }
22 }
23
24 pub fn push(&mut self, val: T) {
25 if self.inline_len < 4 {
26 self.inline[self.inline_len] = val;
27 self.inline_len += 1;
28 } else {
29 self.overflow.push(val);
30 }
31 }
32
33 pub fn pop(&mut self) -> Option<T> {
34 if let Some(v) = self.overflow.pop() {
35 return Some(v);
36 }
37 if self.inline_len > 0 {
38 self.inline_len -= 1;
39 let val = self.inline[self.inline_len].clone();
40 self.inline[self.inline_len] = T::default();
41 Some(val)
42 } else {
43 None
44 }
45 }
46
47 pub fn len(&self) -> usize {
48 self.inline_len + self.overflow.len()
49 }
50
51 pub fn is_empty(&self) -> bool {
52 self.inline_len == 0 && self.overflow.is_empty()
53 }
54
55 pub fn get(&self, index: usize) -> Option<&T> {
56 if index < self.inline_len {
57 Some(&self.inline[index])
58 } else {
59 self.overflow.get(index - self.inline_len)
60 }
61 }
62
63 pub fn is_inline(&self) -> bool {
64 self.overflow.is_empty()
65 }
66
67 pub fn clear(&mut self) {
68 for i in 0..self.inline_len {
69 self.inline[i] = T::default();
70 }
71 self.inline_len = 0;
72 self.overflow.clear();
73 }
74
75 pub fn contains(&self, val: &T) -> bool {
76 for i in 0..self.inline_len {
77 if &self.inline[i] == val {
78 return true;
79 }
80 }
81 self.overflow.contains(val)
82 }
83
84 pub fn to_vec(&self) -> Vec<T> {
85 let mut v = Vec::with_capacity(self.len());
86 for i in 0..self.inline_len {
87 v.push(self.inline[i].clone());
88 }
89 v.extend_from_slice(&self.overflow);
90 v
91 }
92}
93
94impl<T: Clone + Default + PartialEq> Default for CompactVec<T> {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_new() {
106 let v: CompactVec<i32> = CompactVec::new();
107 assert!(v.is_empty());
108 assert!(v.is_inline());
109 }
110
111 #[test]
112 fn test_push_inline() {
113 let mut v = CompactVec::new();
114 v.push(1);
115 v.push(2);
116 assert_eq!(v.len(), 2);
117 assert!(v.is_inline());
118 }
119
120 #[test]
121 fn test_push_overflow() {
122 let mut v = CompactVec::new();
123 for i in 0..6 {
124 v.push(i);
125 }
126 assert_eq!(v.len(), 6);
127 assert!(!v.is_inline());
128 }
129
130 #[test]
131 fn test_get() {
132 let mut v = CompactVec::new();
133 v.push(10);
134 v.push(20);
135 v.push(30);
136 v.push(40);
137 v.push(50);
138 assert_eq!(v.get(0), Some(&10));
139 assert_eq!(v.get(4), Some(&50));
140 assert_eq!(v.get(10), None);
141 }
142
143 #[test]
144 fn test_pop() {
145 let mut v = CompactVec::new();
146 v.push(1);
147 v.push(2);
148 assert_eq!(v.pop(), Some(2));
149 assert_eq!(v.pop(), Some(1));
150 assert_eq!(v.pop(), None);
151 }
152
153 #[test]
154 fn test_clear() {
155 let mut v = CompactVec::new();
156 v.push(1);
157 v.push(2);
158 v.push(3);
159 v.push(4);
160 v.push(5);
161 v.clear();
162 assert!(v.is_empty());
163 }
164
165 #[test]
166 fn test_contains() {
167 let mut v = CompactVec::new();
168 v.push(10);
169 v.push(20);
170 assert!(v.contains(&10));
171 assert!(!v.contains(&30));
172 }
173
174 #[test]
175 fn test_to_vec() {
176 let mut v = CompactVec::new();
177 v.push(1);
178 v.push(2);
179 v.push(3);
180 assert_eq!(v.to_vec(), vec![1, 2, 3]);
181 }
182
183 #[test]
184 fn test_pop_from_overflow() {
185 let mut v = CompactVec::new();
186 for i in 0..6 {
187 v.push(i);
188 }
189 assert_eq!(v.pop(), Some(5));
190 assert_eq!(v.len(), 5);
191 }
192
193 #[test]
194 fn test_default() {
195 let v: CompactVec<f32> = CompactVec::default();
196 assert!(v.is_empty());
197 }
198}