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..5fec718 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -23,6 +23,7 @@ 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; /// A vector with a fixed capacity. @@ -45,6 +46,12 @@ pub struct ArrayVec { len: LenUint, } +// Safety: when the `copy` feature is enabled the only way +// to construct an `ArrayVec` is if `T: Copy`. +#[cfg(feature="copy")] +impl Copy for ArrayVec {} + +#[cfg(not(feature="copy"))] impl Drop for ArrayVec { fn drop(&mut self) { self.clear(); @@ -60,10 +67,8 @@ macro_rules! panic_oob { } } -impl ArrayVec { - /// Capacity - const CAPACITY: usize = CAP; - +// 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`. @@ -93,11 +98,30 @@ 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 } } + /// 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()) + } +} + +impl ArrayVec { + /// Capacity + const CAPACITY: usize = CAP; + /// Return the number of elements in the `ArrayVec`. /// /// ``` @@ -651,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) @@ -730,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(); @@ -755,7 +766,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<#[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; @@ -884,7 +895,7 @@ impl Drop for IntoIter { } } -impl Clone for IntoIter +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> Clone for IntoIter where T: Clone, { fn clone(&self) -> IntoIter { @@ -1074,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. @@ -1085,7 +1096,7 @@ impl iter::FromIterator for ArrayVec { } } -impl Clone for ArrayVec +impl<#[cfg(feature="copy")] T: Copy, #[cfg(not(feature="copy"))] T, const CAP: usize> Clone for ArrayVec where T: Clone { fn clone(&self) -> Self { @@ -1153,7 +1164,7 @@ 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() @@ -1214,16 +1225,16 @@ 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, #[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 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();