From d52af1e050238ec7ef83b9bfe6ac2887baeb7b08 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Thu, 18 Jul 2024 20:41:53 +0100 Subject: [PATCH] Implement a generic length parameter for Vec --- src/binary_heap.rs | 4 +- src/de.rs | 11 +- src/defmt.rs | 4 +- src/indexmap.rs | 4 +- src/len_type.rs | 99 ++++++++++++ src/lib.rs | 2 + src/linear_map.rs | 4 +- src/ser.rs | 6 +- src/string/mod.rs | 19 ++- src/ufmt.rs | 4 +- src/vec/drain.rs | 46 +++--- src/vec/mod.rs | 380 +++++++++++++++++++++++++++------------------ 12 files changed, 381 insertions(+), 202 deletions(-) create mode 100644 src/len_type.rs diff --git a/src/binary_heap.rs b/src/binary_heap.rs index 7e676a3851..224692ba26 100644 --- a/src/binary_heap.rs +++ b/src/binary_heap.rs @@ -60,7 +60,7 @@ impl private::Sealed for Min {} /// struct if you want to write code that's generic over both. pub struct BinaryHeapInner { pub(crate) _kind: PhantomData, - pub(crate) data: VecInner, + pub(crate) data: VecInner, } /// A priority queue implemented with a binary heap. @@ -184,7 +184,7 @@ impl BinaryHeap { impl BinaryHeap { /// Returns the underlying `Vec`. Order is arbitrary and time is *O*(1). - pub fn into_vec(self) -> Vec { + pub fn into_vec(self) -> Vec { self.data } diff --git a/src/de.rs b/src/de.rs index 455295b717..f81ee82955 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,6 +1,6 @@ use crate::{ binary_heap::Kind as BinaryHeapKind, BinaryHeap, Deque, HistoryBuffer, IndexMap, IndexSet, - LinearMap, String, Vec, + LenType, LinearMap, String, Vec, }; use core::{ fmt, @@ -95,7 +95,7 @@ where } } -impl<'de, T, const N: usize> Deserialize<'de> for Vec +impl<'de, T, LenT: LenType, const N: usize> Deserialize<'de> for Vec where T: Deserialize<'de>, { @@ -103,13 +103,14 @@ where where D: Deserializer<'de>, { - struct ValueVisitor<'de, T, const N: usize>(PhantomData<(&'de (), T)>); + struct ValueVisitor<'de, T, LenT: LenType, const N: usize>(PhantomData<(&'de (), T, LenT)>); - impl<'de, T, const N: usize> serde::de::Visitor<'de> for ValueVisitor<'de, T, N> + impl<'de, T, LenT, const N: usize> serde::de::Visitor<'de> for ValueVisitor<'de, T, LenT, N> where T: Deserialize<'de>, + LenT: LenType, { - type Value = Vec; + type Value = Vec; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence") diff --git a/src/defmt.rs b/src/defmt.rs index 6d547c09b7..6d5f07fcea 100644 --- a/src/defmt.rs +++ b/src/defmt.rs @@ -1,9 +1,9 @@ //! Defmt implementations for heapless types -use crate::{storage::Storage, string::StringInner, vec::VecInner}; +use crate::{storage::Storage, string::StringInner, vec::VecInner, LenType}; use defmt::Formatter; -impl defmt::Format for VecInner +impl defmt::Format for VecInner where T: defmt::Format, { diff --git a/src/indexmap.rs b/src/indexmap.rs index 80efe62e73..56bd33a618 100644 --- a/src/indexmap.rs +++ b/src/indexmap.rs @@ -138,7 +138,7 @@ macro_rules! probe_loop { } struct CoreMap { - entries: Vec, N>, + entries: Vec, N, usize>, indices: [Option; N], } @@ -1298,7 +1298,7 @@ where #[derive(Clone)] pub struct IntoIter { - entries: Vec, N>, + entries: Vec, N, usize>, } impl Iterator for IntoIter { diff --git a/src/len_type.rs b/src/len_type.rs new file mode 100644 index 0000000000..9263a5f980 --- /dev/null +++ b/src/len_type.rs @@ -0,0 +1,99 @@ +use core::{ + fmt::{Debug, Display}, + ops::{Add, AddAssign, Sub, SubAssign}, +}; + +mod private { + pub trait Sealed {} + + impl Sealed for u8 {} + impl Sealed for u16 {} + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] + impl Sealed for u32 {} + + impl Sealed for usize {} +} + +macro_rules! impl_lentype { + ($($(#[$meta:meta])* $LenT:ty),*) => {$( + $(#[$meta])* + impl LenType for $LenT { + const ZERO: Self = 0; + const ONE: Self = 1; + const MAX: usize = Self::MAX as _; + } + )*} +} + +/// A sealed trait representing a valid type to use as a length for a container. +/// +/// This cannot be implemented in user code, and is restricted to `u8`, `u16`, `u32`, and `usize`. +pub trait LenType: + private::Sealed + + Send + + Sync + + Copy + + Display + + Debug + + PartialEq + + Add + + AddAssign + + Sub + + SubAssign + + PartialOrd + + TryFrom + + TryInto +{ + /// The zero value of the integer type. + const ZERO: Self; + /// The one value of the integer type. + const ONE: Self; + /// The maxiumum value of this type, as a usize. + const MAX: usize; + + /// An infallible conversion from `usize` to `LenT`. + fn from_usize(val: usize) -> Self { + val.try_into().unwrap() + } + + /// An infallible conversion from `LenT` to `usize`. + fn into_usize(self) -> usize { + self.try_into().unwrap() + } +} + +impl_lentype!( + u8, + u16, + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] + u32, + usize +); + +macro_rules! impl_lentodefault { + ($LenT:ty: $($len:literal),*) => {$( + impl LenToDefault for Const<$len> { + type Default = $LenT; + } + )*}; +} + +pub struct Const; + +#[diagnostic::on_unimplemented( + message = "Length `N` does not have a default LenType mapping", + note = "Provide the `LenType` explicitly, such as `usize`" +)] +pub trait LenToDefault { + type Default: LenType; +} + +pub type DefaultLenType = as LenToDefault>::Default; + +impl_lentodefault!(u8: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255); +impl_lentodefault!(u16: 256, 300, 400, 500, 512, 600, 700, 800, 900, 1000, 1024, 2000, 2048, 4000, 4096, 8000, 8192, 16000, 16384, 32000, 32768, 65000, 65535); +impl_lentodefault!(u32: 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648); + +pub const fn check_capacity_fits() { + assert!(LenT::MAX >= N, "The capacity is larger than LenT can hold, increase the size of `LenT` or reduce the capacity") +} diff --git a/src/lib.rs b/src/lib.rs index 17f6056dc3..eb465e84f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,6 +94,7 @@ pub use indexmap::{ ValuesMut as IndexMapValuesMut, }; pub use indexset::{FnvIndexSet, IndexSet, Iter as IndexSetIter}; +pub use len_type::LenType; pub use linear_map::LinearMap; pub use string::String; @@ -107,6 +108,7 @@ pub mod deque; pub mod histbuf; mod indexmap; mod indexset; +mod len_type; pub mod linear_map; mod slice; pub mod storage; diff --git a/src/linear_map.rs b/src/linear_map.rs index 28f4e83d42..808505f7fc 100644 --- a/src/linear_map.rs +++ b/src/linear_map.rs @@ -12,7 +12,7 @@ use crate::{ /// Base struct for [`LinearMap`] and [`LinearMapView`] pub struct LinearMapInner { - pub(crate) buffer: VecInner<(K, V), S>, + pub(crate) buffer: VecInner<(K, V), usize, S>, } /// A fixed capacity map/dictionary that performs lookups via linear search. @@ -445,7 +445,7 @@ pub struct IntoIter where K: Eq, { - inner: as IntoIterator>::IntoIter, + inner: as IntoIterator>::IntoIter, } impl Iterator for IntoIter diff --git a/src/ser.rs b/src/ser.rs index d26add100d..f0234d26db 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -8,7 +8,7 @@ use crate::{ storage::Storage, string::StringInner, vec::VecInner, - IndexMap, IndexSet, + IndexMap, IndexSet, LenType, }; use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer}; @@ -49,7 +49,7 @@ where } } -impl Serialize for VecInner +impl Serialize for VecInner where T: Serialize, { @@ -57,7 +57,7 @@ where where S: Serializer, { - let mut seq = serializer.serialize_seq(Some(self.len()))?; + let mut seq = serializer.serialize_seq(Some(self.len().into_usize()))?; for element in self { seq.serialize_element(element)?; } diff --git a/src/string/mod.rs b/src/string/mod.rs index d88dbf0fd0..6fe05a6da9 100644 --- a/src/string/mod.rs +++ b/src/string/mod.rs @@ -12,6 +12,7 @@ use core::{ }; use crate::{ + len_type::LenType, storage::{OwnedStorage, Storage, ViewStorage}, vec::VecInner, Vec, @@ -47,7 +48,7 @@ impl fmt::Display for FromUtf16Error { /// In most cases you should use [`String`] or [`StringView`] directly. Only use this /// struct if you want to write code that's generic over both. pub struct StringInner { - vec: VecInner, + vec: VecInner, } /// A fixed capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html). @@ -210,9 +211,9 @@ impl String { /// # Ok::<(), core::str::Utf8Error>(()) /// ``` #[inline] - pub fn from_utf8(vec: Vec) -> Result { + pub fn from_utf8(vec: Vec) -> Result { core::str::from_utf8(&vec)?; - Ok(Self { vec }) + Ok(unsafe { Self::from_utf8_unchecked(vec) }) } /// Convert UTF-8 bytes into a `String`, without checking that the string @@ -237,8 +238,10 @@ impl String { /// assert_eq!("💖", sparkle_heart); /// ``` #[inline] - pub unsafe fn from_utf8_unchecked(vec: Vec) -> Self { - Self { vec } + pub unsafe fn from_utf8_unchecked(vec: Vec) -> Self { + Self { + vec: vec.cast_len_type(), + } } /// Converts a `String` into a byte vector. @@ -260,7 +263,7 @@ impl String { /// # Ok::<(), ()>(()) /// ``` #[inline] - pub fn into_bytes(self) -> Vec { + pub fn into_bytes(self) -> Vec { self.vec } @@ -417,7 +420,7 @@ impl StringInner { /// assert_eq!(s, "olleh"); /// # Ok::<(), ()>(()) /// ``` - pub unsafe fn as_mut_vec(&mut self) -> &mut VecInner { + pub unsafe fn as_mut_vec(&mut self) -> &mut VecInner { &mut self.vec } @@ -1025,7 +1028,7 @@ mod tests { #[test] fn into_bytes() { let s: String<4> = String::try_from("ab").unwrap(); - let b: Vec = s.into_bytes(); + let b: Vec = s.into_bytes(); assert_eq!(b.len(), 2); assert_eq!(&[b'a', b'b'], &b[..]); } diff --git a/src/ufmt.rs b/src/ufmt.rs index 002ce04c46..7bb0573cd5 100644 --- a/src/ufmt.rs +++ b/src/ufmt.rs @@ -1,4 +1,4 @@ -use crate::{storage::Storage, string::StringInner, vec::VecInner}; +use crate::{storage::Storage, string::StringInner, vec::VecInner, LenType}; use ufmt_write::uWrite; impl uWrite for StringInner { @@ -8,7 +8,7 @@ impl uWrite for StringInner { } } -impl uWrite for VecInner { +impl uWrite for VecInner { type Error = (); fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { self.extend_from_slice(s.as_bytes()) diff --git a/src/vec/drain.rs b/src/vec/drain.rs index f501cfb188..85c423488f 100644 --- a/src/vec/drain.rs +++ b/src/vec/drain.rs @@ -6,7 +6,7 @@ use core::{ slice, }; -use super::VecView; +use super::{LenType, VecView}; /// A draining iterator for [`Vec`](super::Vec). /// @@ -19,25 +19,25 @@ use super::VecView; /// use heapless::{vec, Vec}; /// /// let mut v = Vec::<_, 4>::from_array([0, 1, 2]); -/// let iter: vec::Drain<'_, _> = v.drain(..); +/// let iter: vec::Drain<'_, _, _> = v.drain(..); /// ``` -pub struct Drain<'a, T: 'a> { +pub struct Drain<'a, T: 'a, LenT: LenType> { /// Index of tail to preserve - pub(super) tail_start: usize, + pub(super) tail_start: LenT, /// Length of tail - pub(super) tail_len: usize, + pub(super) tail_len: LenT, /// Current remaining range to remove pub(super) iter: slice::Iter<'a, T>, - pub(super) vec: NonNull>, + pub(super) vec: NonNull>, } -impl fmt::Debug for Drain<'_, T> { +impl fmt::Debug for Drain<'_, T, LenT> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() } } -impl<'a, T> Drain<'a, T> { +impl<'a, T, LenT: LenType> Drain<'a, T, LenT> { /// Returns the remaining items of this iterator as a slice. /// /// # Examples @@ -57,16 +57,16 @@ impl<'a, T> Drain<'a, T> { } } -impl<'a, T> AsRef<[T]> for Drain<'a, T> { +impl<'a, T, LenT: LenType> AsRef<[T]> for Drain<'a, T, LenT> { fn as_ref(&self) -> &[T] { self.as_slice() } } -unsafe impl Sync for Drain<'_, T> {} -unsafe impl Send for Drain<'_, T> {} +unsafe impl Sync for Drain<'_, T, LenT> {} +unsafe impl Send for Drain<'_, T, LenT> {} -impl Iterator for Drain<'_, T> { +impl Iterator for Drain<'_, T, LenT> { type Item = T; #[inline] @@ -81,7 +81,7 @@ impl Iterator for Drain<'_, T> { } } -impl DoubleEndedIterator for Drain<'_, T> { +impl DoubleEndedIterator for Drain<'_, T, LenT> { #[inline] fn next_back(&mut self) -> Option { self.iter @@ -90,23 +90,23 @@ impl DoubleEndedIterator for Drain<'_, T> { } } -impl Drop for Drain<'_, T> { +impl Drop for Drain<'_, T, LenT> { fn drop(&mut self) { /// Moves back the un-`Drain`ed elements to restore the original `Vec`. - struct DropGuard<'r, 'a, T>(&'r mut Drain<'a, T>); + struct DropGuard<'r, 'a, T, LenT: LenType>(&'r mut Drain<'a, T, LenT>); - impl<'r, 'a, T> Drop for DropGuard<'r, 'a, T> { + impl<'r, 'a, T, LenT: LenType> Drop for DropGuard<'r, 'a, T, LenT> { fn drop(&mut self) { - if self.0.tail_len > 0 { + if self.0.tail_len > LenT::ZERO { unsafe { let source_vec = self.0.vec.as_mut(); // memmove back untouched tail, update to new length let start = source_vec.len(); let tail = self.0.tail_start; if tail != start { - let dst = source_vec.as_mut_ptr().add(start); - let src = source_vec.as_ptr().add(tail); - ptr::copy(src, dst, self.0.tail_len); + let dst = source_vec.as_mut_ptr().add(start.into_usize()); + let src = source_vec.as_ptr().add(tail.into_usize()); + ptr::copy(src, dst, self.0.tail_len.into_usize()); } source_vec.set_len(start + self.0.tail_len); } @@ -125,7 +125,7 @@ impl Drop for Drain<'_, T> { unsafe { let vec = vec.as_mut(); let old_len = vec.len(); - vec.set_len(old_len + drop_len + self.tail_len); + vec.set_len(old_len + LenT::from_usize(drop_len) + self.tail_len); vec.truncate(old_len + self.tail_len); } @@ -159,9 +159,9 @@ impl Drop for Drain<'_, T> { } } -impl ExactSizeIterator for Drain<'_, T> {} +impl ExactSizeIterator for Drain<'_, T, LenT> {} -impl FusedIterator for Drain<'_, T> {} +impl FusedIterator for Drain<'_, T, LenT> {} #[cfg(test)] mod tests { diff --git a/src/vec/mod.rs b/src/vec/mod.rs index 1e1583a43e..345d1eb652 100644 --- a/src/vec/mod.rs +++ b/src/vec/mod.rs @@ -1,6 +1,7 @@ //! A fixed capacity [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html). use core::borrow; +use core::cmp::PartialOrd; use core::{ borrow::{Borrow, BorrowMut}, cmp::Ordering, @@ -11,6 +12,7 @@ use core::{ slice, }; +use crate::len_type::{check_capacity_fits, DefaultLenType, LenType}; use crate::storage::{OwnedStorage, Storage, ViewStorage}; mod drain; @@ -20,8 +22,8 @@ pub use drain::Drain; /// /// In most cases you should use [`Vec`] or [`VecView`] directly. Only use this /// struct if you want to write code that's generic over both. -pub struct VecInner { - len: usize, +pub struct VecInner { + len: LenT, buffer: S::Buffer>, } @@ -60,9 +62,13 @@ pub struct VecInner { /// use heapless::{Vec, VecView}; /// /// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); -/// let view: &VecView<_> = &vec; +/// let view: &VecView<_, _> = &vec; /// ``` -pub type Vec = VecInner>; +/// +/// For uncommmon capacity values, or in generic scenarios, you may have to provide the `LenT` generic yourself. +/// +/// This should be the smallest unsigned integer type that your capacity fits in, or `usize` if you don't want to consider this. +pub type Vec> = VecInner>; /// A [`Vec`] with dynamic capacity /// @@ -72,22 +78,22 @@ pub type Vec = VecInner>; /// This has the ergonomic advantage of making it possible to use functions without needing to know at /// compile-time the size of the buffers used, for example for use in `dyn` traits. /// -/// `VecView` is to `Vec` what `[T]` is to `[T; N]`. +/// `VecView` is to `Vec` what `[T]` is to `[T; N]`. /// /// ```rust /// use heapless::{Vec, VecView}; /// /// let mut vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); -/// let view: &VecView<_> = &vec; +/// let view: &VecView<_, _> = &vec; /// assert_eq!(view, &[1, 2, 3, 4]); /// -/// let mut_view: &mut VecView<_> = &mut vec; +/// let mut_view: &mut VecView<_, _> = &mut vec; /// mut_view.push(5); /// assert_eq!(vec, [1, 2, 3, 4, 5]); /// ``` -pub type VecView = VecInner; +pub type VecView = VecInner; -impl Vec { +impl Vec { const ELEM: MaybeUninit = MaybeUninit::uninit(); const INIT: [MaybeUninit; N] = [Self::ELEM; N]; // important for optimization of `new` @@ -105,8 +111,10 @@ impl Vec { /// static mut X: Vec = Vec::new(); /// ``` pub const fn new() -> Self { + const { check_capacity_fits::() } + Self { - len: 0, + len: LenT::ZERO, buffer: Self::INIT, } } @@ -141,6 +149,8 @@ impl Vec { /// If the length of the provided array is greater than the capacity of the /// vector a compile-time error will be produced. pub fn from_array(src: [T; M]) -> Self { + const { check_capacity_fits::() } + // Const assert M >= 0 crate::sealed::greater_than_eq_0::(); // Const assert N >= M @@ -152,13 +162,13 @@ impl Vec { if N == M { Self { - len: N, + len: LenType::from_usize(N), // NOTE(unsafe) ManuallyDrop<[T; M]> and [MaybeUninit; N] // have the same layout when N == M. buffer: unsafe { mem::transmute_copy(&src) }, } } else { - let mut v = Vec::::new(); + let mut v = Vec::::new(); for (src_elem, dst_elem) in src.iter().zip(v.buffer.iter_mut()) { // NOTE(unsafe) src element is not going to drop as src itself @@ -166,11 +176,26 @@ impl Vec { dst_elem.write(unsafe { ptr::read(src_elem) }); } - v.len = M; + v.len = LenType::from_usize(M); v } } + /// Casts the `LenT` type to a new type, preserving everything else about the vector. + /// + /// This can be useful if you need to pass a `Vec` into a `Vec` for example. + /// + /// This will check at compile time if the `N` value will fit into `NewLenT`, and error if not. + pub fn cast_len_type(self) -> Vec { + const { check_capacity_fits::() } + let this = ManuallyDrop::new(self); + + Vec { + len: NewLenT::from_usize(this.len.into_usize()), + buffer: unsafe { ptr::read(&this.buffer) }, + } + } + /// Returns the contents of the vector as an array of length `M` if the length /// of the vector is exactly `M`, otherwise returns `Err(self)`. /// @@ -183,7 +208,7 @@ impl Vec { /// assert_eq!(array, [1, 2, 3, 5, 8]); /// ``` pub fn into_array(self) -> Result<[T; M], Self> { - if self.len() == M { + if self.len.into_usize() == M { // This is how the unstable `MaybeUninit::array_assume_init` method does it let array = unsafe { (&self.buffer as *const _ as *const [T; M]).read() }; @@ -218,7 +243,7 @@ impl Vec { /// ```rust /// # use heapless::{Vec, VecView}; /// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); - /// let view: &VecView = vec.as_view(); + /// let view: &VecView = vec.as_view(); /// ``` /// /// It is often preferable to do the same through type coerction, since `Vec` implements `Unsize>`: @@ -226,10 +251,10 @@ impl Vec { /// ```rust /// # use heapless::{Vec, VecView}; /// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); - /// let view: &VecView = &vec; + /// let view: &VecView = &vec; /// ``` #[inline] - pub const fn as_view(&self) -> &VecView { + pub const fn as_view(&self) -> &VecView { self } @@ -238,7 +263,7 @@ impl Vec { /// ```rust /// # use heapless::{Vec, VecView}; /// let mut vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); - /// let view: &mut VecView = vec.as_mut_view(); + /// let view: &mut VecView = vec.as_mut_view(); /// ``` /// /// It is often preferable to do the same through type coerction, since `Vec` implements `Unsize>`: @@ -246,10 +271,10 @@ impl Vec { /// ```rust /// # use heapless::{Vec, VecView}; /// let mut vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); - /// let view: &mut VecView = &mut vec; + /// let view: &mut VecView = &mut vec; /// ``` #[inline] - pub fn as_mut_view(&mut self) -> &mut VecView { + pub fn as_mut_view(&mut self) -> &mut VecView { self } @@ -285,7 +310,7 @@ impl Vec { /// v.drain(..); /// assert_eq!(v, &[]); /// ``` - pub fn drain(&mut self, range: R) -> Drain<'_, T> + pub fn drain(&mut self, range: R) -> Drain<'_, T, LenT> where R: RangeBounds, { @@ -300,7 +325,7 @@ impl Vec { } } -impl VecView { +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. @@ -333,7 +358,7 @@ impl VecView { /// v.drain(..); /// assert_eq!(v, &[]); /// ``` - pub fn drain(&mut self, range: R) -> Drain<'_, T> + pub fn drain(&mut self, range: R) -> Drain<'_, T, LenT> where R: RangeBounds, { @@ -348,16 +373,16 @@ impl VecView { // 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); + let Range { start, end } = crate::slice::range(range, ..len.into_usize()); unsafe { // Set `self.vec` length's to `start`, to be safe in case `Drain` is leaked. - self.set_len(start); + self.set_len(LenT::from_usize(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, + tail_start: LenT::from_usize(end), + tail_len: LenT::from_usize(len.into_usize() - end), iter: range_slice.iter(), vec, } @@ -365,7 +390,12 @@ impl VecView { } } -impl VecInner { +impl VecInner { + /// Returns the length of the vector. + pub fn len(&self) -> LenT { + self.len + } + /// Returns a raw pointer to the vector’s buffer. pub fn as_ptr(&self) -> *const T { self.buffer.borrow().as_ptr() as *const T @@ -390,7 +420,12 @@ impl VecInner { pub fn as_slice(&self) -> &[T] { // NOTE(unsafe) avoid bound checks in the slicing operation // &buffer[..self.len] - unsafe { slice::from_raw_parts(self.buffer.borrow().as_ptr() as *const T, self.len) } + unsafe { + slice::from_raw_parts( + self.buffer.borrow().as_ptr() as *const T, + self.len.into_usize(), + ) + } } /// Extracts a mutable slice containing the entire vector. @@ -410,7 +445,10 @@ impl VecInner { // NOTE(unsafe) avoid bound checks in the slicing operation // &mut buffer[..self.len] unsafe { - slice::from_raw_parts_mut(self.buffer.borrow_mut().as_mut_ptr() as *mut T, self.len) + slice::from_raw_parts_mut( + self.buffer.borrow_mut().as_mut_ptr() as *mut T, + self.len.into_usize(), + ) } } @@ -421,7 +459,7 @@ impl VecInner { /// Clears the vector, removing all values. pub fn clear(&mut self) { - self.truncate(0); + self.truncate(LenT::ZERO); } /// Extends the vec from an iterator. @@ -459,31 +497,33 @@ impl VecInner { T: Clone, { pub fn extend_from_slice_inner( - len: &mut usize, + mut len: usize, buf: &mut [MaybeUninit], other: &[T], - ) -> Result<(), ()> + ) -> Result where T: Clone, { - if *len + other.len() > buf.len() { + if len + other.len() > buf.len() { // won't fit in the `Vec`; don't modify anything and return an error Err(()) } else { for elem in other { - unsafe { *buf.get_unchecked_mut(*len) = MaybeUninit::new(elem.clone()) } - *len += 1; + unsafe { *buf.get_unchecked_mut(len) = MaybeUninit::new(elem.clone()) } + len += 1; } - Ok(()) + Ok(len) } } - extend_from_slice_inner(&mut self.len, self.buffer.borrow_mut(), other) + let len = extend_from_slice_inner(self.len.into_usize(), self.buffer.borrow_mut(), other)?; + self.len = LenT::from_usize(len); + Ok(()) } /// Removes the last element from a vector and returns it, or `None` if it's empty pub fn pop(&mut self) -> Option { - if self.len != 0 { + if self.len != LenT::ZERO { Some(unsafe { self.pop_unchecked() }) } else { None @@ -494,7 +534,7 @@ impl VecInner { /// /// Returns back the `item` if the vector is full. pub fn push(&mut self, item: T) -> Result<(), T> { - if self.len < self.storage_capacity() { + if self.len.into_usize() < self.storage_capacity() { unsafe { self.push_unchecked(item) } Ok(()) } else { @@ -510,10 +550,10 @@ impl VecInner { pub unsafe fn pop_unchecked(&mut self) -> T { debug_assert!(!self.is_empty()); - self.len -= 1; + self.len -= LenT::ONE; self.buffer .borrow_mut() - .get_unchecked_mut(self.len) + .get_unchecked_mut(self.len.into_usize()) .as_ptr() .read() } @@ -528,13 +568,16 @@ impl VecInner { // use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory debug_assert!(!self.is_full()); - *self.buffer.borrow_mut().get_unchecked_mut(self.len) = MaybeUninit::new(item); + *self + .buffer + .borrow_mut() + .get_unchecked_mut(self.len.into_usize()) = MaybeUninit::new(item); - self.len += 1; + self.len += LenT::ONE; } /// Shortens the vector, keeping the first `len` elements and dropping the rest. - pub fn truncate(&mut self, len: usize) { + pub fn truncate(&mut self, len: LenT) { // This is safe because: // // * the slice passed to `drop_in_place` is valid; the `len > self.len` @@ -550,7 +593,10 @@ impl VecInner { return; } let remaining_len = self.len - len; - let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len); + let s = ptr::slice_from_raw_parts_mut( + self.as_mut_ptr().add(len.into_usize()), + remaining_len.into_usize(), + ); self.len = len; ptr::drop_in_place(s); } @@ -564,11 +610,11 @@ impl VecInner { /// /// See also [`resize_default`](Self::resize_default). #[allow(clippy::result_unit_err)] - pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()> + pub fn resize(&mut self, new_len: LenT, value: T) -> Result<(), ()> where T: Clone, { - if new_len > self.storage_capacity() { + if new_len.into_usize() > self.storage_capacity() { return Err(()); } @@ -591,7 +637,7 @@ impl VecInner { /// /// See also [`resize`](Self::resize). #[allow(clippy::result_unit_err)] - pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()> + pub fn resize_default(&mut self, new_len: LenT) -> Result<(), ()> where T: Clone + Default, { @@ -651,7 +697,7 @@ impl VecInner { /// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length); /// if r == Z_OK { /// // ...and update the length to what was initialized. - /// dict.set_len(dict_length); + /// dict.set_len(dict_length as u16); /// Some(dict) /// } else { /// None @@ -687,8 +733,8 @@ impl VecInner { /// /// Normally, here, one would use [`clear`] instead to correctly drop /// the contents and thus not leak memory. - pub unsafe fn set_len(&mut self, new_len: usize) { - debug_assert!(new_len <= self.storage_capacity()); + pub unsafe fn set_len(&mut self, new_len: LenT) { + debug_assert!(new_len.into_usize() <= self.storage_capacity()); self.len = new_len } @@ -720,7 +766,7 @@ impl VecInner { /// assert_eq!(v.swap_remove(0), "foo"); /// assert_eq!(&*v, ["baz", "qux"]); /// ``` - pub fn swap_remove(&mut self, index: usize) -> T { + pub fn swap_remove(&mut self, index: LenT) -> T { assert!(index < self.len); unsafe { self.swap_remove_unchecked(index) } } @@ -752,24 +798,28 @@ impl VecInner { /// assert_eq!(unsafe { v.swap_remove_unchecked(0) }, "foo"); /// assert_eq!(&*v, ["baz", "qux"]); /// ``` - pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T { + pub unsafe fn swap_remove_unchecked(&mut self, index: LenT) -> T { let length = self.len(); debug_assert!(index < length); - let value = ptr::read(self.as_ptr().add(index)); + let value = ptr::read(self.as_ptr().add(index.into_usize())); let base_ptr = self.as_mut_ptr(); - ptr::copy(base_ptr.add(length - 1), base_ptr.add(index), 1); - self.len -= 1; + ptr::copy( + base_ptr.add((length - LenT::ONE).into_usize()), + base_ptr.add(index.into_usize()), + 1, + ); + self.len -= LenT::ONE; value } /// Returns true if the vec is full pub fn is_full(&self) -> bool { - self.len == self.storage_capacity() + self.len.into_usize() == self.storage_capacity() } /// Returns true if the vec is empty pub fn is_empty(&self) -> bool { - self.len == 0 + self.len == LenT::ZERO } /// Returns `true` if `needle` is a prefix of the Vec. @@ -791,7 +841,7 @@ impl VecInner { T: PartialEq, { let n = needle.len(); - self.len >= n && needle == &self[..n] + self.len.into_usize() >= n && needle == &self[..n] } /// Returns `true` if `needle` is a suffix of the Vec. @@ -812,7 +862,7 @@ impl VecInner { where T: PartialEq, { - let (v, n) = (self.len(), needle.len()); + let (v, n) = (self.len().into_usize(), needle.len()); v >= n && needle == &self[v - n..] } @@ -836,7 +886,7 @@ impl VecInner { /// vec.insert(4, 5); /// assert_eq!(vec, [1, 4, 2, 3, 5]); /// ``` - pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> { + pub fn insert(&mut self, index: LenT, element: T) -> Result<(), T> { let len = self.len(); if index > len { panic!( @@ -854,15 +904,15 @@ impl VecInner { // infallible // The spot to put the new value { - let p = self.as_mut_ptr().add(index); + let p = self.as_mut_ptr().add(index.into_usize()); // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.) - ptr::copy(p, p.offset(1), len - index); + ptr::copy(p, p.offset(1), (len - index).into_usize()); // Write it in, overwriting the first copy of the `index`th // element. ptr::write(p, element); } - self.set_len(len + 1); + self.set_len(len + LenT::ONE); } Ok(()) @@ -893,7 +943,7 @@ impl VecInner { /// assert_eq!(v.remove(1), 2); /// assert_eq!(v, [1, 3]); /// ``` - pub fn remove(&mut self, index: usize) -> T { + pub fn remove(&mut self, index: LenT) -> T { let len = self.len(); if index >= len { panic!("removal index (is {}) should be < len (is {})", index, len); @@ -903,15 +953,15 @@ impl VecInner { let ret; { // the place we are taking from. - let ptr = self.as_mut_ptr().add(index); + let ptr = self.as_mut_ptr().add(index.into_usize()); // copy it out, unsafely having a copy of the value on // the stack and in the vector at the same time. ret = ptr::read(ptr); // Shift everything down to fill in that spot. - ptr::copy(ptr.offset(1), ptr, len - index - 1); + ptr::copy(ptr.offset(1), ptr, (len - index - LenT::ONE).into_usize()); } - self.set_len(len - 1); + self.set_len(len - LenT::ONE); ret } } @@ -980,7 +1030,7 @@ impl VecInner { let original_len = self.len(); // Avoid double drop if the drop guard is not executed, // since we may make some holes during the process. - unsafe { self.set_len(0) }; + unsafe { self.set_len(LenT::ZERO) }; // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked] // |<- processed len ->| ^- next to check @@ -993,24 +1043,24 @@ impl VecInner { // This drop guard will be invoked when predicate or `drop` of element panicked. // It shifts unchecked elements to cover holes and `set_len` to the correct length. // In cases when predicate and `drop` never panick, it will be optimized out. - struct BackshiftOnDrop<'a, T, S: Storage> { - v: &'a mut VecInner, - processed_len: usize, - deleted_cnt: usize, - original_len: usize, + struct BackshiftOnDrop<'a, T, LenT: LenType, S: Storage> { + v: &'a mut VecInner, + processed_len: LenT, + deleted_cnt: LenT, + original_len: LenT, } - impl<'a, T, S: Storage> Drop for BackshiftOnDrop<'a, T, S> { + impl<'a, T, LenT: LenType, S: Storage> Drop for BackshiftOnDrop<'a, T, LenT, S> { fn drop(&mut self) { - if self.deleted_cnt > 0 { + if self.deleted_cnt > LenT::ZERO { // SAFETY: Trailing unchecked items must be valid since we never touch them. unsafe { ptr::copy( - self.v.as_ptr().add(self.processed_len), + self.v.as_ptr().add(self.processed_len.into_usize()), self.v .as_mut_ptr() - .add(self.processed_len - self.deleted_cnt), - self.original_len - self.processed_len, + .add((self.processed_len - self.deleted_cnt).into_usize()), + (self.original_len - self.processed_len).into_usize(), ); } } @@ -1023,26 +1073,26 @@ impl VecInner { let mut g = BackshiftOnDrop { v: self, - processed_len: 0, - deleted_cnt: 0, + processed_len: LenT::ZERO, + deleted_cnt: LenT::ZERO, original_len, }; - fn process_loop( - original_len: usize, + fn process_loop( + original_len: LenT, f: &mut F, - g: &mut BackshiftOnDrop<'_, T, S>, + g: &mut BackshiftOnDrop<'_, T, LenT, S>, ) where F: FnMut(&mut T) -> bool, { while g.processed_len != original_len { let p = g.v.as_mut_ptr(); // SAFETY: Unchecked element must be valid. - let cur = unsafe { &mut *p.add(g.processed_len) }; + let cur = unsafe { &mut *p.add(g.processed_len.into_usize()) }; if !f(cur) { // Advance early to avoid double drop if `drop_in_place` panicked. - g.processed_len += 1; - g.deleted_cnt += 1; + g.processed_len += LenT::ONE; + g.deleted_cnt += LenT::ONE; // SAFETY: We never touch this element again after dropped. unsafe { ptr::drop_in_place(cur) }; // We already advanced the counter. @@ -1056,19 +1106,19 @@ impl VecInner { // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element. // We use copy for move, and never touch this element again. unsafe { - let hole_slot = p.add(g.processed_len - g.deleted_cnt); + let hole_slot = p.add((g.processed_len - g.deleted_cnt).into_usize()); ptr::copy_nonoverlapping(cur, hole_slot, 1); } } - g.processed_len += 1; + g.processed_len += LenT::ONE; } } // Stage 1: Nothing was deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::<_, _, _, _, false>(original_len, &mut f, &mut g); // Stage 2: Some elements were deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::<_, _, _, _, true>(original_len, &mut f, &mut g); // All item are processed. This can be optimized to `set_len` by LLVM. drop(g); @@ -1102,19 +1152,19 @@ impl VecInner { /// ``` #[inline] pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { - &mut self.buffer.borrow_mut()[self.len..] + &mut self.buffer.borrow_mut()[self.len.into_usize()..] } } // Trait implementations -impl Default for Vec { +impl Default for Vec { fn default() -> Self { Self::new() } } -impl fmt::Debug for VecInner +impl fmt::Debug for VecInner where T: fmt::Debug, { @@ -1123,7 +1173,7 @@ where } } -impl fmt::Write for VecInner { +impl fmt::Write for VecInner { fn write_str(&mut self, s: &str) -> fmt::Result { match self.extend_from_slice(s.as_bytes()) { Ok(()) => Ok(()), @@ -1132,13 +1182,13 @@ impl fmt::Write for VecInner { } } -impl From<[T; M]> for Vec { +impl From<[T; M]> for Vec { fn from(array: [T; M]) -> Self { Self::from_array(array) } } -impl Drop for VecInner { +impl Drop for VecInner { fn drop(&mut self) { let mut_slice = self.as_mut_slice(); // We drop each element used in the vector by turning into a `&mut [T]`. @@ -1147,7 +1197,7 @@ impl Drop for VecInner { } } -impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec { +impl<'a, T: Clone, LenT: LenType, const N: usize> TryFrom<&'a [T]> for Vec { type Error = (); fn try_from(slice: &'a [T]) -> Result { @@ -1155,7 +1205,7 @@ impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec { } } -impl Extend for VecInner { +impl Extend for VecInner { fn extend(&mut self, iter: I) where I: IntoIterator, @@ -1164,7 +1214,7 @@ impl Extend for VecInner { } } -impl<'a, T, S: Storage> Extend<&'a T> for VecInner +impl<'a, T, LenT: LenType, S: Storage> Extend<&'a T> for VecInner where T: 'a + Copy, { @@ -1176,7 +1226,7 @@ where } } -impl hash::Hash for VecInner +impl hash::Hash for VecInner where T: core::hash::Hash, { @@ -1185,7 +1235,7 @@ where } } -impl<'a, T, S: Storage> IntoIterator for &'a VecInner { +impl<'a, T, LenT: LenType, S: Storage> IntoIterator for &'a VecInner { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -1194,7 +1244,7 @@ impl<'a, T, S: Storage> IntoIterator for &'a VecInner { } } -impl<'a, T, S: Storage> IntoIterator for &'a mut VecInner { +impl<'a, T, LenT: LenType, S: Storage> IntoIterator for &'a mut VecInner { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; @@ -1203,7 +1253,7 @@ impl<'a, T, S: Storage> IntoIterator for &'a mut VecInner { } } -impl FromIterator for Vec { +impl FromIterator for Vec { fn from_iter(iter: I) -> Self where I: IntoIterator, @@ -1219,17 +1269,23 @@ impl FromIterator for Vec { /// An iterator that moves out of an [`Vec`][`Vec`]. /// /// This struct is created by calling the `into_iter` method on [`Vec`][`Vec`]. -pub struct IntoIter { - vec: Vec, - next: usize, +pub struct IntoIter { + vec: Vec, + next: LenT, } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { if self.next < self.vec.len() { - let item = unsafe { self.vec.buffer.get_unchecked_mut(self.next).as_ptr().read() }; - self.next += 1; + let item = unsafe { + self.vec + .buffer + .get_unchecked_mut(self.next.into_usize()) + .as_ptr() + .read() + }; + self.next += LenT::ONE; Some(item) } else { None @@ -1237,7 +1293,7 @@ impl Iterator for IntoIter { } } -impl Clone for IntoIter +impl Clone for IntoIter where T: Clone, { @@ -1247,92 +1303,105 @@ where if self.next < self.vec.len() { let s = unsafe { slice::from_raw_parts( - (self.vec.buffer.as_ptr() as *const T).add(self.next), - self.vec.len() - self.next, + (self.vec.buffer.as_ptr() as *const T).add(self.next.into_usize()), + (self.vec.len() - self.next).into_usize(), ) }; vec.extend_from_slice(s).ok(); } - Self { vec, next: 0 } + Self { + vec, + next: LenT::ZERO, + } } } -impl Drop for IntoIter { +impl Drop for IntoIter { fn drop(&mut self) { unsafe { // Drop all the elements that have not been moved out of vec - ptr::drop_in_place(&mut self.vec.as_mut_slice()[self.next..]); + ptr::drop_in_place(&mut self.vec.as_mut_slice()[self.next.into_usize()..]); // Prevent dropping of other elements - self.vec.len = 0; + self.vec.len = LenT::ZERO; } } } -impl IntoIterator for Vec { +impl IntoIterator for Vec { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { - IntoIter { vec: self, next: 0 } + IntoIter { + vec: self, + next: LenT::ZERO, + } } } -impl PartialEq> for VecInner +impl PartialEq> for VecInner where A: PartialEq, + LenTA: LenType, + LenTB: LenType, + SA: Storage, + SB: Storage, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { self.as_slice().eq(other.as_slice()) } } -impl PartialEq> for [A; M] +impl PartialEq> for [A; M] where A: PartialEq, + LenTB: LenType, + SB: Storage, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { self.eq(other.as_slice()) } } -impl PartialEq> for &[A; M] +impl PartialEq> + for &[A; M] where A: PartialEq, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { (*self).eq(other) } } -impl PartialEq> for [A] +impl PartialEq> for [A] where A: PartialEq, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { self.eq(other.as_slice()) } } -impl PartialEq> for &[A] +impl PartialEq> for &[A] where A: PartialEq, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { (*self).eq(other) } } -impl PartialEq> for &mut [A] +impl PartialEq> for &mut [A] where A: PartialEq, { - fn eq(&self, other: &VecInner) -> bool { + fn eq(&self, other: &VecInner) -> bool { (**self).eq(other) } } -impl PartialEq<[B; N]> for VecInner +impl PartialEq<[B; N]> for VecInner where A: PartialEq, { @@ -1342,7 +1411,8 @@ where } } -impl PartialEq<&[B; N]> for VecInner +impl PartialEq<&[B; N]> + for VecInner where A: PartialEq, { @@ -1352,7 +1422,7 @@ where } } -impl PartialEq<[B]> for VecInner +impl PartialEq<[B]> for VecInner where A: PartialEq, { @@ -1362,7 +1432,7 @@ where } } -impl PartialEq<&[B]> for VecInner +impl PartialEq<&[B]> for VecInner where A: PartialEq, { @@ -1372,7 +1442,7 @@ where } } -impl PartialEq<&mut [B]> for VecInner +impl PartialEq<&mut [B]> for VecInner where A: PartialEq, { @@ -1383,18 +1453,22 @@ where } // Implements Eq if underlying data is Eq -impl Eq for VecInner where T: Eq {} +impl Eq for VecInner where T: Eq {} -impl PartialOrd> for VecInner +impl PartialOrd> for VecInner where T: PartialOrd, + LenTA: LenType, + LenTB: LenType, + SA: Storage, + SB: Storage, { - fn partial_cmp(&self, other: &VecInner) -> Option { + fn partial_cmp(&self, other: &VecInner) -> Option { self.as_slice().partial_cmp(other.as_slice()) } } -impl Ord for VecInner +impl Ord for VecInner where T: Ord, { @@ -1404,7 +1478,7 @@ where } } -impl ops::Deref for VecInner { +impl ops::Deref for VecInner { type Target = [T]; fn deref(&self) -> &Self::Target { @@ -1412,52 +1486,52 @@ impl ops::Deref for VecInner { } } -impl ops::DerefMut for VecInner { +impl ops::DerefMut for VecInner { fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() } } -impl borrow::Borrow<[T]> for VecInner { +impl borrow::Borrow<[T]> for VecInner { fn borrow(&self) -> &[T] { self.as_slice() } } -impl borrow::BorrowMut<[T]> for VecInner { +impl borrow::BorrowMut<[T]> for VecInner { fn borrow_mut(&mut self) -> &mut [T] { self.as_mut_slice() } } -impl AsRef> for VecInner { +impl AsRef> for VecInner { #[inline] fn as_ref(&self) -> &Self { self } } -impl AsMut> for VecInner { +impl AsMut> for VecInner { #[inline] fn as_mut(&mut self) -> &mut Self { self } } -impl AsRef<[T]> for VecInner { +impl AsRef<[T]> for VecInner { #[inline] fn as_ref(&self) -> &[T] { self } } -impl AsMut<[T]> for VecInner { +impl AsMut<[T]> for VecInner { #[inline] fn as_mut(&mut self) -> &mut [T] { self } } -impl Clone for Vec +impl Clone for Vec where T: Clone, { @@ -1540,7 +1614,7 @@ mod tests { { let v: Vec = Vec::new(); let v: Box> = Box::new(v); - let mut v: Box> = v; + let mut v: Box> = v; v.push(Droppable::new()).ok().unwrap(); v.push(Droppable::new()).ok().unwrap(); assert_eq!(Droppable::count(), 2); @@ -1553,7 +1627,7 @@ mod tests { { let v: Vec = Vec::new(); let v: Box> = Box::new(v); - let mut v: Box> = v; + let mut v: Box> = v; v.push(Droppable::new()).ok().unwrap(); v.push(Droppable::new()).ok().unwrap(); assert_eq!(Droppable::count(), 2);