rustpython_common/
boxvec.rs

1//! An unresizable vector backed by a `Box<[T]>`
2
3use std::{
4    alloc,
5    borrow::{Borrow, BorrowMut},
6    cmp, fmt,
7    mem::{self, MaybeUninit},
8    ops::{Bound, Deref, DerefMut, RangeBounds},
9    ptr, slice,
10};
11
12pub struct BoxVec<T> {
13    xs: Box<[MaybeUninit<T>]>,
14    len: usize,
15}
16
17impl<T> Drop for BoxVec<T> {
18    fn drop(&mut self) {
19        self.clear();
20
21        // MaybeUninit inhibits array's drop
22    }
23}
24
25macro_rules! panic_oob {
26    ($method_name:expr, $index:expr, $len:expr) => {
27        panic!(
28            concat!(
29                "BoxVec::",
30                $method_name,
31                ": index {} is out of bounds in vector of length {}"
32            ),
33            $index, $len
34        )
35    };
36}
37
38fn capacity_overflow() -> ! {
39    panic!("capacity overflow")
40}
41
42impl<T> BoxVec<T> {
43    pub fn new(n: usize) -> BoxVec<T> {
44        unsafe {
45            let layout = match alloc::Layout::array::<T>(n) {
46                Ok(l) => l,
47                Err(_) => capacity_overflow(),
48            };
49            let ptr = if mem::size_of::<T>() == 0 {
50                ptr::NonNull::<MaybeUninit<T>>::dangling().as_ptr()
51            } else {
52                let ptr = alloc::alloc(layout);
53                if ptr.is_null() {
54                    alloc::handle_alloc_error(layout)
55                }
56                ptr as *mut MaybeUninit<T>
57            };
58            let ptr = ptr::slice_from_raw_parts_mut(ptr, n);
59            let xs = Box::from_raw(ptr);
60            BoxVec { xs, len: 0 }
61        }
62    }
63
64    #[inline]
65    pub fn len(&self) -> usize {
66        self.len
67    }
68
69    #[inline]
70    pub fn is_empty(&self) -> bool {
71        self.len() == 0
72    }
73
74    #[inline]
75    pub fn capacity(&self) -> usize {
76        self.xs.len()
77    }
78
79    pub fn is_full(&self) -> bool {
80        self.len() == self.capacity()
81    }
82
83    pub fn remaining_capacity(&self) -> usize {
84        self.capacity() - self.len()
85    }
86
87    pub fn push(&mut self, element: T) {
88        self.try_push(element).unwrap()
89    }
90
91    pub fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> {
92        if self.len() < self.capacity() {
93            unsafe {
94                self.push_unchecked(element);
95            }
96            Ok(())
97        } else {
98            Err(CapacityError::new(element))
99        }
100    }
101
102    /// # Safety
103    /// Must ensure that self.len() < self.capacity()
104    pub unsafe fn push_unchecked(&mut self, element: T) {
105        let len = self.len();
106        debug_assert!(len < self.capacity());
107        ptr::write(self.get_unchecked_ptr(len), element);
108        self.set_len(len + 1);
109    }
110
111    /// Get pointer to where element at `index` would be
112    unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T {
113        self.xs.as_mut_ptr().add(index).cast()
114    }
115
116    pub fn insert(&mut self, index: usize, element: T) {
117        self.try_insert(index, element).unwrap()
118    }
119
120    pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), CapacityError<T>> {
121        if index > self.len() {
122            panic_oob!("try_insert", index, self.len())
123        }
124        if self.len() == self.capacity() {
125            return Err(CapacityError::new(element));
126        }
127        let len = self.len();
128
129        // follows is just like Vec<T>
130        unsafe {
131            // infallible
132            // The spot to put the new value
133            {
134                let p: *mut _ = self.get_unchecked_ptr(index);
135                // Shift everything over to make space. (Duplicating the
136                // `index`th element into two consecutive places.)
137                ptr::copy(p, p.offset(1), len - index);
138                // Write it in, overwriting the first copy of the `index`th
139                // element.
140                ptr::write(p, element);
141            }
142            self.set_len(len + 1);
143        }
144        Ok(())
145    }
146
147    pub fn pop(&mut self) -> Option<T> {
148        if self.is_empty() {
149            return None;
150        }
151        unsafe {
152            let new_len = self.len() - 1;
153            self.set_len(new_len);
154            Some(ptr::read(self.get_unchecked_ptr(new_len)))
155        }
156    }
157
158    pub fn swap_remove(&mut self, index: usize) -> T {
159        self.swap_pop(index)
160            .unwrap_or_else(|| panic_oob!("swap_remove", index, self.len()))
161    }
162
163    pub fn swap_pop(&mut self, index: usize) -> Option<T> {
164        let len = self.len();
165        if index >= len {
166            return None;
167        }
168        self.swap(index, len - 1);
169        self.pop()
170    }
171
172    pub fn remove(&mut self, index: usize) -> T {
173        self.pop_at(index)
174            .unwrap_or_else(|| panic_oob!("remove", index, self.len()))
175    }
176
177    pub fn pop_at(&mut self, index: usize) -> Option<T> {
178        if index >= self.len() {
179            None
180        } else {
181            self.drain(index..index + 1).next()
182        }
183    }
184
185    pub fn truncate(&mut self, new_len: usize) {
186        unsafe {
187            if new_len < self.len() {
188                let tail: *mut [_] = &mut self[new_len..];
189                self.len = new_len;
190                ptr::drop_in_place(tail);
191            }
192        }
193    }
194
195    /// Remove all elements in the vector.
196    pub fn clear(&mut self) {
197        self.truncate(0)
198    }
199
200    /// Retains only the elements specified by the predicate.
201    ///
202    /// In other words, remove all elements `e` such that `f(&mut e)` returns false.
203    /// This method operates in place and preserves the order of the retained
204    /// elements.
205    pub fn retain<F>(&mut self, mut f: F)
206    where
207        F: FnMut(&mut T) -> bool,
208    {
209        let len = self.len();
210        let mut del = 0;
211        {
212            let v = &mut **self;
213
214            for i in 0..len {
215                if !f(&mut v[i]) {
216                    del += 1;
217                } else if del > 0 {
218                    v.swap(i - del, i);
219                }
220            }
221        }
222        if del > 0 {
223            self.drain(len - del..);
224        }
225    }
226
227    /// Set the vector’s length without dropping or moving out elements
228    ///
229    /// This method is `unsafe` because it changes the notion of the
230    /// number of “valid” elements in the vector. Use with care.
231    ///
232    /// This method uses *debug assertions* to check that `length` is
233    /// not greater than the capacity.
234    ///
235    /// # Safety
236    /// Must ensure that length <= self.capacity()
237    pub unsafe fn set_len(&mut self, length: usize) {
238        debug_assert!(length <= self.capacity());
239        self.len = length;
240    }
241
242    /// Copy and appends all elements in a slice to the `BoxVec`.
243    ///
244    /// # Errors
245    ///
246    /// This method will return an error if the capacity left (see
247    /// [`remaining_capacity`]) is smaller then the length of the provided
248    /// slice.
249    ///
250    /// [`remaining_capacity`]: #method.remaining_capacity
251    pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
252    where
253        T: Copy,
254    {
255        if self.remaining_capacity() < other.len() {
256            return Err(CapacityError::new(()));
257        }
258
259        let self_len = self.len();
260        let other_len = other.len();
261
262        unsafe {
263            let dst = self.as_mut_ptr().add(self_len);
264            ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len);
265            self.set_len(self_len + other_len);
266        }
267        Ok(())
268    }
269
270    /// Create a draining iterator that removes the specified range in the vector
271    /// and yields the removed items from start to end. The element range is
272    /// removed even if the iterator is not consumed until the end.
273    ///
274    /// Note: It is unspecified how many elements are removed from the vector,
275    /// if the `Drain` value is leaked.
276    ///
277    /// **Panics** if the starting point is greater than the end point or if
278    /// the end point is greater than the length of the vector.
279    pub fn drain<R>(&mut self, range: R) -> Drain<T>
280    where
281        R: RangeBounds<usize>,
282    {
283        // Memory safety
284        //
285        // When the Drain is first created, it shortens the length of
286        // the source vector to make sure no uninitialized or moved-from elements
287        // are accessible at all if the Drain's destructor never gets to run.
288        //
289        // Drain will ptr::read out the values to remove.
290        // When finished, remaining tail of the vec is copied back to cover
291        // the hole, and the vector length is restored to the new length.
292        //
293        let len = self.len();
294        let start = match range.start_bound() {
295            Bound::Unbounded => 0,
296            Bound::Included(&i) => i,
297            Bound::Excluded(&i) => i.saturating_add(1),
298        };
299        let end = match range.end_bound() {
300            Bound::Excluded(&j) => j,
301            Bound::Included(&j) => j.saturating_add(1),
302            Bound::Unbounded => len,
303        };
304        self.drain_range(start, end)
305    }
306
307    fn drain_range(&mut self, start: usize, end: usize) -> Drain<T> {
308        let len = self.len();
309
310        // bounds check happens here (before length is changed!)
311        let range_slice: *const _ = &self[start..end];
312
313        // Calling `set_len` creates a fresh and thus unique mutable references, making all
314        // older aliases we created invalid. So we cannot call that function.
315        self.len = start;
316
317        unsafe {
318            Drain {
319                tail_start: end,
320                tail_len: len - end,
321                iter: (*range_slice).iter(),
322                vec: ptr::NonNull::from(self),
323            }
324        }
325    }
326
327    /// Return a slice containing all elements of the vector.
328    pub fn as_slice(&self) -> &[T] {
329        self
330    }
331
332    /// Return a mutable slice containing all elements of the vector.
333    pub fn as_mut_slice(&mut self) -> &mut [T] {
334        self
335    }
336
337    /// Return a raw pointer to the vector's buffer.
338    #[inline]
339    pub fn as_ptr(&self) -> *const T {
340        self.xs.as_ptr().cast()
341    }
342
343    /// Return a raw mutable pointer to the vector's buffer.
344    #[inline]
345    pub fn as_mut_ptr(&mut self) -> *mut T {
346        self.xs.as_mut_ptr().cast()
347    }
348}
349
350impl<T> Deref for BoxVec<T> {
351    type Target = [T];
352    #[inline]
353    fn deref(&self) -> &[T] {
354        unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
355    }
356}
357
358impl<T> DerefMut for BoxVec<T> {
359    #[inline]
360    fn deref_mut(&mut self) -> &mut [T] {
361        let len = self.len();
362        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), len) }
363    }
364}
365
366/// Iterate the `BoxVec` with references to each element.
367impl<'a, T> IntoIterator for &'a BoxVec<T> {
368    type Item = &'a T;
369    type IntoIter = slice::Iter<'a, T>;
370    fn into_iter(self) -> Self::IntoIter {
371        self.iter()
372    }
373}
374
375/// Iterate the `BoxVec` with mutable references to each element.
376impl<'a, T> IntoIterator for &'a mut BoxVec<T> {
377    type Item = &'a mut T;
378    type IntoIter = slice::IterMut<'a, T>;
379    fn into_iter(self) -> Self::IntoIter {
380        self.iter_mut()
381    }
382}
383
384/// Iterate the `BoxVec` with each element by value.
385///
386/// The vector is consumed by this operation.
387impl<T> IntoIterator for BoxVec<T> {
388    type Item = T;
389    type IntoIter = IntoIter<T>;
390    fn into_iter(self) -> IntoIter<T> {
391        IntoIter { index: 0, v: self }
392    }
393}
394
395/// By-value iterator for `BoxVec`.
396pub struct IntoIter<T> {
397    index: usize,
398    v: BoxVec<T>,
399}
400
401impl<T> Iterator for IntoIter<T> {
402    type Item = T;
403
404    fn next(&mut self) -> Option<T> {
405        if self.index == self.v.len {
406            None
407        } else {
408            unsafe {
409                let index = self.index;
410                self.index += 1;
411                Some(ptr::read(self.v.get_unchecked_ptr(index)))
412            }
413        }
414    }
415
416    fn size_hint(&self) -> (usize, Option<usize>) {
417        let len = self.v.len() - self.index;
418        (len, Some(len))
419    }
420}
421
422impl<T> DoubleEndedIterator for IntoIter<T> {
423    fn next_back(&mut self) -> Option<T> {
424        if self.index == self.v.len {
425            None
426        } else {
427            unsafe {
428                let new_len = self.v.len() - 1;
429                self.v.set_len(new_len);
430                Some(ptr::read(self.v.get_unchecked_ptr(new_len)))
431            }
432        }
433    }
434}
435
436impl<T> ExactSizeIterator for IntoIter<T> {}
437
438impl<T> Drop for IntoIter<T> {
439    fn drop(&mut self) {
440        // panic safety: Set length to 0 before dropping elements.
441        let index = self.index;
442        let len = self.v.len();
443        unsafe {
444            self.v.set_len(0);
445            let elements = slice::from_raw_parts_mut(self.v.get_unchecked_ptr(index), len - index);
446            ptr::drop_in_place(elements);
447        }
448    }
449}
450
451impl<T> fmt::Debug for IntoIter<T>
452where
453    T: fmt::Debug,
454{
455    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
456        f.debug_list().entries(&self.v[self.index..]).finish()
457    }
458}
459
460/// A draining iterator for `BoxVec`.
461pub struct Drain<'a, T> {
462    /// Index of tail to preserve
463    tail_start: usize,
464    /// Length of tail
465    tail_len: usize,
466    /// Current remaining range to remove
467    iter: slice::Iter<'a, T>,
468    vec: ptr::NonNull<BoxVec<T>>,
469}
470
471unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
472unsafe impl<'a, T: Sync> Send for Drain<'a, T> {}
473
474impl<T> Iterator for Drain<'_, T> {
475    type Item = T;
476
477    fn next(&mut self) -> Option<Self::Item> {
478        self.iter
479            .next()
480            .map(|elt| unsafe { ptr::read(elt as *const _) })
481    }
482
483    fn size_hint(&self) -> (usize, Option<usize>) {
484        self.iter.size_hint()
485    }
486}
487
488impl<T> DoubleEndedIterator for Drain<'_, T> {
489    fn next_back(&mut self) -> Option<Self::Item> {
490        self.iter
491            .next_back()
492            .map(|elt| unsafe { ptr::read(elt as *const _) })
493    }
494}
495
496impl<T> ExactSizeIterator for Drain<'_, T> {}
497
498impl<'a, T> Drain<'a, T> {
499    pub fn as_slice(&self) -> &'a [T] {
500        self.iter.as_slice()
501    }
502}
503
504impl<T> Drop for Drain<'_, T> {
505    fn drop(&mut self) {
506        // len is currently 0 so panicking while dropping will not cause a double drop.
507
508        for _ in self.by_ref() {}
509
510        if self.tail_len > 0 {
511            unsafe {
512                let source_vec = self.vec.as_mut();
513                // memmove back untouched tail, update to new length
514                let start = source_vec.len();
515                let tail = self.tail_start;
516                let src = source_vec.as_ptr().add(tail);
517                let dst = source_vec.as_mut_ptr().add(start);
518                ptr::copy(src, dst, self.tail_len);
519                source_vec.set_len(start + self.tail_len);
520            }
521        }
522    }
523}
524
525struct ScopeExitGuard<T, Data, F>
526where
527    F: FnMut(&Data, &mut T),
528{
529    value: T,
530    data: Data,
531    f: F,
532}
533
534impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F>
535where
536    F: FnMut(&Data, &mut T),
537{
538    fn drop(&mut self) {
539        (self.f)(&self.data, &mut self.value)
540    }
541}
542
543/// Extend the `BoxVec` with an iterator.
544///
545/// Does not extract more items than there is space for. No error
546/// occurs if there are more iterator elements.
547impl<T> Extend<T> for BoxVec<T> {
548    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
549        let take = self.capacity() - self.len();
550        unsafe {
551            let len = self.len();
552            let mut ptr = raw_ptr_add(self.as_mut_ptr(), len);
553            let end_ptr = raw_ptr_add(ptr, take);
554            // Keep the length in a separate variable, write it back on scope
555            // exit. To help the compiler with alias analysis and stuff.
556            // We update the length to handle panic in the iteration of the
557            // user's iterator, without dropping any elements on the floor.
558            let mut guard = ScopeExitGuard {
559                value: &mut self.len,
560                data: len,
561                f: move |&len, self_len| {
562                    **self_len = len;
563                },
564            };
565            let mut iter = iter.into_iter();
566            loop {
567                if ptr == end_ptr {
568                    break;
569                }
570                if let Some(elt) = iter.next() {
571                    raw_ptr_write(ptr, elt);
572                    ptr = raw_ptr_add(ptr, 1);
573                    guard.data += 1;
574                } else {
575                    break;
576                }
577            }
578        }
579    }
580}
581
582/// Rawptr add but uses arithmetic distance for ZST
583unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
584    if mem::size_of::<T>() == 0 {
585        // Special case for ZST
586        (ptr as usize).wrapping_add(offset) as _
587    } else {
588        ptr.add(offset)
589    }
590}
591
592unsafe fn raw_ptr_write<T>(ptr: *mut T, value: T) {
593    if mem::size_of::<T>() == 0 {
594        /* nothing */
595    } else {
596        ptr::write(ptr, value)
597    }
598}
599
600impl<T> Clone for BoxVec<T>
601where
602    T: Clone,
603{
604    fn clone(&self) -> Self {
605        let mut new = BoxVec::new(self.capacity());
606        new.extend(self.iter().cloned());
607        new
608    }
609
610    fn clone_from(&mut self, rhs: &Self) {
611        // recursive case for the common prefix
612        let prefix = cmp::min(self.len(), rhs.len());
613        self[..prefix].clone_from_slice(&rhs[..prefix]);
614
615        if prefix < self.len() {
616            // rhs was shorter
617            for _ in 0..self.len() - prefix {
618                self.pop();
619            }
620        } else {
621            let rhs_elems = rhs[self.len()..].iter().cloned();
622            self.extend(rhs_elems);
623        }
624    }
625}
626
627impl<T> PartialEq for BoxVec<T>
628where
629    T: PartialEq,
630{
631    fn eq(&self, other: &Self) -> bool {
632        **self == **other
633    }
634}
635
636impl<T> PartialEq<[T]> for BoxVec<T>
637where
638    T: PartialEq,
639{
640    fn eq(&self, other: &[T]) -> bool {
641        **self == *other
642    }
643}
644
645impl<T> Eq for BoxVec<T> where T: Eq {}
646
647impl<T> Borrow<[T]> for BoxVec<T> {
648    fn borrow(&self) -> &[T] {
649        self
650    }
651}
652
653impl<T> BorrowMut<[T]> for BoxVec<T> {
654    fn borrow_mut(&mut self) -> &mut [T] {
655        self
656    }
657}
658
659impl<T> AsRef<[T]> for BoxVec<T> {
660    fn as_ref(&self) -> &[T] {
661        self
662    }
663}
664
665impl<T> AsMut<[T]> for BoxVec<T> {
666    fn as_mut(&mut self) -> &mut [T] {
667        self
668    }
669}
670
671impl<T> fmt::Debug for BoxVec<T>
672where
673    T: fmt::Debug,
674{
675    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
676        (**self).fmt(f)
677    }
678}
679
680/// Error value indicating insufficient capacity
681#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
682pub struct CapacityError<T = ()> {
683    element: T,
684}
685
686impl<T> CapacityError<T> {
687    /// Create a new `CapacityError` from `element`.
688    pub fn new(element: T) -> CapacityError<T> {
689        CapacityError { element }
690    }
691
692    /// Extract the overflowing element
693    pub fn element(self) -> T {
694        self.element
695    }
696
697    /// Convert into a `CapacityError` that does not carry an element.
698    pub fn simplify(self) -> CapacityError {
699        CapacityError { element: () }
700    }
701}
702
703const CAPERROR: &str = "insufficient capacity";
704
705impl<T> std::error::Error for CapacityError<T> {}
706
707impl<T> fmt::Display for CapacityError<T> {
708    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
709        write!(f, "{CAPERROR}")
710    }
711}
712
713impl<T> fmt::Debug for CapacityError<T> {
714    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
715        write!(f, "capacity error: {CAPERROR}")
716    }
717}