Skip to main content

rustpython_common/
boxvec.rs

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