1use std::cell::UnsafeCell;
32use std::fmt::Debug;
33
34pub struct ValueVec<V: Copy> {
38 data: UnsafeCell<Vec<V>>,
39}
40
41impl<V: Copy> ValueVec<V> {
42 #[must_use]
44 pub fn new() -> Self {
45 Self {
46 data: UnsafeCell::new(Vec::new()),
47 }
48 }
49
50 #[must_use]
52 pub fn with_capacity(cap: usize) -> Self {
53 Self {
54 data: UnsafeCell::new(Vec::with_capacity(cap)),
55 }
56 }
57
58 #[inline]
60 #[must_use]
61 pub fn len(&self) -> usize {
62 unsafe { (&*self.data.get()).len() }
64 }
65
66 #[inline]
68 #[must_use]
69 pub fn capacity(&self) -> usize {
70 unsafe { (&*self.data.get()).capacity() }
72 }
73
74 #[inline]
76 #[must_use]
77 pub fn is_empty(&self) -> bool {
78 self.len() == 0
79 }
80
81 pub fn reserve(&self, additional: usize) {
83 self.with_vec(|v| v.reserve(additional));
84 }
85
86 pub fn shrink_to_fit(&self) {
88 self.with_vec(|v| v.shrink_to_fit());
89 }
90
91 pub fn push(&self, value: V) {
93 self.with_vec(|v| v.push(value));
94 }
95
96 #[must_use]
98 pub fn pop(&self) -> Option<V> {
99 self.with_vec(|v| v.pop())
100 }
101
102 #[must_use]
105 pub fn get(&self, index: usize) -> Option<V> {
106 unsafe { (&*self.data.get()).get(index).copied() }
107 }
108
109 #[must_use]
113 pub fn at(&self, index: usize) -> V {
114 unsafe { (&*self.data.get())[index] }
115 }
116
117 #[must_use]
119 pub fn replace(&self, index: usize, value: V) -> V {
120 self.with_vec(|v| core::mem::replace(&mut v[index], value))
121 }
122
123 pub fn set(&self, index: usize, value: V) {
125 self.with_vec(|v| v[index] = value)
126 }
127
128 pub fn swap_value(&self, index: usize, value: &mut V) {
132 self.with_vec(|v| {
133 core::mem::swap(&mut v[index], value);
134 })
135 }
136
137 pub fn insert(&self, index: usize, value: V) {
139 self.with_vec(|v| {
140 v.insert(index, value);
141 })
142 }
143
144 #[must_use]
146 pub fn remove(&self, index: usize) -> V {
147 self.with_vec(|v| v.remove(index))
148 }
149
150 #[must_use]
154 pub fn swap_remove(&self, index: usize) -> V {
155 self.with_vec(|v| v.swap_remove(index))
156 }
157
158 #[must_use]
160 pub fn contains(&self, value: &V) -> bool
161 where
162 V: PartialEq,
163 {
164 self.with_vec(|v| v.contains(value))
165 }
166
167 pub fn clear(&self) {
169 self.with_vec(|v| v.clear());
170 }
171
172 pub fn extend<I>(&self, iter: I)
174 where
175 I: IntoIterator<Item = V>,
176 {
177 self.with_vec(|v| v.extend(iter));
178 }
179
180 pub fn resize(&self, new_len: usize, value: V) {
181 self.with_vec(|v| v.resize(new_len, value));
182 }
183
184 pub fn resize_with<F>(&self, new_len: usize, f: F)
185 where
186 F: FnMut() -> V,
187 {
188 self.with_vec(|v| v.resize_with(new_len, f));
189 }
190
191 #[must_use]
195 pub fn to_vec(&self) -> Vec<V>
196 where
197 V: Clone,
198 {
199 unsafe { (&*self.data.get()).clone() }
200 }
201
202 #[inline]
227 fn with_vec<R>(&self, f: impl FnOnce(&mut Vec<V>) -> R) -> R {
228 let vec: &mut Vec<V> = unsafe { &mut *self.data.get() };
232 f(vec)
233 }
234}
235
236impl<V: Copy> Default for ValueVec<V> {
237 fn default() -> Self {
238 Self::new()
239 }
240}
241
242impl<V: Copy + Debug> Debug for ValueVec<V> {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 let vec = unsafe { &*self.data.get() };
247 vec.fmt(f)
248 }
249}
250
251impl<V: Copy> From<Vec<V>> for ValueVec<V> {
252 fn from(src: Vec<V>) -> Self {
254 Self {
255 data: UnsafeCell::new(src),
256 }
257 }
258}
259
260impl<V: Copy> From<ValueVec<V>> for Vec<V> {
261 fn from(val: ValueVec<V>) -> Self {
262 val.data.into_inner()
263 }
264}
265
266impl<V: Copy> IntoIterator for ValueVec<V> {
267 type Item = V;
268 type IntoIter = std::vec::IntoIter<V>;
269
270 fn into_iter(self) -> Self::IntoIter {
271 let vec = self.data.into_inner();
274 vec.into_iter()
275 }
276}
277
278impl<V: Copy> FromIterator<V> for ValueVec<V> {
279 fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
280 Self::from(Vec::from_iter(iter))
281 }
282}
283
284#[cfg(test)]
285mod tests {
286 use super::ValueVec;
287
288 #[test]
289 fn push_pop() {
290 let v = ValueVec::new();
291 assert!(v.is_empty());
292 v.push(1);
293 v.push(2);
294 v.push(3);
295 assert_eq!(v.len(), 3);
296 assert_eq!(v.pop(), Some(3));
297 assert_eq!(v.pop(), Some(2));
298 assert_eq!(v.pop(), Some(1));
299 assert_eq!(v.pop(), None);
300 }
301
302 #[test]
303 fn capacity_reserve_and_shrink_to_fit() {
304 let v = ValueVec::with_capacity(4);
305 assert!(v.capacity() >= 4);
306
307 v.reserve(16);
308 assert!(v.capacity() >= 16);
309
310 v.extend([1, 2]);
311 v.shrink_to_fit();
312 assert!(v.capacity() >= v.len());
313 }
314
315 #[test]
316 fn get_cloned_and_replace() {
317 let v = ValueVec::new();
318 v.extend([10, 20, 30]);
319 assert_eq!(v.get(1), Some(20));
320 assert_eq!(v.replace(1, 99), 20);
321 assert_eq!(v.get(1), Some(99));
322 }
323
324 #[test]
325 fn set_swap_contains_clear_and_resize() {
326 let v = ValueVec::default();
327 assert!(v.is_empty());
328
329 v.resize(3, 7);
330 assert_eq!(v.to_vec(), vec![7, 7, 7]);
331
332 v.set(1, 9);
333 assert_eq!(v.at(1), 9);
334
335 let mut replacement = 42;
336 v.swap_value(1, &mut replacement);
337 assert_eq!(v.at(1), 42);
338 assert_eq!(replacement, 9);
339
340 assert!(v.contains(&42));
341 assert!(!v.contains(&9));
342
343 let mut next = 0;
344 v.resize_with(5, || {
345 next += 1;
346 next
347 });
348 assert_eq!(v.to_vec(), vec![7, 42, 7, 1, 2]);
349
350 v.clear();
351 assert!(v.is_empty());
352 }
353
354 #[test]
355 fn insert_and_remove() {
356 let v = ValueVec::new();
357 v.extend([1, 2, 3]);
358 v.insert(1, 9); assert_eq!(v.len(), 4);
360 assert_eq!(v.remove(2), 2); assert_eq!(v.get(0), Some(1));
362 assert_eq!(v.at(1), 9);
363 assert_eq!(v.at(2), 3);
364 assert_eq!(v.remove(1), 9);
365 }
366
367 #[test]
368 fn swap_remove_works() {
369 let v = ValueVec::new();
370 v.extend([10, 20, 30, 40]);
371 let got = v.swap_remove(1);
372 assert_eq!(got, 20);
373 assert_eq!(v.len(), 3);
375 let snapshot = v.to_vec();
376 assert!(snapshot.contains(&10));
377 assert!(snapshot.contains(&30));
378 assert!(snapshot.contains(&40));
379 assert!(!snapshot.contains(&20));
380
381 let v: Vec<i32> = v.into();
382 assert_eq!(snapshot, v);
383 }
384
385 #[test]
386 fn to_vec_clone_snapshot() {
387 let v = ValueVec::new();
388 v.extend(["a", "b"]);
389 let snap = v.to_vec();
390 assert_eq!(snap, vec!["a", "b"]);
391 v.push("c");
393 assert_eq!(v.len(), 3);
394 assert_eq!(snap.len(), 2);
395 }
396
397 #[test]
398 fn debug_impl() {
399 let v = ValueVec::from(vec![1, 2, 3]);
400 let s = format!("{v:?}");
401 assert!(!s.contains("ValueVec"));
402 assert!(s.contains("[1, 2, 3]"));
403 }
404
405 #[test]
406 fn from_vec_wraps_without_copy() {
407 let v = vec![1, 2, 3];
408 let vv = ValueVec::from(v);
409 assert_eq!(vv.len(), 3);
411 assert_eq!(vv.at(0), 1);
412 assert_eq!(vv.at(1), 2);
413 assert_eq!(vv.at(2), 3);
414 }
416
417 #[test]
418 fn into_vec_unwraps_without_copy() {
419 let vv = ValueVec::from(vec!["a", "b"]);
420 let v: Vec<_> = vv.into(); assert_eq!(v, vec!["a", "b"]);
422 }
423
424 #[test]
425 fn round_trip_from_vec_into_vec() {
426 let original = vec![10, 20, 30];
427 let vv = ValueVec::from(original);
428 let roundtrip: Vec<_> = vv.into();
429 assert_eq!(roundtrip, vec![10, 20, 30]);
430 }
431
432 #[test]
433 fn into_iterator_consumes_valuevec() {
434 let vv = ValueVec::from(vec![1, 2, 3]);
435 let collected: Vec<_> = vv.into_iter().collect();
436 assert_eq!(collected, vec![1, 2, 3]);
437 }
438
439 #[test]
440 fn into_iterator_and_into_vec_equivalence() {
441 let vv1 = ValueVec::from(vec![5, 6, 7]);
442 let vv2 = ValueVec::from(vec![5, 6, 7]);
443 let collected_from_iter: Vec<_> = vv1.into_iter().collect();
444 let collected_from_into: Vec<_> = vv2.into();
445 assert_eq!(collected_from_iter, collected_from_into);
446 }
447
448 #[test]
449 fn from_iterator_collect() {
450 let source = [1, 2, 3, 4, 5];
451 let vv: ValueVec<i32> = source.iter().copied().collect();
452 assert_eq!(vv.len(), 5);
453 assert_eq!(vv.at(0), 1);
454 assert_eq!(vv.at(4), 5);
455 }
456}