| { | ||
| "git": { | ||
| "sha1": "198a4031940fcfd8f63d731aea33da42eed6e898" | ||
| "sha1": "5685049fbeefc683d22d3d5ef130d2682ed2a018" | ||
| } | ||
| } |
+1
-2
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "arrayvec" | ||
| version = "0.6.1" | ||
| version = "0.7.0" | ||
| authors = ["bluss"] | ||
@@ -62,2 +62,1 @@ description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString." | ||
| std = [] | ||
| unstable-const-fn = [] |
+9
-0
| Recent Changes (arrayvec) | ||
| ========================= | ||
| ## 0.7.0 | ||
| - `fn new_const` is now the way to const-construct arrayvec and arraystring, | ||
| and `fn new` has been reverted to a regular "non-const" function. | ||
| This works around performance issue #182, where the const fn version did not | ||
| optimize well. Change by @bluss with thanks to @rodrimati1992 and @niklasf | ||
| for analyzing the problem. | ||
| - The deprecated feature flag `unstable-const-fn` was removed, since it's not needed | ||
| ## 0.6.1 | ||
@@ -5,0 +14,0 @@ |
+17
-1
@@ -62,4 +62,20 @@ use std::borrow::Borrow; | ||
| /// ``` | ||
| pub const fn new() -> ArrayString<CAP> { | ||
| pub fn new() -> ArrayString<CAP> { | ||
| assert_capacity_limit!(CAP); | ||
| unsafe { | ||
| ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } | ||
| } | ||
| } | ||
| /// Create a new empty `ArrayString` (const fn). | ||
| /// | ||
| /// Capacity is inferred from the type parameter. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayString; | ||
| /// | ||
| /// static ARRAY: ArrayString<1024> = ArrayString::new_const(); | ||
| /// ``` | ||
| pub const fn new_const() -> ArrayString<CAP> { | ||
| assert_capacity_limit_const!(CAP); | ||
| ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 } | ||
@@ -66,0 +82,0 @@ } |
+64
-12
@@ -80,4 +80,20 @@ | ||
| /// ``` | ||
| pub const fn new() -> ArrayVec<T, CAP> { | ||
| pub fn new() -> ArrayVec<T, CAP> { | ||
| 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`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// static ARRAY: ArrayVec<u8, 1024> = ArrayVec::new_const(); | ||
| /// ``` | ||
| pub const fn new_const() -> ArrayVec<T, CAP> { | ||
| assert_capacity_limit_const!(CAP); | ||
| ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 } | ||
@@ -447,18 +463,54 @@ } | ||
| { | ||
| let len = self.len(); | ||
| let mut del = 0; | ||
| { | ||
| let v = &mut **self; | ||
| // Check the implementation of | ||
| // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain | ||
| // for safety arguments (especially regarding panics in f and when | ||
| // dropping elements). Implementation closely mirrored here. | ||
| for i in 0..len { | ||
| if !f(&mut v[i]) { | ||
| del += 1; | ||
| } else if del > 0 { | ||
| v.swap(i - del, i); | ||
| let original_len = self.len(); | ||
| unsafe { self.set_len(0) }; | ||
| struct BackshiftOnDrop<'a, T, const CAP: usize> { | ||
| v: &'a mut ArrayVec<T, CAP>, | ||
| processed_len: usize, | ||
| deleted_cnt: usize, | ||
| original_len: usize, | ||
| } | ||
| impl<T, const CAP: usize> Drop for BackshiftOnDrop<'_, T, CAP> { | ||
| 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 | ||
| ); | ||
| } | ||
| } | ||
| unsafe { | ||
| self.v.set_len(self.original_len - self.deleted_cnt); | ||
| } | ||
| } | ||
| } | ||
| if del > 0 { | ||
| self.drain(len - del..); | ||
| let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; | ||
| while g.processed_len < original_len { | ||
| let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) }; | ||
| if !f(unsafe { &mut *cur }) { | ||
| g.processed_len += 1; | ||
| g.deleted_cnt += 1; | ||
| unsafe { ptr::drop_in_place(cur) }; | ||
| continue; | ||
| } | ||
| if g.deleted_cnt > 0 { | ||
| unsafe { | ||
| let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt); | ||
| ptr::copy_nonoverlapping(cur, hole_slot, 1); | ||
| } | ||
| } | ||
| g.processed_len += 1; | ||
| } | ||
| drop(g); | ||
| } | ||
@@ -465,0 +517,0 @@ |
+10
-4
@@ -14,6 +14,2 @@ //! **arrayvec** provides the types [`ArrayVec`] and [`ArrayString`]: | ||
| //! | ||
| //! - `unstable-const-fn` | ||
| //! - **deprecated** (has no effect) | ||
| //! - Not needed, [`ArrayVec::new`] and [`ArrayString::new`] are always `const fn` now | ||
| //! | ||
| //! ## Rust Version | ||
@@ -38,2 +34,12 @@ //! | ||
| 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::<usize>() > std::mem::size_of::<LenUint>() { | ||
| if $cap > LenUint::MAX as usize { | ||
| [/*ArrayVec: largest supported capacity is u32::MAX*/][$cap] | ||
@@ -40,0 +46,0 @@ } |
+14
-4
@@ -721,7 +721,7 @@ extern crate arrayvec; | ||
| #[should_panic(expected="index out of bounds")] | ||
| #[should_panic(expected="largest supported capacity")] | ||
| #[test] | ||
| fn deny_max_capacity_arrayvec_value() { | ||
| if mem::size_of::<usize>() <= mem::size_of::<u32>() { | ||
| panic!("This test does not work on this platform. 'index out of bounds'"); | ||
| panic!("This test does not work on this platform. 'largest supported capacity'"); | ||
| } | ||
@@ -732,5 +732,15 @@ // this type is allowed to be used (but can't be constructed) | ||
| #[should_panic(expected="index out of bounds")] | ||
| #[test] | ||
| fn deny_max_capacity_arrayvec_value_const() { | ||
| if mem::size_of::<usize>() <= mem::size_of::<u32>() { | ||
| 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<Vec<u8>, 10> = ArrayVec::new(); | ||
| const OF_U8: ArrayVec<Vec<u8>, 10> = ArrayVec::new_const(); | ||
@@ -747,3 +757,3 @@ let mut var = OF_U8; | ||
| fn test_arraystring_const_constructible() { | ||
| const AS: ArrayString<10> = ArrayString::new(); | ||
| const AS: ArrayString<10> = ArrayString::new_const(); | ||
@@ -750,0 +760,0 @@ let mut var = AS; |
Sorry, the diff of this file is not supported yet