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}