diff --git a/src/array_string.rs b/src/array_string.rs index 1144360..fcf0836 100644 --- a/src/array_string.rs +++ b/src/array_string.rs @@ -11,12 +11,12 @@ use std::str; use std::str::FromStr; use std::str::Utf8Error; +use crate::len_type::{check_cap_fits_in_len_type, DefaultLenType, LenUint}; use crate::CapacityError; -use crate::LenUint; use crate::char::encode_utf8; use crate::utils::MakeMaybeUninit; -#[cfg(feature="serde")] +#[cfg(feature = "serde")] use serde::{Serialize, Deserialize, Serializer, Deserializer}; @@ -32,21 +32,21 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer}; /// if needed. #[derive(Copy)] #[repr(C)] -pub struct ArrayString { +pub struct ArrayString> { // the `len` first elements of the array are initialized - len: LenUint, + len: LenType, xs: [MaybeUninit; CAP], } -impl Default for ArrayString +impl Default for ArrayString { /// Return an empty `ArrayString` - fn default() -> ArrayString { + fn default() -> Self { ArrayString::new() } } -impl ArrayString +impl ArrayString { /// Create a new empty `ArrayString`. /// @@ -60,11 +60,14 @@ impl ArrayString /// assert_eq!(&string[..], "foo"); /// assert_eq!(string.capacity(), 16); /// ``` - pub fn new() -> ArrayString { - assert_capacity_limit!(CAP); - unsafe { - ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } + /// + /// If you provide a capacity greater than a length type, this will fail at compile time. + /// ```compile_fail + /// let string = arrayvec::ArrayString::<256, u8>::new(); + /// ``` + pub fn new() -> Self { + check_cap_fits_in_len_type::(); + ArrayString { len: LenType::from_usize(0), xs: MakeMaybeUninit::ARRAY } } /// Create a new empty `ArrayString` (const fn). @@ -74,20 +77,20 @@ impl ArrayString /// ``` /// use arrayvec::ArrayString; /// - /// static ARRAY: ArrayString<1024> = ArrayString::new_const(); + /// const ARRAY: ArrayString<1024> = ArrayString::new_const(); /// ``` - pub const fn new_const() -> ArrayString { - assert_capacity_limit_const!(CAP); - ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 } + pub const fn new_const() -> Self { + check_cap_fits_in_len_type::(); + ArrayString { len: LenType::ZERO, xs: MakeMaybeUninit::ARRAY } } /// Return the length of the string. #[inline] - pub const fn len(&self) -> usize { self.len as usize } + pub fn len(&self) -> usize { LenType::to_usize(self.len) } /// Returns whether the string is empty. #[inline] - pub const fn is_empty(&self) -> bool { self.len() == 0 } + pub fn is_empty(&self) -> bool { self.len == LenType::ZERO } /// Create a new `ArrayString` from a `str`. /// @@ -116,7 +119,7 @@ impl ArrayString /// ``` /// use arrayvec::ArrayString; /// - /// let string = ArrayString::from_byte_string(b"hello world").unwrap(); + /// let string = ArrayString::<11>::from_byte_string(b"hello world").unwrap(); /// ``` pub fn from_byte_string(b: &[u8; CAP]) -> Result { let len = str::from_utf8(b)?.len(); @@ -139,15 +142,20 @@ impl ArrayString /// let string = ArrayString::<16>::zero_filled(); /// assert_eq!(string.len(), 16); /// ``` + /// + /// If you provide a capacity greater than a length type, this will fail at compile time. + /// ```compile_fail + /// let string = arrayvec::ArrayString::<256, u8>::zero_filled(); + /// ``` #[inline] pub fn zero_filled() -> Self { - assert_capacity_limit!(CAP); - // SAFETY: `assert_capacity_limit` asserts that `len` won't overflow and + check_cap_fits_in_len_type::(); + // SAFETY: `check_cap_fits_in_len_type` asserts that `len` won't overflow and // `zeroed` fully fills the array with nulls. unsafe { ArrayString { xs: MaybeUninit::zeroed().assume_init(), - len: CAP as _ + len: LenType::from_usize(CAP), } } } @@ -173,7 +181,7 @@ impl ArrayString /// string.push_str("A"); /// assert!(string.is_full()); /// ``` - pub const fn is_full(&self) -> bool { self.len() == self.capacity() } + pub fn is_full(&self) -> bool { self.len() == self.capacity() } /// Returns the capacity left in the `ArrayString`. /// @@ -184,7 +192,7 @@ impl ArrayString /// string.pop(); /// assert_eq!(string.remaining_capacity(), 1); /// ``` - pub const fn remaining_capacity(&self) -> usize { + pub fn remaining_capacity(&self) -> usize { self.capacity() - self.len() } @@ -299,7 +307,7 @@ impl ArrayString /// /// ``` /// use arrayvec::ArrayString; - /// + /// /// let mut s = ArrayString::<3>::from("foo").unwrap(); /// /// assert_eq!(s.pop(), Some('o')); @@ -339,7 +347,7 @@ impl ArrayString pub fn truncate(&mut self, new_len: usize) { if new_len <= self.len() { assert!(self.is_char_boundary(new_len)); - unsafe { + unsafe { // In libstd truncate is called on the underlying vector, // which in turns drops each element. // As we know we don't have to worry about Drop, @@ -359,7 +367,7 @@ impl ArrayString /// /// ``` /// use arrayvec::ArrayString; - /// + /// /// let mut s = ArrayString::<3>::from("foo").unwrap(); /// /// assert_eq!(s.remove(0), 'f'); @@ -402,7 +410,7 @@ impl ArrayString pub unsafe fn set_len(&mut self, length: usize) { // type invariant that capacity always fits in LenUint debug_assert!(length <= self.capacity()); - self.len = length as LenUint; + self.len = LenUint::from_usize(length); } /// Return a string slice of the whole `ArrayString`. @@ -426,7 +434,7 @@ impl ArrayString } } -impl Deref for ArrayString +impl Deref for ArrayString { type Target = str; #[inline] @@ -438,7 +446,7 @@ impl Deref for ArrayString } } -impl DerefMut for ArrayString +impl DerefMut for ArrayString { #[inline] fn deref_mut(&mut self) -> &mut str { @@ -450,64 +458,64 @@ impl DerefMut for ArrayString } } -impl PartialEq for ArrayString +impl PartialEq for ArrayString { fn eq(&self, rhs: &Self) -> bool { **self == **rhs } } -impl PartialEq for ArrayString +impl PartialEq for ArrayString { fn eq(&self, rhs: &str) -> bool { &**self == rhs } } -impl PartialEq> for str +impl PartialEq> for str { - fn eq(&self, rhs: &ArrayString) -> bool { + fn eq(&self, rhs: &ArrayString) -> bool { self == &**rhs } } -impl Eq for ArrayString -{ } +impl Eq for ArrayString +{} -impl Hash for ArrayString +impl Hash for ArrayString { fn hash(&self, h: &mut H) { (**self).hash(h) } } -impl Borrow for ArrayString +impl Borrow for ArrayString { fn borrow(&self) -> &str { self } } -impl BorrowMut for ArrayString +impl BorrowMut for ArrayString { fn borrow_mut(&mut self) -> &mut str { self } } -impl AsRef for ArrayString +impl AsRef for ArrayString { fn as_ref(&self) -> &str { self } } -impl fmt::Debug for ArrayString +impl fmt::Debug for ArrayString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } } -impl fmt::Display for ArrayString +impl fmt::Display for ArrayString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } } /// `Write` appends written data to the end of the string. -impl fmt::Write for ArrayString +impl fmt::Write for ArrayString { fn write_char(&mut self, c: char) -> fmt::Result { self.try_push(c).map_err(|_| fmt::Error) @@ -518,9 +526,9 @@ impl fmt::Write for ArrayString } } -impl Clone for ArrayString +impl Clone for ArrayString { - fn clone(&self) -> ArrayString { + fn clone(&self) -> ArrayString { *self } fn clone_from(&mut self, rhs: &Self) { @@ -530,7 +538,7 @@ impl Clone for ArrayString } } -impl PartialOrd for ArrayString +impl PartialOrd for ArrayString { fn partial_cmp(&self, rhs: &Self) -> Option { (**self).partial_cmp(&**rhs) @@ -541,7 +549,7 @@ impl PartialOrd for ArrayString fn ge(&self, rhs: &Self) -> bool { **self >= **rhs } } -impl PartialOrd for ArrayString +impl PartialOrd for ArrayString { fn partial_cmp(&self, rhs: &str) -> Option { (**self).partial_cmp(rhs) @@ -552,25 +560,25 @@ impl PartialOrd for ArrayString fn ge(&self, rhs: &str) -> bool { &**self >= rhs } } -impl PartialOrd> for str +impl PartialOrd> for str { - fn partial_cmp(&self, rhs: &ArrayString) -> Option { + fn partial_cmp(&self, rhs: &ArrayString) -> Option { self.partial_cmp(&**rhs) } - fn lt(&self, rhs: &ArrayString) -> bool { self < &**rhs } - fn le(&self, rhs: &ArrayString) -> bool { self <= &**rhs } - fn gt(&self, rhs: &ArrayString) -> bool { self > &**rhs } - fn ge(&self, rhs: &ArrayString) -> bool { self >= &**rhs } + fn lt(&self, rhs: &ArrayString) -> bool { self < &**rhs } + fn le(&self, rhs: &ArrayString) -> bool { self <= &**rhs } + fn gt(&self, rhs: &ArrayString) -> bool { self > &**rhs } + fn ge(&self, rhs: &ArrayString) -> bool { self >= &**rhs } } -impl Ord for ArrayString +impl Ord for ArrayString { fn cmp(&self, rhs: &Self) -> cmp::Ordering { (**self).cmp(&**rhs) } } -impl FromStr for ArrayString +impl FromStr for ArrayString { type Err = CapacityError; @@ -579,9 +587,9 @@ impl FromStr for ArrayString } } -#[cfg(feature="serde")] +#[cfg(feature = "serde")] /// Requires crate feature `"serde"` -impl Serialize for ArrayString +impl Serialize for ArrayString { fn serialize(&self, serializer: S) -> Result where S: Serializer @@ -590,9 +598,9 @@ impl Serialize for ArrayString } } -#[cfg(feature="serde")] +#[cfg(feature = "serde")] /// Requires crate feature `"serde"` -impl<'de, const CAP: usize> Deserialize<'de> for ArrayString +impl<'de, const CAP: usize, LenType: LenUint> Deserialize<'de> for ArrayString { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> @@ -600,10 +608,10 @@ impl<'de, const CAP: usize> Deserialize<'de> for ArrayString use serde::de::{self, Visitor}; use std::marker::PhantomData; - struct ArrayStringVisitor(PhantomData<[u8; CAP]>); + struct ArrayStringVisitor(PhantomData<([u8; CAP], LenType)>); - impl<'de, const CAP: usize> Visitor<'de> for ArrayStringVisitor { - type Value = ArrayString; + impl<'de, const CAP: usize, LenType: LenUint> Visitor<'de> for ArrayStringVisitor { + type Value = ArrayString; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a string no more than {} bytes long", CAP) @@ -630,7 +638,7 @@ impl<'de, const CAP: usize> Deserialize<'de> for ArrayString #[cfg(feature = "borsh")] /// Requires crate feature `"borsh"` -impl borsh::BorshSerialize for ArrayString { +impl borsh::BorshSerialize for ArrayString { fn serialize(&self, writer: &mut W) -> borsh::io::Result<()> { ::serialize(&*self, writer) } @@ -638,14 +646,14 @@ impl borsh::BorshSerialize for ArrayString { #[cfg(feature = "borsh")] /// Requires crate feature `"borsh"` -impl borsh::BorshDeserialize for ArrayString { +impl borsh::BorshDeserialize for ArrayString { fn deserialize_reader(reader: &mut R) -> borsh::io::Result { let len = ::deserialize_reader(reader)? as usize; if len > CAP { return Err(borsh::io::Error::new( borsh::io::ErrorKind::InvalidData, format!("Expected a string no more than {} bytes long", CAP), - )) + )); } let mut buf = [0u8; CAP]; @@ -659,7 +667,7 @@ impl borsh::BorshDeserialize for ArrayString { } } -impl<'a, const CAP: usize> TryFrom<&'a str> for ArrayString +impl<'a, const CAP: usize, LenType: LenUint> TryFrom<&'a str> for ArrayString { type Error = CapacityError<&'a str>; @@ -670,7 +678,7 @@ impl<'a, const CAP: usize> TryFrom<&'a str> for ArrayString } } -impl<'a, const CAP: usize> TryFrom> for ArrayString +impl<'a, const CAP: usize, LenType: LenUint> TryFrom> for ArrayString { type Error = CapacityError; @@ -697,7 +705,7 @@ impl<'a, const CAP: usize> TryFrom> for ArrayString /// unsafe { string.set_len(string.capacity()) }; /// assert_eq!(&*string, "\0\0\0\0\0\0"); /// ``` -impl zeroize::Zeroize for ArrayString { +impl zeroize::Zeroize for ArrayString { fn zeroize(&mut self) { // There are no elements to drop self.clear(); diff --git a/src/arrayvec.rs b/src/arrayvec.rs index e87b3ef..f7993cf 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -1,4 +1,3 @@ - use std::cmp; use std::iter; use std::mem; @@ -11,16 +10,17 @@ use std::borrow::{Borrow, BorrowMut}; use std::hash::{Hash, Hasher}; use std::fmt; -#[cfg(feature="std")] +#[cfg(feature = "std")] use std::io; use std::mem::ManuallyDrop; use std::mem::MaybeUninit; -#[cfg(feature="serde")] +#[cfg(feature = "serde")] use serde::{Serialize, Deserialize, Serializer, Deserializer}; -use crate::LenUint; +use crate::len_type::{check_cap_fits_in_len_type, ConstGenericSmuggler, CapToDefaultLenType}; +use crate::len_type::{LenUint, DefaultLenType}; use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; use crate::utils::MakeMaybeUninit; @@ -40,13 +40,13 @@ use crate::utils::MakeMaybeUninit; /// It offers a simple API but also dereferences to a slice, so that the full slice API is /// available. The ArrayVec can be converted into a by value iterator. #[repr(C)] -pub struct ArrayVec { - len: LenUint, +pub struct ArrayVec> { + len: LenT, // the `len` first elements of the array are initialized xs: [MaybeUninit; CAP], } -impl Drop for ArrayVec { +impl Drop for ArrayVec { fn drop(&mut self) { self.clear(); @@ -61,7 +61,7 @@ macro_rules! panic_oob { } } -impl ArrayVec { +impl ArrayVec { /// Capacity const CAPACITY: usize = CAP; @@ -80,11 +80,9 @@ impl ArrayVec { /// ``` #[inline] #[track_caller] - pub fn new() -> ArrayVec { - assert_capacity_limit!(CAP); - unsafe { - ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } + pub fn new() -> Self { + check_cap_fits_in_len_type::(); + ArrayVec { len: LenType::ZERO, xs: MakeMaybeUninit::ARRAY } } /// Create a new empty `ArrayVec` (const fn). @@ -96,9 +94,9 @@ impl ArrayVec { /// /// static ARRAY: ArrayVec = ArrayVec::new_const(); /// ``` - pub const fn new_const() -> ArrayVec { - assert_capacity_limit_const!(CAP); - ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } + pub const fn new_const() -> Self { + check_cap_fits_in_len_type::(); + ArrayVec { len: LenType::ZERO, xs: MakeMaybeUninit::ARRAY } } /// Return the number of elements in the `ArrayVec`. @@ -111,7 +109,7 @@ impl ArrayVec { /// assert_eq!(array.len(), 2); /// ``` #[inline(always)] - pub const fn len(&self) -> usize { self.len as usize } + pub fn len(&self) -> usize { self.len.to_usize() } /// Returns whether the `ArrayVec` is empty. /// @@ -123,7 +121,7 @@ impl ArrayVec { /// assert_eq!(array.is_empty(), true); /// ``` #[inline] - pub const fn is_empty(&self) -> bool { self.len() == 0 } + pub fn is_empty(&self) -> bool { self.len == LenType::ZERO } /// Return the capacity of the `ArrayVec`. /// @@ -146,7 +144,7 @@ impl ArrayVec { /// array.push(1); /// assert!(array.is_full()); /// ``` - pub const fn is_full(&self) -> bool { self.len() == self.capacity() } + pub fn is_full(&self) -> bool { self.len() == self.capacity() } /// Returns the capacity left in the `ArrayVec`. /// @@ -157,7 +155,7 @@ impl ArrayVec { /// array.pop(); /// assert_eq!(array.remaining_capacity(), 1); /// ``` - pub const fn remaining_capacity(&self) -> usize { + pub fn remaining_capacity(&self) -> usize { self.capacity() - self.len() } @@ -472,21 +470,21 @@ impl ArrayVec { let original_len = self.len(); unsafe { self.set_len(0) }; - struct BackshiftOnDrop<'a, T, const CAP: usize> { - v: &'a mut ArrayVec, + struct BackshiftOnDrop<'a, T, const CAP: usize, LenType: LenUint> { + v: &'a mut ArrayVec, processed_len: usize, deleted_cnt: usize, original_len: usize, } - impl Drop for BackshiftOnDrop<'_, T, CAP> { + impl Drop for BackshiftOnDrop<'_, T, CAP, LenType> { fn drop(&mut self) { if self.deleted_cnt > 0 { unsafe { ptr::copy( self.v.as_ptr().add(self.processed_len), self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt), - self.original_len - self.processed_len + self.original_len - self.processed_len, ); } } @@ -499,9 +497,9 @@ impl ArrayVec { let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; #[inline(always)] - fn process_one bool, T, const CAP: usize, const DELETED: bool>( + fn process_one bool, T, const CAP: usize, const DELETED: bool, LenType: LenUint>( f: &mut F, - g: &mut BackshiftOnDrop<'_, T, CAP> + g: &mut BackshiftOnDrop<'_, T, CAP, LenType>, ) -> bool { let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) }; if !f(unsafe { &mut *cur }) { @@ -522,14 +520,14 @@ impl ArrayVec { // Stage 1: Nothing was deleted. while g.processed_len != original_len { - if !process_one::(&mut f, &mut g) { + if !process_one::(&mut f, &mut g) { break; } } // Stage 2: Some elements were deleted. while g.processed_len != original_len { - process_one::(&mut f, &mut g); + process_one::(&mut f, &mut g); } drop(g); @@ -545,7 +543,7 @@ impl ArrayVec { pub unsafe fn set_len(&mut self, length: usize) { // type invariant that capacity always fits in LenUint debug_assert!(length <= self.capacity()); - self.len = length as LenUint; + self.len = LenType::from_usize(length); } /// Copy all elements from the slice and append to the `ArrayVec`. @@ -602,7 +600,7 @@ impl ArrayVec { /// assert_eq!(&v1[..], &[3]); /// assert_eq!(&v2[..], &[1, 2]); /// ``` - pub fn drain(&mut self, range: R) -> Drain + pub fn drain(&mut self, range: R) -> Drain where R: RangeBounds { // Memory safety @@ -629,7 +627,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(); @@ -638,7 +636,8 @@ impl ArrayVec { // Calling `set_len` creates a fresh and thus unique mutable references, making all // older aliases we created invalid. So we cannot call that function. - self.len = start as LenUint; + // safety: we just checked that the start is in bounds + self.len = LenType::from_usize(start); unsafe { Drain { @@ -682,7 +681,7 @@ impl ArrayVec { /// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap()); /// assert!(v.is_empty()); /// ``` - pub fn take(&mut self) -> Self { + pub fn take(&mut self) -> Self { mem::replace(self, Self::new()) } @@ -707,15 +706,15 @@ impl ArrayVec { } } -impl ArrayVecImpl for ArrayVec { +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) { - debug_assert!(length <= CAP); - self.len = length as LenUint; + debug_assert!(length <= CAP, "length {} exceeds capacity {}", length, CAP); + self.len = LenType::from_usize(length); } fn as_ptr(&self) -> *const Self::Item { @@ -727,7 +726,7 @@ impl ArrayVecImpl for ArrayVec { } } -impl Deref for ArrayVec { +impl Deref for ArrayVec { type Target = [T]; #[inline] fn deref(&self) -> &Self::Target { @@ -735,7 +734,7 @@ impl Deref for ArrayVec { } } -impl DerefMut for ArrayVec { +impl DerefMut for ArrayVec { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() @@ -752,11 +751,13 @@ impl DerefMut for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 3); /// ``` -impl From<[T; CAP]> for ArrayVec { +impl From<[T; CAP]> for ArrayVec + where ConstGenericSmuggler: CapToDefaultLenType +{ #[track_caller] fn from(array: [T; CAP]) -> Self { let array = ManuallyDrop::new(array); - let mut vec = >::new(); + let mut vec = Self::new(); unsafe { (&*array as *const [T; CAP] as *const [MaybeUninit; CAP]) .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit; CAP], 1); @@ -778,7 +779,7 @@ impl From<[T; CAP]> for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 4); /// ``` -impl std::convert::TryFrom<&[T]> for ArrayVec +impl std::convert::TryFrom<&[T]> for ArrayVec where T: Clone, { type Error = CapacityError; @@ -806,7 +807,7 @@ impl std::convert::TryFrom<&[T]> for ArrayVec /// // ... /// } /// ``` -impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec { +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> IntoIterator for &'a ArrayVec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter() } @@ -823,7 +824,7 @@ impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec { /// // ... /// } /// ``` -impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec { +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> 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() } @@ -840,11 +841,11 @@ impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec { /// // ... /// } /// ``` -impl IntoIterator for ArrayVec { +impl IntoIterator for ArrayVec { type Item = T; - type IntoIter = IntoIter; - fn into_iter(self) -> IntoIter { - IntoIter { index: 0, v: self, } + type IntoIter = IntoIter; + fn into_iter(self) -> Self::IntoIter { + IntoIter { index: 0, v: self } } } @@ -864,7 +865,7 @@ impl IntoIterator for ArrayVec { /// let data = unsafe { core::slice::from_raw_parts(array.as_ptr(), array.capacity()) }; /// assert_eq!(data, [0, 0, 0]); /// ``` -impl zeroize::Zeroize for ArrayVec { +impl zeroize::Zeroize for ArrayVec { fn zeroize(&mut self) { // Zeroize all the contained elements. self.iter_mut().zeroize(); @@ -876,11 +877,12 @@ impl zeroize::Zeroize for ArrayVec { +pub struct IntoIter> { index: usize, - v: ArrayVec, + v: ArrayVec, } -impl IntoIter { + +impl IntoIter { /// Returns the remaining items of this iterator as a slice. pub fn as_slice(&self) -> &[T] { &self.v[self.index..] @@ -892,7 +894,7 @@ impl IntoIter { } } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { @@ -913,7 +915,7 @@ impl Iterator for IntoIter { } } -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { if self.index == self.v.len() { None @@ -927,9 +929,9 @@ 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; @@ -944,19 +946,19 @@ impl Drop for IntoIter { } } -impl Clone for IntoIter -where T: Clone, +impl Clone for IntoIter + where T: Clone, { - fn clone(&self) -> IntoIter { + fn clone(&self) -> Self { let mut v = ArrayVec::new(); v.extend_from_slice(&self.v[self.index..]); v.into_iter() } } -impl fmt::Debug for IntoIter -where - T: fmt::Debug, +impl fmt::Debug for IntoIter + where + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() @@ -966,20 +968,21 @@ where } /// A draining iterator for `ArrayVec`. -pub struct Drain<'a, T: 'a, const CAP: usize> { +pub struct Drain<'a, T: 'a, const CAP: usize, LenType: LenUint> { /// Index of tail to preserve tail_start: usize, /// Length of tail tail_len: usize, /// Current remaining range to remove iter: slice::Iter<'a, T>, - vec: *mut ArrayVec, + vec: *mut ArrayVec, } -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> {} +unsafe impl<'a, T: Sync, const CAP: usize, LenType: LenUint> Sync for Drain<'a, T, CAP, LenType> {} -impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { +unsafe impl<'a, T: Send, const CAP: usize, LenType: LenUint> Send for Drain<'a, T, CAP, LenType> {} + +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> Iterator for Drain<'a, T, CAP, LenType> { type Item = T; fn next(&mut self) -> Option { @@ -995,7 +998,7 @@ impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { } } -impl<'a, T: 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> DoubleEndedIterator for Drain<'a, T, CAP, LenType> { fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| @@ -1006,14 +1009,14 @@ impl<'a, T: 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> } } -impl<'a, T: 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> ExactSizeIterator for Drain<'a, T, CAP, LenType> {} -impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { +impl<'a, T: 'a, const CAP: usize, LenType: LenUint> Drop for Drain<'a, T, CAP, LenType> { fn drop(&mut self) { // len is currently 0 so panicking while dropping will not cause a double drop. // exhaust self first - while let Some(_) = self.next() { } + while let Some(_) = self.next() {} if self.tail_len > 0 { unsafe { @@ -1046,13 +1049,12 @@ impl Drop for ScopeExitGuard } - /// Extend the `ArrayVec` with an iterator. -/// +/// /// ***Panics*** if extending the vector exceeds its capacity. -impl Extend for ArrayVec { +impl Extend for ArrayVec { /// Extend the `ArrayVec` with an iterator. - /// + /// /// ***Panics*** if extending the vector exceeds its capacity. #[track_caller] fn extend>(&mut self, iter: I) { @@ -1069,7 +1071,7 @@ fn extend_panic() { panic!("ArrayVec: capacity exceeded in extend/from_iter"); } -impl ArrayVec { +impl ArrayVec { /// Extend the arrayvec from the iterable. /// /// ## Safety @@ -1078,7 +1080,7 @@ impl ArrayVec { /// The caller must ensure the length of the input fits in the capacity. #[track_caller] pub(crate) unsafe fn extend_from_iter(&mut self, iterable: I) - where I: IntoIterator + where I: IntoIterator { let take = self.capacity() - self.len(); let len = self.len(); @@ -1092,8 +1094,8 @@ impl ArrayVec { value: &mut self.len, data: len, f: move |&len, self_len| { - **self_len = len as LenUint; - } + **self_len = LenUint::from_usize(len); + }, }; let mut iter = iterable.into_iter(); loop { @@ -1136,11 +1138,11 @@ unsafe fn raw_ptr_add(ptr: *mut T, offset: usize) -> *mut T { } /// Create an `ArrayVec` from an iterator. -/// +/// /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. -impl iter::FromIterator for ArrayVec { +impl iter::FromIterator for ArrayVec { /// Create an `ArrayVec` from an iterator. - /// + /// /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. fn from_iter>(iter: I) -> Self { let mut array = ArrayVec::new(); @@ -1149,7 +1151,7 @@ impl iter::FromIterator for ArrayVec { } } -impl Clone for ArrayVec +impl Clone for ArrayVec where T: Clone { fn clone(&self) -> Self { @@ -1171,7 +1173,7 @@ impl Clone for ArrayVec } } -impl Hash for ArrayVec +impl Hash for ArrayVec where T: Hash { fn hash(&self, state: &mut H) { @@ -1179,7 +1181,7 @@ impl Hash for ArrayVec } } -impl PartialEq for ArrayVec +impl PartialEq for ArrayVec where T: PartialEq { fn eq(&self, other: &Self) -> bool { @@ -1187,7 +1189,7 @@ impl PartialEq for ArrayVec } } -impl PartialEq<[T]> for ArrayVec +impl PartialEq<[T]> for ArrayVec where T: PartialEq { fn eq(&self, other: &[T]) -> bool { @@ -1195,36 +1197,36 @@ impl PartialEq<[T]> for ArrayVec } } -impl Eq for ArrayVec where T: Eq { } +impl Eq for ArrayVec where T: Eq {} -impl Borrow<[T]> for ArrayVec { +impl Borrow<[T]> for ArrayVec { fn borrow(&self) -> &[T] { self } } -impl BorrowMut<[T]> for ArrayVec { +impl BorrowMut<[T]> for ArrayVec { fn borrow_mut(&mut self) -> &mut [T] { self } } -impl AsRef<[T]> for ArrayVec { +impl AsRef<[T]> for ArrayVec { fn as_ref(&self) -> &[T] { self } } -impl AsMut<[T]> for ArrayVec { +impl AsMut<[T]> for ArrayVec { fn as_mut(&mut self) -> &mut [T] { self } } -impl fmt::Debug for ArrayVec where T: 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() -> Self { ArrayVec::new() } } -impl PartialOrd for ArrayVec where T: PartialOrd { +impl PartialOrd for ArrayVec where T: PartialOrd { fn partial_cmp(&self, other: &Self) -> Option { (**self).partial_cmp(other) } @@ -1246,17 +1248,17 @@ impl PartialOrd for ArrayVec where T: PartialOrd { } } -impl Ord for ArrayVec where T: Ord { +impl Ord for ArrayVec where T: Ord { fn cmp(&self, other: &Self) -> cmp::Ordering { (**self).cmp(other) } } -#[cfg(feature="std")] +#[cfg(feature = "std")] /// `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]); @@ -1266,9 +1268,9 @@ impl io::Write for ArrayVec { fn flush(&mut self) -> io::Result<()> { Ok(()) } } -#[cfg(feature="serde")] +#[cfg(feature = "serde")] /// Requires crate feature `"serde"` -impl Serialize for ArrayVec { +impl Serialize for ArrayVec { fn serialize(&self, serializer: S) -> Result where S: Serializer { @@ -1276,19 +1278,19 @@ impl Serialize for ArrayVec { } } -#[cfg(feature="serde")] +#[cfg(feature = "serde")] /// Requires crate feature `"serde"` -impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec { +impl<'de, T: Deserialize<'de>, const CAP: usize, LenType: LenUint> 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>, const CAP: usize>(PhantomData<(&'de (), [T; CAP])>); + struct ArrayVecVisitor<'de, T: Deserialize<'de>, const CAP: usize, LenType: LenUint>(PhantomData<(&'de (), [T; CAP], LenType)>); - impl<'de, T: Deserialize<'de>, const CAP: usize> Visitor<'de> for ArrayVecVisitor<'de, T, CAP> { - type Value = ArrayVec; + impl<'de, T: Deserialize<'de>, const CAP: usize, LenType: LenUint> Visitor<'de> for ArrayVecVisitor<'de, T, CAP, LenType> { + type Value = ArrayVec; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an array with no more than {} items", CAP) @@ -1297,7 +1299,7 @@ impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec(self, mut seq: SA) -> Result where SA: SeqAccess<'de>, { - let mut values = ArrayVec::::new(); + let mut values = ArrayVec::::new(); while let Some(value) = seq.next_element()? { if let Err(_) = values.try_push(value) { @@ -1309,15 +1311,15 @@ impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec(PhantomData)) + deserializer.deserialize_seq(ArrayVecVisitor::(PhantomData)) } } #[cfg(feature = "borsh")] /// Requires crate feature `"borsh"` -impl borsh::BorshSerialize for ArrayVec -where - T: borsh::BorshSerialize, +impl borsh::BorshSerialize for ArrayVec + where + T: borsh::BorshSerialize, { fn serialize(&self, writer: &mut W) -> borsh::io::Result<()> { <[T] as borsh::BorshSerialize>::serialize(self.as_slice(), writer) @@ -1326,9 +1328,9 @@ where #[cfg(feature = "borsh")] /// Requires crate feature `"borsh"` -impl borsh::BorshDeserialize for ArrayVec -where - T: borsh::BorshDeserialize, +impl borsh::BorshDeserialize for ArrayVec + where + T: borsh::BorshDeserialize, { fn deserialize_reader(reader: &mut R) -> borsh::io::Result { let mut values = Self::new(); diff --git a/src/len_type.rs b/src/len_type.rs new file mode 100644 index 0000000..f9dfe8c --- /dev/null +++ b/src/len_type.rs @@ -0,0 +1,69 @@ +use core::ops::{Add, Sub}; + +macro_rules! impl_lenuint { + ($Sealed:ty, $LenUint:ty, $ty: path) => { + impl $Sealed for $ty {} + impl $LenUint for $ty { + const MAX: usize = <$ty>::MAX as usize; + const ZERO: Self = 0; + fn from_usize(n: usize) -> Self { n as $ty } + fn to_usize(self) -> usize { self as usize } + } + }; +} + +macro_rules! impl_default_lentype_from_cap { + ($LenT:ty => $($CAP:literal),*) => { + $( + impl CapToDefaultLenType for ConstGenericSmuggler<$CAP> { + type T = $LenT; + } + )* + }; +} + +pub trait LenUint: Add + Sub + Copy + PartialOrd + PartialEq + private::Sealed { + const MAX: usize; + const ZERO: Self; + fn from_usize(n: usize) -> Self; + fn to_usize(self) -> usize; +} + +mod private { + pub trait Sealed {} + + impl_lenuint!(Sealed, super::LenUint, u8); + impl_lenuint!(Sealed, super::LenUint, u16); + impl_lenuint!(Sealed, super::LenUint, u32); + #[cfg(target_pointer_width = "64")] + impl_lenuint!(Sealed, super::LenUint, u64); + impl_lenuint!(Sealed, super::LenUint, usize); +} + +pub struct ConstGenericSmuggler {} + +pub trait CapToDefaultLenType { + type T: LenUint; +} + +impl_default_lentype_from_cap!(u8 => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64, 100, 128, 200, 255); +impl_default_lentype_from_cap!(u16 => 256, 500, 512, 1000, 1024, 2048, 4096, 8192, 16384, 32768, 65535); +impl_default_lentype_from_cap!(u32 => 65536, 1000000, 4294967295); +impl_default_lentype_from_cap!(u64 => 18446744073709551615); + +pub trait CapFitsInLenType { + const CHECK: (); +} + +impl CapFitsInLenType for (ConstGenericSmuggler, LenType) { + const CHECK: () = { + if CAP > LenType::MAX { + panic!("Cannot fit CAP into provided LenType"); + } + }; +} + +pub type DefaultLenType = as CapToDefaultLenType>::T; +pub const fn check_cap_fits_in_len_type() { + <(ConstGenericSmuggler, LenType) as CapFitsInLenType>::CHECK +} diff --git a/src/lib.rs b/src/lib.rs index f9a2fe6..9b6cbda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,28 +28,7 @@ extern crate serde; #[cfg(not(feature="std"))] extern crate core as std; -pub(crate) type LenUint = u32; - -macro_rules! assert_capacity_limit { - ($cap:expr) => { - if std::mem::size_of::() > std::mem::size_of::() { - if $cap > LenUint::MAX as usize { - panic!("ArrayVec: largest supported capacity is u32::MAX") - } - } - } -} - -macro_rules! assert_capacity_limit_const { - ($cap:expr) => { - if std::mem::size_of::() > std::mem::size_of::() { - if $cap > LenUint::MAX as usize { - [/*ArrayVec: largest supported capacity is u32::MAX*/][$cap] - } - } - } -} - +mod len_type; mod arrayvec_impl; mod arrayvec; mod array_string; @@ -59,5 +38,6 @@ mod utils; pub use crate::array_string::ArrayString; pub use crate::errors::CapacityError; +pub use len_type::LenUint; pub use crate::arrayvec::{ArrayVec, IntoIter, Drain}; diff --git a/src/utils.rs b/src/utils.rs index b8e5ddb..b425a51 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -8,4 +8,3 @@ impl MakeMaybeUninit { pub(crate) const ARRAY: [MaybeUninit; N] = [Self::VALUE; N]; } - diff --git a/tests/borsh.rs b/tests/borsh.rs index f05abcf..0f31481 100644 --- a/tests/borsh.rs +++ b/tests/borsh.rs @@ -59,7 +59,7 @@ mod array_string { #[test] fn test_full() { - let string = ArrayString::from_byte_string(b"hello world").unwrap(); + let string = ArrayString::<11>::from_byte_string(b"hello world").unwrap(); assert_ser(&string, b"\x0b\0\0\0hello world"); assert_roundtrip(&string); } diff --git a/tests/tests.rs b/tests/tests.rs index 2f8a5ef..ffd6729 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,5 +1,6 @@ extern crate arrayvec; -#[macro_use] extern crate matches; +#[macro_use] +extern crate matches; use arrayvec::ArrayVec; use arrayvec::ArrayString; @@ -13,7 +14,7 @@ use std::collections::HashMap; fn test_simple() { use std::ops::Add; - let mut vec: ArrayVec, 3> = ArrayVec::new(); + let mut vec: ArrayVec, 3> = ArrayVec::new(); vec.push(vec![1, 2, 3, 4]); vec.push(vec![10]); @@ -29,7 +30,7 @@ fn test_simple() { #[test] fn test_capacity_left() { - let mut vec: ArrayVec = ArrayVec::new(); + let mut vec: ArrayVec = ArrayVec::new(); assert_eq!(vec.remaining_capacity(), 4); vec.push(1); assert_eq!(vec.remaining_capacity(), 3); @@ -43,7 +44,7 @@ fn test_capacity_left() { #[test] fn test_extend_from_slice() { - let mut vec: ArrayVec = ArrayVec::new(); + let mut vec: ArrayVec = ArrayVec::new(); vec.try_extend_from_slice(&[1, 2, 3]).unwrap(); assert_eq!(vec.len(), 3); @@ -54,13 +55,13 @@ fn test_extend_from_slice() { #[test] fn test_extend_from_slice_error() { - let mut vec: ArrayVec = ArrayVec::new(); + let mut vec: ArrayVec = ArrayVec::new(); vec.try_extend_from_slice(&[1, 2, 3]).unwrap(); let res = vec.try_extend_from_slice(&[0; 8]); assert_matches!(res, Err(_)); - let mut vec: ArrayVec = ArrayVec::new(); + let mut vec: ArrayVec = ArrayVec::new(); let res = vec.try_extend_from_slice(&[0; 1]); assert_matches!(res, Err(_)); } @@ -70,14 +71,14 @@ fn test_try_from_slice_error() { use arrayvec::ArrayVec; use std::convert::TryInto as _; - let res: Result, _> = (&[1, 2, 3] as &[_]).try_into(); + let res: Result, _> = (&[1, 2, 3] as &[_]).try_into(); assert_matches!(res, Err(_)); } #[test] fn test_u16_index() { const N: usize = 4096; - let mut vec: ArrayVec<_, N> = ArrayVec::new(); + let mut vec: ArrayVec<_, N> = ArrayVec::new(); for _ in 0..N { assert!(vec.try_push(1u8).is_ok()); } @@ -87,7 +88,8 @@ fn test_u16_index() { #[test] fn test_iter() { - let mut iter = ArrayVec::from([1, 2, 3]).into_iter(); + let vec: ArrayVec<_, 3> = ArrayVec::from([1, 2, 3]); + let mut iter = vec.into_iter(); assert_eq!(iter.size_hint(), (3, Some(3))); assert_eq!(iter.next_back(), Some(3)); assert_eq!(iter.next(), Some(1)); @@ -113,7 +115,7 @@ fn test_drop() { } { - let mut array = ArrayVec::::new(); + let mut array = ArrayVec::::new(); array.push(Bump(flag)); array.push(Bump(flag)); } @@ -123,7 +125,7 @@ fn test_drop() { flag.set(0); { - let mut array = ArrayVec::<_, 3>::new(); + let mut array = ArrayVec::<_, 3>::new(); array.push(vec![Bump(flag)]); array.push(vec![Bump(flag), Bump(flag)]); array.push(vec![]); @@ -142,7 +144,7 @@ fn test_drop() { // test into_inner flag.set(0); { - let mut array = ArrayVec::<_, 3>::new(); + let mut array = ArrayVec::<_, 3>::new(); array.push(Bump(flag)); array.push(Bump(flag)); array.push(Bump(flag)); @@ -156,7 +158,7 @@ fn test_drop() { // test take flag.set(0); { - let mut array1 = ArrayVec::<_, 3>::new(); + let mut array1 = ArrayVec::<_, 3>::new(); array1.push(Bump(flag)); array1.push(Bump(flag)); array1.push(Bump(flag)); @@ -171,7 +173,7 @@ fn test_drop() { // test cloning into_iter flag.set(0); { - let mut array = ArrayVec::<_, 3>::new(); + let mut array = ArrayVec::<_, 3>::new(); array.push(Bump(flag)); array.push(Bump(flag)); array.push(Bump(flag)); @@ -225,7 +227,7 @@ fn test_drop_panics() { flag.set(0); { - let mut array = ArrayVec::::new(); + let mut array = ArrayVec::::new(); array.push(Bump(flag)); array.push(Bump(flag)); array.push(Bump(flag)); @@ -241,7 +243,7 @@ fn test_drop_panics() { flag.set(0); { - let mut array = ArrayVec::::new(); + let mut array = ArrayVec::::new(); array.push(Bump(flag)); array.push(Bump(flag)); array.push(Bump(flag)); @@ -258,22 +260,20 @@ fn test_drop_panics() { // Check that all the tail elements drop, even if the first drop panics. assert_eq!(flag.get(), tail_len as i32); } - - } #[test] fn test_extend() { let mut range = 0..10; - let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); + let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); assert_eq!(&array[..], &[0, 1, 2, 3, 4]); assert_eq!(range.next(), Some(5)); array.extend(range.by_ref().take(0)); assert_eq!(range.next(), Some(6)); - let mut array: ArrayVec<_, 10> = (0..3).collect(); + let mut array: ArrayVec<_, 10> = (0..3).collect(); assert_eq!(&array[..], &[0, 1, 2]); array.extend(3..5); assert_eq!(&array[..], &[0, 1, 2, 3, 4]); @@ -284,7 +284,7 @@ fn test_extend() { fn test_extend_capacity_panic_1() { let mut range = 0..10; - let _: ArrayVec<_, 5> = range.by_ref().collect(); + let _: ArrayVec<_, 5> = range.by_ref().collect(); } #[should_panic] @@ -292,7 +292,7 @@ fn test_extend_capacity_panic_1() { fn test_extend_capacity_panic_2() { let mut range = 0..10; - let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); + let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); assert_eq!(&array[..], &[0, 1, 2, 3, 4]); assert_eq!(range.next(), Some(5)); array.extend(range.by_ref().take(1)); @@ -300,7 +300,7 @@ fn test_extend_capacity_panic_2() { #[test] fn test_is_send_sync() { - let data = ArrayVec::, 5>::new(); + let data = ArrayVec::, 5>::new(); &data as &dyn Send; &data as &dyn Sync; } @@ -308,24 +308,24 @@ fn test_is_send_sync() { #[test] fn test_compact_size() { // 4 bytes + padding + length - type ByteArray = ArrayVec; + type ByteArray = ArrayVec; println!("{}", mem::size_of::()); assert!(mem::size_of::() <= 2 * mem::size_of::()); // just length - type EmptyArray = ArrayVec; + type EmptyArray = ArrayVec; println!("{}", mem::size_of::()); assert!(mem::size_of::() <= mem::size_of::()); // 3 elements + padding + length - type QuadArray = ArrayVec; + type QuadArray = ArrayVec; println!("{}", mem::size_of::()); assert!(mem::size_of::() <= 4 * 4 + mem::size_of::()); } #[test] fn test_still_works_with_option_arrayvec() { - type RefArray = ArrayVec<&'static i32, 2>; + type RefArray = ArrayVec<&'static i32, 2>; let array = Some(RefArray::new()); assert!(array.is_some()); println!("{:?}", array); @@ -333,7 +333,7 @@ fn test_still_works_with_option_arrayvec() { #[test] fn test_drain() { - let mut v = ArrayVec::from([0; 8]); + let mut v: ArrayVec = ArrayVec::from([0; 8]); v.pop(); v.drain(0..7); assert_eq!(&v[..], &[]); @@ -341,7 +341,7 @@ fn test_drain() { v.extend(0..8); v.drain(1..4); assert_eq!(&v[..], &[0, 4, 5, 6, 7]); - let u: ArrayVec<_, 3> = v.drain(1..4).rev().collect(); + let u: ArrayVec<_, 3> = v.drain(1..4).rev().collect(); assert_eq!(&u[..], &[6, 5, 4]); assert_eq!(&v[..], &[0, 7]); v.drain(..); @@ -350,14 +350,14 @@ fn test_drain() { #[test] fn test_drain_range_inclusive() { - let mut v = ArrayVec::from([0; 8]); + let mut v: ArrayVec<_, 8> = ArrayVec::from([0; 8]); v.drain(0..=7); assert_eq!(&v[..], &[]); v.extend(0..8); v.drain(1..=4); assert_eq!(&v[..], &[0, 5, 6, 7]); - let u: ArrayVec<_, 3> = v.drain(1..=2).rev().collect(); + let u: ArrayVec<_, 3> = v.drain(1..=2).rev().collect(); assert_eq!(&u[..], &[6, 5]); assert_eq!(&v[..], &[0, 7]); v.drain(..); @@ -367,13 +367,13 @@ fn test_drain_range_inclusive() { #[test] #[should_panic] fn test_drain_range_inclusive_oob() { - let mut v = ArrayVec::from([0; 0]); + let mut v: ArrayVec<_, 0> = ArrayVec::from([0; 0]); v.drain(0..=0); } #[test] fn test_retain() { - let mut v = ArrayVec::from([0; 8]); + let mut v: ArrayVec<_, 8> = ArrayVec::from([0; 8]); for (i, elt) in v.iter_mut().enumerate() { *elt = i; } @@ -391,7 +391,7 @@ fn test_retain() { #[test] #[should_panic] fn test_drain_oob() { - let mut v = ArrayVec::from([0; 8]); + let mut v: ArrayVec<_, 8> = ArrayVec::from([0; 8]); v.pop(); v.drain(0..8); } @@ -407,7 +407,7 @@ fn test_drop_panic() { } } - let mut array = ArrayVec::::new(); + let mut array = ArrayVec::::new(); array.push(DropPanic); } @@ -422,17 +422,17 @@ fn test_drop_panic_into_iter() { } } - let mut array = ArrayVec::::new(); + let mut array = ArrayVec::::new(); array.push(DropPanic); array.into_iter(); } #[test] fn test_insert() { - let mut v = ArrayVec::from([]); + let mut v: ArrayVec<_, 0> = ArrayVec::from([]); assert_matches!(v.try_push(1), Err(_)); - let mut v = ArrayVec::<_, 3>::new(); + let mut v = ArrayVec::<_, 3>::new(); v.insert(0, 0); v.insert(1, 1); //let ret1 = v.try_insert(3, 3); @@ -445,7 +445,7 @@ fn test_insert() { assert_eq!(&v[..], &[0, 1, 2]); assert_matches!(ret2, Err(_)); - let mut v = ArrayVec::from([2]); + let mut v: ArrayVec<_, 1> = ArrayVec::from([2]); assert_matches!(v.try_insert(0, 1), Err(CapacityError { .. })); assert_matches!(v.try_insert(1, 1), Err(CapacityError { .. })); //assert_matches!(v.try_insert(2, 1), Err(CapacityError { .. })); @@ -453,7 +453,7 @@ fn test_insert() { #[test] fn test_into_inner_1() { - let mut v = ArrayVec::from([1, 2]); + let mut v: ArrayVec<_, 2> = ArrayVec::from([1, 2]); v.pop(); let u = v.clone(); assert_eq!(v.into_inner(), Err(u)); @@ -461,7 +461,7 @@ fn test_into_inner_1() { #[test] fn test_into_inner_2() { - let mut v = ArrayVec::::new(); + let mut v = ArrayVec::::new(); v.push("a".into()); v.push("b".into()); v.push("c".into()); @@ -471,25 +471,25 @@ fn test_into_inner_2() { #[test] fn test_into_inner_3() { - let mut v = ArrayVec::::new(); + let mut v = ArrayVec::::new(); v.extend(1..=4); assert_eq!(v.into_inner().unwrap(), [1, 2, 3, 4]); } #[test] fn test_take() { - let mut v1 = ArrayVec::::new(); + let mut v1 = ArrayVec::::new(); v1.extend(1..=4); let v2 = v1.take(); assert!(v1.into_inner().is_err()); assert_eq!(v2.into_inner().unwrap(), [1, 2, 3, 4]); } -#[cfg(feature="std")] +#[cfg(feature = "std")] #[test] fn test_write() { use std::io::Write; - let mut v = ArrayVec::<_, 8>::new(); + let mut v = ArrayVec::<_, 8>::new(); write!(&mut v, "\x01\x02\x03").unwrap(); assert_eq!(&v[..], &[1, 2, 3]); let r = v.write(&[9; 16]).unwrap(); @@ -499,16 +499,16 @@ fn test_write() { #[test] fn array_clone_from() { - let mut v = ArrayVec::<_, 4>::new(); + let mut v = ArrayVec::<_, 4>::new(); v.push(vec![1, 2]); v.push(vec![3, 4, 5]); v.push(vec![6]); let reference = v.to_vec(); - let mut u = ArrayVec::<_, 4>::new(); + let mut u = ArrayVec::<_, 4>::new(); u.clone_from(&v); assert_eq!(&u, &reference[..]); - let mut t = ArrayVec::<_, 4>::new(); + let mut t = ArrayVec::<_, 4>::new(); t.push(vec![97]); t.push(vec![]); t.push(vec![5, 6, 2]); @@ -520,7 +520,7 @@ fn array_clone_from() { assert_eq!(&t, &reference[..]); } -#[cfg(feature="std")] +#[cfg(feature = "std")] #[test] fn test_string() { use std::error::Error; @@ -557,7 +557,7 @@ fn test_string() { #[test] fn test_string_from() { let text = "hello world"; - // Test `from` constructor + // Test `from` constructor let u = ArrayString::<11>::from(text).unwrap(); assert_eq!(&u, text); assert_eq!(u.len(), text.len()); @@ -574,7 +574,7 @@ fn test_string_parse_from_str() { #[test] fn test_string_from_bytes() { let text = "hello world"; - let u = ArrayString::from_byte_string(b"hello world").unwrap(); + let u: ArrayString<11> = ArrayString::from_byte_string(b"hello world").unwrap(); assert_eq!(&u, text); assert_eq!(u.len(), text.len()); } @@ -607,7 +607,7 @@ fn test_string_push() { #[test] fn test_insert_at_length() { - let mut v = ArrayVec::<_, 8>::new(); + let mut v = ArrayVec::<_, 8>::new(); let result1 = v.try_insert(0, "a"); let result2 = v.try_insert(1, "b"); assert!(result1.is_ok() && result2.is_ok()); @@ -617,7 +617,7 @@ fn test_insert_at_length() { #[should_panic] #[test] fn test_insert_out_of_bounds() { - let mut v = ArrayVec::<_, 8>::new(); + let mut v = ArrayVec::<_, 8>::new(); let _ = v.try_insert(1, "test"); } @@ -650,7 +650,7 @@ fn test_drop_in_insert() { flag.set(0); { - let mut array = ArrayVec::<_, 2>::new(); + let mut array = ArrayVec::<_, 2>::new(); array.push(Bump(flag)); array.insert(0, Bump(flag)); assert_eq!(flag.get(), 0); @@ -665,7 +665,7 @@ fn test_drop_in_insert() { #[test] fn test_pop_at() { - let mut v = ArrayVec::::new(); + let mut v = ArrayVec::::new(); let s = String::from; v.push(s("a")); v.push(s("b")); @@ -681,7 +681,7 @@ fn test_pop_at() { #[test] fn test_sizes() { - let v = ArrayVec::from([0u8; 1 << 16]); + let v: ArrayVec<_, { 1 << 16 }> = ArrayVec::from([0u8; 1 << 16]); assert_eq!(vec![0u8; v.len()], &v[..]); } @@ -690,19 +690,19 @@ fn test_default() { use std::net; let s: ArrayString<4> = Default::default(); // Something without `Default` implementation. - let v: ArrayVec = Default::default(); + let v: ArrayVec = Default::default(); assert_eq!(s.len(), 0); assert_eq!(v.len(), 0); } -#[cfg(feature="array-sizes-33-128")] +#[cfg(feature = "array-sizes-33-128")] #[test] fn test_sizes_33_128() { ArrayVec::from([0u8; 52]); ArrayVec::from([0u8; 127]); } -#[cfg(feature="array-sizes-129-255")] +#[cfg(feature = "array-sizes-129-255")] #[test] fn test_sizes_129_255() { ArrayVec::from([0u8; 237]); @@ -715,14 +715,14 @@ fn test_extend_zst() { #[derive(Copy, Clone, PartialEq, Debug)] struct Z; // Zero sized type - let mut array: ArrayVec<_, 5> = range.by_ref().take(5).map(|_| Z).collect(); + let mut array: ArrayVec<_, 5> = range.by_ref().take(5).map(|_| Z).collect(); assert_eq!(&array[..], &[Z; 5]); assert_eq!(range.next(), Some(5)); array.extend(range.by_ref().take(0).map(|_| Z)); assert_eq!(range.next(), Some(6)); - let mut array: ArrayVec<_, 10> = (0..3).map(|_| Z).collect(); + let mut array: ArrayVec<_, 10> = (0..3).map(|_| Z).collect(); assert_eq!(&array[..], &[Z; 3]); array.extend((3..5).map(|_| Z)); assert_eq!(&array[..], &[Z; 5]); @@ -736,32 +736,6 @@ fn test_try_from_argument() { assert_eq!(&v, "Hello 123"); } -#[test] -fn allow_max_capacity_arrayvec_type() { - // this type is allowed to be used (but can't be constructed) - let _v: ArrayVec<(), {usize::MAX}>; -} - -#[should_panic(expected="largest supported capacity")] -#[test] -fn deny_max_capacity_arrayvec_value() { - if mem::size_of::() <= mem::size_of::() { - panic!("This test does not work on this platform. 'largest supported capacity'"); - } - // this type is allowed to be used (but can't be constructed) - let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new(); -} - -#[should_panic(expected="index out of bounds")] -#[test] -fn deny_max_capacity_arrayvec_value_const() { - if mem::size_of::() <= mem::size_of::() { - panic!("This test does not work on this platform. 'index out of bounds'"); - } - // this type is allowed to be used (but can't be constructed) - let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new_const(); -} - #[test] fn test_arrayvec_const_constructible() { const OF_U8: ArrayVec, 10> = ArrayVec::new_const();