From 02ab4dc79663eb6f3b4e49a7df0951ef9c0e18d5 Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 16 Dec 2020 21:48:34 +0100 Subject: [PATCH] FEAT: Add new const generics version of ArrayVec (first draft) --- src/arrayvec.rs | 385 +++++++++++++++++++++---------------------- src/arrayvec_impl.rs | 20 ++- 2 files changed, 203 insertions(+), 202 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index a2450b0..0fb3c75 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -14,13 +14,15 @@ use std::fmt; #[cfg(feature="std")] use std::io; -use crate::maybe_uninit::MaybeUninit; +use std::mem::ManuallyDrop; +use std::mem::MaybeUninit; + +//use crate::maybe_uninit::MaybeUninit; #[cfg(feature="serde")] use serde::{Serialize, Deserialize, Serializer, Deserializer}; -use crate::array::Array; use crate::errors::CapacityError; use crate::array::Index; use crate::arrayvec_impl::ArrayVecImpl; @@ -37,12 +39,13 @@ use crate::arrayvec_impl::ArrayVecImpl; /// that the full slice API is available. /// /// ArrayVec can be converted into a by value iterator. -pub struct ArrayVec { - xs: MaybeUninit, - len: A::Index, +pub struct ArrayVec { + // the `len` first elements of the array are initialized + xs: [MaybeUninit; CAP], + len: usize, } -impl Drop for ArrayVec { +impl Drop for ArrayVec { fn drop(&mut self) { self.clear(); @@ -57,7 +60,10 @@ macro_rules! panic_oob { } } -impl ArrayVec { +impl ArrayVec { + /// Capacity + const CAPACITY: usize = CAP; + /// Create a new empty `ArrayVec`. /// /// Capacity is inferred from the type parameter. @@ -72,16 +78,16 @@ impl ArrayVec { /// assert_eq!(array.capacity(), 16); /// ``` #[cfg(not(feature="unstable-const-fn"))] - pub fn new() -> ArrayVec { + pub fn new() -> ArrayVec { unsafe { - ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::ZERO } + ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } } } #[cfg(feature="unstable-const-fn")] - pub const fn new() -> ArrayVec { + pub const fn new() -> ArrayVec { unsafe { - ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::ZERO } + ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } } } @@ -95,7 +101,7 @@ impl ArrayVec { /// assert_eq!(array.len(), 2); /// ``` #[inline] - pub fn len(&self) -> usize { self.len.to_usize() } + pub fn len(&self) -> usize { self.len as usize } /// Returns whether the `ArrayVec` is empty. /// @@ -118,7 +124,7 @@ impl ArrayVec { /// assert_eq!(array.capacity(), 3); /// ``` #[inline(always)] - pub fn capacity(&self) -> usize { A::CAPACITY } + pub fn capacity(&self) -> usize { CAP } /// Return if the `ArrayVec` is completely filled. /// @@ -159,7 +165,7 @@ impl ArrayVec { /// /// assert_eq!(&array[..], &[1, 2]); /// ``` - pub fn push(&mut self, element: A::Item) { + pub fn push(&mut self, element: T) { ArrayVecImpl::push(self, element) } @@ -185,11 +191,10 @@ impl ArrayVec { /// /// assert!(overflow.is_err()); /// ``` - pub fn try_push(&mut self, element: A::Item) -> Result<(), CapacityError> { + pub fn try_push(&mut self, element: T) -> Result<(), CapacityError> { ArrayVecImpl::try_push(self, element) } - /// Push `element` to the end of the vector without checking the capacity. /// /// It is up to the caller to ensure the capacity of the vector is @@ -211,13 +216,38 @@ impl ArrayVec { /// /// assert_eq!(&array[..], &[1, 2]); /// ``` - pub unsafe fn push_unchecked(&mut self, element: A::Item) { + pub unsafe fn push_unchecked(&mut self, element: T) { ArrayVecImpl::push_unchecked(self, element) } + /// Shortens the vector, keeping the first `len` elements and dropping + /// the rest. + /// + /// If `len` is greater than the vector’s current length this has no + /// effect. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut array = ArrayVec::from([1, 2, 3, 4, 5]); + /// array.truncate(3); + /// assert_eq!(&array[..], &[1, 2, 3]); + /// array.truncate(4); + /// assert_eq!(&array[..], &[1, 2, 3]); + /// ``` + pub fn truncate(&mut self, new_len: usize) { + ArrayVecImpl::truncate(self, new_len) + } + + /// Remove all elements in the vector. + pub fn clear(&mut self) { + ArrayVecImpl::clear(self) + } + + /// Get pointer to where element at `index` would be - unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut A::Item { - self.xs.ptr_mut().add(index) + unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T { + self.as_mut_ptr().add(index) } /// Insert `element` at position `index`. @@ -240,7 +270,7 @@ impl ArrayVec { /// assert_eq!(&array[..], &["y", "x"]); /// /// ``` - pub fn insert(&mut self, index: usize, element: A::Item) { + pub fn insert(&mut self, index: usize, element: T) { self.try_insert(index, element).unwrap() } @@ -264,7 +294,7 @@ impl ArrayVec { /// assert_eq!(&array[..], &["y", "x"]); /// /// ``` - pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), CapacityError> { + pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), CapacityError> { if index > self.len() { panic_oob!("try_insert", index, self.len()) } @@ -304,7 +334,7 @@ impl ArrayVec { /// assert_eq!(array.pop(), Some(1)); /// assert_eq!(array.pop(), None); /// ``` - pub fn pop(&mut self) -> Option { + pub fn pop(&mut self) -> Option { ArrayVecImpl::pop(self) } @@ -327,7 +357,7 @@ impl ArrayVec { /// assert_eq!(array.swap_remove(1), 2); /// assert_eq!(&array[..], &[3]); /// ``` - pub fn swap_remove(&mut self, index: usize) -> A::Item { + pub fn swap_remove(&mut self, index: usize) -> T { self.swap_pop(index) .unwrap_or_else(|| { panic_oob!("swap_remove", index, self.len()) @@ -351,7 +381,7 @@ impl ArrayVec { /// /// assert_eq!(array.swap_pop(10), None); /// ``` - pub fn swap_pop(&mut self, index: usize) -> Option { + pub fn swap_pop(&mut self, index: usize) -> Option { let len = self.len(); if index >= len { return None; @@ -375,7 +405,7 @@ impl ArrayVec { /// assert_eq!(removed_elt, 1); /// assert_eq!(&array[..], &[2, 3]); /// ``` - pub fn remove(&mut self, index: usize) -> A::Item { + pub fn remove(&mut self, index: usize) -> T { self.pop_at(index) .unwrap_or_else(|| { panic_oob!("remove", index, self.len()) @@ -398,7 +428,7 @@ impl ArrayVec { /// assert!(array.pop_at(2).is_none()); /// assert!(array.pop_at(10).is_none()); /// ``` - pub fn pop_at(&mut self, index: usize) -> Option { + pub fn pop_at(&mut self, index: usize) -> Option { if index >= self.len() { None } else { @@ -406,30 +436,6 @@ impl ArrayVec { } } - /// Shortens the vector, keeping the first `len` elements and dropping - /// the rest. - /// - /// If `len` is greater than the vector’s current length this has no - /// effect. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut array = ArrayVec::from([1, 2, 3, 4, 5]); - /// array.truncate(3); - /// assert_eq!(&array[..], &[1, 2, 3]); - /// array.truncate(4); - /// assert_eq!(&array[..], &[1, 2, 3]); - /// ``` - pub fn truncate(&mut self, new_len: usize) { - ArrayVecImpl::truncate(self, new_len) - } - - /// Remove all elements in the vector. - pub fn clear(&mut self) { - ArrayVecImpl::clear(self) - } - /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&mut e)` returns false. @@ -444,7 +450,7 @@ impl ArrayVec { /// assert_eq!(&array[..], &[1, 3]); /// ``` pub fn retain(&mut self, mut f: F) - where F: FnMut(&mut A::Item) -> bool + where F: FnMut(&mut T) -> bool { let len = self.len(); let mut del = 0; @@ -494,8 +500,8 @@ impl ArrayVec { /// slice. /// /// [`remaining_capacity`]: #method.remaining_capacity - pub fn try_extend_from_slice(&mut self, other: &[A::Item]) -> Result<(), CapacityError> - where A::Item: Copy, + pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError> + where T: Copy, { if self.remaining_capacity() < other.len() { return Err(CapacityError::new(())); @@ -505,7 +511,7 @@ impl ArrayVec { let other_len = other.len(); unsafe { - let dst = self.xs.ptr_mut().add(self_len); + let dst = self.get_unchecked_ptr(self_len); ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len); self.set_len(self_len + other_len); } @@ -530,7 +536,7 @@ impl ArrayVec { /// assert_eq!(&v[..], &[3]); /// assert_eq!(&u[..], &[1, 2]); /// ``` - pub fn drain(&mut self, range: R) -> Drain + pub fn drain(&mut self, range: R) -> Drain where R: RangeBounds { // Memory safety @@ -557,7 +563,7 @@ impl ArrayVec { self.drain_range(start, end) } - fn drain_range(&mut self, start: usize, end: usize) -> Drain + fn drain_range(&mut self, start: usize, end: usize) -> Drain { let len = self.len(); @@ -582,12 +588,12 @@ impl ArrayVec { /// /// Return an `Ok` value with the array if length equals capacity, /// return an `Err` with self otherwise. - pub fn into_inner(self) -> Result { + pub fn into_inner(self) -> Result<[T; CAP], Self> { if self.len() < self.capacity() { Err(self) } else { unsafe { - let array = ptr::read(self.xs.ptr() as *const A); + let array = ptr::read(self.as_ptr() as *const [T; CAP]); mem::forget(self); Ok(array) } @@ -602,72 +608,58 @@ impl ArrayVec { } /// Return a slice containing all elements of the vector. - pub fn as_slice(&self) -> &[A::Item] { - self + pub fn as_slice(&self) -> &[T] { + ArrayVecImpl::as_slice(self) } /// Return a mutable slice containing all elements of the vector. - pub fn as_mut_slice(&mut self) -> &mut [A::Item] { - self + pub fn as_mut_slice(&mut self) -> &mut [T] { + ArrayVecImpl::as_mut_slice(self) } /// Return a raw pointer to the vector's buffer. - pub fn as_ptr(&self) -> *const A::Item { - self.xs.ptr() + pub fn as_ptr(&self) -> *const T { + ArrayVecImpl::as_ptr(self) } /// Return a raw mutable pointer to the vector's buffer. - pub fn as_mut_ptr(&mut self) -> *mut A::Item { - self.xs.ptr_mut() + pub fn as_mut_ptr(&mut self) -> *mut T { + ArrayVecImpl::as_mut_ptr(self) } } -impl Deref for ArrayVec { - type Target = [A::Item]; - #[inline] - fn deref(&self) -> &[A::Item] { - unsafe { - slice::from_raw_parts(self.xs.ptr(), self.len()) - } - } -} - -impl DerefMut for ArrayVec { - #[inline] - fn deref_mut(&mut self) -> &mut [A::Item] { - let len = self.len(); - unsafe { - slice::from_raw_parts_mut(self.xs.ptr_mut(), len) - } - } -} - -impl ArrayVecImpl for ArrayVec { - type Item = A::Item; - - const CAPACITY: usize = A::CAPACITY; +impl ArrayVecImpl for ArrayVec { + type Item = T; + const CAPACITY: usize = CAP; fn len(&self) -> usize { self.len() } - unsafe fn set_len(&mut self, length: usize) { self.set_len(length) } - /// Return a slice containing all elements of the vector. - fn as_slice(&self) -> &[A::Item] { - self + unsafe fn set_len(&mut self, length: usize) { + debug_assert!(length <= CAP); + self.len = length; } - /// Return a mutable slice containing all elements of the vector. - fn as_mut_slice(&mut self) -> &mut [A::Item] { - self + fn as_ptr(&self) -> *const Self::Item { + self.xs.as_ptr() as _ } - /// Return a raw pointer to the vector's buffer. - fn as_ptr(&self) -> *const A::Item { - self.xs.ptr() + fn as_mut_ptr(&mut self) -> *mut Self::Item { + self.xs.as_mut_ptr() as _ } +} - /// Return a raw mutable pointer to the vector's buffer. - fn as_mut_ptr(&mut self) -> *mut A::Item { - self.xs.ptr_mut() +impl Deref for ArrayVec { + type Target = [T]; + #[inline] + fn deref(&self) -> &Self::Target { + self.as_slice() + } +} + +impl DerefMut for ArrayVec { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() } } @@ -681,9 +673,16 @@ impl ArrayVecImpl for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 3); /// ``` -impl From for ArrayVec { - fn from(array: A) -> Self { - ArrayVec { xs: MaybeUninit::from(array), len: Index::from(A::CAPACITY) } +impl From<[T; CAP]> for ArrayVec { + fn from(array: [T; CAP]) -> Self { + let array = ManuallyDrop::new(array); + let mut vec = >::new(); + unsafe { + + (&*array as *const [T; CAP] as *const [MaybeUninit; CAP]) + .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit; CAP], 1); + } + vec } } @@ -699,14 +698,13 @@ impl From for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 4); /// ``` -impl std::convert::TryFrom<&[A::Item]> for ArrayVec - where - A::Item: Clone, +impl std::convert::TryFrom<&[T]> for ArrayVec + where T: Clone, { type Error = CapacityError; - fn try_from(slice: &[A::Item]) -> Result { - if A::CAPACITY < slice.len() { + fn try_from(slice: &[T]) -> Result { + if Self::CAPACITY < slice.len() { Err(CapacityError::new(())) } else { let mut array = Self::new(); @@ -728,9 +726,9 @@ impl std::convert::TryFrom<&[A::Item]> for ArrayVec /// // ... /// } /// ``` -impl<'a, A: Array> IntoIterator for &'a ArrayVec { - type Item = &'a A::Item; - type IntoIter = slice::Iter<'a, A::Item>; +impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter() } } @@ -745,9 +743,9 @@ impl<'a, A: Array> IntoIterator for &'a ArrayVec { /// // ... /// } /// ``` -impl<'a, A: Array> IntoIterator for &'a mut ArrayVec { - type Item = &'a mut A::Item; - type IntoIter = slice::IterMut<'a, A::Item>; +impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } @@ -762,44 +760,44 @@ impl<'a, A: Array> IntoIterator for &'a mut ArrayVec { /// // ... /// } /// ``` -impl IntoIterator for ArrayVec { - type Item = A::Item; - type IntoIter = IntoIter; - fn into_iter(self) -> IntoIter { +impl IntoIterator for ArrayVec { + type Item = T; + type IntoIter = IntoIter; + fn into_iter(self) -> IntoIter { IntoIter { index: Index::from(0), v: self, } } } /// By-value iterator for `ArrayVec`. -pub struct IntoIter { - index: A::Index, - v: ArrayVec, +pub struct IntoIter { + index: usize, + v: ArrayVec, } -impl Iterator for IntoIter { - type Item = A::Item; +impl Iterator for IntoIter { + type Item = T; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { if self.index == self.v.len { None } else { unsafe { - let index = self.index.to_usize(); - self.index = Index::from(index + 1); + let index = self.index; + self.index = index + 1; Some(ptr::read(self.v.get_unchecked_ptr(index))) } } } fn size_hint(&self) -> (usize, Option) { - let len = self.v.len() - self.index.to_usize(); + let len = self.v.len() - self.index; (len, Some(len)) } } -impl DoubleEndedIterator for IntoIter { - fn next_back(&mut self) -> Option { +impl DoubleEndedIterator for IntoIter { + fn next_back(&mut self) -> Option { if self.index == self.v.len { None } else { @@ -812,12 +810,12 @@ impl DoubleEndedIterator for IntoIter { } } -impl ExactSizeIterator for IntoIter { } +impl ExactSizeIterator for IntoIter { } -impl Drop for IntoIter { +impl Drop for IntoIter { fn drop(&mut self) { // panic safety: Set length to 0 before dropping elements. - let index = self.index.to_usize(); + let index = self.index; let len = self.v.len(); unsafe { self.v.set_len(0); @@ -829,51 +827,45 @@ impl Drop for IntoIter { } } -impl Clone for IntoIter -where - A::Item: Clone, +impl Clone for IntoIter +where T: Clone, { - fn clone(&self) -> IntoIter { - self.v[self.index.to_usize()..] + fn clone(&self) -> IntoIter { + self.v[self.index..] .iter() .cloned() - .collect::>() + .collect::>() .into_iter() } } -impl fmt::Debug for IntoIter +impl fmt::Debug for IntoIter where - A::Item: fmt::Debug, + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() - .entries(&self.v[self.index.to_usize()..]) + .entries(&self.v[self.index..]) .finish() } } /// A draining iterator for `ArrayVec`. -pub struct Drain<'a, A> - where A: Array, - A::Item: 'a, -{ +pub struct Drain<'a, T: 'a, const CAP: usize> { /// Index of tail to preserve tail_start: usize, /// Length of tail tail_len: usize, /// Current remaining range to remove - iter: slice::Iter<'a, A::Item>, - vec: *mut ArrayVec, + iter: slice::Iter<'a, T>, + vec: *mut ArrayVec, } -unsafe impl<'a, A: Array + Sync> Sync for Drain<'a, A> {} -unsafe impl<'a, A: Array + Send> Send for Drain<'a, A> {} +unsafe impl<'a, T: Sync, const CAP: usize> Sync for Drain<'a, T, CAP> {} +unsafe impl<'a, T: Send, const CAP: usize> Send for Drain<'a, T, CAP> {} -impl<'a, A: Array> Iterator for Drain<'a, A> - where A::Item: 'a, -{ - type Item = A::Item; +impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { + type Item = T; fn next(&mut self) -> Option { self.iter.next().map(|elt| @@ -888,8 +880,7 @@ impl<'a, A: Array> Iterator for Drain<'a, A> } } -impl<'a, A: Array> DoubleEndedIterator for Drain<'a, A> - where A::Item: 'a, +impl<'a, T: 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> { fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| @@ -900,11 +891,9 @@ impl<'a, A: Array> DoubleEndedIterator for Drain<'a, A> } } -impl<'a, A: Array> ExactSizeIterator for Drain<'a, A> where A::Item: 'a {} +impl<'a, T: 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} -impl<'a, A: Array> Drop for Drain<'a, A> - where A::Item: 'a -{ +impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { fn drop(&mut self) { // len is currently 0 so panicking while dropping will not cause a double drop. @@ -948,8 +937,8 @@ impl Drop for ScopeExitGuard /// /// Does not extract more items than there is space for. No error /// occurs if there are more iterator elements. -impl Extend for ArrayVec { - fn extend>(&mut self, iter: T) { +impl Extend for ArrayVec { + fn extend>(&mut self, iter: I) { let take = self.capacity() - self.len(); unsafe { let len = self.len(); @@ -1003,16 +992,16 @@ unsafe fn raw_ptr_write(ptr: *mut T, value: T) { /// /// Does not extract more items than there is space for. No error /// occurs if there are more iterator elements. -impl iter::FromIterator for ArrayVec { - fn from_iter>(iter: T) -> Self { +impl iter::FromIterator for ArrayVec { + fn from_iter>(iter: I) -> Self { let mut array = ArrayVec::new(); array.extend(iter); array } } -impl Clone for ArrayVec - where A::Item: Clone +impl Clone for ArrayVec + where T: Clone { fn clone(&self) -> Self { self.iter().cloned().collect() @@ -1035,61 +1024,61 @@ impl Clone for ArrayVec } } -impl Hash for ArrayVec - where A::Item: Hash +impl Hash for ArrayVec + where T: Hash { fn hash(&self, state: &mut H) { Hash::hash(&**self, state) } } -impl PartialEq for ArrayVec - where A::Item: PartialEq +impl PartialEq for ArrayVec + where T: PartialEq { fn eq(&self, other: &Self) -> bool { **self == **other } } -impl PartialEq<[A::Item]> for ArrayVec - where A::Item: PartialEq +impl PartialEq<[T]> for ArrayVec + where T: PartialEq { - fn eq(&self, other: &[A::Item]) -> bool { + fn eq(&self, other: &[T]) -> bool { **self == *other } } -impl Eq for ArrayVec where A::Item: Eq { } +impl Eq for ArrayVec where T: Eq { } -impl Borrow<[A::Item]> for ArrayVec { - fn borrow(&self) -> &[A::Item] { self } +impl Borrow<[T]> for ArrayVec { + fn borrow(&self) -> &[T] { self } } -impl BorrowMut<[A::Item]> for ArrayVec { - fn borrow_mut(&mut self) -> &mut [A::Item] { self } +impl BorrowMut<[T]> for ArrayVec { + fn borrow_mut(&mut self) -> &mut [T] { self } } -impl AsRef<[A::Item]> for ArrayVec { - fn as_ref(&self) -> &[A::Item] { self } +impl AsRef<[T]> for ArrayVec { + fn as_ref(&self) -> &[T] { self } } -impl AsMut<[A::Item]> for ArrayVec { - fn as_mut(&mut self) -> &mut [A::Item] { self } +impl AsMut<[T]> for ArrayVec { + fn as_mut(&mut self) -> &mut [T] { self } } -impl fmt::Debug for ArrayVec where A::Item: fmt::Debug { +impl fmt::Debug for ArrayVec where T: fmt::Debug { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } } -impl Default for ArrayVec { +impl Default for ArrayVec { /// Return an empty array - fn default() -> ArrayVec { + fn default() -> ArrayVec { ArrayVec::new() } } -impl PartialOrd for ArrayVec where A::Item: PartialOrd { - fn partial_cmp(&self, other: &ArrayVec) -> Option { +impl PartialOrd for ArrayVec where T: PartialOrd { + fn partial_cmp(&self, other: &Self) -> Option { (**self).partial_cmp(other) } @@ -1110,8 +1099,8 @@ impl PartialOrd for ArrayVec where A::Item: PartialOrd { } } -impl Ord for ArrayVec where A::Item: Ord { - fn cmp(&self, other: &ArrayVec) -> cmp::Ordering { +impl Ord for ArrayVec where T: Ord { + fn cmp(&self, other: &Self) -> cmp::Ordering { (**self).cmp(other) } } @@ -1120,7 +1109,7 @@ impl Ord for ArrayVec where A::Item: Ord { /// `Write` appends written data to the end of the vector. /// /// Requires `features="std"`. -impl> io::Write for ArrayVec { +impl io::Write for ArrayVec { fn write(&mut self, data: &[u8]) -> io::Result { let len = cmp::min(self.remaining_capacity(), data.len()); let _result = self.try_extend_from_slice(&data[..len]); @@ -1132,7 +1121,7 @@ impl> io::Write for ArrayVec { #[cfg(feature="serde")] /// Requires crate feature `"serde"` -impl> Serialize for ArrayVec { +impl Serialize for ArrayVec { fn serialize(&self, serializer: S) -> Result where S: Serializer { @@ -1142,17 +1131,17 @@ impl> Serialize for ArrayVec { #[cfg(feature="serde")] /// Requires crate feature `"serde"` -impl<'de, T: Deserialize<'de>, A: Array> Deserialize<'de> for ArrayVec { +impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { use serde::de::{Visitor, SeqAccess, Error}; use std::marker::PhantomData; - struct ArrayVecVisitor<'de, T: Deserialize<'de>, A: Array>(PhantomData<(&'de (), T, A)>); + struct ArrayVecVisitor<'de, T: Deserialize<'de>, const CAP: usize>(PhantomData<(&'de (), [T; CAP])>); - impl<'de, T: Deserialize<'de>, A: Array> Visitor<'de> for ArrayVecVisitor<'de, T, A> { - type Value = ArrayVec; + impl<'de, T: Deserialize<'de>, const CAP: usize> Visitor<'de> for ArrayVecVisitor<'de, T, CAP> { + type Value = ArrayVec; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an array with no more than {} items", A::CAPACITY) @@ -1173,6 +1162,6 @@ impl<'de, T: Deserialize<'de>, A: Array> Deserialize<'de> for ArrayVec(PhantomData)) + deserializer.deserialize_seq(ArrayVecVisitor::(PhantomData)) } } diff --git a/src/arrayvec_impl.rs b/src/arrayvec_impl.rs index 3772fda..6c09834 100644 --- a/src/arrayvec_impl.rs +++ b/src/arrayvec_impl.rs @@ -1,4 +1,5 @@ use std::ptr; +use std::slice; use crate::CapacityError; @@ -13,10 +14,20 @@ pub(crate) trait ArrayVecImpl { unsafe fn set_len(&mut self, new_len: usize); /// Return a slice containing all elements of the vector. - fn as_slice(&self) -> &[Self::Item]; + fn as_slice(&self) -> &[Self::Item] { + let len = self.len(); + unsafe { + slice::from_raw_parts(self.as_ptr(), len) + } + } /// Return a mutable slice containing all elements of the vector. - fn as_mut_slice(&mut self) -> &mut [Self::Item]; + fn as_mut_slice(&mut self) -> &mut [Self::Item] { + let len = self.len(); + unsafe { + std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } + } /// Return a raw pointer to the vector's buffer. fn as_ptr(&self) -> *const Self::Item; @@ -63,9 +74,10 @@ pub(crate) trait ArrayVecImpl { fn truncate(&mut self, new_len: usize) { unsafe { - if new_len < self.len() { - let tail: *mut [_] = &mut self.as_mut_slice()[new_len..]; + let len = self.len(); + if new_len < len { self.set_len(new_len); + let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len); ptr::drop_in_place(tail); } }