diff --git a/src/binary_heap.rs b/src/binary_heap.rs index c275682ba4..ccef458db9 100644 --- a/src/binary_heap.rs +++ b/src/binary_heap.rs @@ -187,22 +187,22 @@ impl BinaryHeap { pub fn into_vec(self) -> Vec { self.data } +} +impl BinaryHeapInner +where + T: Ord, + K: Kind, +{ /// Get a reference to the `BinaryHeap`, erasing the `N` const-generic. pub fn as_view(&self) -> &BinaryHeapView { - self + S::as_binary_heap_view(self) } /// Get a mutable reference to the `BinaryHeap`, erasing the `N` const-generic. pub fn as_mut_view(&mut self) -> &mut BinaryHeapView { - self + S::as_mut_binary_heap_view(self) } -} -impl BinaryHeapInner -where - T: Ord, - K: Kind, -{ /* Public API */ /// Returns the capacity of the binary heap. pub fn capacity(&self) -> usize { diff --git a/src/deque.rs b/src/deque.rs index 25bf6b97b1..6e79867fc8 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -179,19 +179,18 @@ impl Deque { self.back - self.front } } +} +impl DequeInner { /// Get a reference to the `Deque`, erasing the `N` const-generic. pub fn as_view(&self) -> &DequeView { - self + S::as_deque_view(self) } /// Get a mutable reference to the `Deque`, erasing the `N` const-generic. pub fn as_mut_view(&mut self) -> &mut DequeView { - self + S::as_mut_deque_view(self) } -} - -impl DequeInner { /// Returns the maximum number of elements the deque can hold. pub fn storage_capacity(&self) -> usize { self.buffer.borrow().len() diff --git a/src/histbuf.rs b/src/histbuf.rs index 93e79fbe33..dc2fa12cc6 100644 --- a/src/histbuf.rs +++ b/src/histbuf.rs @@ -200,6 +200,15 @@ impl HistoryBufferInner { } impl HistoryBufferInner { + /// Get a reference to the `HistoryBuffer`, erasing the `N` const-generic. + pub fn as_view(&self) -> &HistoryBufferView { + S::as_histbuf_view(self) + } + /// Get a mutable reference to the `HistoryBuffer`, erasing the `N` const-generic. + pub fn as_mut_view(&mut self) -> &mut HistoryBufferView { + S::as_mut_histbuf_view(self) + } + unsafe fn drop_contents(&mut self) { unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut( diff --git a/src/linear_map.rs b/src/linear_map.rs index d6e74df480..3c5e5d7af9 100644 --- a/src/linear_map.rs +++ b/src/linear_map.rs @@ -42,22 +42,22 @@ impl LinearMap { pub const fn new() -> Self { Self { buffer: Vec::new() } } +} +impl LinearMapInner +where + K: Eq, +{ /// Get a reference to the `LinearMap`, erasing the `N` const-generic. pub fn as_view(&self) -> &LinearMapView { - self + S::as_linear_map_view(self) } /// Get a mutable reference to the `LinearMap`, erasing the `N` const-generic. pub fn as_mut_view(&mut self) -> &mut LinearMapView { - self + S::as_mut_linear_map_view(self) } -} -impl LinearMapInner -where - K: Eq, -{ /// Returns the number of elements that the map can hold. /// /// Computes in *O*(1) time. diff --git a/src/mpmc.rs b/src/mpmc.rs index 7c90d1f562..c5d09836b5 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -177,6 +177,9 @@ impl MpMcQueue { enqueue_pos: AtomicTargetSize::new(0), } } +} + +impl MpMcQueueInner { /// Get a reference to the `MpMcQueue`, erasing the `N` const-generic. /// /// @@ -194,8 +197,8 @@ impl MpMcQueue { /// let view: &MpMcQueueView = &queue; /// ``` #[inline] - pub const fn as_view(&self) -> &MpMcQueueView { - self + pub fn as_view(&self) -> &MpMcQueueView { + S::as_mpmc_queue_view(self) } /// Get a mutable reference to the `MpMcQueue`, erasing the `N` const-generic. @@ -215,11 +218,9 @@ impl MpMcQueue { /// ``` #[inline] pub fn as_mut_view(&mut self) -> &mut MpMcQueueView { - self + S::as_mut_mpmc_queue_view(self) } -} -impl MpMcQueueInner { fn mask(&self) -> UintSize { (S::len(self.buffer.get()) - 1) as _ } diff --git a/src/sorted_linked_list.rs b/src/sorted_linked_list.rs index a3c9cb502f..35219a2d52 100644 --- a/src/sorted_linked_list.rs +++ b/src/sorted_linked_list.rs @@ -197,26 +197,20 @@ impl_index_and_const_new!(LinkedIndexU8, u8, new_u8, { u8::MAX as usize - 1 }); impl_index_and_const_new!(LinkedIndexU16, u16, new_u16, { u16::MAX as usize - 1 }); impl_index_and_const_new!(LinkedIndexUsize, usize, new_usize, { usize::MAX - 1 }); -impl SortedLinkedList +impl SortedLinkedListInner where Idx: SortedLinkedListIndex, + S: Storage, { /// Get a reference to the `SortedLinkedList`, erasing the `N` const-generic. pub fn as_view(&self) -> &SortedLinkedListView { - self + S::as_sorted_linked_list_view(self) } /// Get a mutable reference to the `Vec`, erasing the `N` const-generic. pub fn as_mut_view(&mut self) -> &mut SortedLinkedListView { - self + S::as_mut_sorted_linked_list_view(self) } -} - -impl SortedLinkedListInner -where - Idx: SortedLinkedListIndex, - S: Storage, -{ /// Internal access helper #[inline(always)] fn node_at(&self, index: usize) -> &Node { diff --git a/src/spsc.rs b/src/spsc.rs index 9ebcb996ab..2eb488409a 100644 --- a/src/spsc.rs +++ b/src/spsc.rs @@ -154,19 +154,19 @@ impl Queue { pub const fn capacity(&self) -> usize { N - 1 } +} +impl QueueInner { /// Get a reference to the `Queue`, erasing the `N` const-generic. pub fn as_view(&self) -> &QueueView { - self + S::as_queue_view(self) } /// Get a mutable reference to the `Queue`, erasing the `N` const-generic. pub fn as_mut_view(&mut self) -> &mut QueueView { - self + S::as_mut_queue_view(self) } -} -impl QueueInner { #[inline] fn increment(&self, val: usize) -> usize { (val + 1) % self.n() diff --git a/src/storage.rs b/src/storage.rs index 34c3746e18..2a91ef4ef6 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -2,7 +2,30 @@ use core::borrow::{Borrow, BorrowMut}; -pub(crate) trait SealedStorage { +#[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") +))] +use crate::mpmc::{MpMcQueueInner, MpMcQueueView}; +#[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store +))] +use crate::spsc::{QueueInner, QueueView}; +use crate::{ + binary_heap::{BinaryHeapInner, BinaryHeapView}, + deque::{DequeInner, DequeView}, + histbuf::{HistoryBufferInner, HistoryBufferView}, + linear_map::{LinearMapInner, LinearMapView}, + sorted_linked_list::{SortedLinkedListIndex, SortedLinkedListInner, SortedLinkedListView}, + string::{StringInner, StringView}, + vec::VecInner, + VecView, +}; + +pub(crate) trait SealedStorage: Sized { type Buffer: ?Sized + Borrow<[T]> + BorrowMut<[T]>; /// Obtain the length of the buffer #[allow(unused)] @@ -10,6 +33,107 @@ pub(crate) trait SealedStorage { /// Obtain access to the first element of the buffer #[allow(unused)] fn as_ptr(this: *mut Self::Buffer) -> *mut T; + + /// Convert a `Vec` to a `VecView` + fn as_vec_view(this: &VecInner) -> &VecView + where + Self: Storage; + /// Convert a `Vec` to a `VecView` + fn as_mut_vec_view(this: &mut VecInner) -> &mut VecView + where + Self: Storage; + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_histbuf_view(this: &HistoryBufferInner) -> &HistoryBufferView + where + Self: Storage; + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_mut_histbuf_view(this: &mut HistoryBufferInner) -> &mut HistoryBufferView + where + Self: Storage; + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView + where + Self: Storage; + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mut_mpmc_queue_view(this: &mut MpMcQueueInner) -> &mut MpMcQueueView + where + Self: Storage; + /// Convert a `LinearMap` to a `LinearMapView` + fn as_linear_map_view(this: &LinearMapInner) -> &LinearMapView + where + Self: Storage; + /// Convert a `LinearMap` to a `LinearMapView` + fn as_mut_linear_map_view( + this: &mut LinearMapInner, + ) -> &mut LinearMapView + where + Self: Storage; + /// Convert a `BinaryHeap` to a `BinaryHeapView` + fn as_binary_heap_view(this: &BinaryHeapInner) -> &BinaryHeapView + where + Self: Storage; + /// Convert a `BinaryHeap` to a `BinaryHeapView` + fn as_mut_binary_heap_view( + this: &mut BinaryHeapInner, + ) -> &mut BinaryHeapView + where + Self: Storage; + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView + where + Self: Storage; + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_mut_queue_view(this: &mut QueueInner) -> &mut QueueView + where + Self: Storage; + /// Convert a `Deque` to a `DequeView` + fn as_deque_view(this: &DequeInner) -> &DequeView + where + Self: Storage; + /// Convert a `Deque` to a `DequeView` + fn as_mut_deque_view(this: &mut DequeInner) -> &mut DequeView + where + Self: Storage; + /// Convert a `String` to a `StringView` + fn as_string_view(this: &StringInner) -> &StringView + where + Self: Storage; + /// Convert a `String` to a `StringView` + fn as_mut_string_view(this: &mut StringInner) -> &mut StringView + where + Self: Storage; + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_sorted_linked_list_view( + this: &SortedLinkedListInner, + ) -> &SortedLinkedListView + where + Self: Storage; + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_mut_sorted_linked_list_view( + this: &mut SortedLinkedListInner, + ) -> &mut SortedLinkedListView + where + Self: Storage; } /// Trait defining how data for a container is stored. @@ -20,7 +144,7 @@ pub(crate) trait SealedStorage { /// - [`ViewStorage`]: stores the data in an unsized `[T]`. /// /// This allows containers to be generic over either sized or unsized storage. For example, -/// the [`vec`](crate::vec) module contains a [`VecInner`](crate::vec::VecInner) struct +/// the [`vec`](crate::vec) module contains a [`VecInner`] struct /// that's generic on [`Storage`], and two type aliases for convenience: /// /// - [`Vec`](crate::vec::Vec) = `VecInner>` @@ -45,6 +169,105 @@ impl SealedStorage for OwnedStorage { fn as_ptr(this: *mut Self::Buffer) -> *mut T { this as _ } + /// Convert a `Vec` to a `VecView` + fn as_vec_view(this: &VecInner) -> &VecView { + this + } + /// Convert a `Vec` to a `VecView` + fn as_mut_vec_view(this: &mut VecInner) -> &mut VecView { + this + } + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_sorted_linked_list_view( + this: &SortedLinkedListInner, + ) -> &SortedLinkedListView { + this + } + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_mut_sorted_linked_list_view( + this: &mut SortedLinkedListInner, + ) -> &mut SortedLinkedListView { + this + } + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView { + this + } + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_mut_queue_view(this: &mut QueueInner) -> &mut QueueView { + this + } + /// Convert a `Deque` to a `DequeView` + fn as_deque_view(this: &DequeInner) -> &DequeView { + this + } + /// Convert a `Deque` to a `DequeView` + fn as_mut_deque_view(this: &mut DequeInner) -> &mut DequeView { + this + } + /// Convert a `String` to a `StringView` + fn as_string_view(this: &StringInner) -> &StringView { + this + } + /// Convert a `String` to a `StringView` + fn as_mut_string_view(this: &mut StringInner) -> &mut StringView { + this + } + /// Convert a `LinearMap` to a `LinearMapView` + fn as_linear_map_view(this: &LinearMapInner) -> &LinearMapView { + this + } + /// Convert a `LinearMap` to a `LinearMapView` + fn as_mut_linear_map_view( + this: &mut LinearMapInner, + ) -> &mut LinearMapView { + this + } + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView { + this + } + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mut_mpmc_queue_view(this: &mut MpMcQueueInner) -> &mut MpMcQueueView { + this + } + fn as_binary_heap_view(this: &BinaryHeapInner) -> &BinaryHeapView { + this + } + /// Convert a `BinaryHeap` to a `BinaryHeapView` + fn as_mut_binary_heap_view( + this: &mut BinaryHeapInner, + ) -> &mut BinaryHeapView { + this + } + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_histbuf_view(this: &HistoryBufferInner) -> &HistoryBufferView { + this + } + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_mut_histbuf_view(this: &mut HistoryBufferInner) -> &mut HistoryBufferView { + this + } } /// Implementation of [`Storage`] that stores the data in an unsized `[T]`. @@ -59,4 +282,103 @@ impl SealedStorage for ViewStorage { fn as_ptr(this: *mut Self::Buffer) -> *mut T { this as _ } + /// Convert a `Vec` to a `VecView` + fn as_vec_view(this: &VecInner) -> &VecView { + this + } + /// Convert a `Vec` to a `VecView` + fn as_mut_vec_view(this: &mut VecInner) -> &mut VecView { + this + } + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_sorted_linked_list_view( + this: &SortedLinkedListInner, + ) -> &SortedLinkedListView { + this + } + /// Convert a `SortedLinkedList` to a `SortedLinkedListView` + fn as_mut_sorted_linked_list_view( + this: &mut SortedLinkedListInner, + ) -> &mut SortedLinkedListView { + this + } + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView { + this + } + #[cfg(any( + feature = "portable-atomic", + target_has_atomic = "ptr", + has_atomic_load_store + ))] + /// Convert a `Queue` to a `QueueView` + fn as_mut_queue_view(this: &mut QueueInner) -> &mut QueueView { + this + } + /// Convert a `Deque` to a `DequeView` + fn as_deque_view(this: &DequeInner) -> &DequeView { + this + } + /// Convert a `Deque` to a `DequeView` + fn as_mut_deque_view(this: &mut DequeInner) -> &mut DequeView { + this + } + /// Convert a `String` to a `StringView` + fn as_string_view(this: &StringInner) -> &StringView { + this + } + /// Convert a `String` to a `StringView` + fn as_mut_string_view(this: &mut StringInner) -> &mut StringView { + this + } + /// Convert a `LinearMap` to a `LinearMapView` + fn as_linear_map_view(this: &LinearMapInner) -> &LinearMapView { + this + } + /// Convert a `LinearMap` to a `LinearMapView` + fn as_mut_linear_map_view( + this: &mut LinearMapInner, + ) -> &mut LinearMapView { + this + } + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView { + this + } + #[cfg(any( + feature = "portable-atomic", + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8") + ))] + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mut_mpmc_queue_view(this: &mut MpMcQueueInner) -> &mut MpMcQueueView { + this + } + fn as_binary_heap_view(this: &BinaryHeapInner) -> &BinaryHeapView { + this + } + /// Convert a `BinaryHeap` to a `BinaryHeapView` + fn as_mut_binary_heap_view( + this: &mut BinaryHeapInner, + ) -> &mut BinaryHeapView { + this + } + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_histbuf_view(this: &HistoryBufferInner) -> &HistoryBufferView { + this + } + /// Convert a `HistoryBuffer` to a `HistoryBufferView` + fn as_mut_histbuf_view(this: &mut HistoryBufferInner) -> &mut HistoryBufferView { + this + } } diff --git a/src/string/mod.rs b/src/string/mod.rs index 6dfe2055dc..596e1a3240 100644 --- a/src/string/mod.rs +++ b/src/string/mod.rs @@ -264,48 +264,6 @@ impl String { self.vec } - /// Get a reference to the `String`, erasing the `N` const-generic. - /// - /// - /// ```rust - /// # use heapless::string::{String, StringView}; - /// let s: String<10> = String::try_from("hello").unwrap(); - /// let view: &StringView = s.as_view(); - /// ``` - /// - /// It is often preferable to do the same through type coerction, since `String` implements `Unsize`: - /// - /// ```rust - /// # use heapless::string::{String, StringView}; - /// let s: String<10> = String::try_from("hello").unwrap(); - /// let view: &StringView = &s; - /// ``` - #[inline] - pub fn as_view(&self) -> &StringView { - self - } - - /// Get a mutable reference to the `String`, erasing the `N` const-generic. - /// - /// - /// ```rust - /// # use heapless::string::{String, StringView}; - /// let mut s: String<10> = String::try_from("hello").unwrap(); - /// let view: &mut StringView = s.as_mut_view(); - /// ``` - /// - /// It is often preferable to do the same through type coerction, since `String` implements `Unsize`: - /// - /// ```rust - /// # use heapless::string::{String, StringView}; - /// let mut s: String<10> = String::try_from("hello").unwrap(); - /// let view: &mut StringView = &mut s; - /// ``` - #[inline] - pub fn as_mut_view(&mut self) -> &mut StringView { - self - } - /// Removes the specified range from the string in bulk, returning all /// removed characters as an iterator. /// @@ -350,6 +308,48 @@ impl String { } impl StringInner { + /// Get a reference to the `String`, erasing the `N` const-generic. + /// + /// + /// ```rust + /// # use heapless::string::{String, StringView}; + /// let s: String<10> = String::try_from("hello").unwrap(); + /// let view: &StringView = s.as_view(); + /// ``` + /// + /// It is often preferable to do the same through type coerction, since `String` implements `Unsize`: + /// + /// ```rust + /// # use heapless::string::{String, StringView}; + /// let s: String<10> = String::try_from("hello").unwrap(); + /// let view: &StringView = &s; + /// ``` + #[inline] + pub fn as_view(&self) -> &StringView { + S::as_string_view(self) + } + + /// Get a mutable reference to the `String`, erasing the `N` const-generic. + /// + /// + /// ```rust + /// # use heapless::string::{String, StringView}; + /// let mut s: String<10> = String::try_from("hello").unwrap(); + /// let view: &mut StringView = s.as_mut_view(); + /// ``` + /// + /// It is often preferable to do the same through type coerction, since `String` implements `Unsize`: + /// + /// ```rust + /// # use heapless::string::{String, StringView}; + /// let mut s: String<10> = String::try_from("hello").unwrap(); + /// let view: &mut StringView = &mut s; + /// ``` + #[inline] + pub fn as_mut_view(&mut self) -> &mut StringView { + S::as_mut_string_view(self) + } + /// Extracts a string slice containing the entire string. /// /// # Examples diff --git a/src/vec/mod.rs b/src/vec/mod.rs index 1e1583a43e..c5eeb2f3ed 100644 --- a/src/vec/mod.rs +++ b/src/vec/mod.rs @@ -212,6 +212,15 @@ impl Vec { new } + /// Returns the maximum number of elements the vector can hold. + /// + /// This method is not available on a `VecView`, use [`storage_len`](VecInner::storage_capacity) instead + pub const fn capacity(&self) -> usize { + self.buffer.len() + } +} + +impl VecInner { /// Get a reference to the `Vec`, erasing the `N` const-generic. /// /// @@ -229,8 +238,8 @@ impl Vec { /// let view: &VecView = &vec; /// ``` #[inline] - pub const fn as_view(&self) -> &VecView { - self + pub fn as_view(&self) -> &VecView { + S::as_vec_view(self) } /// Get a mutable reference to the `Vec`, erasing the `N` const-generic. @@ -250,122 +259,9 @@ impl Vec { /// ``` #[inline] pub fn as_mut_view(&mut self) -> &mut VecView { - self + S::as_mut_vec_view(self) } - /// Removes the specified range from the vector in bulk, returning all - /// removed elements as an iterator. If the iterator is dropped before - /// being fully consumed, it drops the remaining removed elements. - /// - /// The returned iterator keeps a mutable borrow on the vector to optimize - /// its implementation. - /// - /// # Panics - /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. - /// - /// # Leaking - /// - /// If the returned iterator goes out of scope without being dropped (due to - /// [`mem::forget`], for example), the vector may have lost and leaked - /// elements arbitrarily, including elements outside the range. - /// - /// # Examples - /// - /// ``` - /// use heapless::Vec; - /// - /// let mut v = Vec::<_, 8>::from_array([1, 2, 3]); - /// let u: Vec<_, 8> = v.drain(1..).collect(); - /// assert_eq!(v, &[1]); - /// assert_eq!(u, &[2, 3]); - /// - /// // A full range clears the vector, like `clear()` does. - /// v.drain(..); - /// assert_eq!(v, &[]); - /// ``` - pub fn drain(&mut self, range: R) -> Drain<'_, T> - where - R: RangeBounds, - { - self.as_mut_view().drain(range) - } - - /// Returns the maximum number of elements the vector can hold. - /// - /// This method is not available on a `VecView`, use [`storage_len`](VecInner::storage_capacity) instead - pub const fn capacity(&self) -> usize { - self.buffer.len() - } -} - -impl VecView { - /// Removes the specified range from the vector in bulk, returning all - /// removed elements as an iterator. If the iterator is dropped before - /// being fully consumed, it drops the remaining removed elements. - /// - /// The returned iterator keeps a mutable borrow on the vector to optimize - /// its implementation. - /// - /// # Panics - /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. - /// - /// # Leaking - /// - /// If the returned iterator goes out of scope without being dropped (due to - /// [`mem::forget`], for example), the vector may have lost and leaked - /// elements arbitrarily, including elements outside the range. - /// - /// # Examples - /// - /// ``` - /// use heapless::Vec; - /// - /// let mut v = Vec::<_, 8>::from_array([1, 2, 3]); - /// let u: Vec<_, 8> = v.drain(1..).collect(); - /// assert_eq!(v, &[1]); - /// assert_eq!(u, &[2, 3]); - /// - /// // A full range clears the vector, like `clear()` does. - /// v.drain(..); - /// assert_eq!(v, &[]); - /// ``` - pub fn drain(&mut self, range: R) -> Drain<'_, T> - where - R: RangeBounds, - { - // Memory Safety - // - // When the `Drain` is first created, it shortens the length of - // the source vector to make sure no uninitialized or moved-from elements - // are accessible at all if the `Drain`'s destructor never gets to run. - // - // `Drain` will `ptr::read` out the values to remove. - // When finished, remaining tail of the vec is copied back to cover - // the hole, and the vector length is restored to the new length. - // - let len = self.len(); - let Range { start, end } = crate::slice::range(range, ..len); - - unsafe { - // Set `self.vec` length's to `start`, to be safe in case `Drain` is leaked. - self.set_len(start); - let vec = NonNull::from(self); - let range_slice = slice::from_raw_parts(vec.as_ref().as_ptr().add(start), end - start); - Drain { - tail_start: end, - tail_len: len - end, - iter: range_slice.iter(), - vec, - } - } - } -} - -impl VecInner { /// Returns a raw pointer to the vector’s buffer. pub fn as_ptr(&self) -> *const T { self.buffer.borrow().as_ptr() as *const T @@ -1104,6 +1000,71 @@ impl VecInner { pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { &mut self.buffer.borrow_mut()[self.len..] } + + /// Removes the specified range from the vector in bulk, returning all + /// removed elements as an iterator. If the iterator is dropped before + /// being fully consumed, it drops the remaining removed elements. + /// + /// The returned iterator keeps a mutable borrow on the vector to optimize + /// its implementation. + /// + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + /// + /// # Leaking + /// + /// If the returned iterator goes out of scope without being dropped (due to + /// [`mem::forget`], for example), the vector may have lost and leaked + /// elements arbitrarily, including elements outside the range. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut v = Vec::<_, 8>::from_array([1, 2, 3]); + /// let u: Vec<_, 8> = v.drain(1..).collect(); + /// assert_eq!(v, &[1]); + /// assert_eq!(u, &[2, 3]); + /// + /// // A full range clears the vector, like `clear()` does. + /// v.drain(..); + /// assert_eq!(v, &[]); + /// ``` + pub fn drain(&mut self, range: R) -> Drain<'_, T> + where + R: RangeBounds, + { + let this = S::as_mut_vec_view(self); + + // Memory Safety + // + // When the `Drain` is first created, it shortens the length of + // the source vector to make sure no uninitialized or moved-from elements + // are accessible at all if the `Drain`'s destructor never gets to run. + // + // `Drain` will `ptr::read` out the values to remove. + // When finished, remaining tail of the vec is copied back to cover + // the hole, and the vector length is restored to the new length. + // + let len = this.len(); + let Range { start, end } = crate::slice::range(range, ..len); + + unsafe { + // Set `self.vec` length's to `start`, to be safe in case `Drain` is leaked. + this.set_len(start); + let vec = NonNull::from(this); + let range_slice = slice::from_raw_parts(vec.as_ref().as_ptr().add(start), end - start); + Drain { + tail_start: end, + tail_len: len - end, + iter: range_slice.iter(), + vec, + } + } + } } // Trait implementations