From 000d5963bca0ab672667286a6e60ec01521a9a86 Mon Sep 17 00:00:00 2001 From: nitram Date: Fri, 16 Jul 2021 19:28:42 +0100 Subject: [PATCH 1/3] add copy feature to ArrayVec --- Cargo.toml | 1 + src/arrayvec.rs | 142 ++++++++++++++++++++++++++++-------------------- tests/tests.rs | 13 +++++ 3 files changed, 98 insertions(+), 58 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c9d16c3..07613fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ harness = false [features] default = ["std"] std = [] +copy = [] [profile.bench] debug = true diff --git a/src/arrayvec.rs b/src/arrayvec.rs index 6b4faf8..d7751a3 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -23,8 +23,27 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer}; use crate::LenUint; use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; +#[cfg(not(feature="copy"))] use crate::utils::MakeMaybeUninit; +/// All types implement this when the `copy` feature is disabled. +/// +/// If `copy` is enabled, only Copy types implement it. +#[cfg(feature="copy")] +pub trait ValidValue: Copy {} + +#[cfg(feature="copy")] +impl ValidValue for T {} + +/// All types implement this when the `copy` feature is disabled. +/// +/// If `copy` is enabled, only Copy types implement it. +#[cfg(not(feature="copy"))] +pub trait ValidValue {} + +#[cfg(not(feature="copy"))] +impl ValidValue for T {} + /// A vector with a fixed capacity. /// /// The `ArrayVec` is a vector backed by a fixed size array. It keeps track of @@ -39,13 +58,17 @@ 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. -pub struct ArrayVec { +pub struct ArrayVec { // the `len` first elements of the array are initialized xs: [MaybeUninit; CAP], len: LenUint, } -impl Drop for ArrayVec { +#[cfg(feature="copy")] +impl Copy for ArrayVec {} + +#[cfg(not(feature="copy"))] +impl Drop for ArrayVec { fn drop(&mut self) { self.clear(); @@ -60,7 +83,24 @@ macro_rules! panic_oob { } } +#[cfg(not(feature="copy"))] impl ArrayVec { + /// Create a new empty `ArrayVec` (const fn). + /// + /// The maximum capacity is given by the generic parameter `CAP`. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// static ARRAY: ArrayVec = ArrayVec::new_const(); + /// ``` + pub const fn new_const() -> ArrayVec { + assert_capacity_limit_const!(CAP); + ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } + } +} + +impl ArrayVec { /// Capacity const CAPACITY: usize = CAP; @@ -84,20 +124,6 @@ impl ArrayVec { } } - /// Create a new empty `ArrayVec` (const fn). - /// - /// The maximum capacity is given by the generic parameter `CAP`. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// static ARRAY: ArrayVec = ArrayVec::new_const(); - /// ``` - pub const fn new_const() -> ArrayVec { - assert_capacity_limit_const!(CAP); - ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } - } - /// Return the number of elements in the `ArrayVec`. /// /// ``` @@ -467,14 +493,14 @@ impl ArrayVec { let original_len = self.len(); unsafe { self.set_len(0) }; - struct BackshiftOnDrop<'a, T, const CAP: usize> { + struct BackshiftOnDrop<'a, T: ValidValue, const CAP: usize> { 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> { fn drop(&mut self) { if self.deleted_cnt > 0 { unsafe { @@ -685,7 +711,7 @@ impl ArrayVec { } } -impl ArrayVecImpl for ArrayVec { +impl ArrayVecImpl for ArrayVec { type Item = T; const CAPACITY: usize = CAP; @@ -705,7 +731,7 @@ impl ArrayVecImpl for ArrayVec { } } -impl Deref for ArrayVec { +impl Deref for ArrayVec { type Target = [T]; #[inline] fn deref(&self) -> &Self::Target { @@ -713,7 +739,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() @@ -730,7 +756,7 @@ 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 { fn from(array: [T; CAP]) -> Self { let array = ManuallyDrop::new(array); let mut vec = >::new(); @@ -756,7 +782,7 @@ impl From<[T; CAP]> for ArrayVec { /// assert_eq!(array.capacity(), 4); /// ``` impl std::convert::TryFrom<&[T]> for ArrayVec - where T: Clone, + where T: Clone + ValidValue, { type Error = CapacityError; @@ -783,7 +809,7 @@ impl std::convert::TryFrom<&[T]> for ArrayVec /// // ... /// } /// ``` -impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec { +impl<'a, T: ValidValue + '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() } @@ -800,7 +826,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: ValidValue + '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() } @@ -817,7 +843,7 @@ 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 { @@ -827,12 +853,12 @@ impl IntoIterator for ArrayVec { /// By-value iterator for `ArrayVec`. -pub struct IntoIter { +pub struct IntoIter { index: usize, v: ArrayVec, } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { @@ -853,7 +879,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 @@ -867,9 +893,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; @@ -885,7 +911,7 @@ impl Drop for IntoIter { } impl Clone for IntoIter -where T: Clone, +where T: Clone + ValidValue, { fn clone(&self) -> IntoIter { let mut v = ArrayVec::new(); @@ -896,7 +922,7 @@ where T: Clone, impl fmt::Debug for IntoIter where - T: fmt::Debug, + T: fmt::Debug + ValidValue, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() @@ -906,7 +932,7 @@ where } /// A draining iterator for `ArrayVec`. -pub struct Drain<'a, T: 'a, const CAP: usize> { +pub struct Drain<'a, T: ValidValue + 'a, const CAP: usize> { /// Index of tail to preserve tail_start: usize, /// Length of tail @@ -916,10 +942,10 @@ pub struct Drain<'a, T: 'a, const CAP: usize> { 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: ValidValue + Sync, const CAP: usize> Sync for Drain<'a, T, CAP> {} +unsafe impl<'a, T: ValidValue + Send, const CAP: usize> Send for Drain<'a, T, CAP> {} -impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { +impl<'a, T: ValidValue + 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { type Item = T; fn next(&mut self) -> Option { @@ -935,7 +961,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: ValidValue + 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> { fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| @@ -946,9 +972,9 @@ 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: ValidValue + 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} -impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { +impl<'a, T: ValidValue + '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. @@ -991,7 +1017,7 @@ 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. @@ -1008,7 +1034,7 @@ fn extend_panic() { panic!("ArrayVec: capacity exceeded in extend/from_iter"); } -impl ArrayVec { +impl ArrayVec { /// Extend the arrayvec from the iterable. /// /// ## Safety @@ -1074,7 +1100,7 @@ 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. @@ -1086,7 +1112,7 @@ impl iter::FromIterator for ArrayVec { } impl Clone for ArrayVec - where T: Clone + where T: Clone + ValidValue { fn clone(&self) -> Self { self.iter().cloned().collect() @@ -1108,7 +1134,7 @@ impl Clone for ArrayVec } impl Hash for ArrayVec - where T: Hash + where T: Hash + ValidValue { fn hash(&self, state: &mut H) { Hash::hash(&**self, state) @@ -1116,7 +1142,7 @@ impl Hash for ArrayVec } impl PartialEq for ArrayVec - where T: PartialEq + where T: PartialEq + ValidValue { fn eq(&self, other: &Self) -> bool { **self == **other @@ -1124,43 +1150,43 @@ impl PartialEq for ArrayVec } impl PartialEq<[T]> for ArrayVec - where T: PartialEq + where T: PartialEq + ValidValue { fn eq(&self, other: &[T]) -> bool { **self == *other } } -impl Eq for ArrayVec where T: Eq { } +impl Eq for ArrayVec where T: Eq + ValidValue { } -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 + ValidValue { 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 { ArrayVec::new() } } -impl PartialOrd for ArrayVec where T: PartialOrd { +impl PartialOrd for ArrayVec where T: PartialOrd + ValidValue { fn partial_cmp(&self, other: &Self) -> Option { (**self).partial_cmp(other) } @@ -1182,7 +1208,7 @@ impl PartialOrd for ArrayVec where T: PartialOrd { } } -impl Ord for ArrayVec where T: Ord { +impl Ord for ArrayVec where T: Ord + ValidValue { fn cmp(&self, other: &Self) -> cmp::Ordering { (**self).cmp(other) } @@ -1204,7 +1230,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 { @@ -1214,7 +1240,7 @@ impl Serialize for ArrayVec { #[cfg(feature="serde")] /// Requires crate feature `"serde"` -impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec { +impl<'de, T: ValidValue + Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { diff --git a/tests/tests.rs b/tests/tests.rs index 26d09ae..2e34317 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -10,6 +10,7 @@ use std::collections::HashMap; #[test] +#[cfg(not(feature="copy"))] fn test_simple() { use std::ops::Add; @@ -97,6 +98,7 @@ fn test_iter() { } #[test] +#[cfg(not(feature="copy"))] fn test_drop() { use std::cell::Cell; @@ -189,6 +191,7 @@ fn test_drop() { } #[test] +#[cfg(not(feature="copy"))] fn test_drop_panics() { use std::cell::Cell; use std::panic::catch_unwind; @@ -299,6 +302,7 @@ fn test_extend_capacity_panic_2() { } #[test] +#[cfg(not(feature="copy"))] fn test_is_send_sync() { let data = ArrayVec::, 5>::new(); &data as &dyn Send; @@ -398,6 +402,7 @@ fn test_drain_oob() { #[test] #[should_panic] +#[cfg(not(feature="copy"))] fn test_drop_panic() { struct DropPanic; @@ -413,6 +418,7 @@ fn test_drop_panic() { #[test] #[should_panic] +#[cfg(not(feature="copy"))] fn test_drop_panic_into_iter() { struct DropPanic; @@ -460,6 +466,7 @@ fn test_into_inner_1() { } #[test] +#[cfg(not(feature="copy"))] fn test_into_inner_2() { let mut v = ArrayVec::::new(); v.push("a".into()); @@ -498,6 +505,7 @@ fn test_write() { } #[test] +#[cfg(not(feature="copy"))] fn array_clone_from() { let mut v = ArrayVec::<_, 4>::new(); v.push(vec![1, 2]); @@ -633,6 +641,7 @@ fn test_insert_out_of_bounds() { */ #[test] +#[cfg(not(feature="copy"))] fn test_drop_in_insert() { use std::cell::Cell; @@ -664,6 +673,7 @@ fn test_drop_in_insert() { } #[test] +#[cfg(not(feature="copy"))] fn test_pop_at() { let mut v = ArrayVec::::new(); let s = String::from; @@ -686,6 +696,7 @@ fn test_sizes() { } #[test] +#[cfg(not(feature="copy"))] fn test_default() { use std::net; let s: ArrayString<4> = Default::default(); @@ -754,6 +765,7 @@ fn deny_max_capacity_arrayvec_value() { #[should_panic(expected="index out of bounds")] #[test] +#[cfg(not(feature="copy"))] 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'"); @@ -763,6 +775,7 @@ fn deny_max_capacity_arrayvec_value_const() { } #[test] +#[cfg(not(feature="copy"))] fn test_arrayvec_const_constructible() { const OF_U8: ArrayVec, 10> = ArrayVec::new_const(); From 960e9fff562729e5b48972b38aaba01ba589ddae Mon Sep 17 00:00:00 2001 From: nitram Date: Fri, 16 Jul 2021 19:40:28 +0100 Subject: [PATCH 2/3] make new_const available for copy also --- src/arrayvec.rs | 10 +++++----- tests/tests.rs | 14 +++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index d7751a3..7f0156a 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -23,7 +23,6 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer}; use crate::LenUint; use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; -#[cfg(not(feature="copy"))] use crate::utils::MakeMaybeUninit; /// All types implement this when the `copy` feature is disabled. @@ -58,17 +57,19 @@ impl ValidValue for T {} /// /// 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. -pub struct ArrayVec { +pub struct ArrayVec { // the `len` first elements of the array are initialized xs: [MaybeUninit; CAP], len: LenUint, } +// Safety: when the `copy` feature is enabled the only way +// to construct an `ArrayVec` is if `T: ValidValue`. #[cfg(feature="copy")] -impl Copy for ArrayVec {} +impl Copy for ArrayVec {} #[cfg(not(feature="copy"))] -impl Drop for ArrayVec { +impl Drop for ArrayVec { fn drop(&mut self) { self.clear(); @@ -83,7 +84,6 @@ macro_rules! panic_oob { } } -#[cfg(not(feature="copy"))] impl ArrayVec { /// Create a new empty `ArrayVec` (const fn). /// diff --git a/tests/tests.rs b/tests/tests.rs index 2e34317..2ae21a6 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -765,7 +765,7 @@ fn deny_max_capacity_arrayvec_value() { #[should_panic(expected="index out of bounds")] #[test] -#[cfg(not(feature="copy"))] +// #[cfg(not(feature="copy"))] 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'"); @@ -774,6 +774,18 @@ fn deny_max_capacity_arrayvec_value_const() { let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new_const(); } +#[test] +#[cfg(feature="copy")] +fn test_arrayvec_const_constructible() { + const OF_U8: ArrayVec = ArrayVec::new_const(); + + let mut var = OF_U8; + assert!(var.is_empty()); + assert_eq!(var, ArrayVec::new()); + var.push(3); + assert_eq!(var[..], [3]); +} + #[test] #[cfg(not(feature="copy"))] fn test_arrayvec_const_constructible() { From b594d69fb1900213fd28215ee9c34a3bc86e8ddd Mon Sep 17 00:00:00 2001 From: nitram Date: Fri, 16 Jul 2021 23:59:34 +0100 Subject: [PATCH 3/3] keep trait bounds to minimum --- src/arrayvec.rs | 181 ++++++++++++++++++++++-------------------------- tests/tests.rs | 14 +--- 2 files changed, 84 insertions(+), 111 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index 7f0156a..5fec718 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -23,25 +23,8 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer}; use crate::LenUint; use crate::errors::CapacityError; use crate::arrayvec_impl::ArrayVecImpl; -use crate::utils::MakeMaybeUninit; - -/// All types implement this when the `copy` feature is disabled. -/// -/// If `copy` is enabled, only Copy types implement it. -#[cfg(feature="copy")] -pub trait ValidValue: Copy {} - -#[cfg(feature="copy")] -impl ValidValue for T {} - -/// All types implement this when the `copy` feature is disabled. -/// -/// If `copy` is enabled, only Copy types implement it. -#[cfg(not(feature="copy"))] -pub trait ValidValue {} - #[cfg(not(feature="copy"))] -impl ValidValue for T {} +use crate::utils::MakeMaybeUninit; /// A vector with a fixed capacity. /// @@ -64,7 +47,7 @@ pub struct ArrayVec { } // Safety: when the `copy` feature is enabled the only way -// to construct an `ArrayVec` is if `T: ValidValue`. +// to construct an `ArrayVec` is if `T: Copy`. #[cfg(feature="copy")] impl Copy for ArrayVec {} @@ -84,7 +67,28 @@ macro_rules! panic_oob { } } -impl ArrayVec { +// creating function: +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> ArrayVec { + /// Create a new empty `ArrayVec`. + /// + /// The maximum capacity is given by the generic parameter `CAP`. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut array = ArrayVec::<_, 16>::new(); + /// array.push(1); + /// array.push(2); + /// assert_eq!(&array[..], &[1, 2]); + /// assert_eq!(array.capacity(), 16); + /// ``` + pub fn new() -> ArrayVec { + assert_capacity_limit!(CAP); + unsafe { + ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } + } + } + /// Create a new empty `ArrayVec` (const fn). /// /// The maximum capacity is given by the generic parameter `CAP`. @@ -94,35 +98,29 @@ impl ArrayVec { /// /// static ARRAY: ArrayVec = ArrayVec::new_const(); /// ``` + #[cfg(not(feature="copy"))] pub const fn new_const() -> ArrayVec { assert_capacity_limit_const!(CAP); ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } } -} -impl ArrayVec { - /// Capacity - const CAPACITY: usize = CAP; - - /// Create a new empty `ArrayVec`. - /// - /// The maximum capacity is given by the generic parameter `CAP`. + /// Returns the ArrayVec, replacing the original with a new empty ArrayVec. /// /// ``` /// use arrayvec::ArrayVec; /// - /// let mut array = ArrayVec::<_, 16>::new(); - /// array.push(1); - /// array.push(2); - /// assert_eq!(&array[..], &[1, 2]); - /// assert_eq!(array.capacity(), 16); + /// let mut v = ArrayVec::from([0, 1, 2, 3]); + /// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap()); + /// assert!(v.is_empty()); /// ``` - pub fn new() -> ArrayVec { - assert_capacity_limit!(CAP); - unsafe { - ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } - } + pub fn take(&mut self) -> Self { + mem::replace(self, Self::new()) } +} + +impl ArrayVec { + /// Capacity + const CAPACITY: usize = CAP; /// Return the number of elements in the `ArrayVec`. /// @@ -493,14 +491,14 @@ impl ArrayVec { let original_len = self.len(); unsafe { self.set_len(0) }; - struct BackshiftOnDrop<'a, T: ValidValue, const CAP: usize> { + struct BackshiftOnDrop<'a, T, const CAP: usize> { 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> { fn drop(&mut self) { if self.deleted_cnt > 0 { unsafe { @@ -677,19 +675,6 @@ impl ArrayVec { array } - /// Returns the ArrayVec, replacing the original with a new empty ArrayVec. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut v = ArrayVec::from([0, 1, 2, 3]); - /// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap()); - /// assert!(v.is_empty()); - /// ``` - pub fn take(&mut self) -> Self { - mem::replace(self, Self::new()) - } - /// Return a slice containing all elements of the vector. pub fn as_slice(&self) -> &[T] { ArrayVecImpl::as_slice(self) @@ -711,7 +696,7 @@ impl ArrayVec { } } -impl ArrayVecImpl for ArrayVec { +impl ArrayVecImpl for ArrayVec { type Item = T; const CAPACITY: usize = CAP; @@ -731,7 +716,7 @@ impl ArrayVecImpl for ArrayVec { } } -impl Deref for ArrayVec { +impl Deref for ArrayVec { type Target = [T]; #[inline] fn deref(&self) -> &Self::Target { @@ -739,7 +724,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() @@ -756,7 +741,7 @@ impl DerefMut for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 3); /// ``` -impl From<[T; CAP]> for ArrayVec { +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> From<[T; CAP]> for ArrayVec { fn from(array: [T; CAP]) -> Self { let array = ManuallyDrop::new(array); let mut vec = >::new(); @@ -781,8 +766,8 @@ impl From<[T; CAP]> for ArrayVec { /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 4); /// ``` -impl std::convert::TryFrom<&[T]> for ArrayVec - where T: Clone + ValidValue, +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> std::convert::TryFrom<&[T]> for ArrayVec + where T: Clone, { type Error = CapacityError; @@ -809,7 +794,7 @@ impl std::convert::TryFrom<&[T]> for ArrayVec /// // ... /// } /// ``` -impl<'a, T: ValidValue + 'a, const CAP: usize> IntoIterator for &'a ArrayVec { +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() } @@ -826,7 +811,7 @@ impl<'a, T: ValidValue + 'a, const CAP: usize> IntoIterator for &'a ArrayVec IntoIterator for &'a mut ArrayVec { +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() } @@ -843,7 +828,7 @@ impl<'a, T: ValidValue + '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 { @@ -853,12 +838,12 @@ impl IntoIterator for ArrayVec { /// By-value iterator for `ArrayVec`. -pub struct IntoIter { +pub struct IntoIter { index: usize, v: ArrayVec, } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { @@ -879,7 +864,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 @@ -893,9 +878,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; @@ -910,8 +895,8 @@ impl Drop for IntoIter { } } -impl Clone for IntoIter -where T: Clone + ValidValue, +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> Clone for IntoIter +where T: Clone, { fn clone(&self) -> IntoIter { let mut v = ArrayVec::new(); @@ -922,7 +907,7 @@ where T: Clone + ValidValue, impl fmt::Debug for IntoIter where - T: fmt::Debug + ValidValue, + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() @@ -932,7 +917,7 @@ where } /// A draining iterator for `ArrayVec`. -pub struct Drain<'a, T: ValidValue + 'a, const CAP: usize> { +pub struct Drain<'a, T: 'a, const CAP: usize> { /// Index of tail to preserve tail_start: usize, /// Length of tail @@ -942,10 +927,10 @@ pub struct Drain<'a, T: ValidValue + 'a, const CAP: usize> { vec: *mut ArrayVec, } -unsafe impl<'a, T: ValidValue + Sync, const CAP: usize> Sync for Drain<'a, T, CAP> {} -unsafe impl<'a, T: ValidValue + Send, const CAP: usize> Send for Drain<'a, T, CAP> {} +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, T: ValidValue + 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { +impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { type Item = T; fn next(&mut self) -> Option { @@ -961,7 +946,7 @@ impl<'a, T: ValidValue + 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { } } -impl<'a, T: ValidValue + 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> +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| @@ -972,9 +957,9 @@ impl<'a, T: ValidValue + 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, } } -impl<'a, T: ValidValue + 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} +impl<'a, T: 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} -impl<'a, T: ValidValue + 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { +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. @@ -1017,7 +1002,7 @@ 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. @@ -1034,7 +1019,7 @@ fn extend_panic() { panic!("ArrayVec: capacity exceeded in extend/from_iter"); } -impl ArrayVec { +impl ArrayVec { /// Extend the arrayvec from the iterable. /// /// ## Safety @@ -1100,7 +1085,7 @@ 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<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> iter::FromIterator for ArrayVec { /// Create an `ArrayVec` from an iterator. /// /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. @@ -1111,8 +1096,8 @@ impl iter::FromIterator for ArrayVec } } -impl Clone for ArrayVec - where T: Clone + ValidValue +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> Clone for ArrayVec + where T: Clone { fn clone(&self) -> Self { self.iter().cloned().collect() @@ -1134,7 +1119,7 @@ impl Clone for ArrayVec } impl Hash for ArrayVec - where T: Hash + ValidValue + where T: Hash { fn hash(&self, state: &mut H) { Hash::hash(&**self, state) @@ -1142,7 +1127,7 @@ impl Hash for ArrayVec } impl PartialEq for ArrayVec - where T: PartialEq + ValidValue + where T: PartialEq { fn eq(&self, other: &Self) -> bool { **self == **other @@ -1150,43 +1135,43 @@ impl PartialEq for ArrayVec } impl PartialEq<[T]> for ArrayVec - where T: PartialEq + ValidValue + where T: PartialEq { fn eq(&self, other: &[T]) -> bool { **self == *other } } -impl Eq for ArrayVec where T: Eq + ValidValue { } +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 + ValidValue { +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<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> Default for ArrayVec { /// Return an empty array fn default() -> ArrayVec { ArrayVec::new() } } -impl PartialOrd for ArrayVec where T: PartialOrd + ValidValue { +impl PartialOrd for ArrayVec where T: PartialOrd { fn partial_cmp(&self, other: &Self) -> Option { (**self).partial_cmp(other) } @@ -1208,7 +1193,7 @@ impl PartialOrd for ArrayVec where T: PartialOrd + } } -impl Ord for ArrayVec where T: Ord + ValidValue { +impl Ord for ArrayVec where T: Ord { fn cmp(&self, other: &Self) -> cmp::Ordering { (**self).cmp(other) } @@ -1230,7 +1215,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 { @@ -1240,16 +1225,16 @@ impl Serialize for ArrayVec #[cfg(feature="serde")] /// Requires crate feature `"serde"` -impl<'de, T: ValidValue + Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec { +impl<'de, #[cfg(feature="copy")] T: Copy + Deserialize<'de>, #[cfg(not(feature="copy"))] 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>, const CAP: usize>(PhantomData<(&'de (), [T; CAP])>); + struct ArrayVecVisitor<'de, #[cfg(feature="copy")] T: Copy + Deserialize<'de>, #[cfg(not(feature="copy"))] T: Deserialize<'de>, const CAP: usize>(PhantomData<(&'de (), [T; CAP])>); - impl<'de, T: Deserialize<'de>, const CAP: usize> Visitor<'de> for ArrayVecVisitor<'de, T, CAP> { + impl<'de, #[cfg(feature="copy")] T: Copy + Deserialize<'de>, #[cfg(not(feature="copy"))] 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 { diff --git a/tests/tests.rs b/tests/tests.rs index 2ae21a6..2e34317 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -765,7 +765,7 @@ fn deny_max_capacity_arrayvec_value() { #[should_panic(expected="index out of bounds")] #[test] -// #[cfg(not(feature="copy"))] +#[cfg(not(feature="copy"))] 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'"); @@ -774,18 +774,6 @@ fn deny_max_capacity_arrayvec_value_const() { let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new_const(); } -#[test] -#[cfg(feature="copy")] -fn test_arrayvec_const_constructible() { - const OF_U8: ArrayVec = ArrayVec::new_const(); - - let mut var = OF_U8; - assert!(var.is_empty()); - assert_eq!(var, ArrayVec::new()); - var.push(3); - assert_eq!(var[..], [3]); -} - #[test] #[cfg(not(feature="copy"))] fn test_arrayvec_const_constructible() {