+1
-1
| [package] | ||
| name = "arrayvec" | ||
| version = "0.3.0" | ||
| version = "0.3.1" | ||
| authors = ["bluss"] | ||
@@ -5,0 +5,0 @@ license = "MIT/Apache-2.0" |
+29
-6
@@ -7,2 +7,5 @@ | ||
| #[doc(hidden)] | ||
| /// The smallest index type that indexes the array. | ||
| type Index: Index; | ||
| #[doc(hidden)] | ||
| fn as_ptr(&self) -> *const Self::Item; | ||
@@ -15,6 +18,25 @@ #[doc(hidden)] | ||
| pub trait Index : PartialEq + Copy { | ||
| fn zero() -> Self; | ||
| fn to_usize(self) -> usize; | ||
| fn from(usize) -> Self; | ||
| } | ||
| impl Index for u8 { | ||
| fn zero() -> Self { 0 } | ||
| fn to_usize(self) -> usize { self as usize } | ||
| fn from(ix: usize) -> Self { ix as u8 } | ||
| } | ||
| impl Index for u16 { | ||
| fn zero() -> Self { 0 } | ||
| fn to_usize(self) -> usize { self as usize } | ||
| fn from(ix: usize) -> Self { ix as u16 } | ||
| } | ||
| macro_rules! fix_array_impl { | ||
| ($len:expr ) => ( | ||
| ($index_type:ty, $len:expr ) => ( | ||
| unsafe impl<T> Array for [T; $len] { | ||
| type Item = T; | ||
| type Index = $index_type; | ||
| #[inline(always)] | ||
@@ -31,12 +53,13 @@ fn as_ptr(&self) -> *const T { self as *const _ as *const _ } | ||
| macro_rules! fix_array_impl_recursive { | ||
| () => (); | ||
| ($len:expr, $($more:expr,)*) => ( | ||
| fix_array_impl!($len); | ||
| fix_array_impl_recursive!($($more,)*); | ||
| ($index_type:ty, ) => (); | ||
| ($index_type:ty, $len:expr, $($more:expr,)*) => ( | ||
| fix_array_impl!($index_type, $len); | ||
| fix_array_impl_recursive!($index_type, $($more,)*); | ||
| ); | ||
| } | ||
| fix_array_impl_recursive!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||
| fix_array_impl_recursive!(u8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||
| 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, | ||
| 32, 40, 48, 56, 64, 72, 96, 128, 160, 192, 224,); | ||
| fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,); | ||
+99
-18
@@ -23,2 +23,3 @@ extern crate nodrop; | ||
| pub use misc::RangeArgument; | ||
| use array::Index; | ||
@@ -48,3 +49,3 @@ | ||
| xs: NoDrop<A>, | ||
| len: u8, | ||
| len: A::Index, | ||
| } | ||
@@ -77,3 +78,3 @@ | ||
| unsafe { | ||
| ArrayVec { xs: NoDrop::new(new_array()), len: 0 } | ||
| ArrayVec { xs: NoDrop::new(new_array()), len: Index::zero() } | ||
| } | ||
@@ -93,4 +94,9 @@ } | ||
| #[inline] | ||
| pub fn len(&self) -> usize { self.len as usize } | ||
| pub fn len(&self) -> usize { self.len.to_usize() } | ||
| fn set_len(&mut self, length: usize) { | ||
| debug_assert!(length <= self.capacity()); | ||
| self.len = Index::from(length); | ||
| } | ||
| /// Return the capacity of the **ArrayVec**. | ||
@@ -129,7 +135,7 @@ /// | ||
| if self.len() < A::capacity() { | ||
| let len = self.len(); | ||
| unsafe { | ||
| let len = self.len(); | ||
| ptr::write(self.get_unchecked_mut(len), element); | ||
| } | ||
| self.len += 1; | ||
| self.len = Index::from(len + 1); | ||
| None | ||
@@ -157,7 +163,7 @@ } else { | ||
| pub fn pop(&mut self) -> Option<A::Item> { | ||
| if self.len == 0 { | ||
| if self.len() == 0 { | ||
| return None | ||
| } | ||
| unsafe { | ||
| self.len -= 1; | ||
| self.len = Index::from(self.len() - 1); | ||
| let len = self.len(); | ||
@@ -194,3 +200,3 @@ Some(ptr::read(self.get_unchecked_mut(len))) | ||
| /// Remove the element at **index** and shift the following elements down. | ||
| /// Remove the element at **index** and shift down the following elements. | ||
| /// | ||
@@ -218,2 +224,49 @@ /// Return **Some(** *element* **)** if the index is in bounds, else **None**. | ||
| /// Insert **element** in position **index**. | ||
| /// | ||
| /// Shift up all elements after **index**. If any is pushed out, it is returned. | ||
| /// | ||
| /// Return None if no element is shifted out. | ||
| /// | ||
| /// ## Examples | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// assert_eq!(array.insert(0, "x"), None); | ||
| /// assert_eq!(array.insert(0, "y"), None); | ||
| /// assert_eq!(array.insert(0, "z"), Some("x")); | ||
| /// assert_eq!(array.insert(1, "w"), Some("y")); | ||
| /// assert_eq!(&array[..], &["z", "w"]); | ||
| /// | ||
| /// ``` | ||
| pub fn insert(&mut self, index: usize, element: A::Item) -> Option<A::Item> { | ||
| if index >= self.capacity() { | ||
| return Some(element); | ||
| } | ||
| let mut ret = None; | ||
| let old_len = self.len(); | ||
| if old_len == self.capacity() { | ||
| ret = self.remove(old_len - 1); | ||
| } | ||
| let len = self.len(); | ||
| // follows is just like Vec<T> | ||
| unsafe { // infallible | ||
| // The spot to put the new value | ||
| { | ||
| let p = self.as_mut_ptr().offset(index as isize); | ||
| // Shift everything over to make space. (Duplicating the | ||
| // `index`th element into two consecutive places.) | ||
| ptr::copy(&*p, p.offset(1), len - index); | ||
| // Write it in, overwriting the first copy of the `index`th | ||
| // element. | ||
| ptr::write(&mut *p, element); | ||
| } | ||
| self.set_len(len + 1); | ||
| } | ||
| ret | ||
| } | ||
| /// Create a draining iterator that removes the specified range in the vector | ||
@@ -260,3 +313,3 @@ /// and yields the removed items from start to end. The element range is | ||
| // set self.vec length's to start, to be safe in case Drain is leaked | ||
| self.len = start as u8; | ||
| self.len = Index::from(start); | ||
| Drain { | ||
@@ -304,3 +357,3 @@ tail_start: end, | ||
| fn from(array: A) -> Self { | ||
| ArrayVec { xs: NoDrop::new(array), len: A::capacity() as u8 } | ||
| ArrayVec { xs: NoDrop::new(array), len: Index::from(A::capacity()) } | ||
| } | ||
@@ -365,3 +418,3 @@ } | ||
| fn into_iter(self) -> IntoIter<A> { | ||
| IntoIter { index: 0, v: self, } | ||
| IntoIter { index: Index::zero(), v: self, } | ||
| } | ||
@@ -373,3 +426,3 @@ } | ||
| pub struct IntoIter<A: Array> { | ||
| index: u8, | ||
| index: A::Index, | ||
| v: ArrayVec<A>, | ||
@@ -387,5 +440,6 @@ } | ||
| unsafe { | ||
| let ptr = self.v.get_unchecked_mut(self.index as usize); | ||
| let index = self.index.to_usize(); | ||
| let ptr = self.v.get_unchecked_mut(index); | ||
| let elt = ptr::read(ptr); | ||
| self.index += 1; | ||
| self.index = Index::from(index + 1); | ||
| Some(elt) | ||
@@ -397,3 +451,3 @@ } | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| let len = self.v.len() - self.index as usize; | ||
| let len = self.v.len() - self.index.to_usize(); | ||
| (len, Some(len)) | ||
@@ -410,3 +464,3 @@ } | ||
| unsafe { | ||
| self.v.len -= 1; | ||
| self.v.len = Index::from(self.v.len() - 1); | ||
| let len = self.v.len(); | ||
@@ -426,3 +480,3 @@ let elt = ptr::read(self.v.get_unchecked_mut(len)); | ||
| while let Some(_) = self.next() { } | ||
| self.v.len = 0; | ||
| self.v.len = Index::zero(); | ||
| } | ||
@@ -499,3 +553,3 @@ } | ||
| ptr::copy(src, dst, self.tail_len); | ||
| source_vec.len = (start + self.tail_len) as u8; | ||
| source_vec.len = Index::from(start + self.tail_len); | ||
| } | ||
@@ -603,2 +657,13 @@ } | ||
| #[test] | ||
| fn test_u16_index() { | ||
| const N: usize = 4096; | ||
| let mut vec: ArrayVec<[_; N]> = ArrayVec::new(); | ||
| for _ in 0..N { | ||
| assert!(vec.push(1u8).is_none()); | ||
| } | ||
| assert!(vec.push(0).is_some()); | ||
| assert_eq!(vec.len(), N); | ||
| } | ||
| #[test] | ||
| fn test_iter() { | ||
@@ -717,1 +782,17 @@ let mut iter = ArrayVec::from([1, 2, 3]).into_iter(); | ||
| } | ||
| #[test] | ||
| fn test_insert() { | ||
| let mut v = ArrayVec::from([]); | ||
| assert_eq!(v.push(1), Some(1)); | ||
| assert_eq!(v.insert(0, 1), Some(1)); | ||
| let mut v = ArrayVec::<[_; 3]>::new(); | ||
| v.insert(0, 0); | ||
| v.insert(1, 1); | ||
| v.insert(2, 2); | ||
| v.insert(3, 3); | ||
| assert_eq!(&v[..], &[0, 1, 2]); | ||
| v.insert(1, 9); | ||
| assert_eq!(&v[..], &[0, 9, 1]); | ||
| } |
-1
| arrayvec - 0.2.0 |