stack_array/
interface.rs

1use crate::{drain::slice_range, *};
2
3pub trait Array<T>: AsRef<[T]> + AsMut<[T]> + Default {
4    /// Returns the number of elements the array can hold.
5    ///
6    /// # Examples
7    ///
8    /// ```
9    /// use stack_array::*;
10    ///
11    /// let arr: ArrayBuf<u8, 4> = ArrayBuf::new();
12    /// assert_eq!(arr.capacity(), 4);
13    /// ```
14    fn capacity(&self) -> usize;
15
16    /// Shortens the array, keeping the first `len` elements and dropping
17    /// the rest.
18    ///
19    /// If `len` is greater than the array's current length, this has no
20    /// effect.
21    #[inline]
22    fn truncate(&mut self, len: usize) {
23        // This is safe because:
24        //
25        // * the slice passed to `drop_in_place` is valid; the `len > self.len`
26        //   case avoids creating an invalid slice, and
27        // * the `len` of the array is shrunk before calling `drop_in_place`,
28        //   such that no value will be dropped twice in case `drop_in_place`
29        //   were to panic once (if it panics twice, the program aborts).
30        unsafe {
31            // Note: It's intentional that this is `>` and not `>=`.
32            //       Changing it to `>=` has negative performance
33            //       implications in some cases. See #78884 for more.
34            if len > self.len() {
35                return;
36            }
37            let remaining_len = self.len() - len;
38            let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
39            self.set_len(len);
40            ptr::drop_in_place(s);
41        }
42    }
43
44    /// Returns a raw pointer to the array's buffer.
45    ///
46    /// The caller must ensure that the array outlives the pointer this
47    /// function returns, or else it will end up pointing to garbage.
48    /// Modifying the array may cause its buffer to be reallocated,
49    /// which would also make any pointers to it invalid.
50    ///
51    /// The caller must also ensure that the memory the pointer (non-transitively) points to
52    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
53    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
54    ///
55    /// [`as_mut_ptr`]: Array::as_mut_ptr
56    fn as_ptr(&self) -> *const T;
57
58    /// Returns an unsafe mutable pointer to the array's buffer.
59    ///
60    /// The caller must ensure that the array outlives the pointer this
61    /// function returns, or else it will end up pointing to garbage.
62    /// Modifying the array may cause its buffer to be reallocated,
63    /// which would also make any pointers to it invalid.
64    fn as_mut_ptr(&mut self) -> *mut T;
65
66    /// Forces the length of the array to `new_len`.
67    ///
68    /// This is a low-level operation that maintains none of the normal
69    /// invariants of the type. Normally changing the length of a array
70    /// is done using one of the safe operations instead, such as
71    /// [`truncate`] or [`clear`].
72    ///
73    /// [`truncate`]: Array::truncate
74    /// [`clear`]: Array::clear
75    ///
76    /// # Safety
77    ///
78    /// - `new_len` must be less than or equal to [`capacity()`].
79    /// - The elements at `old_len..new_len` must be initialized.
80    ///
81    /// [`capacity()`]: Vec::capacity
82    unsafe fn set_len(&mut self, len: usize);
83
84    /// Extracts a slice containing the entire array.
85    ///
86    /// Equivalent to `&s[..]`.
87    #[inline]
88    fn as_slice(&self) -> &[T] {
89        // SAFETY: slice will contain only initialized objects.
90        unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
91    }
92
93    /// Extracts a mutable slice of the entire array.
94    ///
95    /// Equivalent to `&mut s[..]`.
96    #[inline]
97    fn as_mut_slice(&mut self) -> &mut [T] {
98        // SAFETY: slice will contain only initialized objects.
99        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
100    }
101
102    /// Removes an element from the array and returns it.
103    ///
104    /// The removed element is replaced by the last element of the array.
105    ///
106    /// This does not preserve ordering, but is *O*(1).
107    /// If you need to preserve the element order, use [`remove`] instead.
108    ///
109    /// [`remove`]: Array::remove
110    ///
111    /// # Panics
112    ///
113    /// Panics if `index` is out of bounds.
114    ///
115    /// # Examples
116    ///
117    /// ```
118    /// use stack_array::*;
119    ///
120    /// let mut arr = ArrayBuf::from(["foo", "bar", "baz", "qux"]);
121    ///
122    /// assert_eq!(arr.swap_remove(1), "bar");
123    /// assert_eq!(arr[..], ["foo", "qux", "baz"]);
124    ///
125    /// assert_eq!(arr.swap_remove(0), "foo");
126    /// assert_eq!(arr[..], ["baz", "qux"]);
127    /// ```
128    #[inline]
129    fn swap_remove(&mut self, index: usize) -> T {
130        #[cold]
131        #[inline(never)]
132        fn assert_failed(index: usize, len: usize) -> ! {
133            panic!(
134                "swap_remove index (is {}) should be < len (is {})",
135                index, len
136            );
137        }
138
139        let len = self.len();
140        if index >= len {
141            assert_failed(index, len);
142        }
143        unsafe {
144            // We replace self[index] with the last element. Note that if the
145            // bounds check above succeeds there must be a last element (which
146            // can be self[index] itself).
147            let value = ptr::read(self.as_ptr().add(index));
148            let base_ptr = self.as_mut_ptr();
149            ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1);
150            self.set_len(len - 1);
151            value
152        }
153    }
154
155    /// Inserts an element at position index within the array, shifting all elements after it to the right.
156    /// # Examples
157    ///
158    /// ```
159    /// use stack_array::*;
160    ///
161    /// let mut list: ArrayBuf<u8, 3> = ArrayBuf::from([3].as_ref());
162    /// list.insert(0, 1);
163    /// assert_eq!(&list[..], [1, 3]);
164    /// list.insert(1, 2);
165    /// assert_eq!(&list, &[1, 2, 3]);
166    /// ```
167    ///
168    /// # Panics
169    /// Panics if the index is out of bounds.
170    #[inline]
171    fn insert(&mut self, index: usize, element: T) {
172        #[cold]
173        #[inline(never)]
174        fn assert_failed(index: usize, len: usize) -> ! {
175            panic!(
176                "insertion index (is {}) should be <= len (is {})",
177                index, len
178            );
179        }
180
181        let len = self.len();
182        if index > len {
183            assert_failed(index, len);
184        }
185
186        // space for the new element
187        let total_len = len + 1;
188        self.ensure_capacity(total_len);
189
190        unsafe {
191            // infallible
192            // The spot to put the new value
193            {
194                let p = self.as_mut_ptr().add(index);
195                // Shift everything over to make space. (Duplicating the
196                // `index`th element into two consecutive places.)
197                ptr::copy(p, p.offset(1), len - index);
198                // Write it in, overwriting the first copy of the `index`th
199                // element.
200                ptr::write(p, element);
201            }
202            self.set_len(total_len);
203        }
204    }
205
206    /// Removes an element from position index within the array, shifting all elements after it to the left.
207    ///
208    /// Note: Because this shifts over the remaining elements, it has a
209    /// worst-case performance of *O*(*n*). If you don't need the order of elements
210    /// to be preserved, use [`swap_remove`] instead.
211    ///
212    /// [`swap_remove`]: Array::swap_remove
213    ///
214    /// # Examples
215    ///
216    /// ```
217    /// use stack_array::*;
218    ///
219    /// let mut list = ArrayBuf::from([1, 2, 3]);
220    /// assert_eq!(list.remove(0), 1);
221    /// assert_eq!(list.remove(0), 2);
222    /// assert_eq!(list.remove(0), 3);
223    /// ```
224    ///
225    /// # Panics
226    /// Panics if the index is out of bounds.
227    #[inline]
228    fn remove(&mut self, index: usize) -> T {
229        #[cold]
230        #[inline(never)]
231        #[track_caller]
232        fn assert_failed(index: usize, len: usize) -> ! {
233            panic!("removal index (is {}) should be < len (is {})", index, len);
234        }
235
236        let len = self.len();
237        if index >= len {
238            assert_failed(index, len);
239        }
240        unsafe {
241            // infallible
242            let ret;
243            {
244                // the place we are taking from.
245                let ptr = self.as_mut_ptr().add(index);
246                // copy it out, unsafely having a copy of the value on
247                // the stack and in the array at the same time.
248                ret = ptr::read(ptr);
249
250                // Shift everything down to fill in that spot.
251                ptr::copy(ptr.offset(1), ptr, len - index - 1);
252            }
253            self.set_len(len - 1);
254            ret
255        }
256    }
257
258    /// Retains only the elements specified by the predicate.
259    ///
260    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
261    /// This method operates in place, visiting each element exactly once in the
262    /// original order, and preserves the order of the retained elements.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use stack_array::*;
268    ///
269    /// let mut arr = ArrayBuf::from([1, 2, 3, 4]);
270    ///
271    /// arr.retain(|x| *x % 2 == 0);
272    /// assert_eq!(arr[..], [2, 4]);
273    /// ```
274    ///
275    /// Because the elements are visited exactly once in the original order,
276    /// external state may be used to decide which elements to keep.
277    ///
278    /// ```
279    /// use stack_array::*;
280    ///
281    /// let mut arr  = ArrayBuf::from([1, 2, 3, 4, 5]);
282    /// let keep = [false, true, true, false, true];
283    /// let mut iter = keep.iter();
284    /// arr.retain(|_| *iter.next().unwrap());
285    /// assert_eq!(arr[..], [2, 3, 5]);
286    /// ```
287    #[inline]
288    fn retain<F>(&mut self, mut f: F)
289    where
290        F: FnMut(&T) -> bool,
291    {
292        retain_mut(self, |elem| f(elem))
293    }
294
295    fn drain<R>(&mut self, range: R) -> Drain<'_, T, Self>
296    where
297        R: RangeBounds<usize>,
298    {
299        let len = self.len();
300        let Range { start, end } = slice_range(range, ..len);
301
302        unsafe {
303            // set self.vec length's to start, to be safe in case Drain is leaked
304            self.set_len(start);
305            // Use the borrow in the IterMut to indicate borrowing behavior of the
306            // whole Drain iterator (like &mut T).
307            let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start);
308            Drain {
309                tail_start: end,
310                tail_len: len - end,
311                iter: range_slice.iter(),
312                vec: ptr::NonNull::from(self),
313            }
314        }
315    }
316
317    #[inline]
318    fn dedup(&mut self)
319    where
320        T: PartialEq,
321    {
322        self.dedup_by(|a, b| a == b)
323    }
324
325    /// Removes all but the first of consecutive elements in the array that resolve to the same
326    /// key.
327    ///
328    /// If the array is sorted, this removes all duplicates.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use stack_array::*;
334    ///
335    /// let mut arr = ArrayBuf::from([10, 20, 21, 30, 20]);
336    ///
337    /// arr.dedup_by_key(|i| *i / 10);
338    ///
339    /// assert_eq!(arr[..], [10, 20, 30, 20]);
340    #[inline]
341    fn dedup_by_key<F, K>(&mut self, mut key: F)
342    where
343        F: FnMut(&mut T) -> K,
344        K: PartialEq,
345    {
346        self.dedup_by(|a, b| key(a) == key(b))
347    }
348
349    fn dedup_by<F>(&mut self, mut same_bucket: F)
350    where
351        F: FnMut(&mut T, &mut T) -> bool,
352    {
353        let len = self.len();
354        if len <= 1 {
355            return;
356        }
357
358        /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */
359        struct FillGapOnDrop<'a, T, A: Array<T>> {
360            /* Offset of the element we want to check if it is duplicate */
361            read: usize,
362
363            /* Offset of the place where we want to place the non-duplicate
364             * when we find it. */
365            write: usize,
366
367            /* The Vec that would need correction if `same_bucket` panicked */
368            vec: &'a mut A,
369            _marker: core::marker::PhantomData<T>,
370        }
371
372        impl<'a, T, A: Array<T>> Drop for FillGapOnDrop<'a, T, A> {
373            fn drop(&mut self) {
374                /* This code gets executed when `same_bucket` panics */
375
376                /* SAFETY: invariant guarantees that `read - write`
377                 * and `len - read` never overflow and that the copy is always
378                 * in-bounds. */
379                unsafe {
380                    let ptr = self.vec.as_mut_ptr();
381                    let len = self.vec.len();
382
383                    /* How many items were left when `same_bucket` panicked.
384                     * Basically vec[read..].len() */
385                    let items_left = len.wrapping_sub(self.read);
386
387                    /* Pointer to first item in vec[write..write+items_left] slice */
388                    let dropped_ptr = ptr.add(self.write);
389                    /* Pointer to first item in vec[read..] slice */
390                    let valid_ptr = ptr.add(self.read);
391
392                    /* Copy `vec[read..]` to `vec[write..write+items_left]`.
393                     * The slices can overlap, so `copy_nonoverlapping` cannot be used */
394                    ptr::copy(valid_ptr, dropped_ptr, items_left);
395
396                    /* How many items have been already dropped
397                     * Basically vec[read..write].len() */
398                    let dropped = self.read.wrapping_sub(self.write);
399
400                    self.vec.set_len(len - dropped);
401                }
402            }
403        }
404
405        let mut gap = FillGapOnDrop {
406            read: 1,
407            write: 1,
408            vec: self,
409            _marker: core::marker::PhantomData,
410        };
411        let ptr = gap.vec.as_mut_ptr();
412
413        /* Drop items while going through Vec, it should be more efficient than
414         * doing slice partition_dedup + truncate */
415
416        /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr
417         * are always in-bounds and read_ptr never aliases prev_ptr */
418        unsafe {
419            while gap.read < len {
420                let read_ptr = ptr.add(gap.read);
421                let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
422
423                if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
424                    // Increase `gap.read` now since the drop may panic.
425                    gap.read += 1;
426                    /* We have found duplicate, drop it in-place */
427                    ptr::drop_in_place(read_ptr);
428                } else {
429                    let write_ptr = ptr.add(gap.write);
430
431                    /* Because `read_ptr` can be equal to `write_ptr`, we either
432                     * have to use `copy` or conditional `copy_nonoverlapping`.
433                     * Looks like the first option is faster. */
434                    ptr::copy(read_ptr, write_ptr, 1);
435
436                    /* We have filled that place, so go further */
437                    gap.write += 1;
438                    gap.read += 1;
439                }
440            }
441
442            /* Technically we could let `gap` clean up with its Drop, but
443             * when `same_bucket` is guaranteed to not panic, this bloats a little
444             * the codegen, so we just do it manually */
445            gap.vec.set_len(gap.write);
446            mem::forget(gap);
447        }
448    }
449
450    #[inline]
451    fn push(&mut self, value: T) {
452        // This will panic or abort if we would allocate > isize::MAX bytes
453        // or if the length increment would overflow for zero-sized types.
454        let len = self.len();
455        let total_len = len + 1;
456        self.ensure_capacity(total_len);
457
458        unsafe {
459            let end = self.as_mut_ptr().add(len);
460            ptr::write(end, value);
461            self.set_len(total_len);
462        }
463    }
464
465    #[inline]
466    fn append(&mut self, other: &mut Self) {
467        unsafe {
468            let count = other.len();
469            let len = self.len();
470            let total_len = len + count;
471
472            self.ensure_capacity(total_len);
473
474            ptr::copy_nonoverlapping(
475                other.as_ptr() as *const T,
476                self.as_mut_ptr().add(len),
477                count,
478            );
479            self.set_len(total_len);
480            other.set_len(0);
481        }
482    }
483
484    /// Clears the array, removing all values.
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// use stack_array::*;
490    ///
491    /// let mut list = ArrayBuf::from([1, 2, 3]);
492    /// list.clear();
493    /// assert!(list.is_empty());
494    /// ```
495    #[inline]
496    fn clear(&mut self) {
497        self.truncate(0)
498    }
499
500    /// Returns the number of elements currently in the array.
501    ///
502    /// # Examples
503    ///
504    /// ```
505    /// use stack_array::*;
506    ///
507    /// let arr: ArrayBuf<u8, 3> = ArrayBuf::from([1, 2].as_ref());
508    /// assert_eq!(arr.len(), 2);
509    /// ```
510    fn len(&self) -> usize;
511
512    /// Returns true if the array contains no elements.
513    ///
514    /// # Examples
515    ///
516    /// ```
517    /// use stack_array::*;
518    ///
519    /// let mut arr: ArrayBuf<u8, 2> = ArrayBuf::new();
520    /// assert!(arr.is_empty());
521    ///
522    /// arr.push(1);
523    /// assert!(!arr.is_empty());
524    /// ```
525    #[inline]
526    fn is_empty(&self) -> bool {
527        self.len() == 0
528    }
529
530    /// Removes the last element from a collection and returns it.
531    ///
532    /// # Examples
533    ///
534    /// ```rust
535    /// use stack_array::*;
536    ///
537    /// let mut arr: ArrayBuf<u8, 3> = ArrayBuf::from([1, 2].as_ref());
538    /// assert_eq!(arr.pop(), Some(2));
539    /// assert_eq!(arr.pop(), Some(1));
540    /// assert!(arr.is_empty());
541    /// ```
542    #[inline]
543    fn pop(&mut self) -> Option<T> {
544        if self.is_empty() {
545            None
546        } else {
547            unsafe {
548                let len = self.len() - 1;
549                self.set_len(len);
550                Some(ptr::read(self.as_ptr().add(len)))
551            }
552        }
553    }
554
555    //============================================================
556    #[inline]
557    fn ensure_capacity(&mut self, total_len: usize) {
558        if total_len > self.capacity() {
559            panic!(
560                "Array is full, Max capacity: {}, But got: {total_len}",
561                self.capacity()
562            );
563        }
564    }
565
566    /// Returns the number of elements can be inserted into the array.
567    ///
568    /// # Examples
569    ///
570    /// ```
571    /// use stack_array::*;
572    ///
573    /// let arr: ArrayBuf<u8, 3> = ArrayBuf::from([1, 2].as_ref());
574    /// assert_eq!(arr.remaining_capacity(), 1);
575    /// ```
576    #[inline]
577    fn remaining_capacity(&self) -> usize {
578        self.capacity() - self.len()
579    }
580
581    #[inline]
582    fn extend_from_slice(&mut self, other: impl AsRef<[T]>)
583    where
584        T: Copy,
585    {
586        let other = other.as_ref();
587        let count = other.len();
588        let len = self.len();
589        let total_len = len + count;
590        self.ensure_capacity(total_len);
591        unsafe {
592            ptr::copy_nonoverlapping(other.as_ptr(), self.as_mut_ptr().add(len), count);
593            self.set_len(total_len);
594        }
595    }
596}