extern crate nodrop; use nodrop::NoDrop; use std::iter; use std::mem; use std::ptr; use std::ops::{ Deref, DerefMut, }; use std::slice; // extra traits use std::borrow::{Borrow, BorrowMut}; use std::hash::{Hash, Hasher}; use std::fmt; /// Trait for fixed size arrays. pub unsafe trait Array { /// The array's element type type Item; #[doc(hidden)] unsafe fn new() -> Self; #[doc(hidden)] fn as_ptr(&self) -> *const Self::Item; #[doc(hidden)] fn as_mut_ptr(&mut self) -> *mut Self::Item; #[doc(hidden)] fn capacity() -> usize; } macro_rules! fix_array_impl { ($len:expr ) => ( unsafe impl Array for [T; $len] { type Item = T; /// Note: Returnin an uninitialized value here only works /// if we can be sure the data is never used. The nullable pointer /// inside enum optimization conflicts with this this for example, /// so we need to be extra careful. See `Flag` enum. unsafe fn new() -> [T; $len] { mem::uninitialized() } #[inline(always)] fn as_ptr(&self) -> *const T { self as *const _ as *const _ } #[inline(always)] fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _} #[inline(always)] fn capacity() -> usize { $len } } ) } macro_rules! fix_array_impl_recursive { () => (); ($len:expr, $($more:expr,)*) => ( fix_array_impl!($len); fix_array_impl_recursive!($($more,)*); ); } fix_array_impl_recursive!(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,); /// A vector with a fixed capacity. /// /// The **ArrayVec** is a vector backed by a fixed size array and keeps track of /// the number of initialized elements. /// /// The vector is a contiguous value that you can store directly on the stack /// if needed. /// /// It offers a simple API of *.push()* and *.pop()* but also dereferences to a slice, so /// that the full slice API is available. /// /// The vector also implements a by value iterator. pub struct ArrayVec { xs: NoDrop, len: u8, } impl Drop for ArrayVec { fn drop(&mut self) { // clear all elements, then NoDrop inhibits drop of inner array while let Some(_) = self.pop() { } } } impl ArrayVec { /// Create a new empty **ArrayVec**. /// /// Capacity is inferred from the type parameter. /// /// ## Examples /// /// ``` /// 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 { unsafe { ArrayVec { xs: NoDrop::new(Array::new()), len: 0 } } } /// Return the number of elements in the **ArrayVec**. /// /// ## Examples /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// array.pop(); /// assert_eq!(array.len(), 2); /// ``` #[inline] pub fn len(&self) -> usize { self.len as usize } /// Return the capacity of the **ArrayVec**. /// /// ## Examples /// ``` /// use arrayvec::ArrayVec; /// /// let array = ArrayVec::from([1, 2, 3]); /// assert_eq!(array.capacity(), 3); /// ``` #[inline] pub fn capacity(&self) -> usize { A::capacity() } /// Push **element** to the end of the vector. /// /// Return **None** if the push succeeds, or and return **Some(** *element* **)** /// if the vector is full. /// /// ## Examples /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<[_; 2]>::new(); /// /// array.push(1); /// array.push(2); /// let overflow = array.push(3); /// /// assert_eq!(&array[..], &[1, 2]); /// assert_eq!(overflow, Some(3)); /// ``` pub fn push(&mut self, element: A::Item) -> Option { if self.len() < A::capacity() { unsafe { let len = self.len(); ptr::write(self.get_unchecked_mut(len), element); } self.len += 1; None } else { Some(element) } } /// Remove the last element in the vector. /// /// Return **Some(** *element* **)** if the vector is non-empty, else **None**. /// /// ## Examples /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<[_; 2]>::new(); /// /// array.push(1); /// /// assert_eq!(array.pop(), Some(1)); /// assert_eq!(array.pop(), None); /// ``` pub fn pop(&mut self) -> Option { if self.len == 0 { return None } unsafe { self.len -= 1; let len = self.len(); Some(ptr::read(self.get_unchecked_mut(len))) } } } impl Deref for ArrayVec { type Target = [A::Item]; #[inline] fn deref(&self) -> &[A::Item] { unsafe { slice::from_raw_parts(self.xs.as_ptr(), self.len()) } } } impl DerefMut for ArrayVec { #[inline] fn deref_mut(&mut self) -> &mut [A::Item] { let len = self.len(); unsafe { slice::from_raw_parts_mut(self.xs.as_mut_ptr(), len) } } } /// Create an **ArrayVec** from an array. /// /// ## Examples /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 3); /// ``` impl From for ArrayVec { fn from(array: A) -> Self { ArrayVec { xs: NoDrop::new(array), len: A::capacity() as u8 } } } /// Iterate the **ArrayVec** with references to each element. /// /// ## Examples /// /// ``` /// use arrayvec::ArrayVec; /// /// let array = ArrayVec::from([1, 2, 3]); /// /// for elt in &array { /// // ... /// } /// ``` impl<'a, A: Array> IntoIterator for &'a ArrayVec { type Item = &'a A::Item; type IntoIter = slice::Iter<'a, A::Item>; fn into_iter(self) -> Self::IntoIter { self.iter() } } /// Iterate the **ArrayVec** with mutable references to each element. /// /// ## Examples /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// for elt in &mut array { /// // ... /// } /// ``` impl<'a, A: Array> IntoIterator for &'a mut ArrayVec { type Item = &'a mut A::Item; type IntoIter = slice::IterMut<'a, A::Item>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } /// Iterate the **ArrayVec** with each element by value. /// /// The vector is consumed by this operation. /// /// ## Examples /// /// ``` /// use arrayvec::ArrayVec; /// /// for elt in ArrayVec::from([1, 2, 3]) { /// // ... /// } /// ``` impl IntoIterator for ArrayVec { type Item = A::Item; type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { IntoIter { index: 0, v: self, } } } /// By-value iterator for ArrayVec. pub struct IntoIter { index: u8, v: ArrayVec, } impl Iterator for IntoIter { type Item = A::Item; #[inline] fn next(&mut self) -> Option { if self.index == self.v.len { None } else { unsafe { let ptr = self.v.get_unchecked_mut(self.index as usize); let elt = ptr::read(ptr); self.index += 1; Some(elt) } } } fn size_hint(&self) -> (usize, Option) { let len = self.v.len() - self.index as usize; (len, Some(len)) } } impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { if self.index == self.v.len { None } else { unsafe { self.v.len -= 1; let len = self.v.len(); let elt = ptr::read(self.v.get_unchecked_mut(len)); Some(elt) } } } } impl ExactSizeIterator for IntoIter { } impl Drop for IntoIter { fn drop(&mut self) { // exhaust iterator and clear the vector while let Some(_) = self.next() { } self.v.len = 0; } } /// Extend the **ArrayVec** with an iterator. /// /// Does not extract more items than there is space for. No error /// occurs if there are more iterator elements. impl Extend for ArrayVec { fn extend>(&mut self, iter: T) { let take = self.capacity() - self.len(); for elt in iter.into_iter().take(take) { self.push(elt); } } } /// Create an **ArrayVec** from an iterator. /// /// Does not extract more items than there is space for. No error /// occurs if there are more iterator elements. impl iter::FromIterator for ArrayVec { fn from_iter>(iter: T) -> Self { let mut array = ArrayVec::new(); array.extend(iter); array } } impl Clone for ArrayVec where A::Item: Clone { fn clone(&self) -> Self { self.iter().cloned().collect() } } impl Hash for ArrayVec where A::Item: Hash { fn hash(&self, state: &mut H) { Hash::hash(&**self, state) } } impl PartialEq for ArrayVec where A::Item: PartialEq { fn eq(&self, other: &Self) -> bool { **self == **other } } impl Eq for ArrayVec where A::Item: Eq { } impl Borrow<[A::Item]> for ArrayVec { fn borrow(&self) -> &[A::Item] { self } } impl BorrowMut<[A::Item]> for ArrayVec { fn borrow_mut(&mut self) -> &mut [A::Item] { self } } impl AsRef<[A::Item]> for ArrayVec { fn as_ref(&self) -> &[A::Item] { self } } impl AsMut<[A::Item]> for ArrayVec { fn as_mut(&mut self) -> &mut [A::Item] { self } } impl fmt::Debug for ArrayVec where A::Item: fmt::Debug { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } } #[test] fn test_simple() { use std::ops::Add; let mut vec: ArrayVec<[Vec; 3]> = ArrayVec::new(); vec.push(vec![1,2,3,4]); vec.push(vec![3]); vec.push(vec![-1, 90, -2]); for elt in &vec { println!("{:?}", elt); } println!("{:?}", vec); let sum = vec.iter().map(|x| x.iter().fold(0, Add::add)).fold(0, Add::add); assert_eq!(sum, 13 + 87); let sum_len = vec.into_iter().map(|x| x.len()).fold(0, Add::add); assert_eq!(sum_len, 8); } #[test] fn test_iter() { let mut iter = ArrayVec::from([1, 2, 3]).into_iter(); assert_eq!(iter.size_hint(), (3, Some(3))); assert_eq!(iter.next_back(), Some(3)); assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next_back(), Some(2)); assert_eq!(iter.size_hint(), (0, Some(0))); assert_eq!(iter.next_back(), None); } #[test] fn test_drop() { use std::rc::Rc; use std::cell::Cell; let flag = Rc::new(Cell::new(0)); struct Foo(Rc>); impl Drop for Foo { fn drop(&mut self) { let n = self.0.get(); self.0.set(n + 1); } } { let mut array = ArrayVec::<[Foo; 128]>::new(); array.push(Foo(flag.clone())); array.push(Foo(flag.clone())); } assert_eq!(flag.get(), 2); // test something with the nullable pointer optimization flag.set(0); { let mut array = ArrayVec::<[_; 3]>::new(); array.push(vec![Foo(flag.clone())]); array.push(vec![Foo(flag.clone()), Foo(flag.clone())]); array.push(vec![]); array.push(vec![Foo(flag.clone())]); assert_eq!(flag.get(), 1); drop(array.pop()); assert_eq!(flag.get(), 1); drop(array.pop()); assert_eq!(flag.get(), 3); } assert_eq!(flag.get(), 4); } #[test] fn test_extend() { let mut range = 0..10; let mut array: ArrayVec<[_; 5]> = range.by_ref().collect(); assert_eq!(&array[..], &[0, 1, 2, 3, 4]); assert_eq!(range.next(), Some(5)); array.extend(range.by_ref()); assert_eq!(range.next(), Some(6)); 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]); } #[test] fn test_is_send_sync() { let data = ArrayVec::<[Vec; 5]>::new(); &data as &Send; &data as &Sync; } #[test] fn test_compact_size() { // Future rust will kill these drop flags! // 4 elements size + 1 len + 1 enum tag + [1 drop flag] + [1 drop flag nodrop] type ByteArray = ArrayVec<[u8; 4]>; println!("{}", mem::size_of::()); assert!(mem::size_of::() <= 8); // 12 element size + 1 len + 1 drop flag + 2 padding + 1 enum tag + 3 padding type QuadArray = ArrayVec<[u32; 3]>; println!("{}", mem::size_of::()); assert!(mem::size_of::() <= 24); }