Skip to main content

qwutils/arc_slice/
imp.rs

1use super::*;
2use std::ops::RangeBounds;
3
4impl<T> ArcSlice<T> {
5    #[inline]
6    pub fn new() -> Self {
7        Self{
8            inner: Arc::new(Vec::new()),
9            slice: 0..0,
10        }
11    }
12    pub fn with_capacity(capacity: usize) -> Self {
13        Self{
14            inner: Arc::new(Vec::with_capacity(capacity)),
15            slice: 0..0,
16        }
17    }
18    /// slice of the current slice
19    /// 
20    /// will not allocate
21    #[inline]
22    pub fn slice<S>(&self, range: S) -> Self where S: RangeBounds<usize> {
23        Self{
24            inner: self.inner.refc(),
25            slice: slice_slice(&self.slice,range),
26        }
27    }
28    /// will always allocate and clone
29    pub fn extract(&self) -> Vec<T> where T: Clone {
30        self.extract_with_capacity(self.len())
31    }
32    pub fn extracted(&self) -> Self where T: Clone {
33        self.extracted_with_capacity(self.len())
34    }
35    pub fn extract_with_capacity(&self, capacity: usize) -> Vec<T> where T: Clone {
36        let mut dest = Vec::with_capacity(self.len().max(capacity));
37        dest.extend_from_slice(&self);
38        dest
39    }
40    pub fn extracted_with_capacity(&self, capacity: usize) -> Self where T: Clone {
41        if self.is_unsliced() {
42            self.refc()
43        }else{
44            Self::from(self.extract_with_capacity(capacity))
45        }
46    }
47
48    #[inline]
49    pub fn len(&self) -> usize {
50        debug_assert!(self.slice.end >= self.slice.start);
51        debug_assert!(self.slice.end <= self.inner.len());
52        let len = self.slice.end - self.slice.start;
53        debug_assert_eq!(len,self[..].len());
54        len
55    }
56    #[inline]
57    pub fn is_empty(&self) -> bool {
58        debug_assert!(self.slice.end >= self.slice.start);
59        debug_assert!(self.slice.end <= self.inner.len());
60        self.slice.start == self.slice.end
61    }
62
63    /// whether this slice views the complete backing vec
64    #[inline]
65    pub fn is_unsliced(&self) -> bool {
66        self.slice.start == 0 && self.slice.end == self.inner.len()
67    }
68
69    /// Minimize memory usage.
70    /// This will only work for unique ArcSlices and then would reallocate and move the contents.
71    pub fn compact(&mut self) -> bool {
72        if let Some(e) = Arc::get_mut(&mut self.inner) {
73            if self.slice.start == 0 {
74                e.truncate(self.slice.end);
75                e.shrink_to_fit();
76            }else{
77                let mut dest = Vec::new();
78                dest.reserve_exact(e.len());
79                dest.append(e);
80                assert_eq!(dest.capacity(),dest.len());
81                self.slice = 0..dest.len();
82                *e = dest;
83            }
84            true
85        }else{
86            false
87        }
88    }
89
90    #[inline]
91    pub fn truncate(&mut self, len: usize) {
92        if len == 0 {
93            self.slice = 0..0;
94        }else{
95            self.slice.end = self.len().min(self.slice.start + len);
96        }
97    }
98
99    pub fn swap_remove(&mut self, index: usize) -> T where T: Clone {
100        assert!(index < self.len(),"swap_remove out of bounds");
101        if index == self.len()-1 {
102            self.remove(index)
103        }else if let Some(e) = Arc::get_mut(&mut self.inner) {
104            e.truncate(self.slice.end);
105            self.slice.end -= 1;
106            e.swap_remove(self.slice.start + index)
107        }else{
108            let origin = &self[..];
109            let mut dest = Vec::with_capacity(self.len()-1);
110            let left = &origin[..index];
111            dest.extend_from_slice(left);
112            let removed = origin[index].clone();
113            let right = &origin[(index+1)..(origin.len()-1)];
114            let end = origin.last().unwrap().clone();
115            dest.push(end);
116            dest.extend_from_slice(right);
117            *self = Self::from(dest);
118            removed
119        }
120    }
121
122    pub fn remove(&mut self, index: usize) -> T where T: Clone {
123        assert!(index < self.len(),"remove out of bounds");
124        if let Some(e) = Arc::get_mut(&mut self.inner) {
125            e.truncate(self.slice.end);
126            self.slice.end -= 1;
127            e.remove(self.slice.start + index)
128        }else{
129            let origin = &self[..];
130            let mut dest = Vec::with_capacity(self.len()-1);
131            let left = &origin[..index];
132            dest.extend_from_slice(left);
133            let removed = origin[index].clone();
134            let right = &origin[(index+1)..];
135            dest.extend_from_slice(right);
136            *self = Self::from(dest);
137            removed
138        }
139    }
140
141    pub fn retain<F>(&mut self, mut f: F) where T: Clone, F: FnMut(&T) -> bool {
142        if let Some(e) = Arc::get_mut(&mut self.inner) {
143            e.truncate(self.slice.end);
144            e.retain(f);
145            self.slice.end = self.slice.start + e.len();
146        }else{
147            let origin = &self[..];
148            let mut dest = Vec::with_capacity(self.len());
149            for v in origin {
150                if f(v) {
151                    dest.push(v.clone());
152                }
153            }
154            *self = Self::from(dest);
155        }
156    }
157
158    pub fn insert(&mut self, index: usize, element: T) where T: Clone {
159        assert!(index <= self.len(),"insert out of bounds");
160        if let Some(e) = Arc::get_mut(&mut self.inner) {
161            e.truncate(self.slice.end);
162            e.insert(self.slice.start + index, element);
163            self.slice.end += 1;
164        }else{
165            let origin = &self[..];
166            let mut dest = Vec::with_capacity(self.len()+1);
167            let (left,right) = origin.split_at(index);
168            dest.extend_from_slice(left);
169            dest.push(element);
170            dest.extend_from_slice(right);
171            *self = Self::from(dest);
172        }
173    }
174
175    pub fn insert_slice(&mut self, index: usize, s: &[T]) where T: Clone {
176        assert!(index <= self.len(),"insert out of bounds");
177        if s.is_empty() {return;}
178        if let Some(e) = Arc::get_mut(&mut self.inner) {
179            e.truncate(self.slice.end);
180            e.insert_slice_clone(self.slice.start + index, s);
181            self.slice.end += s.len();
182        }else{
183            let origin = &self[..];
184            let mut dest = Vec::with_capacity(self.len()+s.len());
185            let (left,right) = origin.split_at(index);
186            dest.extend_from_slice(left);
187            dest.extend_from_slice(s);
188            dest.extend_from_slice(right);
189            *self = Self::from(dest);
190        }
191    }
192
193    #[inline]
194    pub fn split_at(&mut self, at: usize) -> (Self,Self) {
195        assert!(at <= self.len(), "`at` out of bounds");
196        let start = self.slice(..at);
197        let end = self.slice(at..);
198        (start,end)
199    }
200    #[inline]
201    pub fn split_off(&mut self, at: usize) -> Self {
202        let (start,end) = self.split_at(at);
203        *self = start;
204        end
205    }
206
207    pub fn resize_with<F>(&mut self, new_len: usize, mut f: F) where T: Clone, F: FnMut() -> T {
208        if new_len > self.len() {
209            let (vec,slice) = self._make_mut_with_capacity(self.len() + 1);
210            vec.truncate(slice.end);
211            vec.reserve( (slice.start+new_len).saturating_sub(vec.capacity()) );
212            for _ in slice.len()..new_len {
213                vec.push(f());
214            }
215            self.slice.end = slice.start + new_len;
216        } else {
217            self.truncate(new_len);
218        }
219    }
220    pub fn resize<F>(&mut self, new_len: usize, value: T) where T: Clone {
221        self.resize_with(new_len, move || value.clone() )
222    }
223    pub fn resize_default<F>(&mut self, new_len: usize) where T: Clone + Default {
224        self.resize_with(new_len, || T::default() )
225    }
226
227    pub fn push(&mut self, v: T) where T: Clone {
228        self.insert(self.len(), v)
229    }
230    pub fn pop(&mut self) -> Option<T> where T: Clone {
231        (self.slice.end > self.slice.start)
232            .map(|| {
233                self.remove(self.len()-1)
234            })
235    }
236
237    pub fn append(&mut self, other: &mut Vec<T>) where T: Clone {
238        if !other.is_empty() {
239            let other_len = other.len();
240            let (vec,slice) = self._make_mut_with_capacity(self.len() + other_len);
241            vec.truncate(slice.end);
242            vec.append(other);
243            self.slice.end += other_len;
244        }
245    }
246    pub fn extend_from_slice(&mut self, other: &[T]) where T: Clone {
247        if !other.is_empty() {
248            let other_len = other.len();
249            let (vec,slice) = self._make_mut_with_capacity(self.len() + other_len);
250            vec.truncate(slice.end);
251            vec.extend_from_slice(other);
252            self.slice.end += other_len;
253        }
254    }
255
256    #[inline]
257    pub fn clear(&mut self) {
258        self.truncate(0);
259    }
260
261    /// mutably access the mutable Vec inside
262    /// Note that self.slice will eventually mutate
263    pub fn _make_mut(&mut self) -> (&mut Vec<T>,&mut Range<usize>) where T: Clone {
264        self._make_mut_with_capacity(self.len())
265    }
266    pub fn _make_mut_with_capacity(&mut self, capacity: usize) -> (&mut Vec<T>,&mut Range<usize>) where T: Clone {
267        if Arc::get_mut(&mut self.inner).is_some() {
268            // In this case Arc::make_mut probably won't clone TODO fix if polonius
269            (Arc::make_mut(&mut self.inner),&mut self.slice)
270        }else{
271            // use optimized clone in which case Arc::make_mut would probably clone
272            *self = self.extracted_with_capacity(capacity);
273            Arc::make_mut(&mut self.inner);
274            assert!(self.is_unsliced());
275            self._make_mut_with_capacity(capacity)
276        }
277    }
278    pub fn _make_mut_extracted(&mut self) -> &mut Vec<T> where T: Clone {
279        self._make_mut_extracted_with_capacity(self.len())
280    }
281    pub fn _make_mut_extracted_with_capacity(&mut self, capacity: usize) -> &mut Vec<T> where T: Clone {
282        *self = self.extracted_with_capacity(capacity);
283        assert!(self.is_unsliced());
284        self._make_mut_with_capacity(capacity).0
285    }
286}
287
288impl<T> Default for ArcSlice<T> {
289    fn default() -> Self {
290        Self::new()
291    }
292}
293
294impl<T> From<Vec<T>> for ArcSlice<T> {
295    fn from(v: Vec<T>) -> Self {
296        Self::from(Arc::new(v))
297    }
298}
299impl<T> From<Arc<Vec<T>>> for ArcSlice<T> {
300    fn from(v: Arc<Vec<T>>) -> Self {
301        Self{
302            slice: 0..v.len(),
303            inner: v,
304        }
305    }
306}
307
308#[inline]
309fn slice_slice<S>(range: &Range<usize>, slice: S) -> Range<usize> where S: RangeBounds<usize> {
310    let (os,oe) = (range.start,range.end);
311    let (mut s,mut e) = (os,oe);
312    match slice.end_bound() {
313        std::ops::Bound::Included(&b) => e = oe.min(b+1+os),
314        std::ops::Bound::Excluded(&b) => e = oe.min(b+os),
315        std::ops::Bound::Unbounded => (),
316    }
317    match slice.start_bound() {
318        std::ops::Bound::Included(&b) => s = os.max(b+os),
319        std::ops::Bound::Excluded(&b) => s = os.max(b-1+os),
320        std::ops::Bound::Unbounded => (),
321    }
322    assert!(s >= os && s <= oe && e >= os && e <= oe && e >= s, "Inner slice out of bounds");
323    s..e
324}
325
326#[test]
327fn ultrion() {
328    let mut a = ArcSlice::from(&b"abcd"[..]);
329    assert_eq!(a,&b"abcd"[..]);
330    assert_eq!(&a[..],&b"abcd"[..]);
331    assert_eq!(&a[2..],&b"cd"[..]);
332    assert_eq!(&a[1..3],&b"bc"[..]);
333    assert_eq!(&a[2..2],&b""[..]);
334
335    a.extend_from_slice(&b"gh"[..]);
336    a.insert_slice(4, &b"ef"[..]);
337    assert_eq!(&a[..],&b"abcdefgh"[..]);
338
339    let mut b = a.slice(2..4);
340    assert_eq!(&b[..],&b"cd"[..]);
341    b.extend_from_slice(&b"io"[..]);
342    assert_eq!(&b[..],&b"cdio"[..]);
343
344    assert_eq!(&a[..],&b"abcdefgh"[..]);
345
346    a.remove(2);
347    assert_eq!(&a[..],&b"abdefgh"[..]);
348    a.swap_remove(2);
349    assert_eq!(&a[..],&b"abhefg"[..]);
350
351    let mut c = a.refc();
352    c.push(b'f');
353    c.retain(|&c| c == b'h' || c == b'f' );
354    assert_eq!(&c[..],&b"hff"[..]);
355    assert_eq!(&a[..],&b"abhefg"[..]);
356    
357    a.pop();
358    assert_eq!(&a[..],&b"abhef"[..]);
359}