qwutils/imp/
vec.rs

1use std::ptr;
2
3pub trait VecExt<T> {
4    fn push_option(&mut self, o: Option<T>);
5
6    fn grow_to_with<F: FnMut() -> T>(&mut self, size: usize, f: F);
7
8    fn grow_to(&mut self, size: usize, value: T) where T: Clone;
9
10    fn grow_to_default(&mut self, size: usize) where T: Default;
11
12    fn insert_slice_copy(&mut self, index: usize, slice: &[T]) where T: Copy;
13
14    fn insert_slice_clone(&mut self, index: usize, slice: &[T]) where T: Clone;
15
16    fn extend_from_slice_copy(&mut self, slice: &[T]) where T: Copy;
17}
18
19impl<T> VecExt<T> for Vec<T> {
20    #[inline]
21    fn push_option(&mut self, o: Option<T>) {
22        if let Some(o) = o {
23            self.push(o);
24        }
25    }
26
27    #[inline]
28    fn grow_to_with<F: FnMut() -> T>(&mut self, size: usize, f: F) {
29        if size > self.len() {
30            self.resize_with(size, f);
31        }
32    }
33
34    #[inline]
35    fn grow_to(&mut self, size: usize, value: T) where T: Clone {
36        if size > self.len() {
37            self.resize(size, value);
38        }
39    }
40
41    #[inline]
42    fn grow_to_default(&mut self, size: usize) where T: Default {
43        if size > self.len() {
44            self.resize_with(size, T::default);
45        }
46    }
47
48    #[inline]
49    fn insert_slice_copy(&mut self, index: usize, slice: &[T]) where T: Copy {
50        let vlen = self.len();
51        let slen = slice.len();
52        assert!(index <= vlen);
53        assert!(slice.len() <= isize::MAX as usize); //no UB plz
54        let dlen = vlen+slen;
55
56        if dlen > self.capacity() {
57            self.reserve(slice.len());
58        }
59
60        unsafe {
61            {
62                let s = slice.as_ptr();
63                let p = self.as_mut_ptr().add(index);
64                ptr::copy(p, p.add(slen), vlen - index);
65                ptr::copy_nonoverlapping(s, p, slen);
66            }
67            self.set_len(dlen);
68        }
69    }
70
71    #[inline]
72    fn insert_slice_clone(&mut self, index: usize, slice: &[T]) where T: Clone {
73        let vlen = self.len();
74        let slen = slice.len();
75        assert!(index <= vlen);
76        assert!(slice.len() <= isize::MAX as usize); //no UB plz
77        let dlen = vlen+slen;
78
79        if dlen > self.capacity() {
80            self.reserve(slice.len());
81        }
82
83        unsafe {
84            self.set_len(0);
85            {
86                let mut p = self.as_mut_ptr().add(index);
87                ptr::copy(p, p.add(slen), vlen - index);
88                for v in slice {
89                    ptr::write(p,v.clone());
90                    p = p.offset(1);
91                }
92            }
93            self.set_len(dlen);
94        }
95    }
96
97    fn extend_from_slice_copy(&mut self, slice: &[T]) where T: Copy {
98        self.insert_slice_copy(self.len(), slice);
99    }
100}
101
102#[test]
103fn insert_extra() {
104    let mut a = vec![1,2,7,8];
105    let b = [3,4,5,6];
106    a.insert_slice_copy(2,&b);
107    a.extend_from_slice_copy(&[9,10,11,12,13,14,15,16]);
108    assert_eq!(&a,&[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
109    assert_eq!(a.len(),16);
110}
111#[test]
112fn insert_extra_b() {
113    let mut a = vec![1,2,7,8];
114    let b = [3,4,5,6];
115    a.insert_slice_clone(2,&b);
116    assert_eq!(&a,&[1,2,3,4,5,6,7,8]);
117    assert_eq!(a.len(),8);
118}