From 90cd4eb220d4e4820977d193808250362d6bf622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 3 Jul 2024 10:22:34 +0200 Subject: [PATCH] Genericise `as_(mut)view` for all containers --- src/binary_heap.rs | 16 +-- src/deque.rs | 9 +- src/histbuf.rs | 9 ++ src/linear_map.rs | 14 +-- src/mpmc.rs | 11 +- src/sorted_linked_list.rs | 14 +-- src/spsc.rs | 8 +- src/storage.rs | 227 +++++++++++++++++++++++++++++++++++++- src/string/mod.rs | 84 +++++++------- 9 files changed, 310 insertions(+), 82 deletions(-) diff --git a/src/binary_heap.rs b/src/binary_heap.rs index 7e676a3851..a3d6a71317 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 5f09756f75..dec2ff207b 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 28f4e83d42..f915c97823 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 caef2caf9d..5758edb977 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -179,6 +179,9 @@ impl MpMcQueue { enqueue_pos: AtomicTargetSize::new(0), } } +} + +impl MpMcQueueInner { /// Get a reference to the `MpMcQueue`, erasing the `N` const-generic. /// /// @@ -196,8 +199,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. @@ -217,11 +220,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 5311a7897e..2ecbcbcf2e 100644 --- a/src/spsc.rs +++ b/src/spsc.rs @@ -155,19 +155,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 af726d4751..40489c5dcb 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -2,7 +2,18 @@ use core::borrow::{Borrow, BorrowMut}; -use crate::{vec::VecInner, VecView}; +use crate::{ + binary_heap::{BinaryHeapInner, BinaryHeapView}, + deque::{DequeInner, DequeView}, + histbuf::{HistoryBufferInner, HistoryBufferView}, + linear_map::{LinearMapInner, LinearMapView}, + mpmc::{MpMcQueueInner, MpMcQueueView}, + sorted_linked_list::{SortedLinkedListIndex, SortedLinkedListInner, SortedLinkedListView}, + spsc::{QueueInner, QueueView}, + string::{StringInner, StringView}, + vec::VecInner, + VecView, +}; pub(crate) trait SealedStorage: Sized { type Buffer: ?Sized + Borrow<[T]> + BorrowMut<[T]>; @@ -21,6 +32,78 @@ pub(crate) trait SealedStorage: Sized { 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; + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView + where + Self: Storage; + /// 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; + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView + where + Self: Storage; + /// 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. @@ -64,6 +147,77 @@ impl SealedStorage for OwnedStorage { 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 + } + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView { + this + } + /// 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 + } + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView { + this + } + /// 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]`. @@ -86,4 +240,75 @@ impl SealedStorage for ViewStorage { 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 + } + /// Convert a `Queue` to a `QueueView` + fn as_queue_view(this: &QueueInner) -> &QueueView { + this + } + /// 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 + } + /// Convert a `MpMcQueue` to a `MpMcQueueView` + fn as_mpmc_queue_view(this: &MpMcQueueInner) -> &MpMcQueueView { + this + } + /// 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 d88dbf0fd0..514540c920 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