dst_container/
fixed_vec.rs

1use crate::*;
2use std::{
3    alloc::{handle_alloc_error, AllocError, Allocator, Global, Layout},
4    iter::FusedIterator,
5    mem::forget,
6    ops::{Index, IndexMut, RangeFull},
7    ptr::{drop_in_place, NonNull},
8    slice::SliceIndex,
9};
10
11#[derive(Clone, Copy)]
12struct FixedAlloc<T: ?Sized> {
13    alloc: Global,
14    metadata: <T as Pointee>::Metadata,
15}
16
17impl<T: ?Sized> FixedAlloc<T> {
18    pub const fn new(metadata: <T as Pointee>::Metadata) -> Self {
19        Self {
20            alloc: Global,
21            metadata,
22        }
23    }
24
25    #[inline]
26    pub const fn metadata(&self) -> <T as Pointee>::Metadata {
27        self.metadata
28    }
29
30    #[inline]
31    pub unsafe fn layout(&self) -> Layout {
32        Layout::for_value_raw(std::ptr::from_raw_parts::<T>(
33            std::ptr::null::<()>(),
34            self.metadata,
35        ))
36    }
37
38    #[inline]
39    pub unsafe fn align_layout(&self, layout: Layout) -> Layout {
40        let single_layout = self.layout();
41        let layout = Layout::from_size_align_unchecked(
42            layout.size(),
43            layout.align().max(single_layout.align()),
44        );
45        layout.pad_to_align()
46    }
47}
48
49unsafe impl<T: ?Sized> Allocator for FixedAlloc<T> {
50    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
51        let layout = unsafe { self.align_layout(layout) };
52        self.alloc.allocate(layout)
53    }
54
55    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
56        let layout = self.align_layout(layout);
57        self.alloc.deallocate(ptr, layout)
58    }
59}
60
61/// A vector designed for DST.
62pub struct FixedVec<T: ?Sized>(Vec<u8, FixedAlloc<T>>);
63
64impl<T: ?Sized> FixedVec<T> {
65    /// Constructs a new, empty `FixedVec<T>`, with provided metadata.
66    ///
67    /// The vector will not allocate until elements are pushed onto it.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// # #![allow(unused_mut)]
73    /// # use dst_container::*;
74    /// let mut vec: FixedVec<UnsizedSlice<u32, u64>> = FixedVec::new(6);
75    /// ```
76    pub const fn new(metadata: <T as Pointee>::Metadata) -> Self {
77        Self(Vec::new_in(FixedAlloc::new(metadata)))
78    }
79
80    /// Constructs a new, empty `FixedVec<T>`.
81    /// The metadata is obtained from the provided pointer.
82    ///
83    /// The vector will not allocate until elements are pushed onto it.
84    ///
85    /// # Examples
86    ///
87    /// ```
88    /// # #![allow(unused_mut)]
89    /// # use dst_container::*;
90    /// let array = [0u32, 1, 2];
91    /// let mut vec: FixedVec<[u32]> = FixedVec::new_like(array.as_slice());
92    /// ```
93    pub const fn new_like(ptr: *const T) -> Self {
94        let (_, metadata) = ptr.to_raw_parts();
95        Self::new(metadata)
96    }
97
98    /// Constructs a new, empty `FixedVec<T>` with at least the specified capacity.
99    pub fn with_capacity(metadata: <T as Pointee>::Metadata, capacity: usize) -> Self {
100        let alloc = FixedAlloc::new(metadata);
101        let layout = unsafe { alloc.layout() };
102        Self(Vec::with_capacity_in(capacity * layout.size(), alloc))
103    }
104
105    /// Constructs a new, empty `FixedVec<T>` with at least the specified capacity.
106    /// The metadata is obtained from the provided pointer.
107    pub fn with_capacity_like(ptr: *const T, capacity: usize) -> Self {
108        let (_, metadata) = ptr.to_raw_parts();
109        Self::with_capacity(metadata, capacity)
110    }
111
112    #[inline]
113    fn metadata(&self) -> <T as Pointee>::Metadata {
114        self.0.allocator().metadata()
115    }
116
117    #[inline]
118    unsafe fn layout(&self) -> Layout {
119        self.0.allocator().layout()
120    }
121
122    #[inline]
123    fn item_size(&self) -> usize {
124        unsafe { self.layout() }.size()
125    }
126
127    #[inline]
128    fn start_index(&self, index: usize) -> usize {
129        index * self.item_size()
130    }
131
132    #[inline]
133    unsafe fn raw(&self, index: usize) -> &T {
134        let start = self.start_index(index);
135        let start_ptr = self.0.as_ptr().add(start);
136        &*std::ptr::from_raw_parts(start_ptr as *mut (), self.metadata())
137    }
138
139    #[inline]
140    unsafe fn raw_mut(&mut self, index: usize) -> &mut T {
141        let start = self.start_index(index);
142        let start_ptr = self.0.as_mut_ptr().add(start);
143        &mut *std::ptr::from_raw_parts_mut(start_ptr as *mut (), self.metadata())
144    }
145
146    /// Returns the total number of elements the vector can hold without
147    /// reallocating.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// # use dst_container::*;
153    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
154    /// // SAFETY: u32 is trivial.
155    /// unsafe{ vec.push_with(|_| {}) };
156    /// assert_eq!(vec.capacity(), 10);
157    /// ```
158    pub fn capacity(&self) -> usize {
159        self.0.capacity() / self.item_size()
160    }
161
162    /// Reserves capacity for at least `additional` more elements to be inserted
163    /// in the given `FixedVec<T>`. The collection may reserve more space to
164    /// speculatively avoid frequent reallocations. After calling `reserve`,
165    /// capacity will be greater than or equal to `self.len() + additional`.
166    /// Does nothing if capacity is already sufficient.
167    ///
168    /// # Panics
169    ///
170    /// Panics if the new capacity exceeds `isize::MAX` bytes.
171    pub fn reserve(&mut self, additional: usize) {
172        self.0.reserve(additional * self.item_size())
173    }
174
175    /// Shrinks the capacity of the vector as much as possible.
176    ///
177    /// It will drop down as close as possible to the length but the allocator
178    /// may still inform the vector that there is space for a few more elements.
179    ///
180    /// # Examples
181    ///
182    /// ```
183    /// # use dst_container::*;
184    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
185    /// // SAFETY: u32 is trivial.
186    /// unsafe{ vec.push_with(|_| {}) };
187    /// assert_eq!(vec.capacity(), 10);
188    /// vec.shrink_to_fit();
189    /// assert!(vec.capacity() >= 1);
190    /// ```
191    pub fn shrink_to_fit(&mut self) {
192        self.0.shrink_to_fit()
193    }
194
195    /// Shrinks the capacity of the vector with a lower bound.
196    ///
197    /// The capacity will remain at least as large as both the length
198    /// and the supplied value.
199    ///
200    /// If the current capacity is less than the lower limit, this is a no-op.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// # use dst_container::*;
206    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
207    /// // SAFETY: u32 is trivial.
208    /// unsafe{ vec.push_with(|_| {}) };
209    /// assert_eq!(vec.capacity(), 10);
210    /// vec.shrink_to(2);
211    /// assert!(vec.capacity() >= 2);
212    /// vec.shrink_to(0);
213    /// assert!(vec.capacity() >= 1);
214    /// ```
215    pub fn shrink_to(&mut self, min_capacity: usize) {
216        self.0.shrink_to(min_capacity * self.item_size())
217    }
218
219    /// Shortens the vector, keeping the first `len` elements and dropping
220    /// the rest.
221    ///
222    /// If `len` is greater than the vector's current length, this has no
223    /// effect.
224    ///
225    /// Note that this method has no effect on the allocated capacity
226    /// of the vector.
227    ///
228    /// # Examples
229    ///
230    /// Truncating a five element vector to two elements:
231    ///
232    /// ```
233    /// # use dst_container::*;
234    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
235    /// // SAFETY: u32 is trivial.
236    /// unsafe{ vec.push_with(|slice| { slice.header.write(1); }) };
237    /// unsafe{ vec.push_with(|slice| { slice.header.write(2); }) };
238    /// unsafe{ vec.push_with(|slice| { slice.header.write(3); }) };
239    /// vec.truncate(2);
240    /// assert_eq!(vec.len(), 2);
241    /// assert_eq!(vec[0].header, 1);
242    /// assert_eq!(vec[1].header, 2);
243    /// ```
244    ///
245    /// No truncation occurs when `len` is greater than the vector's current
246    /// length:
247    ///
248    /// ```
249    /// # use dst_container::*;
250    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
251    /// // SAFETY: u32 is trivial.
252    /// unsafe{ vec.push_with(|slice| { slice.header.write(1); }) };
253    /// unsafe{ vec.push_with(|slice| { slice.header.write(2); }) };
254    /// unsafe{ vec.push_with(|slice| { slice.header.write(3); }) };
255    /// vec.truncate(8);
256    /// assert_eq!(vec.len(), 3);
257    /// assert_eq!(vec[0].header, 1);
258    /// assert_eq!(vec[1].header, 2);
259    /// assert_eq!(vec[2].header, 3);
260    /// ```
261    ///
262    /// Truncating when `len == 0` is equivalent to calling the [`clear`]
263    /// method.
264    ///
265    /// ```
266    /// # use dst_container::*;
267    /// let mut vec: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(3, 10);
268    /// // SAFETY: u32 is trivial.
269    /// unsafe{ vec.push_with(|slice| { slice.header.write(1); }) };
270    /// unsafe{ vec.push_with(|slice| { slice.header.write(2); }) };
271    /// unsafe{ vec.push_with(|slice| { slice.header.write(3); }) };
272    /// vec.truncate(0);
273    /// assert_eq!(vec.len(), 0);
274    /// ```
275    ///
276    /// [`clear`]: FixedVec::clear
277    pub fn truncate(&mut self, len: usize) {
278        if len < self.len() {
279            for i in len..self.len() {
280                unsafe {
281                    let raw = self.raw_mut(i);
282                    drop_in_place(raw)
283                }
284            }
285            self.0.truncate(len * self.item_size())
286        }
287    }
288
289    /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
290    /// valid for zero sized reads if the vector didn't allocate.
291    ///
292    /// The caller must ensure that the vector outlives the pointer this
293    /// function returns, or else it will end up pointing to garbage.
294    /// Modifying the vector may cause its buffer to be reallocated,
295    /// which would also make any pointers to it invalid.
296    ///
297    /// The caller must also ensure that the memory the pointer (non-transitively) points to
298    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
299    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
300    ///
301    /// [`as_mut_ptr`]: FixedVec::as_mut_ptr
302    #[inline]
303    pub fn as_ptr(&self) -> *const T {
304        unsafe { self.raw(0) }
305    }
306
307    /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
308    /// raw pointer valid for zero sized reads if the vector didn't allocate.
309    ///
310    /// The caller must ensure that the vector outlives the pointer this
311    /// function returns, or else it will end up pointing to garbage.
312    /// Modifying the vector may cause its buffer to be reallocated,
313    /// which would also make any pointers to it invalid.
314    ///
315    /// # Examples
316    ///
317    /// ```
318    /// #![feature(ptr_metadata)]
319    /// # use dst_container::*;
320    ///
321    /// // Allocate vector big enough for 1 elements.
322    /// let size = 1;
323    /// let mut x: FixedVec<UnsizedSlice<u32, u32>> = FixedVec::with_capacity(2, size);
324    /// let x_ptr = x.as_mut_ptr();
325    ///
326    /// // Initialize elements via raw pointer writes, then set length.
327    /// unsafe {
328    ///     let u32_ptr = x_ptr.to_raw_parts().0 as *mut u32;
329    ///     for i in 0..3 {
330    ///         *u32_ptr.add(i) = i as u32;
331    ///     }
332    ///     x.set_len(size);
333    /// }
334    /// assert_eq!(x[0].header, 0);
335    /// assert_eq!(&x[0].slice, &[1, 2]);
336    /// ```
337    #[inline]
338    pub fn as_mut_ptr(&mut self) -> *mut T {
339        unsafe { self.raw_mut(0) }
340    }
341
342    /// Forces the length of the vector to `new_len`.
343    ///
344    /// This is a low-level operation that maintains none of the normal
345    /// invariants of the type. Normally changing the length of a vector
346    /// is done using one of the safe operations instead, such as
347    /// [`truncate`], [`extend`], or [`clear`].
348    ///
349    /// [`truncate`]: FixedVec::truncate
350    /// [`extend`]: Extend::extend
351    /// [`clear`]: FixedVec::clear
352    ///
353    /// # Safety
354    ///
355    /// - `new_len` must be less than or equal to [`capacity()`].
356    /// - The elements at `old_len..new_len` must be initialized.
357    ///
358    /// [`capacity()`]: FixedVec::capacity
359    pub unsafe fn set_len(&mut self, new_len: usize) {
360        self.0.set_len(new_len * self.item_size())
361    }
362
363    unsafe fn copy_to_box(&self, index: usize) -> Box<T> {
364        let layout = self.layout();
365        if let Ok(ptr) = Global.allocate(layout) {
366            let ptr = ptr.as_mut_ptr();
367            ptr.copy_from_nonoverlapping(
368                self.0.as_ptr().add(index * self.item_size()),
369                self.item_size(),
370            );
371            Box::from_raw(std::ptr::from_raw_parts_mut(
372                ptr as *mut (),
373                self.metadata(),
374            ))
375        } else {
376            handle_alloc_error(layout)
377        }
378    }
379
380    /// Removes an element from the vector and returns it.
381    ///
382    /// The removed element is replaced by the last element of the vector.
383    ///
384    /// This does not preserve ordering, but is *O*(1).
385    /// If you need to preserve the element order, use [`remove`] instead.
386    ///
387    /// [`remove`]: FixedVec::remove
388    ///
389    /// # Panics
390    ///
391    /// Panics if `index` is out of bounds.
392    ///
393    /// # Examples
394    ///
395    /// ```
396    /// # use dst_container::*;
397    /// let mut v = FixedVec::<str>::new(3);
398    /// v.push(Box::from("foo"));
399    /// v.push(Box::from("bar"));
400    /// v.push(Box::from("baz"));
401    /// v.push(Box::from("qux"));
402    ///
403    /// assert_eq!(v.swap_remove(1).as_ref(), "bar");
404    /// assert_eq!(&v[1], "qux");
405    ///
406    /// assert_eq!(v.swap_remove(0).as_ref(), "foo");
407    /// assert_eq!(&v[0], "baz");
408    /// ```
409    pub fn swap_remove(&mut self, index: usize) -> Box<T> {
410        let len = self.len();
411        if index >= len {
412            panic!("swap_remove index (is {index}) should be < len (is {len})");
413        }
414        let index = index * self.item_size();
415        let last_index = (self.len() - 1) * self.item_size();
416        unsafe {
417            std::ptr::swap_nonoverlapping(
418                self.0.as_mut_ptr().add(index),
419                self.0.as_mut_ptr().add(last_index),
420                self.item_size(),
421            );
422            self.set_len(self.len() - 1);
423            self.copy_to_box(self.len())
424        }
425    }
426
427    #[allow(clippy::comparison_chain)]
428    unsafe fn insert_raw(&mut self, index: usize, f: impl FnOnce(*mut u8)) {
429        self.reserve(1);
430        let start = self.start_index(index);
431        let len = self.len();
432        unsafe {
433            if index < len {
434                std::ptr::copy(
435                    self.0.as_ptr().add(start),
436                    self.0.as_mut_ptr().add(start + self.item_size()),
437                    (len - index) * self.item_size(),
438                );
439            } else if index == len {
440                // Nop.
441            } else {
442                panic!("insertion index (is {index}) should be <= len (is {len})");
443            }
444            f(self.0.as_mut_ptr().add(start));
445            self.set_len(len + 1);
446        }
447    }
448
449    /// Inserts an element at position `index` within the vector, shifting all
450    /// elements after it to the right.
451    ///
452    /// # Panics
453    ///
454    /// Panics if `index > len`.
455    ///
456    /// # Examples
457    ///
458    /// ```
459    /// #![feature(maybe_uninit_write_slice)]
460    /// # use dst_container::*;
461    /// # use std::mem::MaybeUninit;
462    ///
463    /// let mut vec = FixedVec::<[i32]>::new(2);
464    /// unsafe {
465    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[1, 1]); });
466    ///     vec.insert(0, Box::<[i32]>::new_zeroed_unsized(2).assume_init());
467    /// }
468    /// assert_eq!(&vec[0], [0, 0]);
469    /// assert_eq!(&vec[1], [1, 1]);
470    /// ```
471    pub fn insert(&mut self, index: usize, element: Box<T>) {
472        let (ptr, metadata) = (element.as_ref() as *const T).to_raw_parts();
473        if metadata != self.metadata() {
474            panic!("Different metadata.");
475        }
476        let item_size = self.item_size();
477        unsafe {
478            self.insert_raw(index, |dest| {
479                std::ptr::copy_nonoverlapping(ptr as *const u8, dest, item_size);
480            });
481        }
482        forget(element);
483    }
484
485    /// Inserts an element at position `index` within the vector, shifting all
486    /// elements after it to the right.
487    ///
488    /// # Panics
489    ///
490    /// Panics if `index > len`.
491    ///
492    /// # Safety
493    /// The caller should ensure the new element being initialized.
494    ///
495    /// # Examples
496    ///
497    /// ```
498    /// #![feature(maybe_uninit_write_slice)]
499    /// # use dst_container::*;
500    /// # use std::mem::MaybeUninit;
501    ///
502    /// let mut vec = FixedVec::<[i32]>::new(2);
503    /// unsafe {
504    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[1, 1]); });
505    ///     vec.insert_with(0, |slice| { slice.write_copy_of_slice(&[0, 0]); });
506    /// }
507    /// assert_eq!(&vec[0], [0, 0]);
508    /// assert_eq!(&vec[1], [1, 1]);
509    /// ```
510    pub unsafe fn insert_with(&mut self, index: usize, f: impl FnOnce(&mut T::Target))
511    where
512        T: MaybeUninitProject,
513    {
514        let metadata = self.metadata();
515        self.insert_raw(index, |dest| {
516            let ptr = std::ptr::from_raw_parts_mut::<T::Target>(dest as *mut (), metadata);
517            f(&mut *ptr);
518        });
519    }
520
521    /// Inserts an element at position `index` within the vector, shifting all
522    /// elements after it to the right.
523    ///
524    /// # Panics
525    ///
526    /// Panics if `index > len`.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// # use dst_container::*;
532    /// # use std::mem::MaybeUninit;
533    ///
534    /// let element0: Box<[i32]> = Box::from([0, 0]);
535    /// let element1: Box<[i32]> = Box::from([1, 1]);
536    ///
537    /// let mut vec = FixedVec::<[i32]>::new(2);
538    /// vec.push_clone(element1.as_ref());
539    /// vec.insert_clone(0, element0.as_ref());
540    /// assert_eq!(&vec[0], [0, 0]);
541    /// assert_eq!(&vec[1], [1, 1]);
542    /// ```
543    pub fn insert_clone(&mut self, index: usize, element: &T)
544    where
545        T: UnsizedClone,
546    {
547        unsafe {
548            self.insert_with(index, |dest| element.clone_to(dest));
549        }
550    }
551
552    /// Removes and returns the element at position `index` within the vector,
553    /// shifting all elements after it to the left.
554    ///
555    /// # Panics
556    ///
557    /// Panics if `index` is out of bounds.
558    ///
559    /// # Examples
560    ///
561    /// ```
562    /// #![feature(maybe_uninit_write_slice)]
563    /// # use dst_container::*;
564    /// # use std::mem::MaybeUninit;
565    ///
566    /// let mut vec = FixedVec::<[i32]>::new(2);
567    /// unsafe {
568    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[0, 0]); });
569    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[1, 1]); });
570    /// }
571    /// assert_eq!(vec.remove(0).as_ref(), &[0, 0]);
572    /// assert_eq!(&vec[0], &[1, 1]);
573    /// ```
574    pub fn remove(&mut self, index: usize) -> Box<T> {
575        let len = self.len();
576        if index >= len {
577            panic!("removal index (is {index}) should be < len (is {len})");
578        }
579        let start = self.start_index(index);
580        unsafe {
581            let b;
582            {
583                b = self.copy_to_box(index);
584
585                std::ptr::copy(
586                    self.0.as_ptr().add(start + self.item_size()),
587                    self.0.as_mut_ptr().add(start),
588                    (len - index - 1) * self.item_size(),
589                );
590            }
591            self.set_len(len - 1);
592            b
593        }
594    }
595
596    /// Appends an element to the back of a collection.
597    ///
598    /// # Panics
599    ///
600    /// Panics if the new capacity exceeds `isize::MAX` bytes.
601    #[inline]
602    pub fn push(&mut self, value: Box<T>) {
603        self.insert(self.len(), value);
604    }
605
606    /// Appends an element to the back of a collection.
607    ///
608    /// # Panics
609    ///
610    /// Panics if the new capacity exceeds `isize::MAX` bytes.
611    ///
612    /// # Safety
613    ///
614    /// The same as [`insert_with`].
615    ///
616    /// [`insert_with`]: FixedVec::insert_with
617    #[inline]
618    pub unsafe fn push_with(&mut self, f: impl FnOnce(&mut T::Target))
619    where
620        T: MaybeUninitProject,
621    {
622        self.insert_with(self.len(), f);
623    }
624
625    /// Appends an element to the back of a collection.
626    ///
627    /// # Panics
628    ///
629    /// Panics if the new capacity exceeds `isize::MAX` bytes.
630    #[inline]
631    pub fn push_clone(&mut self, value: &T)
632    where
633        T: UnsizedClone,
634    {
635        self.insert_clone(self.len(), value);
636    }
637
638    /// Removes the last element from a vector and returns it, or [`None`] if it
639    /// is empty.
640    pub fn pop(&mut self) -> Option<Box<T>> {
641        if self.is_empty() {
642            None
643        } else {
644            Some(self.remove(self.len() - 1))
645        }
646    }
647
648    /// Clears the vector, removing all values.
649    ///
650    /// Note that this method has no effect on the allocated capacity
651    /// of the vector.
652    ///
653    /// # Examples
654    ///
655    /// ```
656    /// # use dst_container::*;
657    /// let mut vec = FixedVec::<[i32]>::new(2);
658    /// unsafe {
659    ///     vec.push_with(|slice| {});
660    ///     vec.push_with(|slice| {});
661    /// }
662    /// vec.clear();
663    /// assert!(vec.is_empty());
664    /// ```
665    #[inline]
666    pub fn clear(&mut self) {
667        self.truncate(0)
668    }
669
670    /// Returns the number of elements in the vector, also referred to
671    /// as its 'length'.
672    ///
673    /// # Examples
674    ///
675    /// ```
676    /// # use dst_container::*;
677    /// let mut vec = FixedVec::<[i32]>::new(2);
678    /// unsafe {
679    ///     vec.push_with(|slice| {});
680    ///     vec.push_with(|slice| {});
681    /// }
682    /// assert_eq!(vec.len(), 2);
683    /// ```
684    #[inline]
685    pub fn len(&self) -> usize {
686        self.0.len() / self.item_size()
687    }
688
689    /// Returns `true` if the vector contains no elements.
690    ///
691    /// # Examples
692    ///
693    /// ```
694    /// # use dst_container::*;
695    /// let mut vec = FixedVec::<[i32]>::new(2);
696    /// assert!(vec.is_empty());
697    /// unsafe {
698    ///     vec.push_with(|slice| {});
699    ///     vec.push_with(|slice| {});
700    /// }
701    /// assert!(!vec.is_empty());
702    /// ```
703    #[inline]
704    pub fn is_empty(&self) -> bool {
705        self.0.len() == 0
706    }
707
708    /// Returns an iterator over the vector.
709    ///
710    /// The iterator yields all items from start to end.
711    ///
712    /// # Examples
713    ///
714    /// ```
715    /// #![feature(maybe_uninit_write_slice)]
716    /// # use dst_container::*;
717    /// # use std::mem::MaybeUninit;
718    ///
719    /// let mut vec = FixedVec::<[i32]>::new(2);
720    /// unsafe {
721    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[0, 0]); });
722    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[1, 1]); });
723    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[2, 2]); });
724    /// }
725    ///
726    /// let mut iterator = vec.iter();
727    ///
728    /// assert_eq!(iterator.next(), Some(&[0, 0][..]));
729    /// assert_eq!(iterator.next(), Some(&[1, 1][..]));
730    /// assert_eq!(iterator.next(), Some(&[2, 2][..]));
731    /// assert_eq!(iterator.next(), None);
732    /// ```
733    #[inline]
734    pub fn iter(&self) -> FixedVecIter<'_, T> {
735        FixedVecIter::new(self)
736    }
737
738    /// Returns an iterator that allows modifying each value.
739    ///
740    /// The iterator yields all items from start to end.
741    ///
742    /// # Examples
743    ///
744    /// ```
745    /// #![feature(maybe_uninit_write_slice)]
746    /// # use dst_container::*;
747    /// # use std::mem::MaybeUninit;
748    ///
749    /// let mut vec = FixedVec::<[i32]>::new(2);
750    /// unsafe {
751    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[0, 0]); });
752    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[1, 1]); });
753    ///     vec.push_with(|slice| { slice.write_copy_of_slice(&[2, 2]); });
754    /// }
755    ///
756    /// for elem in vec.iter_mut() {
757    ///     elem[0] += 2;
758    ///     elem[1] *= 2;
759    /// }
760    ///
761    /// let mut iterator = vec.iter();
762    ///
763    /// assert_eq!(iterator.next(), Some(&[2, 0][..]));
764    /// assert_eq!(iterator.next(), Some(&[3, 2][..]));
765    /// assert_eq!(iterator.next(), Some(&[4, 4][..]));
766    /// assert_eq!(iterator.next(), None);
767    /// ```
768    #[inline]
769    pub fn iter_mut(&mut self) -> FixedVecIterMut<'_, T> {
770        FixedVecIterMut::new(self)
771    }
772
773    /// Returns a reference to an element or subslice depending on the type of
774    /// index.
775    ///
776    /// - If given a position, returns a reference to the element at that
777    ///   position or `None` if out of bounds.
778    /// - If given a range, returns the subslice corresponding to that range,
779    ///   or `None` if out of bounds.
780    #[inline]
781    pub fn get<I: SliceIndex<Self>>(&self, index: I) -> Option<&I::Output> {
782        index.get(self)
783    }
784
785    /// Returns a mutable reference to an element or subslice depending on the
786    /// type of index (see [`get`]) or `None` if the index is out of bounds.
787    ///
788    /// [`get`]: FixedVec::get
789    #[inline]
790    pub fn get_mut<I: SliceIndex<Self>>(&mut self, index: I) -> Option<&mut I::Output> {
791        index.get_mut(self)
792    }
793
794    /// Returns a reference to an element or subslice, without doing bounds
795    /// checking.
796    ///
797    /// For a safe alternative see [`get`].
798    ///
799    /// # Safety
800    ///
801    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
802    /// even if the resulting reference is not used.
803    ///
804    /// [`get`]: FixedVec::get
805    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
806    #[inline]
807    pub unsafe fn get_unchecked<I: SliceIndex<Self>>(&self, index: I) -> &I::Output {
808        &*index.get_unchecked(self)
809    }
810
811    /// Returns a mutable reference to an element or subslice, without doing
812    /// bounds checking.
813    ///
814    /// For a safe alternative see [`get_mut`].
815    ///
816    /// # Safety
817    ///
818    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
819    /// even if the resulting reference is not used.
820    ///
821    /// [`get_mut`]: FixedVec::get_mut
822    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
823    #[inline]
824    pub unsafe fn get_unchecked_mut<I: SliceIndex<Self>>(&mut self, index: I) -> &mut I::Output {
825        &mut *index.get_unchecked_mut(self)
826    }
827}
828
829impl<T: ?Sized> Drop for FixedVec<T> {
830    fn drop(&mut self) {
831        self.clear()
832    }
833}
834
835impl<T: ?Sized, I: SliceIndex<FixedVec<T>>> Index<I> for FixedVec<T> {
836    type Output = I::Output;
837
838    fn index(&self, index: I) -> &Self::Output {
839        index.index(self)
840    }
841}
842
843impl<T: ?Sized, I: SliceIndex<FixedVec<T>>> IndexMut<I> for FixedVec<T> {
844    fn index_mut(&mut self, index: I) -> &mut Self::Output {
845        index.index_mut(self)
846    }
847}
848
849unsafe impl<T: ?Sized> SliceIndex<FixedVec<T>> for usize {
850    type Output = T;
851
852    fn get(self, slice: &FixedVec<T>) -> Option<&Self::Output> {
853        if self < slice.len() {
854            Some(unsafe { slice.raw(self) })
855        } else {
856            None
857        }
858    }
859
860    fn get_mut(self, slice: &mut FixedVec<T>) -> Option<&mut Self::Output> {
861        if self < slice.len() {
862            Some(unsafe { slice.raw_mut(self) })
863        } else {
864            None
865        }
866    }
867
868    unsafe fn get_unchecked(self, slice: *const FixedVec<T>) -> *const Self::Output {
869        (*slice).raw(self)
870    }
871
872    unsafe fn get_unchecked_mut(self, slice: *mut FixedVec<T>) -> *mut Self::Output {
873        (*slice).raw_mut(self)
874    }
875
876    fn index(self, slice: &FixedVec<T>) -> &Self::Output {
877        self.get(slice).expect("Index out of bound.")
878    }
879
880    fn index_mut(self, slice: &mut FixedVec<T>) -> &mut Self::Output {
881        self.get_mut(slice).expect("Index out of bound.")
882    }
883}
884
885unsafe impl<T: ?Sized> SliceIndex<FixedVec<T>> for RangeFull {
886    type Output = FixedVec<T>;
887
888    fn get(self, slice: &FixedVec<T>) -> Option<&Self::Output> {
889        Some(slice)
890    }
891
892    fn get_mut(self, slice: &mut FixedVec<T>) -> Option<&mut Self::Output> {
893        Some(slice)
894    }
895
896    unsafe fn get_unchecked(self, slice: *const FixedVec<T>) -> *const Self::Output {
897        slice
898    }
899
900    unsafe fn get_unchecked_mut(self, slice: *mut FixedVec<T>) -> *mut Self::Output {
901        slice
902    }
903
904    fn index(self, slice: &FixedVec<T>) -> &Self::Output {
905        slice
906    }
907
908    fn index_mut(self, slice: &mut FixedVec<T>) -> &mut Self::Output {
909        slice
910    }
911}
912
913pub struct FixedVecIter<'a, T: ?Sized> {
914    vec: &'a FixedVec<T>,
915    index: usize,
916}
917
918impl<'a, T: ?Sized> FixedVecIter<'a, T> {
919    pub(crate) fn new(vec: &'a FixedVec<T>) -> Self {
920        Self { vec, index: 0 }
921    }
922}
923
924impl<'a, T: ?Sized> Iterator for FixedVecIter<'a, T> {
925    type Item = &'a T;
926
927    fn next(&mut self) -> Option<Self::Item> {
928        if self.index < self.vec.len() {
929            let res = Some(unsafe { self.vec.get_unchecked(self.index) });
930            self.index += 1;
931            res
932        } else {
933            None
934        }
935    }
936
937    fn size_hint(&self) -> (usize, Option<usize>) {
938        let len = self.vec.len();
939        (len, Some(len))
940    }
941
942    fn count(self) -> usize {
943        self.vec.len()
944    }
945
946    fn nth(&mut self, n: usize) -> Option<Self::Item> {
947        self.vec.get(n)
948    }
949}
950
951impl<T: ?Sized> ExactSizeIterator for FixedVecIter<'_, T> {}
952
953impl<'a, T: ?Sized> DoubleEndedIterator for FixedVecIter<'a, T> {
954    fn next_back(&mut self) -> Option<Self::Item> {
955        if self.index > 0 {
956            self.index -= 1;
957            Some(unsafe { self.vec.get_unchecked(self.index) })
958        } else {
959            None
960        }
961    }
962
963    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
964        if n >= self.vec.len() {
965            None
966        } else {
967            Some(unsafe { self.vec.get_unchecked(self.vec.len() - n - 1) })
968        }
969    }
970}
971
972impl<T: ?Sized> FusedIterator for FixedVecIter<'_, T> {}
973
974impl<'a, T: ?Sized> IntoIterator for &'a FixedVec<T> {
975    type Item = &'a T;
976
977    type IntoIter = FixedVecIter<'a, T>;
978
979    fn into_iter(self) -> Self::IntoIter {
980        self.iter()
981    }
982}
983
984pub struct FixedVecIterMut<'a, T: ?Sized> {
985    vec: &'a mut FixedVec<T>,
986    index: usize,
987}
988
989impl<'a, T: ?Sized> FixedVecIterMut<'a, T> {
990    pub(crate) fn new(vec: &'a mut FixedVec<T>) -> Self {
991        Self { vec, index: 0 }
992    }
993}
994
995impl<'a, T: ?Sized> Iterator for FixedVecIterMut<'a, T> {
996    type Item = &'a mut T;
997
998    fn next(&mut self) -> Option<Self::Item> {
999        if self.index < self.vec.len() {
1000            let res = Some(unsafe { self.vec.get_unchecked_mut(self.index) });
1001            self.index += 1;
1002            res.map(|p| unsafe { &mut *(p as *mut T) })
1003        } else {
1004            None
1005        }
1006    }
1007
1008    fn size_hint(&self) -> (usize, Option<usize>) {
1009        let len = self.vec.len();
1010        (len, Some(len))
1011    }
1012
1013    fn count(self) -> usize {
1014        self.vec.len()
1015    }
1016
1017    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1018        self.vec.get_mut(n).map(|p| unsafe { &mut *(p as *mut T) })
1019    }
1020}
1021
1022impl<T: ?Sized> ExactSizeIterator for FixedVecIterMut<'_, T> {}
1023
1024impl<'a, T: ?Sized> DoubleEndedIterator for FixedVecIterMut<'a, T> {
1025    fn next_back(&mut self) -> Option<Self::Item> {
1026        if self.index > 0 {
1027            self.index -= 1;
1028            Some(unsafe { &mut *(self.vec.get_unchecked_mut(self.index) as *mut T) })
1029        } else {
1030            None
1031        }
1032    }
1033
1034    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1035        if n >= self.vec.len() {
1036            None
1037        } else {
1038            Some(unsafe { &mut *(self.vec.get_unchecked_mut(self.vec.len() - n - 1) as *mut T) })
1039        }
1040    }
1041}
1042
1043impl<T: ?Sized> FusedIterator for FixedVecIterMut<'_, T> {}
1044
1045impl<'a, T: ?Sized> IntoIterator for &'a mut FixedVec<T> {
1046    type Item = &'a mut T;
1047
1048    type IntoIter = FixedVecIterMut<'a, T>;
1049
1050    fn into_iter(self) -> Self::IntoIter {
1051        self.iter_mut()
1052    }
1053}
1054
1055impl<T: ?Sized> Extend<Box<T>> for FixedVec<T> {
1056    fn extend<I: IntoIterator<Item = Box<T>>>(&mut self, iter: I) {
1057        for item in iter {
1058            self.push(item);
1059        }
1060    }
1061}
1062
1063impl<T: ?Sized + UnsizedClone> Clone for FixedVec<T> {
1064    fn clone(&self) -> Self {
1065        let mut vec = FixedVec::<T>::with_capacity(self.metadata(), self.len());
1066        for item in self {
1067            unsafe {
1068                vec.push_with(|dest| item.clone_to(dest));
1069            }
1070        }
1071        vec
1072    }
1073}
1074
1075#[cfg(test)]
1076mod test {
1077    use crate::*;
1078    use std::sync::Arc;
1079
1080    #[test]
1081    fn basic() {
1082        let mut vec: FixedVec<UnsizedSlice<u32, u64>> = FixedVec::new(6);
1083        assert_eq!(vec.len(), 0);
1084        vec.push(unsafe {
1085            Box::<UnsizedSlice<u32, u64>>::new_unsized_with(6, |slice| {
1086                slice.header.write(114514);
1087                slice.slice.write_copy_of_slice(&[1, 1, 4, 5, 1, 4]);
1088            })
1089        });
1090        assert_eq!(vec.len(), 1);
1091        assert_eq!(&vec[0].header, &114514);
1092        assert_eq!(&vec[0].slice, &[1, 1, 4, 5, 1, 4]);
1093    }
1094
1095    #[test]
1096    fn in_place() {
1097        let mut vec: FixedVec<UnsizedSlice<u32, u64>> = FixedVec::new(6);
1098        assert_eq!(vec.len(), 0);
1099        unsafe {
1100            vec.push_with(|slice| {
1101                slice.header.write(114514);
1102                slice.slice.write_copy_of_slice(&[1, 1, 4, 5, 1, 4]);
1103            })
1104        };
1105        assert_eq!(vec.len(), 1);
1106        assert_eq!(&vec[0].header, &114514);
1107        assert_eq!(&vec[0].slice, &[1, 1, 4, 5, 1, 4]);
1108    }
1109
1110    #[test]
1111    fn untrivial_drop() {
1112        let data = Arc::new(());
1113        assert_eq!(Arc::strong_count(&data), 1);
1114
1115        let b = unsafe {
1116            Box::<UnsizedSlice<Arc<()>, Arc<()>>>::new_unsized_with(2, |slice| {
1117                slice.header.write(data.clone());
1118                slice
1119                    .slice
1120                    .write_clone_of_slice(&[data.clone(), data.clone()]);
1121            })
1122        };
1123        assert_eq!(Arc::strong_count(&data), 4);
1124
1125        let mut vec: FixedVec<UnsizedSlice<Arc<()>, Arc<()>>> = FixedVec::new(2);
1126        vec.push_clone(&b);
1127        assert_eq!(Arc::strong_count(&data), 7);
1128        vec.push_clone(&b);
1129        assert_eq!(Arc::strong_count(&data), 10);
1130
1131        drop(vec);
1132        assert_eq!(Arc::strong_count(&data), 4);
1133        drop(b);
1134        assert_eq!(Arc::strong_count(&data), 1);
1135    }
1136
1137    #[test]
1138    fn clone() {
1139        let mut vec = FixedVec::<[i32]>::new(2);
1140        vec.push(Box::from([1, 1]));
1141        vec.push(Box::from([2, 2]));
1142        vec.push(Box::from([3, 3]));
1143        assert_eq!(&vec[0], &[1, 1]);
1144        assert_eq!(&vec[1], &[2, 2]);
1145        assert_eq!(&vec[2], &[3, 3]);
1146
1147        let vec2 = vec.clone();
1148        assert_eq!(&vec2[0], &[1, 1]);
1149        assert_eq!(&vec2[1], &[2, 2]);
1150        assert_eq!(&vec2[2], &[3, 3]);
1151    }
1152
1153    #[test]
1154    #[should_panic]
1155    fn different_meta() {
1156        let mut vec: FixedVec<UnsizedSlice<u32, u64>> = FixedVec::new(6);
1157        vec.push(unsafe {
1158            Box::<UnsizedSlice<u32, u64>>::new_unsized_with(3, |slice| {
1159                slice.header.write(114514);
1160                slice.slice.write_copy_of_slice(&[1, 1, 4]);
1161            })
1162        });
1163    }
1164}
1165
1166#[cfg(test)]
1167mod bench {
1168    use crate::*;
1169    use test::{black_box, Bencher};
1170
1171    const SLICE_LEN: usize = 1000;
1172
1173    #[bench]
1174    fn fixed_vec(b: &mut Bencher) {
1175        b.iter(|| unsafe {
1176            let mut vec = FixedVec::<[u32]>::with_capacity(SLICE_LEN, SLICE_LEN);
1177            for _i in 0..SLICE_LEN {
1178                vec.push_with(|_| {});
1179            }
1180            black_box(vec)
1181        })
1182    }
1183
1184    #[bench]
1185    fn fixed_vec_zeroed(b: &mut Bencher) {
1186        b.iter(|| unsafe {
1187            let mut vec = FixedVec::<[u32]>::with_capacity(SLICE_LEN, SLICE_LEN);
1188            for _i in 0..SLICE_LEN {
1189                vec.push_with(|slice| {
1190                    slice.write_copy_of_slice(&[0; SLICE_LEN]);
1191                });
1192            }
1193            black_box(vec)
1194        })
1195    }
1196
1197    #[bench]
1198    fn flatten_vec(b: &mut Bencher) {
1199        b.iter(|| {
1200            let mut vec = Vec::with_capacity(SLICE_LEN * SLICE_LEN);
1201            for _i in 0..(SLICE_LEN * SLICE_LEN) {
1202                vec.push(0u32);
1203            }
1204            black_box(vec)
1205        })
1206    }
1207
1208    #[bench]
1209    fn vec_box(b: &mut Bencher) {
1210        b.iter(|| unsafe {
1211            let mut vec: Vec<Box<[u32]>> = Vec::with_capacity(SLICE_LEN);
1212            for _i in 0..SLICE_LEN {
1213                vec.push(Box::new_uninit_slice(SLICE_LEN).assume_init());
1214            }
1215            black_box(vec)
1216        })
1217    }
1218
1219    #[bench]
1220    fn vec_box_zeroed(b: &mut Bencher) {
1221        b.iter(|| unsafe {
1222            let mut vec: Vec<Box<[u32]>> = Vec::with_capacity(SLICE_LEN);
1223            for _i in 0..SLICE_LEN {
1224                vec.push(Box::new_zeroed_slice(SLICE_LEN).assume_init());
1225            }
1226            black_box(vec)
1227        })
1228    }
1229}
1230
1231#[cfg(test)]
1232mod bench_clone {
1233    use crate::*;
1234    use test::{black_box, Bencher};
1235
1236    const SLICE_LEN: usize = 1000;
1237
1238    #[bench]
1239    fn fixed_vec(b: &mut Bencher) {
1240        let mut vec = FixedVec::<[u32]>::with_capacity(SLICE_LEN, SLICE_LEN);
1241        for _i in 0..SLICE_LEN {
1242            unsafe {
1243                vec.push_with(|_| {});
1244            }
1245        }
1246        b.iter(|| black_box(vec.clone()))
1247    }
1248
1249    #[bench]
1250    fn vec(b: &mut Bencher) {
1251        let mut vec = Vec::with_capacity(SLICE_LEN * SLICE_LEN);
1252        for _i in 0..(SLICE_LEN * SLICE_LEN) {
1253            vec.push(0u32);
1254        }
1255        b.iter(|| black_box(vec.clone()))
1256    }
1257
1258    #[bench]
1259    fn vec_box(b: &mut Bencher) {
1260        let mut vec: Vec<Box<[u32]>> = Vec::with_capacity(SLICE_LEN);
1261        for _i in 0..SLICE_LEN {
1262            vec.push(unsafe { Box::new_uninit_slice(SLICE_LEN).assume_init() });
1263        }
1264        b.iter(|| black_box(vec.clone()))
1265    }
1266}