diff --git a/src/array_string.rs b/src/array_string.rs new file mode 100644 index 0000000..65b27dc --- /dev/null +++ b/src/array_string.rs @@ -0,0 +1,165 @@ +use std::borrow::Borrow; +use std::fmt; +use std::mem; +use std::ops::Deref; +use std::str; + +use array::Array; +use array_vec::ArrayVec; + + +/// A string with a fixed capacity. +/// +/// The `ArrayString` is a string backed by a fixed size array. It keeps track +/// of its length. +/// +/// The string is a contiguous value that you can store directly on the stack +/// if needed. +/// +/// Due to technical restrictions, this struct does not implement `Copy` even +/// though it would be safe to do so. +pub struct ArrayString> { + vec: ArrayVec, +} + +impl> ArrayString { + /// Create a new empty `ArrayString`. + /// + /// Capacity is inferred from the type parameter. + /// + /// ``` + /// use arrayvec::ArrayString; + /// + /// let mut string = ArrayString::<[_; 16]>::new(); + /// string.push_str("foo"); + /// assert_eq!(&string[..], "foo"); + /// assert_eq!(string.capacity(), 16); + /// ``` + pub fn new() -> ArrayString { + ArrayString { + vec: ArrayVec::new() + } + } + + /// Return the capacity of the `ArrayString`. + /// + /// ``` + /// use arrayvec::ArrayString; + /// + /// let string = ArrayString::<[_; 3]>::new(); + /// assert_eq!(string.capacity(), 3); + /// ``` + #[inline] + pub fn capacity(&self) -> usize { self.vec.capacity() } + + /// Adds the given character to the end of the string. + /// + /// Returns `None` if the push succeeds, or and returns `Some(c)` if the + /// backing array is not large enough to fit the additional character. + /// + /// ``` + /// use arrayvec::ArrayString; + /// + /// let mut string = ArrayString::<[_; 2]>::new(); + /// + /// let none1 = string.push('a'); + /// let none2 = string.push('b'); + /// let overflow = string.push('c'); + /// + /// assert_eq!(&string[..], "ab"); + /// assert_eq!(none1, None); + /// assert_eq!(none2, None); + /// assert_eq!(overflow, Some('c')); + /// ``` + pub fn push(&mut self, c: char) -> Option { + use std::fmt::Write; + self.write_char(c).err().map(|_| c) + } + + /// Adds the given string slice to the end of the string. + /// + /// Returns `None` if the push succeeds, or and returns `Some(s)` if the + /// backing array is not large enough to fit the string. + /// + /// ``` + /// use arrayvec::ArrayString; + /// + /// let mut string = ArrayString::<[_; 2]>::new(); + /// + /// let none1 = string.push_str("a"); + /// let overflow1 = string.push_str("bc"); + /// let none2 = string.push_str("d"); + /// let overflow2 = string.push_str("ef"); + /// + /// assert_eq!(&string[..], "ad"); + /// assert_eq!(none1, None); + /// assert_eq!(none2, None); + /// assert_eq!(overflow1, Some("bc")); + /// assert_eq!(overflow2, Some("ef")); + /// ``` + pub fn push_str<'a>(&mut self, s: &'a str) -> Option<&'a str> { + if self.len() + s.len() > self.capacity() { + return Some(s); + } + let mut bytes = s.bytes(); + self.vec.extend(&mut bytes); + assert!(bytes.next().is_none()); + None + } + + + + /// Make the string empty. + pub fn clear(&mut self) { + mem::replace(self, ArrayString::new()); + } + + /// Set the strings's length. + /// + /// May panic if `length` is greater than the capacity. + /// + /// This function is `unsafe` because it changes the notion of the + /// number of “valid” characters in the string. Use with care. + #[inline] + pub unsafe fn set_len(&mut self, length: usize) { + self.vec.set_len(length) + } +} + +impl> Deref for ArrayString { + type Target = str; + #[inline] + fn deref(&self) -> &str { + unsafe { str::from_utf8_unchecked(&self.vec) } + } +} + +impl> Borrow for ArrayString { + fn borrow(&self) -> &str { self } +} + +impl> AsRef for ArrayString { + fn as_ref(&self) -> &str { self } +} + +impl> fmt::Debug for ArrayString where A::Item: fmt::Debug { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } +} + +/// `Write` appends written data to the end of the string. +impl> fmt::Write for ArrayString { + fn write_str(&mut self, s: &str) -> fmt::Result { + match self.push_str(s) { + None => Ok(()), + Some(_) => Err(fmt::Error), + } + } +} + +//#[derive(Clone, /*Copy,*/ Eq, Hash, Ord, PartialEq, PartialOrd)] +impl> Clone for ArrayString { + fn clone(&self) -> ArrayString { + ArrayString { vec: self.vec.clone() } + } +} + diff --git a/src/array_vec.rs b/src/array_vec.rs new file mode 100644 index 0000000..03d2087 --- /dev/null +++ b/src/array_vec.rs @@ -0,0 +1,691 @@ +use std::cmp; +use std::io; +use std::iter; +use std::mem; +use std::ptr; +use std::ops::{ + Deref, + DerefMut, +}; +use std::slice; + +use nodrop::NoDrop; + +// extra traits +use std::borrow::{Borrow, BorrowMut}; +use std::hash::{Hash, Hasher}; +use std::fmt; + +use array::Array; +use odds::IndexRange as RangeArgument; +use array::Index; + + +unsafe fn new_array() -> A { + // Note: Returning 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 `NoDrop` enum. + mem::uninitialized() +} + +/// A vector with a fixed capacity. +/// +/// The `ArrayVec` is a vector backed by a fixed size array. It 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 but also dereferences to a slice, so +/// that the full slice API is available. +/// +/// ArrayVec can be converted into a by value iterator. +pub struct ArrayVec { + xs: NoDrop, + len: A::Index, +} + +impl Drop for ArrayVec { + fn drop(&mut self) { + // clear all elements + while let Some(_) = self.pop() { + } + + // NoDrop inhibits array's drop + // panic safety: NoDrop::drop will trigger on panic, so the inner + // array will not drop even after panic. + } +} + +impl ArrayVec { + /// Create a new empty `ArrayVec`. + /// + /// Capacity is inferred from the type parameter. + /// + /// ``` + /// 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(new_array()), len: Index::zero() } + } + } + + /// Return the number of elements in the `ArrayVec`. + /// + /// ``` + /// 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.to_usize() } + + /// Return the capacity of the `ArrayVec`. + /// + /// ``` + /// 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. + /// + /// ``` + /// 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() { + let len = self.len(); + unsafe { + ptr::write(self.get_unchecked_mut(len), element); + self.set_len(len + 1); + } + None + } else { + Some(element) + } + } + + /// Remove the last element in the vector. + /// + /// Return `Some(` *element* `)` if the vector is non-empty, else `None`. + /// + /// ``` + /// 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 { + let new_len = self.len() - 1; + self.set_len(new_len); + Some(ptr::read(self.get_unchecked_mut(new_len))) + } + } + + /// 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. + /// + /// ``` + /// 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 { + if index >= self.capacity() { + return Some(element); + } + let mut ret = None; + if self.len() == self.capacity() { + ret = self.pop(); + } + let len = self.len(); + + // follows is just like Vec + unsafe { // infallible + // The spot to put the new value + { + let p = self.get_unchecked_mut(index) as *mut _; + // 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(p, element); + } + self.set_len(len + 1); + } + ret + } + + /// Remove the element at `index` and swap the last element into its place. + /// + /// This operation is O(1). + /// + /// Return `Some(` *element* `)` if the index is in bounds, else `None`. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut array = ArrayVec::from([1, 2, 3]); + /// + /// assert_eq!(array.swap_remove(0), Some(1)); + /// assert_eq!(&array[..], &[3, 2]); + /// + /// assert_eq!(array.swap_remove(10), None); + /// ``` + pub fn swap_remove(&mut self, index: usize) -> Option { + let len = self.len(); + if index >= len { + return None + } + self.swap(index, len - 1); + self.pop() + } + + /// Remove the element at `index` and shift down the following elements. + /// + /// Return `Some(` *element* `)` if the index is in bounds, else `None`. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut array = ArrayVec::from([1, 2, 3]); + /// + /// assert_eq!(array.remove(0), Some(1)); + /// assert_eq!(&array[..], &[2, 3]); + /// + /// assert_eq!(array.remove(10), None); + /// ``` + pub fn remove(&mut self, index: usize) -> Option { + if index >= self.len() { + None + } else { + self.drain(index..index + 1).next() + } + } + + /// Remove all elements in the vector. + pub fn clear(&mut self) { + while let Some(_) = self.pop() { } + } + + /// Set the vector's length without dropping or moving out elements + /// + /// May panic if `length` is greater than the capacity. + /// + /// This function is `unsafe` because it changes the notion of the + /// number of “valid” elements in the vector. Use with care. + #[inline] + pub unsafe fn set_len(&mut self, length: usize) { + debug_assert!(length <= self.capacity()); + self.len = Index::from(length); + } + + + /// Create a draining iterator that removes the specified range in the vector + /// and yields the removed items from start to end. The element range is + /// removed even if the iterator is not consumed until the end. + /// + /// Note: It is unspecified how many elements are removed from the vector, + /// if the `Drain` value is leaked. + /// + /// **Panics** if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut v = ArrayVec::from([1, 2, 3]); + /// let u: Vec<_> = v.drain(0..2).collect(); + /// assert_eq!(&v[..], &[3]); + /// assert_eq!(&u[..], &[1, 2]); + /// ``` + pub fn drain(&mut self, range: R) -> Drain { + // Memory safety + // + // When the Drain is first created, it shortens the length of + // the source vector to make sure no uninitalized or moved-from elements + // are accessible at all if the Drain's destructor never gets to run. + // + // Drain will ptr::read out the values to remove. + // When finished, remaining tail of the vec is copied back to cover + // the hole, and the vector length is restored to the new length. + // + let len = self.len(); + let start = range.start().unwrap_or(0); + let end = range.end().unwrap_or(len); + // bounds check happens here + let range_slice: *const _ = &self[start..end]; + + unsafe { + // set self.vec length's to start, to be safe in case Drain is leaked + self.set_len(start); + Drain { + tail_start: end, + tail_len: len - end, + iter: (*range_slice).iter(), + vec: self as *mut _, + } + } + } + + /// Return the inner fixed size array, if it is full to its capacity. + /// + /// Return an `Ok` value with the array if length equals capacity, + /// return an `Err` with self otherwise. + /// + /// `Note:` This function may incur unproportionally large overhead + /// to move the array out, its performance is not optimal. + pub fn into_inner(self) -> Result { + if self.len() < self.capacity() { + Err(self) + } else { + unsafe { + let array = ptr::read(&*self.xs); + mem::forget(self); + Ok(array) + } + } + } +} + +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. +/// +/// ``` +/// 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: Index::from(A::capacity()) } + } +} + + +/// Iterate the `ArrayVec` with references to each element. +/// +/// ``` +/// 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. +/// +/// ``` +/// 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. +/// +/// ``` +/// 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: Index::zero(), v: self, } + } +} + + +/// By-value iterator for `ArrayVec`. +pub struct IntoIter { + index: A::Index, + 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 index = self.index.to_usize(); + self.index = Index::from(index + 1); + Some(ptr::read(self.v.get_unchecked_mut(index))) + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.v.len() - self.index.to_usize(); + (len, Some(len)) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { + if self.index == self.v.len { + None + } else { + unsafe { + let new_len = self.v.len() - 1; + self.v.set_len(new_len); + Some(ptr::read(self.v.get_unchecked_mut(new_len))) + } + } + } +} + +impl ExactSizeIterator for IntoIter { } + +impl Drop for IntoIter { + fn drop(&mut self) { + // panic safety: Set length to 0 before dropping elements. + let index = self.index.to_usize(); + let len = self.v.len(); + unsafe { + self.v.set_len(0); + let elements = slice::from_raw_parts(self.v.get_unchecked_mut(index), + len - index); + for elt in elements { + ptr::read(elt); + } + } + } +} + +/// A draining iterator for `ArrayVec`. +pub struct Drain<'a, A> + where A: Array, + A::Item: 'a, +{ + /// Index of tail to preserve + tail_start: usize, + /// Length of tail + tail_len: usize, + /// Current remaining range to remove + iter: slice::Iter<'a, A::Item>, + vec: *mut ArrayVec, +} + +unsafe impl<'a, A: Array + Sync> Sync for Drain<'a, A> {} +unsafe impl<'a, A: Array + Send> Send for Drain<'a, A> {} + +impl<'a, A: Array> Iterator for Drain<'a, A> + where A::Item: 'a, +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().map(|elt| + unsafe { + ptr::read(elt as *const _) + } + ) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +impl<'a, A: Array> DoubleEndedIterator for Drain<'a, A> + where A::Item: 'a, +{ + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().map(|elt| + unsafe { + ptr::read(elt as *const _) + } + ) + } +} + +impl<'a, A: Array> ExactSizeIterator for Drain<'a, A> where A::Item: 'a {} + +impl<'a, A: Array> Drop for Drain<'a, A> + where A::Item: 'a +{ + fn drop(&mut self) { + // len is currently 0 so panicking while dropping will not cause a double drop. + + // exhaust self first + while let Some(_) = self.next() { } + + if self.tail_len > 0 { + unsafe { + let source_vec = &mut *self.vec; + // memmove back untouched tail, update to new length + let start = source_vec.len(); + let tail = self.tail_start; + let src = source_vec.as_ptr().offset(tail as isize); + let dst = source_vec.as_mut_ptr().offset(start as isize); + ptr::copy(src, dst, self.tail_len); + source_vec.set_len(start + self.tail_len); + } + } + } +} + + + + +/// 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) } +} + +impl Default for ArrayVec { + fn default() -> ArrayVec { + ArrayVec::new() + } +} + +impl PartialOrd for ArrayVec where A::Item: PartialOrd { + #[inline] + fn partial_cmp(&self, other: &ArrayVec) -> Option { + (**self).partial_cmp(other) + } + + #[inline] + fn lt(&self, other: &Self) -> bool { + (**self).lt(other) + } + + #[inline] + fn le(&self, other: &Self) -> bool { + (**self).le(other) + } + + #[inline] + fn ge(&self, other: &Self) -> bool { + (**self).ge(other) + } + + #[inline] + fn gt(&self, other: &Self) -> bool { + (**self).gt(other) + } +} + +impl Ord for ArrayVec where A::Item: Ord { + fn cmp(&self, other: &ArrayVec) -> cmp::Ordering { + (**self).cmp(other) + } +} + +/// `Write` appends written data to the end of the vector. +impl> io::Write for ArrayVec { + fn write(&mut self, data: &[u8]) -> io::Result { + unsafe { + let len = self.len(); + let mut tail = slice::from_raw_parts_mut(self.get_unchecked_mut(len), + A::capacity() - len); + let result = tail.write(data); + if let Ok(written) = result { + self.set_len(len + written); + } + result + } + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} diff --git a/src/lib.rs b/src/lib.rs index b1679b8..2cf4dc6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,695 +1,11 @@ extern crate odds; extern crate nodrop; -use std::cmp; -use std::io; -use std::iter; -use std::mem; -use std::ptr; -use std::ops::{ - Deref, - DerefMut, -}; -use std::slice; - -use nodrop::NoDrop; - -// extra traits -use std::borrow::{Borrow, BorrowMut}; -use std::hash::{Hash, Hasher}; -use std::fmt; - mod array; +pub mod array_vec; +pub mod array_string; + +pub use array_vec::ArrayVec; +pub use array_string::ArrayString; pub use array::Array; pub use odds::IndexRange as RangeArgument; -use array::Index; - - -unsafe fn new_array() -> A { - // Note: Returning 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 `NoDrop` enum. - mem::uninitialized() -} - -/// A vector with a fixed capacity. -/// -/// The `ArrayVec` is a vector backed by a fixed size array. It 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 but also dereferences to a slice, so -/// that the full slice API is available. -/// -/// ArrayVec can be converted into a by value iterator. -pub struct ArrayVec { - xs: NoDrop, - len: A::Index, -} - -impl Drop for ArrayVec { - fn drop(&mut self) { - // clear all elements - while let Some(_) = self.pop() { - } - - // NoDrop inhibits array's drop - // panic safety: NoDrop::drop will trigger on panic, so the inner - // array will not drop even after panic. - } -} - -impl ArrayVec { - /// Create a new empty `ArrayVec`. - /// - /// Capacity is inferred from the type parameter. - /// - /// ``` - /// 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(new_array()), len: Index::zero() } - } - } - - /// Return the number of elements in the `ArrayVec`. - /// - /// ``` - /// 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.to_usize() } - - /// Return the capacity of the `ArrayVec`. - /// - /// ``` - /// 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. - /// - /// ``` - /// 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() { - let len = self.len(); - unsafe { - ptr::write(self.get_unchecked_mut(len), element); - self.set_len(len + 1); - } - None - } else { - Some(element) - } - } - - /// Remove the last element in the vector. - /// - /// Return `Some(` *element* `)` if the vector is non-empty, else `None`. - /// - /// ``` - /// 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 { - let new_len = self.len() - 1; - self.set_len(new_len); - Some(ptr::read(self.get_unchecked_mut(new_len))) - } - } - - /// 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. - /// - /// ``` - /// 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 { - if index >= self.capacity() { - return Some(element); - } - let mut ret = None; - if self.len() == self.capacity() { - ret = self.pop(); - } - let len = self.len(); - - // follows is just like Vec - unsafe { // infallible - // The spot to put the new value - { - let p = self.get_unchecked_mut(index) as *mut _; - // 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(p, element); - } - self.set_len(len + 1); - } - ret - } - - /// Remove the element at `index` and swap the last element into its place. - /// - /// This operation is O(1). - /// - /// Return `Some(` *element* `)` if the index is in bounds, else `None`. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut array = ArrayVec::from([1, 2, 3]); - /// - /// assert_eq!(array.swap_remove(0), Some(1)); - /// assert_eq!(&array[..], &[3, 2]); - /// - /// assert_eq!(array.swap_remove(10), None); - /// ``` - pub fn swap_remove(&mut self, index: usize) -> Option { - let len = self.len(); - if index >= len { - return None - } - self.swap(index, len - 1); - self.pop() - } - - /// Remove the element at `index` and shift down the following elements. - /// - /// Return `Some(` *element* `)` if the index is in bounds, else `None`. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut array = ArrayVec::from([1, 2, 3]); - /// - /// assert_eq!(array.remove(0), Some(1)); - /// assert_eq!(&array[..], &[2, 3]); - /// - /// assert_eq!(array.remove(10), None); - /// ``` - pub fn remove(&mut self, index: usize) -> Option { - if index >= self.len() { - None - } else { - self.drain(index..index + 1).next() - } - } - - /// Remove all elements in the vector. - pub fn clear(&mut self) { - while let Some(_) = self.pop() { } - } - - /// Set the vector's length without dropping or moving out elements - /// - /// May panic if `length` is greater than the capacity. - /// - /// This function is `unsafe` because it changes the notion of the - /// number of “valid” elements in the vector. Use with care. - #[inline] - pub unsafe fn set_len(&mut self, length: usize) { - debug_assert!(length <= self.capacity()); - self.len = Index::from(length); - } - - - /// Create a draining iterator that removes the specified range in the vector - /// and yields the removed items from start to end. The element range is - /// removed even if the iterator is not consumed until the end. - /// - /// Note: It is unspecified how many elements are removed from the vector, - /// if the `Drain` value is leaked. - /// - /// **Panics** if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut v = ArrayVec::from([1, 2, 3]); - /// let u: Vec<_> = v.drain(0..2).collect(); - /// assert_eq!(&v[..], &[3]); - /// assert_eq!(&u[..], &[1, 2]); - /// ``` - pub fn drain(&mut self, range: R) -> Drain { - // Memory safety - // - // When the Drain is first created, it shortens the length of - // the source vector to make sure no uninitalized or moved-from elements - // are accessible at all if the Drain's destructor never gets to run. - // - // Drain will ptr::read out the values to remove. - // When finished, remaining tail of the vec is copied back to cover - // the hole, and the vector length is restored to the new length. - // - let len = self.len(); - let start = range.start().unwrap_or(0); - let end = range.end().unwrap_or(len); - // bounds check happens here - let range_slice: *const _ = &self[start..end]; - - unsafe { - // set self.vec length's to start, to be safe in case Drain is leaked - self.set_len(start); - Drain { - tail_start: end, - tail_len: len - end, - iter: (*range_slice).iter(), - vec: self as *mut _, - } - } - } - - /// Return the inner fixed size array, if it is full to its capacity. - /// - /// Return an `Ok` value with the array if length equals capacity, - /// return an `Err` with self otherwise. - /// - /// `Note:` This function may incur unproportionally large overhead - /// to move the array out, its performance is not optimal. - pub fn into_inner(self) -> Result { - if self.len() < self.capacity() { - Err(self) - } else { - unsafe { - let array = ptr::read(&*self.xs); - mem::forget(self); - Ok(array) - } - } - } -} - -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. -/// -/// ``` -/// 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: Index::from(A::capacity()) } - } -} - - -/// Iterate the `ArrayVec` with references to each element. -/// -/// ``` -/// 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. -/// -/// ``` -/// 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. -/// -/// ``` -/// 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: Index::zero(), v: self, } - } -} - - -/// By-value iterator for `ArrayVec`. -pub struct IntoIter { - index: A::Index, - 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 index = self.index.to_usize(); - self.index = Index::from(index + 1); - Some(ptr::read(self.v.get_unchecked_mut(index))) - } - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = self.v.len() - self.index.to_usize(); - (len, Some(len)) - } -} - -impl DoubleEndedIterator for IntoIter { - #[inline] - fn next_back(&mut self) -> Option { - if self.index == self.v.len { - None - } else { - unsafe { - let new_len = self.v.len() - 1; - self.v.set_len(new_len); - Some(ptr::read(self.v.get_unchecked_mut(new_len))) - } - } - } -} - -impl ExactSizeIterator for IntoIter { } - -impl Drop for IntoIter { - fn drop(&mut self) { - // panic safety: Set length to 0 before dropping elements. - let index = self.index.to_usize(); - let len = self.v.len(); - unsafe { - self.v.set_len(0); - let elements = slice::from_raw_parts(self.v.get_unchecked_mut(index), - len - index); - for elt in elements { - ptr::read(elt); - } - } - } -} - -/// A draining iterator for `ArrayVec`. -pub struct Drain<'a, A> - where A: Array, - A::Item: 'a, -{ - /// Index of tail to preserve - tail_start: usize, - /// Length of tail - tail_len: usize, - /// Current remaining range to remove - iter: slice::Iter<'a, A::Item>, - vec: *mut ArrayVec, -} - -unsafe impl<'a, A: Array + Sync> Sync for Drain<'a, A> {} -unsafe impl<'a, A: Array + Send> Send for Drain<'a, A> {} - -impl<'a, A: Array> Iterator for Drain<'a, A> - where A::Item: 'a, -{ - type Item = A::Item; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().map(|elt| - unsafe { - ptr::read(elt as *const _) - } - ) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl<'a, A: Array> DoubleEndedIterator for Drain<'a, A> - where A::Item: 'a, -{ - #[inline] - fn next_back(&mut self) -> Option { - self.iter.next_back().map(|elt| - unsafe { - ptr::read(elt as *const _) - } - ) - } -} - -impl<'a, A: Array> ExactSizeIterator for Drain<'a, A> where A::Item: 'a {} - -impl<'a, A: Array> Drop for Drain<'a, A> - where A::Item: 'a -{ - fn drop(&mut self) { - // len is currently 0 so panicking while dropping will not cause a double drop. - - // exhaust self first - while let Some(_) = self.next() { } - - if self.tail_len > 0 { - unsafe { - let source_vec = &mut *self.vec; - // memmove back untouched tail, update to new length - let start = source_vec.len(); - let tail = self.tail_start; - let src = source_vec.as_ptr().offset(tail as isize); - let dst = source_vec.as_mut_ptr().offset(start as isize); - ptr::copy(src, dst, self.tail_len); - source_vec.set_len(start + self.tail_len); - } - } - } -} - - - - -/// 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) } -} - -impl Default for ArrayVec { - fn default() -> ArrayVec { - ArrayVec::new() - } -} - -impl PartialOrd for ArrayVec where A::Item: PartialOrd { - #[inline] - fn partial_cmp(&self, other: &ArrayVec) -> Option { - (**self).partial_cmp(other) - } - - #[inline] - fn lt(&self, other: &Self) -> bool { - (**self).lt(other) - } - - #[inline] - fn le(&self, other: &Self) -> bool { - (**self).le(other) - } - - #[inline] - fn ge(&self, other: &Self) -> bool { - (**self).ge(other) - } - - #[inline] - fn gt(&self, other: &Self) -> bool { - (**self).gt(other) - } -} - -impl Ord for ArrayVec where A::Item: Ord { - fn cmp(&self, other: &ArrayVec) -> cmp::Ordering { - (**self).cmp(other) - } -} - -/// `Write` appends written data to the end of the vector. -impl> io::Write for ArrayVec { - fn write(&mut self, data: &[u8]) -> io::Result { - unsafe { - let len = self.len(); - let mut tail = slice::from_raw_parts_mut(self.get_unchecked_mut(len), - A::capacity() - len); - let result = tail.write(data); - if let Ok(written) = result { - self.set_len(len + written); - } - result - } - } - fn flush(&mut self) -> io::Result<()> { Ok(()) } -}