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}