diff --git a/CHANGELOG.md b/CHANGELOG.md index a04a468db8..ff4ee28f26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `Vec::spare_capacity_mut`. - Added `Extend` impls for `Deque`. - Added `Deque::make_contiguous`. +- Added `VecView`, the `!Sized` version of `Vec`. ### Changed diff --git a/cfail/ui/not-send.stderr b/cfail/ui/not-send.stderr index 40645b7a6d..058e28e8f5 100644 --- a/cfail/ui/not-send.stderr +++ b/cfail/ui/not-send.stderr @@ -72,7 +72,7 @@ error[E0277]: `*const ()` cannot be sent between threads safely 22 | is_send::>(); | ^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely | - = help: within `heapless::Vec, 4>`, the trait `Send` is not implemented for `*const ()` + = help: within `heapless::vec::VecInner<[MaybeUninit>; 4]>`, the trait `Send` is not implemented for `*const ()` note: required because it appears within the type `PhantomData<*const ()>` --> $RUST/core/src/marker.rs note: required because it appears within the type `ManuallyDrop>` @@ -80,11 +80,11 @@ note: required because it appears within the type `ManuallyDrop>` --> $RUST/core/src/mem/maybe_uninit.rs = note: required because it appears within the type `[MaybeUninit>; 4]` -note: required because it appears within the type `Vec, 4>` +note: required because it appears within the type `VecInner<[MaybeUninit>; 4]>` --> $HEAPLESS/src/vec.rs | - | pub struct Vec { - | ^^^ + | pub struct VecInner { + | ^^^^^^^^ note: required by a bound in `is_send` --> ui/not-send.rs:14:8 | diff --git a/src/lib.rs b/src/lib.rs index 82a358e86b..baaef35d96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,14 @@ pub use indexmap::{ pub use indexset::{FnvIndexSet, IndexSet, Iter as IndexSetIter}; pub use linear_map::LinearMap; pub use string::String; -pub use vec::Vec; + +// Workaround https://github.com/rust-lang/rust/issues/119015. This is required so that the methods on `VecView` and `Vec` are properly documented. +// cfg(doc) prevents `VecInner` being part of the public API. +// doc(hidden) prevents the `pub use vec::VecInner` from being visible in the documentation. +#[cfg(doc)] +#[doc(hidden)] +pub use vec::VecInner as _; +pub use vec::{Vec, VecView}; #[macro_use] #[cfg(test)] diff --git a/src/vec.rs b/src/vec.rs index 20da22e092..be7aaf30a9 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -7,6 +7,38 @@ use core::{ ops, ptr, slice, }; +/// Workaround forbidden specialization of Drop +pub trait VecDrop { + // SAFETY: drop_with_len will be called to call drop in place the first `len` elements of the buffer. + // Only the Owned buffer (`[MaybeUninit; N]`) must drop the items + // and the view (`[MaybeUninit]`) drops nothing. + // `drop_with_len `assumes that the buffer can contain `len` elements. + unsafe fn drop_with_len(&mut self, len: usize); +} + +impl VecDrop for [MaybeUninit] { + unsafe fn drop_with_len(&mut self, _len: usize) { + // Case of a view, drop does nothing + } +} + +impl VecDrop for [MaybeUninit; N] { + unsafe fn drop_with_len(&mut self, len: usize) { + // NOTE(unsafe) avoid bound checks in the slicing operation + // &mut buffer[..len] + // SAFETY: buffer[..len] must be valid to drop given the safety requirement of the trait definition. + let mut_slice = slice::from_raw_parts_mut(self.as_mut_ptr() as *mut T, len); + // We drop each element used in the vector by turning into a `&mut [T]`. + ptr::drop_in_place(mut_slice); + } +} + +///
This is private API and should not be used
+pub struct VecInner { + len: usize, + buffer: B, +} + /// A fixed capacity [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html). /// /// # Examples @@ -35,117 +67,41 @@ use core::{ /// } /// assert_eq!(*vec, [7, 1, 2, 3]); /// ``` -pub struct Vec { - // NOTE order is important for optimizations. the `len` first layout lets the compiler optimize - // `new` to: reserve stack space and zero the first word. With the fields in the reverse order - // the compiler optimizes `new` to `memclr`-ing the *entire* stack space, including the `buffer` - // field which should be left uninitialized. Optimizations were last checked with Rust 1.60 - len: usize, - - buffer: [MaybeUninit; N], -} - -impl Vec { - const ELEM: MaybeUninit = MaybeUninit::uninit(); - const INIT: [MaybeUninit; N] = [Self::ELEM; N]; // important for optimization of `new` - - /// Constructs a new, empty vector with a fixed capacity of `N` - /// - /// # Examples - /// - /// ``` - /// use heapless::Vec; - /// - /// // allocate the vector on the stack - /// let mut x: Vec = Vec::new(); - /// - /// // allocate the vector in a static variable - /// static mut X: Vec = Vec::new(); - /// ``` - /// `Vec` `const` constructor; wrap the returned value in [`Vec`]. - pub const fn new() -> Self { - Self { - len: 0, - buffer: Self::INIT, - } - } - - /// Constructs a new vector with a fixed capacity of `N` and fills it - /// with the provided slice. - /// - /// This is equivalent to the following code: - /// - /// ``` - /// use heapless::Vec; - /// - /// let mut v: Vec = Vec::new(); - /// v.extend_from_slice(&[1, 2, 3]).unwrap(); - /// ``` - #[inline] - #[allow(clippy::result_unit_err)] - pub fn from_slice(other: &[T]) -> Result - where - T: Clone, - { - let mut v = Vec::new(); - v.extend_from_slice(other)?; - Ok(v) - } - - /// Constructs a new vector with a fixed capacity of `N`, initializing - /// it with the provided array. - /// - /// The length of the provided array, `M` may be equal to _or_ less than - /// the capacity of the vector, `N`. - /// - /// 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 assert M >= 0 - crate::sealed::greater_than_eq_0::(); - // Const assert N >= M - crate::sealed::greater_than_eq::(); - - // We've got to copy `src`, but we're functionally moving it. Don't run - // any Drop code for T. - let src = ManuallyDrop::new(src); - - if N == M { - Self { - len: 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(); - - 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 - // is wrapped in a ManuallyDrop. - dst_elem.write(unsafe { ptr::read(src_elem) }); - } - - v.len = M; - v - } - } +/// +/// In some cases, the const-generic might be cumbersome. `Vec` can coerce into a [`VecView`] to remove the need for the const-generic: +/// +/// ```rust +/// use heapless::{Vec, VecView}; +/// +/// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); +/// let view: &VecView<_> = &vec; +/// ``` +pub type Vec = VecInner<[MaybeUninit; N]>; - /// Clones a vec into a new vec - pub(crate) fn clone(&self) -> Self - where - T: Clone, - { - let mut new = Self::new(); - // avoid `extend_from_slice` as that introduces a runtime check/panicking branch - for elem in self { - unsafe { - new.push_unchecked(elem.clone()); - } - } - new - } +/// A [`Vec`] with dynamic capacity +/// +/// [`Vec`] coerces to `VecView`. `VecView` is `!Sized`, meaning it can only ever be used by reference. +/// +/// Unlike [`Vec`], `VecView` does not have an `N` const-generic parameter. +/// 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]`. +/// +/// ```rust +/// use heapless::{Vec, VecView}; +/// +/// let mut vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); +/// let view: &VecView<_> = &vec; +/// assert_eq!(view, &[1, 2, 3, 4]); +/// +/// let mut_view: &mut VecView<_> = &mut vec; +/// mut_view.push(5); +/// assert_eq!(vec, [1, 2, 3, 4, 5]); +/// ``` +pub type VecView = VecInner<[MaybeUninit]>; +impl VecView { /// Returns a raw pointer to the vector’s buffer. pub fn as_ptr(&self) -> *const T { self.buffer.as_ptr() as *const T @@ -163,8 +119,8 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; - /// let buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); + /// use heapless::{Vec, VecView}; + /// let buffer: &VecView = &Vec::::from_slice(&[1, 2, 3, 5, 8]).unwrap(); /// assert_eq!(buffer.as_slice(), &[1, 2, 3, 5, 8]); /// ``` pub fn as_slice(&self) -> &[T] { @@ -173,32 +129,6 @@ impl Vec { unsafe { slice::from_raw_parts(self.buffer.as_ptr() as *const T, self.len) } } - /// 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)`. - /// - /// # Examples - /// - /// ``` - /// use heapless::Vec; - /// let buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); - /// let array: [u8; 5] = buffer.into_array().unwrap(); - /// assert_eq!(array, [1, 2, 3, 5, 8]); - /// ``` - pub fn into_array(self) -> Result<[T; M], Self> { - if self.len() == 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() }; - - // We don't want `self`'s destructor to be called because that would drop all the - // items in the array - core::mem::forget(self); - - Ok(array) - } else { - Err(self) - } - } - /// Extracts a mutable slice containing the entire vector. /// /// Equivalent to `&mut s[..]`. @@ -206,9 +136,10 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; - /// let mut buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); - /// buffer[0] = 9; + /// use heapless::{Vec, VecView}; + /// let mut buffer: &mut VecView = &mut Vec::::from_slice(&[1, 2, 3, 5, 8]).unwrap(); + /// let buffer_slice = buffer.as_mut_slice(); + /// buffer_slice[0] = 9; /// assert_eq!(buffer.as_slice(), &[9, 2, 3, 5, 8]); /// ``` pub fn as_mut_slice(&mut self) -> &mut [T] { @@ -219,7 +150,7 @@ impl Vec { /// Returns the maximum number of elements the vector can hold. pub const fn capacity(&self) -> usize { - N + self.buffer.len() } /// Clears the vector, removing all values. @@ -249,9 +180,9 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut vec = Vec::::new(); + /// let vec: &mut VecView = &mut Vec::::new(); /// vec.push(1).unwrap(); /// vec.extend_from_slice(&[2, 3, 4]).unwrap(); /// assert_eq!(*vec, [1, 2, 3, 4]); @@ -413,7 +344,7 @@ impl Vec { /// /// ```no_run /// # #![allow(dead_code)] - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// /// # // This is just a minimal skeleton for the doc example; /// # // don't use this as a starting point for a real library. @@ -430,6 +361,7 @@ impl Vec { /// pub fn get_dictionary(&self) -> Option> { /// // Per the FFI method's docs, "32768 bytes is always enough". /// let mut dict = Vec::new(); + /// let mut dict_view: &mut VecView<_> = &mut dict; /// let mut dict_length = 0; /// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that: /// // 1. `dict_length` elements were initialized. @@ -437,10 +369,10 @@ impl Vec { /// // which makes `set_len` safe to call. /// unsafe { /// // Make the FFI call... - /// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length); + /// let r = deflateGetDictionary(self.strm, dict_view.as_mut_ptr(), &mut dict_length); /// if r == Z_OK { /// // ...and update the length to what was initialized. - /// dict.set_len(dict_length); + /// dict_view.set_len(dict_length); /// Some(dict) /// } else { /// None @@ -455,7 +387,7 @@ impl Vec { /// /// ``` /// use core::iter::FromIterator; - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// /// let mut vec = Vec::, 3>::from_iter( /// [ @@ -470,7 +402,7 @@ impl Vec { /// // 1. `old_len..0` is empty so no elements need to be initialized. /// // 2. `0 <= capacity` always holds whatever `capacity` is. /// unsafe { - /// vec.set_len(0); + /// vec.as_mut_view().set_len(0); /// } /// ``` /// @@ -495,20 +427,19 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; - ///// use heapless::consts::*; + /// use heapless::{Vec, VecView}; /// - /// let mut v: Vec<_, 8> = Vec::new(); + /// let v: &mut VecView<_> = &mut Vec::<_, 8>::new(); /// v.push("foo").unwrap(); /// v.push("bar").unwrap(); /// v.push("baz").unwrap(); /// v.push("qux").unwrap(); /// /// assert_eq!(v.swap_remove(1), "bar"); - /// assert_eq!(&*v, ["foo", "qux", "baz"]); + /// assert_eq!(v, &["foo", "qux", "baz"]); /// /// assert_eq!(v.swap_remove(0), "foo"); - /// assert_eq!(&*v, ["baz", "qux"]); + /// assert_eq!(v, &["baz", "qux"]); /// ``` pub fn swap_remove(&mut self, index: usize) -> T { assert!(index < self.len); @@ -528,19 +459,19 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut v: Vec<_, 8> = Vec::new(); + /// let mut v: &mut VecView<_> = &mut Vec::<_, 8>::new(); /// v.push("foo").unwrap(); /// v.push("bar").unwrap(); /// v.push("baz").unwrap(); /// v.push("qux").unwrap(); /// /// assert_eq!(unsafe { v.swap_remove_unchecked(1) }, "bar"); - /// assert_eq!(&*v, ["foo", "qux", "baz"]); + /// assert_eq!(v, &["foo", "qux", "baz"]); /// /// assert_eq!(unsafe { v.swap_remove_unchecked(0) }, "foo"); - /// assert_eq!(&*v, ["baz", "qux"]); + /// assert_eq!(v, &["baz", "qux"]); /// ``` pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T { let length = self.len(); @@ -571,9 +502,9 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap(); + /// let v: &VecView<_> = &Vec::<_, 8>::from_slice(b"abc").unwrap(); /// assert_eq!(v.starts_with(b""), true); /// assert_eq!(v.starts_with(b"ab"), true); /// assert_eq!(v.starts_with(b"bc"), false); @@ -594,9 +525,9 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap(); + /// let v: &VecView<_> = &Vec::<_, 8>::from_slice(b"abc").unwrap(); /// assert_eq!(v.ends_with(b""), true); /// assert_eq!(v.ends_with(b"ab"), false); /// assert_eq!(v.ends_with(b"bc"), true); @@ -622,13 +553,13 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap(); + /// let mut vec: &mut VecView<_> = &mut Vec::<_, 8>::from_slice(&[1, 2, 3]).unwrap(); /// vec.insert(1, 4); - /// assert_eq!(vec, [1, 4, 2, 3]); + /// assert_eq!(vec, &[1, 4, 2, 3]); /// vec.insert(4, 5); - /// assert_eq!(vec, [1, 4, 2, 3, 5]); + /// assert_eq!(vec, &[1, 4, 2, 3, 5]); /// ``` pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> { let len = self.len(); @@ -681,11 +612,11 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut v: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap(); + /// let mut v: &mut VecView<_> = &mut Vec::<_, 8>::from_slice(&[1, 2, 3]).unwrap(); /// assert_eq!(v.remove(1), 2); - /// assert_eq!(v, [1, 3]); + /// assert_eq!(v, &[1, 3]); /// ``` pub fn remove(&mut self, index: usize) -> T { let len = self.len(); @@ -719,24 +650,24 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// let mut vec: &mut VecView<_> = &mut Vec::<_, 8>::from_slice(&[1, 2, 3, 4]).unwrap(); /// vec.retain(|&x| x % 2 == 0); - /// assert_eq!(vec, [2, 4]); + /// assert_eq!(vec, &[2, 4]); /// ``` /// /// Because the elements are visited exactly once in the original order, /// external state may be used to decide which elements to keep. /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4, 5]).unwrap(); + /// let mut vec: &mut VecView<_> = &mut Vec::<_, 8>::from_slice(&[1, 2, 3, 4, 5]).unwrap(); /// let keep = [false, true, true, false, true]; /// let mut iter = keep.iter(); /// vec.retain(|_| *iter.next().unwrap()); - /// assert_eq!(vec, [2, 3, 5]); + /// assert_eq!(vec, &[2, 3, 5]); /// ``` pub fn retain(&mut self, mut f: F) where @@ -754,9 +685,9 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// - /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// let mut vec: &mut VecView<_> = &mut Vec::<_, 8>::from_slice(&[1, 2, 3, 4]).unwrap(); /// vec.retain_mut(|x| { /// if *x <= 3 { /// *x += 1; @@ -765,7 +696,7 @@ impl Vec { /// false /// } /// }); - /// assert_eq!(vec, [2, 3, 4]); + /// assert_eq!(vec, &[2, 3, 4]); /// ``` pub fn retain_mut(&mut self, mut f: F) where @@ -787,14 +718,14 @@ impl Vec { // 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, const N: usize> { - v: &'a mut Vec, + struct BackshiftOnDrop<'a, T> { + v: &'a mut VecView, processed_len: usize, deleted_cnt: usize, original_len: usize, } - impl Drop for BackshiftOnDrop<'_, T, N> { + impl Drop for BackshiftOnDrop<'_, T> { fn drop(&mut self) { if self.deleted_cnt > 0 { // SAFETY: Trailing unchecked items must be valid since we never touch them. @@ -822,10 +753,10 @@ impl Vec { original_len, }; - fn process_loop( + fn process_loop( original_len: usize, f: &mut F, - g: &mut BackshiftOnDrop<'_, T, N>, + g: &mut BackshiftOnDrop<'_, T>, ) where F: FnMut(&mut T) -> bool, { @@ -859,10 +790,10 @@ impl Vec { } // Stage 1: Nothing was deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::(original_len, &mut f, &mut g); // Stage 2: Some elements were deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::(original_len, &mut f, &mut g); // All item are processed. This can be optimized to `set_len` by LLVM. drop(g); @@ -876,60 +807,740 @@ impl Vec { /// # Examples /// /// ``` - /// use heapless::Vec; + /// use heapless::{Vec, VecView}; /// /// // Allocate vector big enough for 10 elements. /// let mut v: Vec<_, 10> = Vec::new(); + /// let view: &mut VecView<_> = &mut v; /// /// // Fill in the first 3 elements. - /// let uninit = v.spare_capacity_mut(); + /// let uninit = view.spare_capacity_mut(); /// uninit[0].write(0); /// uninit[1].write(1); /// uninit[2].write(2); /// /// // Mark the first 3 elements of the vector as being initialized. /// unsafe { - /// v.set_len(3); + /// view.set_len(3); /// } /// - /// assert_eq!(&v, &[0, 1, 2]); + /// assert_eq!(view, &[0, 1, 2]); /// ``` pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { &mut self.buffer[self.len..] } } -// Trait implementations +impl Vec { + const ELEM: MaybeUninit = MaybeUninit::uninit(); + const INIT: [MaybeUninit; N] = [Self::ELEM; N]; // important for optimization of `new` -impl Default for Vec { - fn default() -> Self { - Self::new() + /// Constructs a new, empty vector with a fixed capacity of `N` + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// // allocate the vector on the stack + /// let mut x: Vec = Vec::new(); + /// + /// // allocate the vector in a static variable + /// static mut X: Vec = Vec::new(); + /// ``` + pub const fn new() -> Self { + Self { + len: 0, + buffer: Self::INIT, + } } -} -impl fmt::Debug for Vec -where - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - <[T] as fmt::Debug>::fmt(self, f) + /// Constructs a new vector with a fixed capacity of `N` and fills it + /// with the provided slice. + /// + /// This is equivalent to the following code: + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut v: Vec = Vec::new(); + /// v.extend_from_slice(&[1, 2, 3]).unwrap(); + /// ``` + #[inline] + #[allow(clippy::result_unit_err)] + pub fn from_slice(other: &[T]) -> Result + where + T: Clone, + { + let mut v = Vec::new(); + v.extend_from_slice(other)?; + Ok(v) } -} -impl fmt::Write for Vec { - fn write_str(&mut self, s: &str) -> fmt::Result { - match self.extend_from_slice(s.as_bytes()) { - Ok(()) => Ok(()), - Err(_) => Err(fmt::Error), - } - } + /// Constructs a new vector with a fixed capacity of `N`, initializing + /// it with the provided array. + /// + /// The length of the provided array, `M` may be equal to _or_ less than + /// the capacity of the vector, `N`. + /// + /// 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 assert M >= 0 + crate::sealed::greater_than_eq_0::(); + // Const assert N >= M + crate::sealed::greater_than_eq::(); + + // We've got to copy `src`, but we're functionally moving it. Don't run + // any Drop code for T. + let src = ManuallyDrop::new(src); + + if N == M { + Self { + len: 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(); + + 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 + // is wrapped in a ManuallyDrop. + dst_elem.write(unsafe { ptr::read(src_elem) }); + } + + v.len = M; + v + } + } + + /// Clones a vec into a new vec + pub(crate) fn clone(&self) -> Self + where + T: Clone, + { + let mut new = Self::new(); + // avoid `extend_from_slice` as that introduces a runtime check/panicking branch + for elem in self { + unsafe { + new.push_unchecked(elem.clone()); + } + } + new + } + + /// Get a reference to the `Vec`, erasing the `N` const-generic. + /// + /// + /// ```rust + /// # use heapless::{Vec, VecView}; + /// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// let view: &VecView = vec.as_view(); + /// ``` + /// + /// It is often preferable to do the same through type coerction, since `Vec` implements `Unsize>`: + /// + /// ```rust + /// # use heapless::{Vec, VecView}; + /// let vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// let view: &VecView = &vec; + /// ``` + pub const fn as_view(&self) -> &VecView { + self + } + + /// Get a mutable reference to the `Vec`, erasing the `N` const-generic. + /// + /// ```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(); + /// ``` + /// + /// It is often preferable to do the same through type coerction, since `Vec` implements `Unsize>`: + /// + /// ```rust + /// # use heapless::{Vec, VecView}; + /// let mut vec: Vec = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// let view: &mut VecView = &mut vec; + /// ``` + pub fn as_mut_view(&mut self) -> &mut VecView { + self + } + + /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// let buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); + /// assert_eq!(buffer.as_slice(), &[1, 2, 3, 5, 8]); + /// ``` + pub fn as_slice(&self) -> &[T] { + self.as_view().as_slice() + } + + /// 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)`. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// let buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); + /// let array: [u8; 5] = buffer.into_array().unwrap(); + /// assert_eq!(array, [1, 2, 3, 5, 8]); + /// ``` + pub fn into_array(self) -> Result<[T; M], Self> { + if self.len() == 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() }; + + // We don't want `self`'s destructor to be called because that would drop all the + // items in the array + core::mem::forget(self); + + Ok(array) + } else { + Err(self) + } + } + + /// Extracts a mutable slice containing the entire vector. + /// + /// Equivalent to `&mut s[..]`. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// let mut buffer: Vec = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap(); + /// let buffer_slice = buffer.as_mut_slice(); + /// buffer_slice[0] = 9; + /// assert_eq!(buffer.as_slice(), &[9, 2, 3, 5, 8]); + /// ``` + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.as_mut_view().as_mut_slice() + } + + /// Returns the maximum number of elements the vector can hold. + pub const fn capacity(&self) -> usize { + N + } + + /// Clears the vector, removing all values. + pub fn clear(&mut self) { + self.as_mut_view().clear() + } + + /// Extends the vec from an iterator. + /// + /// # Panic + /// + /// Panics if the vec cannot hold all elements of the iterator. + pub fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + self.as_mut_view().extend(iter) + } + + /// Clones and appends all elements in a slice to the `Vec`. + /// + /// Iterates over the slice `other`, clones each element, and then appends + /// it to this `Vec`. The `other` vector is traversed in-order. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut vec = Vec::::new(); + /// vec.push(1).unwrap(); + /// vec.extend_from_slice(&[2, 3, 4]).unwrap(); + /// assert_eq!(*vec, [1, 2, 3, 4]); + /// ``` + #[allow(clippy::result_unit_err)] + pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()> + where + T: Clone, + { + self.as_mut_view().extend_from_slice(other) + } + + /// Removes the last element from a vector and returns it, or `None` if it's empty + pub fn pop(&mut self) -> Option { + self.as_mut_view().pop() + } + + /// Appends an `item` to the back of the collection + /// + /// Returns back the `item` if the vector is full + pub fn push(&mut self, item: T) -> Result<(), T> { + self.as_mut_view().push(item) + } + + /// Removes the last element from a vector and returns it + /// + /// # Safety + /// + /// This assumes the vec to have at least one element. + pub unsafe fn pop_unchecked(&mut self) -> T { + self.as_mut_view().pop_unchecked() + } + + /// Appends an `item` to the back of the collection + /// + /// # Safety + /// + /// This assumes the vec is not full. + pub unsafe fn push_unchecked(&mut self, item: T) { + self.as_mut_view().push_unchecked(item) + } + + /// Shortens the vector, keeping the first `len` elements and dropping the rest. + pub fn truncate(&mut self, len: usize) { + self.as_mut_view().truncate(len) + } + + /// Resizes the Vec in-place so that len is equal to new_len. + /// + /// If new_len is greater than len, the Vec is extended by the + /// difference, with each additional slot filled with value. If + /// new_len is less than len, the Vec is simply truncated. + /// + /// See also [`resize_default`](Self::resize_default). + #[allow(clippy::result_unit_err)] + pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()> + where + T: Clone, + { + self.as_mut_view().resize(new_len, value) + } + + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with `Default::default()`. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// See also [`resize`](Self::resize). + #[allow(clippy::result_unit_err)] + pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()> + where + T: Clone + Default, + { + self.as_mut_view().resize_default(new_len) + } + + /// Forces the length of the vector to `new_len`. + /// + /// This is a low-level operation that maintains none of the normal + /// invariants of the type. Normally changing the length of a vector + /// is done using one of the safe operations instead, such as + /// [`truncate`], [`resize`], [`extend`], or [`clear`]. + /// + /// [`truncate`]: Self::truncate + /// [`resize`]: Self::resize + /// [`extend`]: core::iter::Extend + /// [`clear`]: Self::clear + /// + /// # Safety + /// + /// - `new_len` must be less than or equal to [`capacity()`]. + /// - The elements at `old_len..new_len` must be initialized. + /// + /// [`capacity()`]: Self::capacity + /// + /// # Examples + /// + /// This method can be useful for situations in which the vector + /// is serving as a buffer for other code, particularly over FFI: + /// + /// ```no_run + /// # #![allow(dead_code)] + /// use heapless::Vec; + /// + /// # // This is just a minimal skeleton for the doc example; + /// # // don't use this as a starting point for a real library. + /// # pub struct StreamWrapper { strm: *mut core::ffi::c_void } + /// # const Z_OK: i32 = 0; + /// # extern "C" { + /// # fn deflateGetDictionary( + /// # strm: *mut core::ffi::c_void, + /// # dictionary: *mut u8, + /// # dictLength: *mut usize, + /// # ) -> i32; + /// # } + /// # impl StreamWrapper { + /// pub fn get_dictionary(&self) -> Option> { + /// // Per the FFI method's docs, "32768 bytes is always enough". + /// let mut dict = Vec::new(); + /// let mut dict_length = 0; + /// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that: + /// // 1. `dict_length` elements were initialized. + /// // 2. `dict_length` <= the capacity (32_768) + /// // which makes `set_len` safe to call. + /// unsafe { + /// // Make the FFI call... + /// 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); + /// Some(dict) + /// } else { + /// None + /// } + /// } + /// } + /// # } + /// ``` + /// + /// While the following example is sound, there is a memory leak since + /// the inner vectors were not freed prior to the `set_len` call: + /// + /// ``` + /// use core::iter::FromIterator; + /// use heapless::Vec; + /// + /// let mut vec = Vec::, 3>::from_iter( + /// [ + /// Vec::from_iter([1, 0, 0].iter().cloned()), + /// Vec::from_iter([0, 1, 0].iter().cloned()), + /// Vec::from_iter([0, 0, 1].iter().cloned()), + /// ] + /// .iter() + /// .cloned(), + /// ); + /// // SAFETY: + /// // 1. `old_len..0` is empty so no elements need to be initialized. + /// // 2. `0 <= capacity` always holds whatever `capacity` is. + /// unsafe { + /// vec.set_len(0); + /// } + /// ``` + /// + /// 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.capacity()); + + self.len = new_len + } + + /// Removes an element from the vector and returns it. + /// + /// The removed element is replaced by the last element of the vector. + /// + /// This does not preserve ordering, but is *O*(1). + /// + /// # Panics + /// + /// Panics if `index` is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut v: Vec<_, 8> = Vec::new(); + /// v.push("foo").unwrap(); + /// v.push("bar").unwrap(); + /// v.push("baz").unwrap(); + /// v.push("qux").unwrap(); + /// + /// assert_eq!(v.swap_remove(1), "bar"); + /// assert_eq!(&*v, ["foo", "qux", "baz"]); + /// + /// assert_eq!(v.swap_remove(0), "foo"); + /// assert_eq!(&*v, ["baz", "qux"]); + /// ``` + pub fn swap_remove(&mut self, index: usize) -> T { + self.as_mut_view().swap_remove(index) + } + + /// Removes an element from the vector and returns it. + /// + /// The removed element is replaced by the last element of the vector. + /// + /// This does not preserve ordering, but is *O*(1). + /// + /// # Safety + /// + /// Assumes `index` within bounds. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut v: Vec<_, 8> = Vec::new(); + /// v.push("foo").unwrap(); + /// v.push("bar").unwrap(); + /// v.push("baz").unwrap(); + /// v.push("qux").unwrap(); + /// + /// assert_eq!(unsafe { v.swap_remove_unchecked(1) }, "bar"); + /// assert_eq!(&*v, ["foo", "qux", "baz"]); + /// + /// 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 { + self.as_mut_view().swap_remove_unchecked(index) + } + + /// Returns true if the vec is full + #[inline] + pub fn is_full(&self) -> bool { + self.len == self.capacity() + } + + /// Returns true if the vec is empty + #[inline] + pub fn is_empty(&self) -> bool { + self.len == 0 + } + + /// Returns `true` if `needle` is a prefix of the Vec. + /// + /// Always returns `true` if `needle` is an empty slice. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap(); + /// assert_eq!(v.starts_with(b""), true); + /// assert_eq!(v.starts_with(b"ab"), true); + /// assert_eq!(v.starts_with(b"bc"), false); + /// ``` + #[inline] + pub fn starts_with(&self, needle: &[T]) -> bool + where + T: PartialEq, + { + let n = needle.len(); + self.len >= n && needle == &self[..n] + } + + /// Returns `true` if `needle` is a suffix of the Vec. + /// + /// Always returns `true` if `needle` is an empty slice. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap(); + /// assert_eq!(v.ends_with(b""), true); + /// assert_eq!(v.ends_with(b"ab"), false); + /// assert_eq!(v.ends_with(b"bc"), true); + /// ``` + #[inline] + pub fn ends_with(&self, needle: &[T]) -> bool + where + T: PartialEq, + { + let (v, n) = (self.len(), needle.len()); + v >= n && needle == &self[v - n..] + } + + /// Inserts an element at position `index` within the vector, shifting all + /// elements after it to the right. + /// + /// Returns back the `element` if the vector is full. + /// + /// # Panics + /// + /// Panics if `index > len`. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap(); + /// vec.insert(1, 4); + /// assert_eq!(vec, [1, 4, 2, 3]); + /// vec.insert(4, 5); + /// assert_eq!(vec, [1, 4, 2, 3, 5]); + /// ``` + pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> { + self.as_mut_view().insert(index, element) + } + + /// Removes and returns the element at position `index` within the vector, + /// shifting all elements after it to the left. + /// + /// Note: Because this shifts over the remaining elements, it has a + /// worst-case performance of *O*(n). If you don't need the order of + /// elements to be preserved, use [`swap_remove`] instead. If you'd like to + /// remove elements from the beginning of the `Vec`, consider using + /// [`Deque::pop_front`] instead. + /// + /// [`swap_remove`]: Vec::swap_remove + /// [`Deque::pop_front`]: crate::Deque::pop_front + /// + /// # Panics + /// + /// Panics if `index` is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut v: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap(); + /// assert_eq!(v.remove(1), 2); + /// assert_eq!(v, [1, 3]); + /// ``` + pub fn remove(&mut self, index: usize) -> T { + self.as_mut_view().remove(index) + } + + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` for which `f(&e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// vec.retain(|&x| x % 2 == 0); + /// assert_eq!(vec, [2, 4]); + /// ``` + /// + /// Because the elements are visited exactly once in the original order, + /// external state may be used to decide which elements to keep. + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4, 5]).unwrap(); + /// let keep = [false, true, true, false, true]; + /// let mut iter = keep.iter(); + /// vec.retain(|_| *iter.next().unwrap()); + /// assert_eq!(vec, [2, 3, 5]); + /// ``` + pub fn retain(&mut self, f: F) + where + F: FnMut(&T) -> bool, + { + self.as_mut_view().retain(f) + } + + /// Retains only the elements specified by the predicate, passing a mutable reference to it. + /// + /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap(); + /// vec.retain_mut(|x| { + /// if *x <= 3 { + /// *x += 1; + /// true + /// } else { + /// false + /// } + /// }); + /// assert_eq!(vec, [2, 3, 4]); + /// ``` + pub fn retain_mut(&mut self, f: F) + where + F: FnMut(&mut T) -> bool, + { + self.as_mut_view().retain_mut(f) + } + + /// Returns the remaining spare capacity of the vector as a slice of `MaybeUninit`. + /// + /// The returned slice can be used to fill the vector with data before marking the data as + /// initialized using the `set_len` method. + /// + /// # Examples + /// + /// ``` + /// use heapless::Vec; + /// + /// // Allocate vector big enough for 10 elements. + /// let mut v: Vec<_, 10> = Vec::new(); + /// + /// // Fill in the first 3 elements. + /// let uninit = v.spare_capacity_mut(); + /// uninit[0].write(0); + /// uninit[1].write(1); + /// uninit[2].write(2); + /// + /// // Mark the first 3 elements of the vector as being initialized. + /// unsafe { + /// v.set_len(3); + /// } + /// + /// assert_eq!(&v, &[0, 1, 2]); + /// ``` + pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { + self.as_mut_view().spare_capacity_mut() + } } -impl Drop for Vec { - fn drop(&mut self) { - // We drop each element used in the vector by turning into a `&mut [T]`. - unsafe { - ptr::drop_in_place(self.as_mut_slice()); +// Trait implementations + +impl Default for Vec { + fn default() -> Self { + Self::new() + } +} + +impl fmt::Debug for VecView +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + <[T] as fmt::Debug>::fmt(self, f) + } +} + +impl fmt::Debug for Vec +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_view().fmt(f) + } +} + +impl fmt::Write for Vec { + fn write_str(&mut self, s: &str) -> fmt::Result { + match self.extend_from_slice(s.as_bytes()) { + Ok(()) => Ok(()), + Err(_) => Err(fmt::Error), + } + } +} + +impl fmt::Write for VecView { + fn write_str(&mut self, s: &str) -> fmt::Result { + match self.extend_from_slice(s.as_bytes()) { + Ok(()) => Ok(()), + Err(_) => Err(fmt::Error), } } } @@ -940,6 +1551,13 @@ impl From<[T; M]> for Vec { } } +impl Drop for VecInner { + fn drop(&mut self) { + // SAFETY: the buffer contains initialized data for the range 0..self.len + unsafe { self.buffer.drop_with_len(self.len) } + } +} + impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec { type Error = (); @@ -948,7 +1566,7 @@ impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec { } } -impl Extend for Vec { +impl Extend for VecView { fn extend(&mut self, iter: I) where I: IntoIterator, @@ -957,7 +1575,28 @@ impl Extend for Vec { } } +impl Extend for Vec { + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + self.as_mut_view().extend(iter) + } +} + impl<'a, T, const N: usize> Extend<&'a T> for Vec +where + T: 'a + Copy, +{ + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + self.as_mut_view().extend(iter.into_iter().cloned()) + } +} + +impl<'a, T> Extend<&'a T> for VecView where T: 'a + Copy, { @@ -970,6 +1609,15 @@ where } impl hash::Hash for Vec +where + T: core::hash::Hash, +{ + fn hash(&self, state: &mut H) { + self.as_view().hash(state) + } +} + +impl hash::Hash for VecView where T: core::hash::Hash, { @@ -982,6 +1630,15 @@ impl<'a, T, const N: usize> IntoIterator for &'a Vec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.as_view().iter() + } +} + +impl<'a, T> IntoIterator for &'a VecView { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + fn into_iter(self) -> Self::IntoIter { self.iter() } @@ -991,6 +1648,15 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut Vec { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.as_mut_view().iter_mut() + } +} + +impl<'a, T> IntoIterator for &'a mut VecView { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + fn into_iter(self) -> Self::IntoIter { self.iter_mut() } @@ -1076,12 +1742,49 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { + self.as_view().eq(other.as_view()) + } +} + +impl PartialEq> for VecView +where + A: PartialEq, +{ + fn eq(&self, other: &Vec) -> bool { + self.eq(other.as_view()) + } +} + +impl PartialEq> for Vec +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { + self.as_view().eq(other) + } +} + +impl PartialEq> for VecView +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { <[A]>::eq(self, &**other) } } // Vec == [B] impl PartialEq<[B]> for Vec +where + A: PartialEq, +{ + fn eq(&self, other: &[B]) -> bool { + self.as_view().eq(other) + } +} + +// VecView == [B] +impl PartialEq<[B]> for VecView where A: PartialEq, { @@ -1096,6 +1799,16 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { + other.as_view().eq(self) + } +} + +// [B] == VecView +impl PartialEq> for [B] +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { <[A]>::eq(other, self) } } @@ -1106,7 +1819,17 @@ where A: PartialEq, { fn eq(&self, other: &&[B]) -> bool { - <[A]>::eq(self, &other[..]) + self.as_view().eq(other) + } +} + +// VecView == &[B] +impl PartialEq<&[B]> for VecView +where + A: PartialEq, +{ + fn eq(&self, other: &&[B]) -> bool { + <[A]>::eq(self, *other) } } @@ -1116,12 +1839,32 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { - <[A]>::eq(other, &self[..]) + other.as_view().eq(self) + } +} + +// &[B] == VecView +impl PartialEq> for &[B] +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { + <[A]>::eq(other, *self) } } // Vec == &mut [B] impl PartialEq<&mut [B]> for Vec +where + A: PartialEq, +{ + fn eq(&self, other: &&mut [B]) -> bool { + self.as_view().eq(other) + } +} + +// VecView == &mut [B] +impl PartialEq<&mut [B]> for VecView where A: PartialEq, { @@ -1136,6 +1879,16 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { + other.as_view().eq(self) + } +} + +// &mut [B] == VecView +impl PartialEq> for &mut [B] +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { <[A]>::eq(other, &self[..]) } } @@ -1147,7 +1900,18 @@ where A: PartialEq, { fn eq(&self, other: &[B; M]) -> bool { - <[A]>::eq(self, &other[..]) + self.as_view().eq(other) + } +} + +// VecView == [B; M] +// Equality does not require equal capacity +impl PartialEq<[B; M]> for VecView +where + A: PartialEq, +{ + fn eq(&self, other: &[B; M]) -> bool { + <[A]>::eq(self, other) } } @@ -1158,7 +1922,18 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { - <[A]>::eq(other, &self[..]) + other.as_view().eq(self) + } +} + +// [B; M] == VecView +// Equality does not require equal capacity +impl PartialEq> for [B; M] +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { + <[A]>::eq(other, self) } } @@ -1169,7 +1944,18 @@ where A: PartialEq, { fn eq(&self, other: &&[B; M]) -> bool { - <[A]>::eq(self, &other[..]) + self.as_view().eq(other) + } +} + +// VecView == &[B; M] +// Equality does not require equal capacity +impl PartialEq<&[B; M]> for VecView +where + A: PartialEq, +{ + fn eq(&self, other: &&[B; M]) -> bool { + <[A]>::eq(self, *other) } } @@ -1180,18 +1966,39 @@ where A: PartialEq, { fn eq(&self, other: &Vec) -> bool { - <[A]>::eq(other, &self[..]) + other.as_view().eq(self) + } +} + +// &[B; M] == VecView +// Equality does not require equal capacity +impl PartialEq> for &[B; M] +where + A: PartialEq, +{ + fn eq(&self, other: &VecView) -> bool { + <[A]>::eq(other, *self) } } // Implements Eq if underlying data is Eq impl Eq for Vec where T: Eq {} +impl Eq for VecView where T: Eq {} impl PartialOrd> for Vec where T: PartialOrd, { fn partial_cmp(&self, other: &Vec) -> Option { + self.as_view().partial_cmp(other.as_view()) + } +} + +impl PartialOrd> for VecView +where + T: PartialOrd, +{ + fn partial_cmp(&self, other: &VecView) -> Option { PartialOrd::partial_cmp(&**self, &**other) } } @@ -1220,6 +2027,20 @@ impl ops::DerefMut for Vec { } } +impl ops::Deref for VecView { + type Target = [T]; + + fn deref(&self) -> &[T] { + self.as_slice() + } +} + +impl ops::DerefMut for VecView { + fn deref_mut(&mut self) -> &mut [T] { + self.as_mut_slice() + } +} + impl AsRef> for Vec { #[inline] fn as_ref(&self) -> &Self {