| on: | ||
| push: | ||
| branches: [ master ] | ||
| pull_request: | ||
| branches: [ master ] | ||
| name: Continuous integration | ||
| env: | ||
| CARGO_TERM_COLOR: always | ||
| CARGO_INCREMENTAL: 0 | ||
| jobs: | ||
| tests: | ||
| runs-on: ubuntu-latest | ||
| continue-on-error: true | ||
| strategy: | ||
| matrix: | ||
| include: | ||
| - rust: 1.51.0 # MSRV | ||
| features: serde | ||
| - rust: stable | ||
| features: | ||
| - rust: beta | ||
| features: serde | ||
| - rust: nightly | ||
| features: serde unstable-const-fn | ||
| steps: | ||
| - uses: actions/checkout@v2 | ||
| - uses: actions-rs/toolchain@v1 | ||
| with: | ||
| profile: minimal | ||
| toolchain: ${{ matrix.rust }} | ||
| override: true | ||
| - name: Tests | ||
| run: | | ||
| cargo build --verbose --features "${{ matrix.features }}" | ||
| cargo doc --verbose --features "${{ matrix.features }}" --no-deps | ||
| cargo test --verbose --features "${{ matrix.features }}" | ||
| cargo test --release --verbose --features "${{ matrix.features }}" | ||
| - name: Test run benchmarks | ||
| if: matrix.bench != '' | ||
| run: cargo test -v --benches | ||
| miri: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v2 | ||
| - name: Miri | ||
| run: ci/miri.sh | ||
| use std::ptr; | ||
| use std::slice; | ||
| use crate::CapacityError; | ||
| /// Implements basic arrayvec methods - based on a few required methods | ||
| /// for length and element access. | ||
| pub(crate) trait ArrayVecImpl { | ||
| type Item; | ||
| const CAPACITY: usize; | ||
| fn len(&self) -> usize; | ||
| unsafe fn set_len(&mut self, new_len: usize); | ||
| /// Return a slice containing all elements of the vector. | ||
| fn as_slice(&self) -> &[Self::Item] { | ||
| let len = self.len(); | ||
| unsafe { | ||
| slice::from_raw_parts(self.as_ptr(), len) | ||
| } | ||
| } | ||
| /// Return a mutable slice containing all elements of the vector. | ||
| fn as_mut_slice(&mut self) -> &mut [Self::Item] { | ||
| let len = self.len(); | ||
| unsafe { | ||
| std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) | ||
| } | ||
| } | ||
| /// Return a raw pointer to the vector's buffer. | ||
| fn as_ptr(&self) -> *const Self::Item; | ||
| /// Return a raw mutable pointer to the vector's buffer. | ||
| fn as_mut_ptr(&mut self) -> *mut Self::Item; | ||
| fn push(&mut self, element: Self::Item) { | ||
| self.try_push(element).unwrap() | ||
| } | ||
| fn try_push(&mut self, element: Self::Item) -> Result<(), CapacityError<Self::Item>> { | ||
| if self.len() < Self::CAPACITY { | ||
| unsafe { | ||
| self.push_unchecked(element); | ||
| } | ||
| Ok(()) | ||
| } else { | ||
| Err(CapacityError::new(element)) | ||
| } | ||
| } | ||
| unsafe fn push_unchecked(&mut self, element: Self::Item) { | ||
| let len = self.len(); | ||
| debug_assert!(len < Self::CAPACITY); | ||
| ptr::write(self.as_mut_ptr().add(len), element); | ||
| self.set_len(len + 1); | ||
| } | ||
| fn pop(&mut self) -> Option<Self::Item> { | ||
| if self.len() == 0 { | ||
| return None; | ||
| } | ||
| unsafe { | ||
| let new_len = self.len() - 1; | ||
| self.set_len(new_len); | ||
| Some(ptr::read(self.as_ptr().add(new_len))) | ||
| } | ||
| } | ||
| fn clear(&mut self) { | ||
| self.truncate(0) | ||
| } | ||
| fn truncate(&mut self, new_len: usize) { | ||
| unsafe { | ||
| let len = self.len(); | ||
| if new_len < len { | ||
| self.set_len(new_len); | ||
| let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len); | ||
| ptr::drop_in_place(tail); | ||
| } | ||
| } | ||
| } | ||
| } | ||
+1190
| use std::cmp; | ||
| use std::iter; | ||
| use std::mem; | ||
| use std::ops::{Bound, Deref, DerefMut, RangeBounds}; | ||
| use std::ptr; | ||
| use std::slice; | ||
| // extra traits | ||
| use std::borrow::{Borrow, BorrowMut}; | ||
| use std::hash::{Hash, Hasher}; | ||
| use std::fmt; | ||
| #[cfg(feature="std")] | ||
| use std::io; | ||
| use std::mem::ManuallyDrop; | ||
| use std::mem::MaybeUninit; | ||
| #[cfg(feature="serde")] | ||
| use serde::{Serialize, Deserialize, Serializer, Deserializer}; | ||
| use crate::LenUint; | ||
| use crate::errors::CapacityError; | ||
| use crate::arrayvec_impl::ArrayVecImpl; | ||
| /// 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 `ArrayVec<T, CAP>` is parameterized | ||
| /// by `T` for the element type and `CAP` for the maximum capacity. | ||
| /// | ||
| /// `CAP` is of type `usize` but is range limited to `u32::MAX`; attempting to create larger | ||
| /// arrayvecs with larger capacity will panic. | ||
| /// | ||
| /// The vector is a contiguous value (storing the elements inline) 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. The ArrayVec can be converted into a by value iterator. | ||
| pub struct ArrayVec<T, const CAP: usize> { | ||
| // the `len` first elements of the array are initialized | ||
| xs: [MaybeUninit<T>; CAP], | ||
| len: LenUint, | ||
| } | ||
| impl<T, const CAP: usize> Drop for ArrayVec<T, CAP> { | ||
| fn drop(&mut self) { | ||
| self.clear(); | ||
| // MaybeUninit inhibits array's drop | ||
| } | ||
| } | ||
| macro_rules! panic_oob { | ||
| ($method_name:expr, $index:expr, $len:expr) => { | ||
| panic!(concat!("ArrayVec::", $method_name, ": index {} is out of bounds in vector of length {}"), | ||
| $index, $len) | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> ArrayVec<T, CAP> { | ||
| /// Capacity | ||
| const CAPACITY: usize = CAP; | ||
| /// Create a new empty `ArrayVec`. | ||
| /// | ||
| /// The maximum capacity is given by the generic parameter `CAP`. | ||
| /// | ||
| /// ``` | ||
| /// 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); | ||
| /// ``` | ||
| #[cfg(not(feature="unstable-const-fn"))] | ||
| pub fn new() -> ArrayVec<T, CAP> { | ||
| assert_capacity_limit!(CAP); | ||
| unsafe { | ||
| ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } | ||
| } | ||
| } | ||
| #[cfg(feature="unstable-const-fn")] | ||
| pub const fn new() -> ArrayVec<T, CAP> { | ||
| assert_capacity_limit!(CAP); | ||
| unsafe { | ||
| ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 } | ||
| } | ||
| } | ||
| /// 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(always)] | ||
| pub fn len(&self) -> usize { self.len as usize } | ||
| /// Returns whether the `ArrayVec` is empty. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1]); | ||
| /// array.pop(); | ||
| /// assert_eq!(array.is_empty(), true); | ||
| /// ``` | ||
| #[inline] | ||
| pub fn is_empty(&self) -> bool { self.len() == 0 } | ||
| /// Return the capacity of the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let array = ArrayVec::from([1, 2, 3]); | ||
| /// assert_eq!(array.capacity(), 3); | ||
| /// ``` | ||
| #[inline(always)] | ||
| pub fn capacity(&self) -> usize { CAP } | ||
| /// Return ture if the `ArrayVec` is completely filled to its capacity, false otherwise. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 1>::new(); | ||
| /// assert!(!array.is_full()); | ||
| /// array.push(1); | ||
| /// assert!(array.is_full()); | ||
| /// ``` | ||
| pub fn is_full(&self) -> bool { self.len() == self.capacity() } | ||
| /// Returns the capacity left in the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// array.pop(); | ||
| /// assert_eq!(array.remaining_capacity(), 1); | ||
| /// ``` | ||
| pub fn remaining_capacity(&self) -> usize { | ||
| self.capacity() - self.len() | ||
| } | ||
| /// Push `element` to the end of the vector. | ||
| /// | ||
| /// ***Panics*** if the vector is already full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 2>::new(); | ||
| /// | ||
| /// array.push(1); | ||
| /// array.push(2); | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// ``` | ||
| pub fn push(&mut self, element: T) { | ||
| ArrayVecImpl::push(self, element) | ||
| } | ||
| /// Push `element` to the end of the vector. | ||
| /// | ||
| /// Return `Ok` if the push succeeds, or return an error if the vector | ||
| /// is already full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 2>::new(); | ||
| /// | ||
| /// let push1 = array.try_push(1); | ||
| /// let push2 = array.try_push(2); | ||
| /// | ||
| /// assert!(push1.is_ok()); | ||
| /// assert!(push2.is_ok()); | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// | ||
| /// let overflow = array.try_push(3); | ||
| /// | ||
| /// assert!(overflow.is_err()); | ||
| /// ``` | ||
| pub fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> { | ||
| ArrayVecImpl::try_push(self, element) | ||
| } | ||
| /// Push `element` to the end of the vector without checking the capacity. | ||
| /// | ||
| /// It is up to the caller to ensure the capacity of the vector is | ||
| /// sufficiently large. | ||
| /// | ||
| /// This method uses *debug assertions* to check that the arrayvec is not full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 2>::new(); | ||
| /// | ||
| /// if array.len() + 2 <= array.capacity() { | ||
| /// unsafe { | ||
| /// array.push_unchecked(1); | ||
| /// array.push_unchecked(2); | ||
| /// } | ||
| /// } | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// ``` | ||
| pub unsafe fn push_unchecked(&mut self, element: T) { | ||
| ArrayVecImpl::push_unchecked(self, element) | ||
| } | ||
| /// Shortens the vector, keeping the first `len` elements and dropping | ||
| /// the rest. | ||
| /// | ||
| /// If `len` is greater than the vector’s current length this has no | ||
| /// effect. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3, 4, 5]); | ||
| /// array.truncate(3); | ||
| /// assert_eq!(&array[..], &[1, 2, 3]); | ||
| /// array.truncate(4); | ||
| /// assert_eq!(&array[..], &[1, 2, 3]); | ||
| /// ``` | ||
| pub fn truncate(&mut self, new_len: usize) { | ||
| ArrayVecImpl::truncate(self, new_len) | ||
| } | ||
| /// Remove all elements in the vector. | ||
| pub fn clear(&mut self) { | ||
| ArrayVecImpl::clear(self) | ||
| } | ||
| /// Get pointer to where element at `index` would be | ||
| unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T { | ||
| self.as_mut_ptr().add(index) | ||
| } | ||
| /// Insert `element` at position `index`. | ||
| /// | ||
| /// Shift up all elements after `index`. | ||
| /// | ||
| /// It is an error if the index is greater than the length or if the | ||
| /// arrayvec is full. | ||
| /// | ||
| /// ***Panics*** if the array is full or the `index` is out of bounds. See | ||
| /// `try_insert` for fallible version. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 2>::new(); | ||
| /// | ||
| /// array.insert(0, "x"); | ||
| /// array.insert(0, "y"); | ||
| /// assert_eq!(&array[..], &["y", "x"]); | ||
| /// | ||
| /// ``` | ||
| pub fn insert(&mut self, index: usize, element: T) { | ||
| self.try_insert(index, element).unwrap() | ||
| } | ||
| /// Insert `element` at position `index`. | ||
| /// | ||
| /// Shift up all elements after `index`; the `index` must be less than | ||
| /// or equal to the length. | ||
| /// | ||
| /// Returns an error if vector is already at full capacity. | ||
| /// | ||
| /// ***Panics*** `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<_, 2>::new(); | ||
| /// | ||
| /// assert!(array.try_insert(0, "x").is_ok()); | ||
| /// assert!(array.try_insert(0, "y").is_ok()); | ||
| /// assert!(array.try_insert(0, "z").is_err()); | ||
| /// assert_eq!(&array[..], &["y", "x"]); | ||
| /// | ||
| /// ``` | ||
| pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), CapacityError<T>> { | ||
| if index > self.len() { | ||
| panic_oob!("try_insert", index, self.len()) | ||
| } | ||
| if self.len() == self.capacity() { | ||
| return Err(CapacityError::new(element)); | ||
| } | ||
| let len = self.len(); | ||
| // follows is just like Vec<T> | ||
| unsafe { // infallible | ||
| // The spot to put the new value | ||
| { | ||
| let p: *mut _ = self.get_unchecked_ptr(index); | ||
| // 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); | ||
| } | ||
| Ok(()) | ||
| } | ||
| /// Remove the last element in the vector and return it. | ||
| /// | ||
| /// 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<T> { | ||
| ArrayVecImpl::pop(self) | ||
| } | ||
| /// Remove the element at `index` and swap the last element into its place. | ||
| /// | ||
| /// This operation is O(1). | ||
| /// | ||
| /// Return the *element* if the index is in bounds, else panic. | ||
| /// | ||
| /// ***Panics*** if the `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// assert_eq!(array.swap_remove(0), 1); | ||
| /// assert_eq!(&array[..], &[3, 2]); | ||
| /// | ||
| /// assert_eq!(array.swap_remove(1), 2); | ||
| /// assert_eq!(&array[..], &[3]); | ||
| /// ``` | ||
| pub fn swap_remove(&mut self, index: usize) -> T { | ||
| self.swap_pop(index) | ||
| .unwrap_or_else(|| { | ||
| panic_oob!("swap_remove", index, self.len()) | ||
| }) | ||
| } | ||
| /// Remove the element at `index` and swap the last element into its place. | ||
| /// | ||
| /// This is a checked version of `.swap_remove`. | ||
| /// 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_pop(0), Some(1)); | ||
| /// assert_eq!(&array[..], &[3, 2]); | ||
| /// | ||
| /// assert_eq!(array.swap_pop(10), None); | ||
| /// ``` | ||
| pub fn swap_pop(&mut self, index: usize) -> Option<T> { | ||
| 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. | ||
| /// | ||
| /// The `index` must be strictly less than the length of the vector. | ||
| /// | ||
| /// ***Panics*** if the `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// let removed_elt = array.remove(0); | ||
| /// assert_eq!(removed_elt, 1); | ||
| /// assert_eq!(&array[..], &[2, 3]); | ||
| /// ``` | ||
| pub fn remove(&mut self, index: usize) -> T { | ||
| self.pop_at(index) | ||
| .unwrap_or_else(|| { | ||
| panic_oob!("remove", index, self.len()) | ||
| }) | ||
| } | ||
| /// Remove the element at `index` and shift down the following elements. | ||
| /// | ||
| /// This is a checked version of `.remove(index)`. Returns `None` if there | ||
| /// is no element at `index`. Otherwise, return the element inside `Some`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// assert!(array.pop_at(0).is_some()); | ||
| /// assert_eq!(&array[..], &[2, 3]); | ||
| /// | ||
| /// assert!(array.pop_at(2).is_none()); | ||
| /// assert!(array.pop_at(10).is_none()); | ||
| /// ``` | ||
| pub fn pop_at(&mut self, index: usize) -> Option<T> { | ||
| if index >= self.len() { | ||
| None | ||
| } else { | ||
| self.drain(index..index + 1).next() | ||
| } | ||
| } | ||
| /// Retains only the elements specified by the predicate. | ||
| /// | ||
| /// In other words, remove all elements `e` such that `f(&mut e)` returns false. | ||
| /// This method operates in place and preserves the order of the retained | ||
| /// elements. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3, 4]); | ||
| /// array.retain(|x| *x & 1 != 0 ); | ||
| /// assert_eq!(&array[..], &[1, 3]); | ||
| /// ``` | ||
| pub fn retain<F>(&mut self, mut f: F) | ||
| where F: FnMut(&mut T) -> bool | ||
| { | ||
| let len = self.len(); | ||
| let mut del = 0; | ||
| { | ||
| let v = &mut **self; | ||
| for i in 0..len { | ||
| if !f(&mut v[i]) { | ||
| del += 1; | ||
| } else if del > 0 { | ||
| v.swap(i - del, i); | ||
| } | ||
| } | ||
| } | ||
| if del > 0 { | ||
| self.drain(len - del..); | ||
| } | ||
| } | ||
| /// Set the vector’s length without dropping or moving out elements | ||
| /// | ||
| /// This method is `unsafe` because it changes the notion of the | ||
| /// number of “valid” elements in the vector. Use with care. | ||
| /// | ||
| /// This method uses *debug assertions* to check that `length` is | ||
| /// not greater than the capacity. | ||
| pub unsafe fn set_len(&mut self, length: usize) { | ||
| // type invariant that capacity always fits in LenUint | ||
| debug_assert!(length <= self.capacity()); | ||
| self.len = length as LenUint; | ||
| } | ||
| /// Copy all elements from the slice and append to the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut vec: ArrayVec<usize, 10> = ArrayVec::new(); | ||
| /// vec.push(1); | ||
| /// vec.try_extend_from_slice(&[2, 3]).unwrap(); | ||
| /// assert_eq!(&vec[..], &[1, 2, 3]); | ||
| /// ``` | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// This method will return an error if the capacity left (see | ||
| /// [`remaining_capacity`]) is smaller then the length of the provided | ||
| /// slice. | ||
| /// | ||
| /// [`remaining_capacity`]: #method.remaining_capacity | ||
| pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError> | ||
| where T: Copy, | ||
| { | ||
| if self.remaining_capacity() < other.len() { | ||
| return Err(CapacityError::new(())); | ||
| } | ||
| let self_len = self.len(); | ||
| let other_len = other.len(); | ||
| unsafe { | ||
| let dst = self.get_unchecked_ptr(self_len); | ||
| ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len); | ||
| self.set_len(self_len + other_len); | ||
| } | ||
| Ok(()) | ||
| } | ||
| /// 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 v1 = ArrayVec::from([1, 2, 3]); | ||
| /// let v2: ArrayVec<_, 3> = v1.drain(0..2).collect(); | ||
| /// assert_eq!(&v1[..], &[3]); | ||
| /// assert_eq!(&v2[..], &[1, 2]); | ||
| /// ``` | ||
| pub fn drain<R>(&mut self, range: R) -> Drain<T, CAP> | ||
| where R: RangeBounds<usize> | ||
| { | ||
| // Memory safety | ||
| // | ||
| // When the Drain is first created, it shortens the length of | ||
| // the source vector to make sure no uninitialized 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 = match range.start_bound() { | ||
| Bound::Unbounded => 0, | ||
| Bound::Included(&i) => i, | ||
| Bound::Excluded(&i) => i.saturating_add(1), | ||
| }; | ||
| let end = match range.end_bound() { | ||
| Bound::Excluded(&j) => j, | ||
| Bound::Included(&j) => j.saturating_add(1), | ||
| Bound::Unbounded => len, | ||
| }; | ||
| self.drain_range(start, end) | ||
| } | ||
| fn drain_range(&mut self, start: usize, end: usize) -> Drain<T, CAP> | ||
| { | ||
| let len = self.len(); | ||
| // bounds check happens here (before length is changed!) | ||
| let range_slice: *const _ = &self[start..end]; | ||
| // Calling `set_len` creates a fresh and thus unique mutable references, making all | ||
| // older aliases we created invalid. So we cannot call that function. | ||
| self.len = start as LenUint; | ||
| unsafe { | ||
| 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. | ||
| pub fn into_inner(self) -> Result<[T; CAP], Self> { | ||
| if self.len() < self.capacity() { | ||
| Err(self) | ||
| } else { | ||
| unsafe { | ||
| let self_ = ManuallyDrop::new(self); | ||
| let array = ptr::read(self_.as_ptr() as *const [T; CAP]); | ||
| Ok(array) | ||
| } | ||
| } | ||
| } | ||
| /// Return a slice containing all elements of the vector. | ||
| pub fn as_slice(&self) -> &[T] { | ||
| ArrayVecImpl::as_slice(self) | ||
| } | ||
| /// Return a mutable slice containing all elements of the vector. | ||
| pub fn as_mut_slice(&mut self) -> &mut [T] { | ||
| ArrayVecImpl::as_mut_slice(self) | ||
| } | ||
| /// Return a raw pointer to the vector's buffer. | ||
| pub fn as_ptr(&self) -> *const T { | ||
| ArrayVecImpl::as_ptr(self) | ||
| } | ||
| /// Return a raw mutable pointer to the vector's buffer. | ||
| pub fn as_mut_ptr(&mut self) -> *mut T { | ||
| ArrayVecImpl::as_mut_ptr(self) | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> ArrayVecImpl for ArrayVec<T, CAP> { | ||
| type Item = T; | ||
| const CAPACITY: usize = CAP; | ||
| fn len(&self) -> usize { self.len() } | ||
| unsafe fn set_len(&mut self, length: usize) { | ||
| debug_assert!(length <= CAP); | ||
| self.len = length as LenUint; | ||
| } | ||
| fn as_ptr(&self) -> *const Self::Item { | ||
| self.xs.as_ptr() as _ | ||
| } | ||
| fn as_mut_ptr(&mut self) -> *mut Self::Item { | ||
| self.xs.as_mut_ptr() as _ | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Deref for ArrayVec<T, CAP> { | ||
| type Target = [T]; | ||
| #[inline] | ||
| fn deref(&self) -> &Self::Target { | ||
| self.as_slice() | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> DerefMut for ArrayVec<T, CAP> { | ||
| #[inline] | ||
| fn deref_mut(&mut self) -> &mut Self::Target { | ||
| self.as_mut_slice() | ||
| } | ||
| } | ||
| /// 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<T, const CAP: usize> From<[T; CAP]> for ArrayVec<T, CAP> { | ||
| fn from(array: [T; CAP]) -> Self { | ||
| let array = ManuallyDrop::new(array); | ||
| let mut vec = <ArrayVec<T, CAP>>::new(); | ||
| unsafe { | ||
| (&*array as *const [T; CAP] as *const [MaybeUninit<T>; CAP]) | ||
| .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<T>; CAP], 1); | ||
| vec.set_len(CAP); | ||
| } | ||
| vec | ||
| } | ||
| } | ||
| /// Try to create an `ArrayVec` from a slice. This will return an error if the slice was too big to | ||
| /// fit. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// use std::convert::TryInto as _; | ||
| /// | ||
| /// let array: ArrayVec<_, 4> = (&[1, 2, 3] as &[_]).try_into().unwrap(); | ||
| /// assert_eq!(array.len(), 3); | ||
| /// assert_eq!(array.capacity(), 4); | ||
| /// ``` | ||
| impl<T, const CAP: usize> std::convert::TryFrom<&[T]> for ArrayVec<T, CAP> | ||
| where T: Clone, | ||
| { | ||
| type Error = CapacityError; | ||
| fn try_from(slice: &[T]) -> Result<Self, Self::Error> { | ||
| if Self::CAPACITY < slice.len() { | ||
| Err(CapacityError::new(())) | ||
| } else { | ||
| let mut array = Self::new(); | ||
| array.extend_from_slice(slice); | ||
| Ok(array) | ||
| } | ||
| } | ||
| } | ||
| /// Iterate the `ArrayVec` with references to each element. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// for elt in &array { | ||
| /// // ... | ||
| /// } | ||
| /// ``` | ||
| impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec<T, CAP> { | ||
| type Item = &'a T; | ||
| type IntoIter = slice::Iter<'a, T>; | ||
| 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, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec<T, CAP> { | ||
| type Item = &'a mut T; | ||
| type IntoIter = slice::IterMut<'a, T>; | ||
| 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<T, const CAP: usize> IntoIterator for ArrayVec<T, CAP> { | ||
| type Item = T; | ||
| type IntoIter = IntoIter<T, CAP>; | ||
| fn into_iter(self) -> IntoIter<T, CAP> { | ||
| IntoIter { index: 0, v: self, } | ||
| } | ||
| } | ||
| /// By-value iterator for `ArrayVec`. | ||
| pub struct IntoIter<T, const CAP: usize> { | ||
| index: usize, | ||
| v: ArrayVec<T, CAP>, | ||
| } | ||
| impl<T, const CAP: usize> Iterator for IntoIter<T, CAP> { | ||
| type Item = T; | ||
| fn next(&mut self) -> Option<Self::Item> { | ||
| if self.index == self.v.len() { | ||
| None | ||
| } else { | ||
| unsafe { | ||
| let index = self.index; | ||
| self.index = index + 1; | ||
| Some(ptr::read(self.v.get_unchecked_ptr(index))) | ||
| } | ||
| } | ||
| } | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| let len = self.v.len() - self.index; | ||
| (len, Some(len)) | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> DoubleEndedIterator for IntoIter<T, CAP> { | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
| 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_ptr(new_len))) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> ExactSizeIterator for IntoIter<T, CAP> { } | ||
| impl<T, const CAP: usize> Drop for IntoIter<T, CAP> { | ||
| fn drop(&mut self) { | ||
| // panic safety: Set length to 0 before dropping elements. | ||
| let index = self.index; | ||
| let len = self.v.len(); | ||
| unsafe { | ||
| self.v.set_len(0); | ||
| let elements = slice::from_raw_parts_mut( | ||
| self.v.get_unchecked_ptr(index), | ||
| len - index); | ||
| ptr::drop_in_place(elements); | ||
| } | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Clone for IntoIter<T, CAP> | ||
| where T: Clone, | ||
| { | ||
| fn clone(&self) -> IntoIter<T, CAP> { | ||
| let mut v = ArrayVec::new(); | ||
| v.extend_from_slice(&self.v[self.index..]); | ||
| v.into_iter() | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> fmt::Debug for IntoIter<T, CAP> | ||
| where | ||
| T: fmt::Debug, | ||
| { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| f.debug_list() | ||
| .entries(&self.v[self.index..]) | ||
| .finish() | ||
| } | ||
| } | ||
| /// A draining iterator for `ArrayVec`. | ||
| pub struct Drain<'a, T: 'a, const CAP: usize> { | ||
| /// Index of tail to preserve | ||
| tail_start: usize, | ||
| /// Length of tail | ||
| tail_len: usize, | ||
| /// Current remaining range to remove | ||
| iter: slice::Iter<'a, T>, | ||
| vec: *mut ArrayVec<T, CAP>, | ||
| } | ||
| unsafe impl<'a, T: Sync, const CAP: usize> Sync for Drain<'a, T, CAP> {} | ||
| unsafe impl<'a, T: Send, const CAP: usize> Send for Drain<'a, T, CAP> {} | ||
| impl<'a, T: 'a, const CAP: usize> Iterator for Drain<'a, T, CAP> { | ||
| type Item = T; | ||
| fn next(&mut self) -> Option<Self::Item> { | ||
| self.iter.next().map(|elt| | ||
| unsafe { | ||
| ptr::read(elt as *const _) | ||
| } | ||
| ) | ||
| } | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| self.iter.size_hint() | ||
| } | ||
| } | ||
| impl<'a, T: 'a, const CAP: usize> DoubleEndedIterator for Drain<'a, T, CAP> | ||
| { | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
| self.iter.next_back().map(|elt| | ||
| unsafe { | ||
| ptr::read(elt as *const _) | ||
| } | ||
| ) | ||
| } | ||
| } | ||
| impl<'a, T: 'a, const CAP: usize> ExactSizeIterator for Drain<'a, T, CAP> {} | ||
| impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { | ||
| 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().add(tail); | ||
| let dst = source_vec.as_mut_ptr().add(start); | ||
| ptr::copy(src, dst, self.tail_len); | ||
| source_vec.set_len(start + self.tail_len); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| struct ScopeExitGuard<T, Data, F> | ||
| where F: FnMut(&Data, &mut T) | ||
| { | ||
| value: T, | ||
| data: Data, | ||
| f: F, | ||
| } | ||
| impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F> | ||
| where F: FnMut(&Data, &mut T) | ||
| { | ||
| fn drop(&mut self) { | ||
| (self.f)(&self.data, &mut self.value) | ||
| } | ||
| } | ||
| /// Extend the `ArrayVec` with an iterator. | ||
| /// | ||
| /// ***Panics*** if extending the vector exceeds its capacity. | ||
| impl<T, const CAP: usize> Extend<T> for ArrayVec<T, CAP> { | ||
| /// Extend the `ArrayVec` with an iterator. | ||
| /// | ||
| /// ***Panics*** if extending the vector exceeds its capacity. | ||
| fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) { | ||
| unsafe { | ||
| self.extend_from_iter::<_, true>(iter) | ||
| } | ||
| } | ||
| } | ||
| #[inline(never)] | ||
| #[cold] | ||
| fn extend_panic() { | ||
| panic!("ArrayVec: capacity exceeded in extend/from_iter"); | ||
| } | ||
| impl<T, const CAP: usize> ArrayVec<T, CAP> { | ||
| /// Extend the arrayvec from the iterable. | ||
| /// | ||
| /// ## Safety | ||
| /// | ||
| /// Unsafe because if CHECK is false, the length of the input is not checked. | ||
| /// The caller must ensure the length of the input fits in the capacity. | ||
| pub(crate) unsafe fn extend_from_iter<I, const CHECK: bool>(&mut self, iterable: I) | ||
| where I: IntoIterator<Item = T> | ||
| { | ||
| let take = self.capacity() - self.len(); | ||
| let len = self.len(); | ||
| let mut ptr = raw_ptr_add(self.as_mut_ptr(), len); | ||
| let end_ptr = raw_ptr_add(ptr, take); | ||
| // Keep the length in a separate variable, write it back on scope | ||
| // exit. To help the compiler with alias analysis and stuff. | ||
| // We update the length to handle panic in the iteration of the | ||
| // user's iterator, without dropping any elements on the floor. | ||
| let mut guard = ScopeExitGuard { | ||
| value: &mut self.len, | ||
| data: len, | ||
| f: move |&len, self_len| { | ||
| **self_len = len as LenUint; | ||
| } | ||
| }; | ||
| let mut iter = iterable.into_iter(); | ||
| loop { | ||
| if let Some(elt) = iter.next() { | ||
| if ptr == end_ptr && CHECK { extend_panic(); } | ||
| debug_assert_ne!(ptr, end_ptr); | ||
| ptr.write(elt); | ||
| ptr = raw_ptr_add(ptr, 1); | ||
| guard.data += 1; | ||
| } else { | ||
| return; // success | ||
| } | ||
| } | ||
| } | ||
| /// Extend the ArrayVec with clones of elements from the slice; | ||
| /// the length of the slice must be <= the remaining capacity in the arrayvec. | ||
| pub(crate) fn extend_from_slice(&mut self, slice: &[T]) | ||
| where T: Clone | ||
| { | ||
| let take = self.capacity() - self.len(); | ||
| debug_assert!(slice.len() <= take); | ||
| unsafe { | ||
| let slice = if take < slice.len() { &slice[..take] } else { slice }; | ||
| self.extend_from_iter::<_, false>(slice.iter().cloned()); | ||
| } | ||
| } | ||
| } | ||
| /// Rawptr add but uses arithmetic distance for ZST | ||
| unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T { | ||
| if mem::size_of::<T>() == 0 { | ||
| // Special case for ZST | ||
| (ptr as usize).wrapping_add(offset) as _ | ||
| } else { | ||
| ptr.add(offset) | ||
| } | ||
| } | ||
| /// Create an `ArrayVec` from an iterator. | ||
| /// | ||
| /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. | ||
| impl<T, const CAP: usize> iter::FromIterator<T> for ArrayVec<T, CAP> { | ||
| /// Create an `ArrayVec` from an iterator. | ||
| /// | ||
| /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. | ||
| fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self { | ||
| let mut array = ArrayVec::new(); | ||
| array.extend(iter); | ||
| array | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Clone for ArrayVec<T, CAP> | ||
| where T: Clone | ||
| { | ||
| fn clone(&self) -> Self { | ||
| self.iter().cloned().collect() | ||
| } | ||
| fn clone_from(&mut self, rhs: &Self) { | ||
| // recursive case for the common prefix | ||
| let prefix = cmp::min(self.len(), rhs.len()); | ||
| self[..prefix].clone_from_slice(&rhs[..prefix]); | ||
| if prefix < self.len() { | ||
| // rhs was shorter | ||
| for _ in 0..self.len() - prefix { | ||
| self.pop(); | ||
| } | ||
| } else { | ||
| let rhs_elems = &rhs[self.len()..]; | ||
| self.extend_from_slice(rhs_elems); | ||
| } | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Hash for ArrayVec<T, CAP> | ||
| where T: Hash | ||
| { | ||
| fn hash<H: Hasher>(&self, state: &mut H) { | ||
| Hash::hash(&**self, state) | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> PartialEq for ArrayVec<T, CAP> | ||
| where T: PartialEq | ||
| { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| **self == **other | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> PartialEq<[T]> for ArrayVec<T, CAP> | ||
| where T: PartialEq | ||
| { | ||
| fn eq(&self, other: &[T]) -> bool { | ||
| **self == *other | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Eq for ArrayVec<T, CAP> where T: Eq { } | ||
| impl<T, const CAP: usize> Borrow<[T]> for ArrayVec<T, CAP> { | ||
| fn borrow(&self) -> &[T] { self } | ||
| } | ||
| impl<T, const CAP: usize> BorrowMut<[T]> for ArrayVec<T, CAP> { | ||
| fn borrow_mut(&mut self) -> &mut [T] { self } | ||
| } | ||
| impl<T, const CAP: usize> AsRef<[T]> for ArrayVec<T, CAP> { | ||
| fn as_ref(&self) -> &[T] { self } | ||
| } | ||
| impl<T, const CAP: usize> AsMut<[T]> for ArrayVec<T, CAP> { | ||
| fn as_mut(&mut self) -> &mut [T] { self } | ||
| } | ||
| impl<T, const CAP: usize> fmt::Debug for ArrayVec<T, CAP> where T: fmt::Debug { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } | ||
| } | ||
| impl<T, const CAP: usize> Default for ArrayVec<T, CAP> { | ||
| /// Return an empty array | ||
| fn default() -> ArrayVec<T, CAP> { | ||
| ArrayVec::new() | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> PartialOrd for ArrayVec<T, CAP> where T: PartialOrd { | ||
| fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { | ||
| (**self).partial_cmp(other) | ||
| } | ||
| fn lt(&self, other: &Self) -> bool { | ||
| (**self).lt(other) | ||
| } | ||
| fn le(&self, other: &Self) -> bool { | ||
| (**self).le(other) | ||
| } | ||
| fn ge(&self, other: &Self) -> bool { | ||
| (**self).ge(other) | ||
| } | ||
| fn gt(&self, other: &Self) -> bool { | ||
| (**self).gt(other) | ||
| } | ||
| } | ||
| impl<T, const CAP: usize> Ord for ArrayVec<T, CAP> where T: Ord { | ||
| fn cmp(&self, other: &Self) -> cmp::Ordering { | ||
| (**self).cmp(other) | ||
| } | ||
| } | ||
| #[cfg(feature="std")] | ||
| /// `Write` appends written data to the end of the vector. | ||
| /// | ||
| /// Requires `features="std"`. | ||
| impl<const CAP: usize> io::Write for ArrayVec<u8, CAP> { | ||
| fn write(&mut self, data: &[u8]) -> io::Result<usize> { | ||
| let len = cmp::min(self.remaining_capacity(), data.len()); | ||
| let _result = self.try_extend_from_slice(&data[..len]); | ||
| debug_assert!(_result.is_ok()); | ||
| Ok(len) | ||
| } | ||
| fn flush(&mut self) -> io::Result<()> { Ok(()) } | ||
| } | ||
| #[cfg(feature="serde")] | ||
| /// Requires crate feature `"serde"` | ||
| impl<T: Serialize, const CAP: usize> Serialize for ArrayVec<T, CAP> { | ||
| fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
| where S: Serializer | ||
| { | ||
| serializer.collect_seq(self) | ||
| } | ||
| } | ||
| #[cfg(feature="serde")] | ||
| /// Requires crate feature `"serde"` | ||
| impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec<T, CAP> { | ||
| fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
| 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])>); | ||
| impl<'de, T: Deserialize<'de>, const CAP: usize> Visitor<'de> for ArrayVecVisitor<'de, T, CAP> { | ||
| type Value = ArrayVec<T, CAP>; | ||
| fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
| write!(formatter, "an array with no more than {} items", CAP) | ||
| } | ||
| fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error> | ||
| where SA: SeqAccess<'de>, | ||
| { | ||
| let mut values = ArrayVec::<T, CAP>::new(); | ||
| while let Some(value) = seq.next_element()? { | ||
| if let Err(_) = values.try_push(value) { | ||
| return Err(SA::Error::invalid_length(CAP + 1, &self)); | ||
| } | ||
| } | ||
| Ok(values) | ||
| } | ||
| } | ||
| deserializer.deserialize_seq(ArrayVecVisitor::<T, CAP>(PhantomData)) | ||
| } | ||
| } |
| { | ||
| "git": { | ||
| "sha1": "d336f8c5c54df87154deb59ffc5c0a91749069be" | ||
| "sha1": "f74f3d2b0289c7c27b2902ac577474c9d9c63abf" | ||
| } | ||
| } |
@@ -10,3 +10,3 @@ | ||
| fn try_push_c(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| b.iter(|| { | ||
@@ -22,3 +22,3 @@ v.clear(); | ||
| fn try_push_alpha(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| b.iter(|| { | ||
@@ -35,3 +35,3 @@ v.clear(); | ||
| fn try_push_string(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| let input = "abcαβγ“”"; | ||
@@ -51,3 +51,3 @@ b.iter(|| { | ||
| fn push_c(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| b.iter(|| { | ||
@@ -64,3 +64,3 @@ v.clear(); | ||
| fn push_alpha(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| b.iter(|| { | ||
@@ -77,3 +77,3 @@ v.clear(); | ||
| fn push_string(b: &mut Bencher) { | ||
| let mut v = ArrayString::<[u8; 512]>::new(); | ||
| let mut v = ArrayString::<512>::new(); | ||
| let input = "abcαβγ“”"; | ||
@@ -80,0 +80,0 @@ b.iter(|| { |
@@ -13,3 +13,3 @@ | ||
| fn extend_with_constant(b: &mut Bencher) { | ||
| let mut v = ArrayVec::<[u8; 512]>::new(); | ||
| let mut v = ArrayVec::<u8, 512>::new(); | ||
| let cap = v.capacity(); | ||
@@ -26,3 +26,3 @@ b.iter(|| { | ||
| fn extend_with_range(b: &mut Bencher) { | ||
| let mut v = ArrayVec::<[u8; 512]>::new(); | ||
| let mut v = ArrayVec::<u8, 512>::new(); | ||
| let cap = v.capacity(); | ||
@@ -39,3 +39,3 @@ b.iter(|| { | ||
| fn extend_with_slice(b: &mut Bencher) { | ||
| let mut v = ArrayVec::<[u8; 512]>::new(); | ||
| let mut v = ArrayVec::<u8, 512>::new(); | ||
| let data = [1; 512]; | ||
@@ -52,3 +52,3 @@ b.iter(|| { | ||
| fn extend_with_write(b: &mut Bencher) { | ||
| let mut v = ArrayVec::<[u8; 512]>::new(); | ||
| let mut v = ArrayVec::<u8, 512>::new(); | ||
| let data = [1; 512]; | ||
@@ -64,3 +64,3 @@ b.iter(|| { | ||
| fn extend_from_slice(b: &mut Bencher) { | ||
| let mut v = ArrayVec::<[u8; 512]>::new(); | ||
| let mut v = ArrayVec::<u8, 512>::new(); | ||
| let data = [1; 512]; | ||
@@ -67,0 +67,0 @@ b.iter(|| { |
+2
-4
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "arrayvec" | ||
| version = "0.5.2" | ||
| version = "0.6.0" | ||
| authors = ["bluss"] | ||
@@ -23,3 +23,3 @@ description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString." | ||
| categories = ["data-structures", "no-std"] | ||
| license = "MIT/Apache-2.0" | ||
| license = "MIT OR Apache-2.0" | ||
| repository = "https://github.com/bluss/arrayvec" | ||
@@ -61,6 +61,4 @@ [package.metadata.docs.rs] | ||
| [features] | ||
| array-sizes-129-255 = [] | ||
| array-sizes-33-128 = [] | ||
| default = ["std"] | ||
| std = [] | ||
| unstable-const-fn = [] |
+69
-44
| Recent Changes (arrayvec) | ||
| ------------------------- | ||
| ========================= | ||
| - 0.5.2 | ||
| ## 0.6.0 | ||
| - Add `is_empty` methods for ArrayVec and ArrayString by @nicbn | ||
| - Implement `TryFrom<Slice>` for ArrayVec by @paulkernfeld | ||
| - Add `unstable-const-fn` to make `new` methods const by @m-ou-se | ||
| - Run miri in CI and a few related fixes by @RalfJung | ||
| - Fix outdated comment by @Phlosioneer | ||
| - Move changelog to a separate file by @Luro02 | ||
| - Remove deprecated `Error::description` by @AnderEnder | ||
| - Use pointer method `add` by @hbina | ||
| - The **const generics** release 🎉. Arrayvec finally implements what it | ||
| wanted to implement, since its first version: a vector backed by an array, | ||
| with generic parameters for the arbitrary element type *and* backing array | ||
| capacity. | ||
| - 0.5.1 | ||
| The New type syntax is `ArrayVec<T, CAP>` where `CAP` is the arrayvec capacity. | ||
| For arraystring the syntax is `ArrayString<CAP>`. | ||
| - Add `as_ptr`, `as_mut_ptr` accessors directly on the `ArrayVec` by @tbu- | ||
| (matches the same addition to `Vec` which happened in Rust 1.37). | ||
| - Add method `ArrayString::len` (now available directly, not just through deref to str). | ||
| - Use raw pointers instead of `&mut [u8]` for encoding chars into `ArrayString` | ||
| (uninit best practice fix). | ||
| - Use raw pointers instead of `get_unchecked_mut` where the target may be | ||
| uninitialized everywhere relevant in the ArrayVec implementation | ||
| (uninit best practice fix). | ||
| - Changed inline hints on many methods, mainly removing inline hints | ||
| - `ArrayVec::dispose` is now deprecated (it has no purpose anymore) | ||
| Length is stored internally as u32; this limits the maximum capacity. The size | ||
| of the `ArrayVec` or `ArrayString` structs for the same capacity may grow | ||
| slightly compared with the previous version (depending on padding requirements | ||
| for the element type). Change by @bluss. | ||
| - 0.4.12 | ||
| - Arrayvec's `.extend()` and `FromIterator`/`.collect()` to arrayvec now | ||
| **panic** if the capacity of the arrayvec is exceeded. Change by @bluss. | ||
| - Use raw pointers instead of `get_unchecked_mut` where the target may be | ||
| uninitialized everywhere relevant in the ArrayVec implementation. | ||
| - Arraystring now implements `TryFrom<&str>` and `TryFrom<fmt::Arguments>` by | ||
| @c410-f3r | ||
| - 0.5.0 | ||
| - Minimum supported rust version is Rust 1.51 | ||
| - Use `MaybeUninit` (now unconditionally) in the implementation of | ||
| `ArrayVec` | ||
| - Use `MaybeUninit` (now unconditionally) in the implementation of | ||
| `ArrayString` | ||
| - The crate feature for serde serialization is now named `serde`. | ||
| - Updated the `Array` trait interface, and it is now easier to use for | ||
| users outside the crate. | ||
| - Add `FromStr` impl for `ArrayString` by @despawnerer | ||
| - Add method `try_extend_from_slice` to `ArrayVec`, which is always | ||
| effecient by @Thomasdezeeuw. | ||
| - Add method `remaining_capacity` by @Thomasdezeeuw | ||
| - Improve performance of the `extend` method. | ||
| - The index type of zero capacity vectors is now itself zero size, by | ||
| @clarfon | ||
| - Use `drop_in_place` for truncate and clear methods. This affects drop order | ||
| and resume from panic during drop. | ||
| - Use Rust 2018 edition for the implementation | ||
| - Require Rust 1.36 or later, for the unconditional `MaybeUninit` | ||
| improvements. | ||
| ## 0.5.2 | ||
| - Add `is_empty` methods for ArrayVec and ArrayString by @nicbn | ||
| - Implement `TryFrom<Slice>` for ArrayVec by @paulkernfeld | ||
| - Add `unstable-const-fn` to make `new` methods const by @m-ou-se | ||
| - Run miri in CI and a few related fixes by @RalfJung | ||
| - Fix outdated comment by @Phlosioneer | ||
| - Move changelog to a separate file by @Luro02 | ||
| - Remove deprecated `Error::description` by @AnderEnder | ||
| - Use pointer method `add` by @hbina | ||
| ## 0.5.1 | ||
| - Add `as_ptr`, `as_mut_ptr` accessors directly on the `ArrayVec` by @tbu- | ||
| (matches the same addition to `Vec` which happened in Rust 1.37). | ||
| - Add method `ArrayString::len` (now available directly, not just through deref to str). | ||
| - Use raw pointers instead of `&mut [u8]` for encoding chars into `ArrayString` | ||
| (uninit best practice fix). | ||
| - Use raw pointers instead of `get_unchecked_mut` where the target may be | ||
| uninitialized everywhere relevant in the ArrayVec implementation | ||
| (uninit best practice fix). | ||
| - Changed inline hints on many methods, mainly removing inline hints | ||
| - `ArrayVec::dispose` is now deprecated (it has no purpose anymore) | ||
| ## 0.4.12 | ||
| - Use raw pointers instead of `get_unchecked_mut` where the target may be | ||
| uninitialized everywhere relevant in the ArrayVec implementation. | ||
| ## 0.5.0 | ||
| - Use `MaybeUninit` (now unconditionally) in the implementation of | ||
| `ArrayVec` | ||
| - Use `MaybeUninit` (now unconditionally) in the implementation of | ||
| `ArrayString` | ||
| - The crate feature for serde serialization is now named `serde`. | ||
| - Updated the `Array` trait interface, and it is now easier to use for | ||
| users outside the crate. | ||
| - Add `FromStr` impl for `ArrayString` by @despawnerer | ||
| - Add method `try_extend_from_slice` to `ArrayVec`, which is always | ||
| effecient by @Thomasdezeeuw. | ||
| - Add method `remaining_capacity` by @Thomasdezeeuw | ||
| - Improve performance of the `extend` method. | ||
| - The index type of zero capacity vectors is now itself zero size, by | ||
| @clarfon | ||
| - Use `drop_in_place` for truncate and clear methods. This affects drop order | ||
| and resume from panic during drop. | ||
| - Use Rust 2018 edition for the implementation | ||
| - Require Rust 1.36 or later, for the unconditional `MaybeUninit` | ||
| improvements. | ||
| ## Older releases | ||
| - 0.4.11 | ||
@@ -56,0 +81,0 @@ |
+1
-1
@@ -1,2 +0,2 @@ | ||
| #!/usr/bin/env sh | ||
| #!/bin/sh | ||
@@ -3,0 +3,0 @@ set -ex |
+5
-2
@@ -5,5 +5,8 @@ | ||
| [](https://crates.io/crates/arrayvec) | ||
| [](https://crates.io/crates/nodrop) | ||
| [](https://docs.rs/arrayvec) | ||
| [](https://travis-ci.org/bluss/arrayvec) | ||
| [](https://github.com/bluss/arrayvec/actions) | ||
| [](LICENSE-APACHE) | ||
@@ -10,0 +13,0 @@ OR |
+117
-105
| use std::borrow::Borrow; | ||
| use std::cmp; | ||
| use std::convert::TryFrom; | ||
| use std::fmt; | ||
| use std::hash::{Hash, Hasher}; | ||
| use std::mem::MaybeUninit; | ||
| use std::ops::{Deref, DerefMut}; | ||
| use std::ptr; | ||
| use std::ops::{Deref, DerefMut}; | ||
| use std::slice; | ||
| use std::str; | ||
| use std::str::FromStr; | ||
| use std::str::Utf8Error; | ||
| use std::slice; | ||
| use crate::array::Array; | ||
| use crate::array::Index; | ||
| use crate::CapacityError; | ||
| use crate::LenUint; | ||
| use crate::char::encode_utf8; | ||
@@ -20,3 +21,2 @@ | ||
| use super::MaybeUninit as MaybeUninitCopy; | ||
@@ -26,19 +26,20 @@ /// A string with a fixed capacity. | ||
| /// The `ArrayString` is a string backed by a fixed size array. It keeps track | ||
| /// of its length. | ||
| /// of its length, and is parameterized by `CAP` for the maximum capacity. | ||
| /// | ||
| /// `CAP` is of type `usize` but is range limited to `u32::MAX`; attempting to create larger | ||
| /// arrayvecs with larger capacity will panic. | ||
| /// | ||
| /// The string is a contiguous value that you can store directly on the stack | ||
| /// if needed. | ||
| #[derive(Copy)] | ||
| pub struct ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| { | ||
| xs: MaybeUninitCopy<A>, | ||
| len: A::Index, | ||
| pub struct ArrayString<const CAP: usize> { | ||
| // the `len` first elements of the array are initialized | ||
| xs: [MaybeUninit<u8>; CAP], | ||
| len: LenUint, | ||
| } | ||
| impl<A> Default for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Default for ArrayString<CAP> | ||
| { | ||
| /// Return an empty `ArrayString` | ||
| fn default() -> ArrayString<A> { | ||
| fn default() -> ArrayString<CAP> { | ||
| ArrayString::new() | ||
@@ -48,4 +49,3 @@ } | ||
| impl<A> ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> ArrayString<CAP> | ||
| { | ||
@@ -59,3 +59,3 @@ /// Create a new empty `ArrayString`. | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 16]>::new(); | ||
| /// let mut string = ArrayString::<16>::new(); | ||
| /// string.push_str("foo"); | ||
@@ -66,8 +66,6 @@ /// assert_eq!(&string[..], "foo"); | ||
| #[cfg(not(feature="unstable-const-fn"))] | ||
| pub fn new() -> ArrayString<A> { | ||
| pub fn new() -> ArrayString<CAP> { | ||
| assert_capacity_limit!(CAP); | ||
| unsafe { | ||
| ArrayString { | ||
| xs: MaybeUninitCopy::uninitialized(), | ||
| len: Index::ZERO, | ||
| } | ||
| ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } | ||
| } | ||
@@ -77,8 +75,6 @@ } | ||
| #[cfg(feature="unstable-const-fn")] | ||
| pub const fn new() -> ArrayString<A> { | ||
| pub const fn new() -> ArrayString<CAP> { | ||
| assert_capacity_limit!(CAP); | ||
| unsafe { | ||
| ArrayString { | ||
| xs: MaybeUninitCopy::uninitialized(), | ||
| len: Index::ZERO, | ||
| } | ||
| ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } | ||
| } | ||
@@ -89,3 +85,3 @@ } | ||
| #[inline] | ||
| pub fn len(&self) -> usize { self.len.to_usize() } | ||
| pub fn len(&self) -> usize { self.len as usize } | ||
@@ -105,3 +101,3 @@ /// Returns whether the string is empty. | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap(); | ||
| /// let mut string = ArrayString::<3>::from("foo").unwrap(); | ||
| /// assert_eq!(&string[..], "foo"); | ||
@@ -126,9 +122,12 @@ /// assert_eq!(string.len(), 3); | ||
| /// ``` | ||
| pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> { | ||
| let len = str::from_utf8(b.as_slice())?.len(); | ||
| debug_assert_eq!(len, A::CAPACITY); | ||
| Ok(ArrayString { | ||
| xs: MaybeUninitCopy::from(*b), | ||
| len: Index::from(A::CAPACITY), | ||
| }) | ||
| pub fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> { | ||
| let len = str::from_utf8(b)?.len(); | ||
| debug_assert_eq!(len, CAP); | ||
| let mut vec = Self::new(); | ||
| unsafe { | ||
| (b as *const [u8; CAP] as *const [MaybeUninit<u8>; CAP]) | ||
| .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<u8>; CAP], 1); | ||
| vec.set_len(CAP); | ||
| } | ||
| Ok(vec) | ||
| } | ||
@@ -141,7 +140,7 @@ | ||
| /// | ||
| /// let string = ArrayString::<[_; 3]>::new(); | ||
| /// let string = ArrayString::<3>::new(); | ||
| /// assert_eq!(string.capacity(), 3); | ||
| /// ``` | ||
| #[inline(always)] | ||
| pub fn capacity(&self) -> usize { A::CAPACITY } | ||
| pub fn capacity(&self) -> usize { CAP } | ||
@@ -153,3 +152,3 @@ /// Return if the `ArrayString` is completely filled. | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 1]>::new(); | ||
| /// let mut string = ArrayString::<1>::new(); | ||
| /// assert!(!string.is_full()); | ||
@@ -168,3 +167,3 @@ /// string.push_str("A"); | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 2]>::new(); | ||
| /// let mut string = ArrayString::<2>::new(); | ||
| /// | ||
@@ -189,3 +188,3 @@ /// string.push('a'); | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 2]>::new(); | ||
| /// let mut string = ArrayString::<2>::new(); | ||
| /// | ||
@@ -202,3 +201,3 @@ /// string.try_push('a').unwrap(); | ||
| unsafe { | ||
| let ptr = self.xs.ptr_mut().add(len); | ||
| let ptr = self.as_mut_ptr().add(len); | ||
| let remaining_cap = self.capacity() - len; | ||
@@ -222,3 +221,3 @@ match encode_utf8(c, ptr, remaining_cap) { | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 2]>::new(); | ||
| /// let mut string = ArrayString::<2>::new(); | ||
| /// | ||
@@ -243,3 +242,3 @@ /// string.push_str("a"); | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 2]>::new(); | ||
| /// let mut string = ArrayString::<2>::new(); | ||
| /// | ||
@@ -260,3 +259,3 @@ /// string.try_push_str("a").unwrap(); | ||
| unsafe { | ||
| let dst = self.xs.ptr_mut().add(self.len()); | ||
| let dst = self.as_mut_ptr().add(self.len()); | ||
| let src = s.as_ptr(); | ||
@@ -277,3 +276,3 @@ ptr::copy_nonoverlapping(src, dst, s.len()); | ||
| /// | ||
| /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); | ||
| /// let mut s = ArrayString::<3>::from("foo").unwrap(); | ||
| /// | ||
@@ -308,3 +307,3 @@ /// assert_eq!(s.pop(), Some('o')); | ||
| /// | ||
| /// let mut string = ArrayString::<[_; 6]>::from("foobar").unwrap(); | ||
| /// let mut string = ArrayString::<6>::from("foobar").unwrap(); | ||
| /// string.truncate(3); | ||
@@ -339,3 +338,3 @@ /// assert_eq!(&string[..], "foo"); | ||
| /// | ||
| /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); | ||
| /// let mut s = ArrayString::<3>::from("foo").unwrap(); | ||
| /// | ||
@@ -355,4 +354,4 @@ /// assert_eq!(s.remove(0), 'f'); | ||
| unsafe { | ||
| ptr::copy(self.xs.ptr().add(next), | ||
| self.xs.ptr_mut().add(idx), | ||
| ptr::copy(self.as_ptr().add(next), | ||
| self.as_mut_ptr().add(idx), | ||
| len - next); | ||
@@ -379,4 +378,5 @@ self.set_len(len - (next - idx)); | ||
| pub unsafe fn set_len(&mut self, length: usize) { | ||
| // type invariant that capacity always fits in LenUint | ||
| debug_assert!(length <= self.capacity()); | ||
| self.len = Index::from(length); | ||
| self.len = length as LenUint; | ||
| } | ||
@@ -388,6 +388,13 @@ | ||
| } | ||
| fn as_ptr(&self) -> *const u8 { | ||
| self.xs.as_ptr() as *const u8 | ||
| } | ||
| fn as_mut_ptr(&mut self) -> *mut u8 { | ||
| self.xs.as_mut_ptr() as *mut u8 | ||
| } | ||
| } | ||
| impl<A> Deref for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Deref for ArrayString<CAP> | ||
| { | ||
@@ -398,3 +405,3 @@ type Target = str; | ||
| unsafe { | ||
| let sl = slice::from_raw_parts(self.xs.ptr(), self.len.to_usize()); | ||
| let sl = slice::from_raw_parts(self.as_ptr(), self.len()); | ||
| str::from_utf8_unchecked(sl) | ||
@@ -405,4 +412,3 @@ } | ||
| impl<A> DerefMut for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> DerefMut for ArrayString<CAP> | ||
| { | ||
@@ -412,3 +418,4 @@ #[inline] | ||
| unsafe { | ||
| let sl = slice::from_raw_parts_mut(self.xs.ptr_mut(), self.len.to_usize()); | ||
| let len = self.len(); | ||
| let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len); | ||
| str::from_utf8_unchecked_mut(sl) | ||
@@ -419,4 +426,3 @@ } | ||
| impl<A> PartialEq for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialEq for ArrayString<CAP> | ||
| { | ||
@@ -428,4 +434,3 @@ fn eq(&self, rhs: &Self) -> bool { | ||
| impl<A> PartialEq<str> for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialEq<str> for ArrayString<CAP> | ||
| { | ||
@@ -437,6 +442,5 @@ fn eq(&self, rhs: &str) -> bool { | ||
| impl<A> PartialEq<ArrayString<A>> for str | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialEq<ArrayString<CAP>> for str | ||
| { | ||
| fn eq(&self, rhs: &ArrayString<A>) -> bool { | ||
| fn eq(&self, rhs: &ArrayString<CAP>) -> bool { | ||
| self == &**rhs | ||
@@ -446,8 +450,6 @@ } | ||
| impl<A> Eq for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Eq for ArrayString<CAP> | ||
| { } | ||
| impl<A> Hash for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Hash for ArrayString<CAP> | ||
| { | ||
@@ -459,4 +461,3 @@ fn hash<H: Hasher>(&self, h: &mut H) { | ||
| impl<A> Borrow<str> for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Borrow<str> for ArrayString<CAP> | ||
| { | ||
@@ -466,4 +467,3 @@ fn borrow(&self) -> &str { self } | ||
| impl<A> AsRef<str> for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> AsRef<str> for ArrayString<CAP> | ||
| { | ||
@@ -473,4 +473,3 @@ fn as_ref(&self) -> &str { self } | ||
| impl<A> fmt::Debug for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> fmt::Debug for ArrayString<CAP> | ||
| { | ||
@@ -480,4 +479,3 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } | ||
| impl<A> fmt::Display for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> fmt::Display for ArrayString<CAP> | ||
| { | ||
@@ -488,4 +486,3 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } | ||
| /// `Write` appends written data to the end of the string. | ||
| impl<A> fmt::Write for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> fmt::Write for ArrayString<CAP> | ||
| { | ||
@@ -501,6 +498,5 @@ fn write_char(&mut self, c: char) -> fmt::Result { | ||
| impl<A> Clone for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Clone for ArrayString<CAP> | ||
| { | ||
| fn clone(&self) -> ArrayString<A> { | ||
| fn clone(&self) -> ArrayString<CAP> { | ||
| *self | ||
@@ -515,4 +511,3 @@ } | ||
| impl<A> PartialOrd for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialOrd for ArrayString<CAP> | ||
| { | ||
@@ -528,4 +523,3 @@ fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> { | ||
| impl<A> PartialOrd<str> for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialOrd<str> for ArrayString<CAP> | ||
| { | ||
@@ -541,16 +535,14 @@ fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> { | ||
| impl<A> PartialOrd<ArrayString<A>> for str | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> PartialOrd<ArrayString<CAP>> for str | ||
| { | ||
| fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> { | ||
| fn partial_cmp(&self, rhs: &ArrayString<CAP>) -> Option<cmp::Ordering> { | ||
| self.partial_cmp(&**rhs) | ||
| } | ||
| fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs } | ||
| fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs } | ||
| fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs } | ||
| fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs } | ||
| fn lt(&self, rhs: &ArrayString<CAP>) -> bool { self < &**rhs } | ||
| fn le(&self, rhs: &ArrayString<CAP>) -> bool { self <= &**rhs } | ||
| fn gt(&self, rhs: &ArrayString<CAP>) -> bool { self > &**rhs } | ||
| fn ge(&self, rhs: &ArrayString<CAP>) -> bool { self >= &**rhs } | ||
| } | ||
| impl<A> Ord for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Ord for ArrayString<CAP> | ||
| { | ||
@@ -562,4 +554,3 @@ fn cmp(&self, rhs: &Self) -> cmp::Ordering { | ||
| impl<A> FromStr for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> FromStr for ArrayString<CAP> | ||
| { | ||
@@ -575,4 +566,3 @@ type Err = CapacityError; | ||
| /// Requires crate feature `"serde"` | ||
| impl<A> Serialize for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<const CAP: usize> Serialize for ArrayString<CAP> | ||
| { | ||
@@ -588,4 +578,3 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
| /// Requires crate feature `"serde"` | ||
| impl<'de, A> Deserialize<'de> for ArrayString<A> | ||
| where A: Array<Item=u8> + Copy | ||
| impl<'de, const CAP: usize> Deserialize<'de> for ArrayString<CAP> | ||
| { | ||
@@ -598,9 +587,9 @@ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
| struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>); | ||
| struct ArrayStringVisitor<const CAP: usize>(PhantomData<[u8; CAP]>); | ||
| impl<'de, A: Copy + Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> { | ||
| type Value = ArrayString<A>; | ||
| impl<'de, const CAP: usize> Visitor<'de> for ArrayStringVisitor<CAP> { | ||
| type Value = ArrayString<CAP>; | ||
| fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
| write!(formatter, "a string no more than {} bytes long", A::CAPACITY) | ||
| write!(formatter, "a string no more than {} bytes long", CAP) | ||
| } | ||
@@ -623,4 +612,27 @@ | ||
| deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData)) | ||
| deserializer.deserialize_str(ArrayStringVisitor(PhantomData)) | ||
| } | ||
| } | ||
| impl<'a, const CAP: usize> TryFrom<&'a str> for ArrayString<CAP> | ||
| { | ||
| type Error = CapacityError<&'a str>; | ||
| fn try_from(f: &'a str) -> Result<Self, Self::Error> { | ||
| let mut v = Self::new(); | ||
| v.try_push_str(f)?; | ||
| Ok(v) | ||
| } | ||
| } | ||
| impl<'a, const CAP: usize> TryFrom<fmt::Arguments<'a>> for ArrayString<CAP> | ||
| { | ||
| type Error = CapacityError<fmt::Error>; | ||
| fn try_from(f: fmt::Arguments<'a>) -> Result<Self, Self::Error> { | ||
| use fmt::Write; | ||
| let mut v = Self::new(); | ||
| v.write_fmt(f).map_err(|e| CapacityError::new(e))?; | ||
| Ok(v) | ||
| } | ||
| } |
+17
-1175
@@ -1,2 +0,2 @@ | ||
| //! **arrayvec** provides the types `ArrayVec` and `ArrayString`: | ||
| //! **arrayvec** provides the types [`ArrayVec`] and [`ArrayString`]: | ||
| //! array-backed vector and string types, which store their contents inline. | ||
@@ -13,5 +13,2 @@ //! | ||
| //! - Enable serialization for ArrayVec and ArrayString using serde 1.x | ||
| //! - `array-sizes-33-128`, `array-sizes-129-255` | ||
| //! - Optional | ||
| //! - Enable more array sizes (see [Array] for more information) | ||
| //! | ||
@@ -26,7 +23,7 @@ //! - `unstable-const-fn` | ||
| //! | ||
| //! This version of arrayvec requires Rust 1.36 or later. | ||
| //! This version of arrayvec requires Rust 1.51 or later. | ||
| //! | ||
| #![doc(html_root_url="https://docs.rs/arrayvec/0.4/")] | ||
| #![doc(html_root_url="https://docs.rs/arrayvec/0.6/")] | ||
| #![cfg_attr(not(feature="std"), no_std)] | ||
| #![cfg_attr(feature="unstable-const-fn", feature(const_fn))] | ||
| #![cfg_attr(feature="unstable-const-fn", feature(const_fn, const_maybe_uninit_assume_init, const_panic))] | ||
@@ -39,25 +36,16 @@ #[cfg(feature="serde")] | ||
| use std::cmp; | ||
| use std::iter; | ||
| use std::mem; | ||
| use std::ops::{Bound, Deref, DerefMut, RangeBounds}; | ||
| use std::ptr; | ||
| use std::slice; | ||
| pub(crate) type LenUint = u32; | ||
| // extra traits | ||
| use std::borrow::{Borrow, BorrowMut}; | ||
| use std::hash::{Hash, Hasher}; | ||
| use std::fmt; | ||
| macro_rules! assert_capacity_limit { | ||
| ($cap:expr) => { | ||
| if std::mem::size_of::<usize>() > std::mem::size_of::<LenUint>() { | ||
| if CAP > LenUint::MAX as usize { | ||
| panic!("ArrayVec: largest supported capacity is u32::MAX") | ||
| } | ||
| } | ||
| } | ||
| } | ||
| #[cfg(feature="std")] | ||
| use std::io; | ||
| mod maybe_uninit; | ||
| use crate::maybe_uninit::MaybeUninit; | ||
| #[cfg(feature="serde")] | ||
| use serde::{Serialize, Deserialize, Serializer, Deserializer}; | ||
| mod array; | ||
| mod arrayvec_impl; | ||
| mod arrayvec; | ||
| mod array_string; | ||
@@ -67,1151 +55,5 @@ mod char; | ||
| pub use crate::array::Array; | ||
| use crate::array::Index; | ||
| pub use crate::array_string::ArrayString; | ||
| pub use crate::errors::CapacityError; | ||
| /// 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<A: Array> { | ||
| xs: MaybeUninit<A>, | ||
| len: A::Index, | ||
| } | ||
| impl<A: Array> Drop for ArrayVec<A> { | ||
| fn drop(&mut self) { | ||
| self.clear(); | ||
| // MaybeUninit inhibits array's drop | ||
| } | ||
| } | ||
| macro_rules! panic_oob { | ||
| ($method_name:expr, $index:expr, $len:expr) => { | ||
| panic!(concat!("ArrayVec::", $method_name, ": index {} is out of bounds in vector of length {}"), | ||
| $index, $len) | ||
| } | ||
| } | ||
| impl<A: Array> ArrayVec<A> { | ||
| /// 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); | ||
| /// ``` | ||
| #[cfg(not(feature="unstable-const-fn"))] | ||
| pub fn new() -> ArrayVec<A> { | ||
| unsafe { | ||
| ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::ZERO } | ||
| } | ||
| } | ||
| #[cfg(feature="unstable-const-fn")] | ||
| pub const fn new() -> ArrayVec<A> { | ||
| unsafe { | ||
| ArrayVec { xs: MaybeUninit::uninitialized(), 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() } | ||
| /// Returns whether the `ArrayVec` is empty. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1]); | ||
| /// array.pop(); | ||
| /// assert_eq!(array.is_empty(), true); | ||
| /// ``` | ||
| #[inline] | ||
| pub fn is_empty(&self) -> bool { self.len() == 0 } | ||
| /// Return the capacity of the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let array = ArrayVec::from([1, 2, 3]); | ||
| /// assert_eq!(array.capacity(), 3); | ||
| /// ``` | ||
| #[inline(always)] | ||
| pub fn capacity(&self) -> usize { A::CAPACITY } | ||
| /// Return if the `ArrayVec` is completely filled. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 1]>::new(); | ||
| /// assert!(!array.is_full()); | ||
| /// array.push(1); | ||
| /// assert!(array.is_full()); | ||
| /// ``` | ||
| pub fn is_full(&self) -> bool { self.len() == self.capacity() } | ||
| /// Returns the capacity left in the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// array.pop(); | ||
| /// assert_eq!(array.remaining_capacity(), 1); | ||
| /// ``` | ||
| pub fn remaining_capacity(&self) -> usize { | ||
| self.capacity() - self.len() | ||
| } | ||
| /// Push `element` to the end of the vector. | ||
| /// | ||
| /// ***Panics*** if the vector is already full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// array.push(1); | ||
| /// array.push(2); | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// ``` | ||
| pub fn push(&mut self, element: A::Item) { | ||
| self.try_push(element).unwrap() | ||
| } | ||
| /// Push `element` to the end of the vector. | ||
| /// | ||
| /// Return `Ok` if the push succeeds, or return an error if the vector | ||
| /// is already full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// let push1 = array.try_push(1); | ||
| /// let push2 = array.try_push(2); | ||
| /// | ||
| /// assert!(push1.is_ok()); | ||
| /// assert!(push2.is_ok()); | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// | ||
| /// let overflow = array.try_push(3); | ||
| /// | ||
| /// assert!(overflow.is_err()); | ||
| /// ``` | ||
| pub fn try_push(&mut self, element: A::Item) -> Result<(), CapacityError<A::Item>> { | ||
| if self.len() < A::CAPACITY { | ||
| unsafe { | ||
| self.push_unchecked(element); | ||
| } | ||
| Ok(()) | ||
| } else { | ||
| Err(CapacityError::new(element)) | ||
| } | ||
| } | ||
| /// Push `element` to the end of the vector without checking the capacity. | ||
| /// | ||
| /// It is up to the caller to ensure the capacity of the vector is | ||
| /// sufficiently large. | ||
| /// | ||
| /// This method uses *debug assertions* to check that the arrayvec is not full. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// if array.len() + 2 <= array.capacity() { | ||
| /// unsafe { | ||
| /// array.push_unchecked(1); | ||
| /// array.push_unchecked(2); | ||
| /// } | ||
| /// } | ||
| /// | ||
| /// assert_eq!(&array[..], &[1, 2]); | ||
| /// ``` | ||
| pub unsafe fn push_unchecked(&mut self, element: A::Item) { | ||
| let len = self.len(); | ||
| debug_assert!(len < A::CAPACITY); | ||
| ptr::write(self.get_unchecked_ptr(len), element); | ||
| self.set_len(len + 1); | ||
| } | ||
| /// Get pointer to where element at `index` would be | ||
| unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut A::Item { | ||
| self.xs.ptr_mut().add(index) | ||
| } | ||
| /// Insert `element` at position `index`. | ||
| /// | ||
| /// Shift up all elements after `index`. | ||
| /// | ||
| /// It is an error if the index is greater than the length or if the | ||
| /// arrayvec is full. | ||
| /// | ||
| /// ***Panics*** if the array is full or the `index` is out of bounds. See | ||
| /// `try_insert` for fallible version. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// array.insert(0, "x"); | ||
| /// array.insert(0, "y"); | ||
| /// assert_eq!(&array[..], &["y", "x"]); | ||
| /// | ||
| /// ``` | ||
| pub fn insert(&mut self, index: usize, element: A::Item) { | ||
| self.try_insert(index, element).unwrap() | ||
| } | ||
| /// Insert `element` at position `index`. | ||
| /// | ||
| /// Shift up all elements after `index`; the `index` must be less than | ||
| /// or equal to the length. | ||
| /// | ||
| /// Returns an error if vector is already at full capacity. | ||
| /// | ||
| /// ***Panics*** `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::<[_; 2]>::new(); | ||
| /// | ||
| /// assert!(array.try_insert(0, "x").is_ok()); | ||
| /// assert!(array.try_insert(0, "y").is_ok()); | ||
| /// assert!(array.try_insert(0, "z").is_err()); | ||
| /// assert_eq!(&array[..], &["y", "x"]); | ||
| /// | ||
| /// ``` | ||
| pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), CapacityError<A::Item>> { | ||
| if index > self.len() { | ||
| panic_oob!("try_insert", index, self.len()) | ||
| } | ||
| if self.len() == self.capacity() { | ||
| return Err(CapacityError::new(element)); | ||
| } | ||
| let len = self.len(); | ||
| // follows is just like Vec<T> | ||
| unsafe { // infallible | ||
| // The spot to put the new value | ||
| { | ||
| let p: *mut _ = self.get_unchecked_ptr(index); | ||
| // 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); | ||
| } | ||
| Ok(()) | ||
| } | ||
| /// Remove the last element in the vector and return it. | ||
| /// | ||
| /// 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<A::Item> { | ||
| if self.len() == 0 { | ||
| return None; | ||
| } | ||
| unsafe { | ||
| let new_len = self.len() - 1; | ||
| self.set_len(new_len); | ||
| Some(ptr::read(self.get_unchecked_ptr(new_len))) | ||
| } | ||
| } | ||
| /// Remove the element at `index` and swap the last element into its place. | ||
| /// | ||
| /// This operation is O(1). | ||
| /// | ||
| /// Return the *element* if the index is in bounds, else panic. | ||
| /// | ||
| /// ***Panics*** if the `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// assert_eq!(array.swap_remove(0), 1); | ||
| /// assert_eq!(&array[..], &[3, 2]); | ||
| /// | ||
| /// assert_eq!(array.swap_remove(1), 2); | ||
| /// assert_eq!(&array[..], &[3]); | ||
| /// ``` | ||
| pub fn swap_remove(&mut self, index: usize) -> A::Item { | ||
| self.swap_pop(index) | ||
| .unwrap_or_else(|| { | ||
| panic_oob!("swap_remove", index, self.len()) | ||
| }) | ||
| } | ||
| /// Remove the element at `index` and swap the last element into its place. | ||
| /// | ||
| /// This is a checked version of `.swap_remove`. | ||
| /// 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_pop(0), Some(1)); | ||
| /// assert_eq!(&array[..], &[3, 2]); | ||
| /// | ||
| /// assert_eq!(array.swap_pop(10), None); | ||
| /// ``` | ||
| pub fn swap_pop(&mut self, index: usize) -> Option<A::Item> { | ||
| 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. | ||
| /// | ||
| /// The `index` must be strictly less than the length of the vector. | ||
| /// | ||
| /// ***Panics*** if the `index` is out of bounds. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// let removed_elt = array.remove(0); | ||
| /// assert_eq!(removed_elt, 1); | ||
| /// assert_eq!(&array[..], &[2, 3]); | ||
| /// ``` | ||
| pub fn remove(&mut self, index: usize) -> A::Item { | ||
| self.pop_at(index) | ||
| .unwrap_or_else(|| { | ||
| panic_oob!("remove", index, self.len()) | ||
| }) | ||
| } | ||
| /// Remove the element at `index` and shift down the following elements. | ||
| /// | ||
| /// This is a checked version of `.remove(index)`. Returns `None` if there | ||
| /// is no element at `index`. Otherwise, return the element inside `Some`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3]); | ||
| /// | ||
| /// assert!(array.pop_at(0).is_some()); | ||
| /// assert_eq!(&array[..], &[2, 3]); | ||
| /// | ||
| /// assert!(array.pop_at(2).is_none()); | ||
| /// assert!(array.pop_at(10).is_none()); | ||
| /// ``` | ||
| pub fn pop_at(&mut self, index: usize) -> Option<A::Item> { | ||
| if index >= self.len() { | ||
| None | ||
| } else { | ||
| self.drain(index..index + 1).next() | ||
| } | ||
| } | ||
| /// Shortens the vector, keeping the first `len` elements and dropping | ||
| /// the rest. | ||
| /// | ||
| /// If `len` is greater than the vector’s current length this has no | ||
| /// effect. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3, 4, 5]); | ||
| /// array.truncate(3); | ||
| /// assert_eq!(&array[..], &[1, 2, 3]); | ||
| /// array.truncate(4); | ||
| /// assert_eq!(&array[..], &[1, 2, 3]); | ||
| /// ``` | ||
| pub fn truncate(&mut self, new_len: usize) { | ||
| unsafe { | ||
| if new_len < self.len() { | ||
| let tail: *mut [_] = &mut self[new_len..]; | ||
| self.len = Index::from(new_len); | ||
| ptr::drop_in_place(tail); | ||
| } | ||
| } | ||
| } | ||
| /// Remove all elements in the vector. | ||
| pub fn clear(&mut self) { | ||
| self.truncate(0) | ||
| } | ||
| /// Retains only the elements specified by the predicate. | ||
| /// | ||
| /// In other words, remove all elements `e` such that `f(&mut e)` returns false. | ||
| /// This method operates in place and preserves the order of the retained | ||
| /// elements. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut array = ArrayVec::from([1, 2, 3, 4]); | ||
| /// array.retain(|x| *x & 1 != 0 ); | ||
| /// assert_eq!(&array[..], &[1, 3]); | ||
| /// ``` | ||
| pub fn retain<F>(&mut self, mut f: F) | ||
| where F: FnMut(&mut A::Item) -> bool | ||
| { | ||
| let len = self.len(); | ||
| let mut del = 0; | ||
| { | ||
| let v = &mut **self; | ||
| for i in 0..len { | ||
| if !f(&mut v[i]) { | ||
| del += 1; | ||
| } else if del > 0 { | ||
| v.swap(i - del, i); | ||
| } | ||
| } | ||
| } | ||
| if del > 0 { | ||
| self.drain(len - del..); | ||
| } | ||
| } | ||
| /// Set the vector’s length without dropping or moving out elements | ||
| /// | ||
| /// This method is `unsafe` because it changes the notion of the | ||
| /// number of “valid” elements in the vector. Use with care. | ||
| /// | ||
| /// This method uses *debug assertions* to check that `length` is | ||
| /// not greater than the capacity. | ||
| pub unsafe fn set_len(&mut self, length: usize) { | ||
| debug_assert!(length <= self.capacity()); | ||
| self.len = Index::from(length); | ||
| } | ||
| /// Copy and appends all elements in a slice to the `ArrayVec`. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// | ||
| /// let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); | ||
| /// vec.push(1); | ||
| /// vec.try_extend_from_slice(&[2, 3]).unwrap(); | ||
| /// assert_eq!(&vec[..], &[1, 2, 3]); | ||
| /// ``` | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// This method will return an error if the capacity left (see | ||
| /// [`remaining_capacity`]) is smaller then the length of the provided | ||
| /// slice. | ||
| /// | ||
| /// [`remaining_capacity`]: #method.remaining_capacity | ||
| pub fn try_extend_from_slice(&mut self, other: &[A::Item]) -> Result<(), CapacityError> | ||
| where A::Item: Copy, | ||
| { | ||
| if self.remaining_capacity() < other.len() { | ||
| return Err(CapacityError::new(())); | ||
| } | ||
| let self_len = self.len(); | ||
| let other_len = other.len(); | ||
| unsafe { | ||
| let dst = self.xs.ptr_mut().add(self_len); | ||
| ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len); | ||
| self.set_len(self_len + other_len); | ||
| } | ||
| Ok(()) | ||
| } | ||
| /// 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: ArrayVec<[_; 3]> = v.drain(0..2).collect(); | ||
| /// assert_eq!(&v[..], &[3]); | ||
| /// assert_eq!(&u[..], &[1, 2]); | ||
| /// ``` | ||
| pub fn drain<R>(&mut self, range: R) -> Drain<A> | ||
| where R: RangeBounds<usize> | ||
| { | ||
| // Memory safety | ||
| // | ||
| // When the Drain is first created, it shortens the length of | ||
| // the source vector to make sure no uninitialized 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 = match range.start_bound() { | ||
| Bound::Unbounded => 0, | ||
| Bound::Included(&i) => i, | ||
| Bound::Excluded(&i) => i.saturating_add(1), | ||
| }; | ||
| let end = match range.end_bound() { | ||
| Bound::Excluded(&j) => j, | ||
| Bound::Included(&j) => j.saturating_add(1), | ||
| Bound::Unbounded => len, | ||
| }; | ||
| self.drain_range(start, end) | ||
| } | ||
| fn drain_range(&mut self, start: usize, end: usize) -> Drain<A> | ||
| { | ||
| let len = self.len(); | ||
| // bounds check happens here (before length is changed!) | ||
| let range_slice: *const _ = &self[start..end]; | ||
| // Calling `set_len` creates a fresh and thus unique mutable references, making all | ||
| // older aliases we created invalid. So we cannot call that function. | ||
| self.len = Index::from(start); | ||
| unsafe { | ||
| 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. | ||
| pub fn into_inner(self) -> Result<A, Self> { | ||
| if self.len() < self.capacity() { | ||
| Err(self) | ||
| } else { | ||
| unsafe { | ||
| let array = ptr::read(self.xs.ptr() as *const A); | ||
| mem::forget(self); | ||
| Ok(array) | ||
| } | ||
| } | ||
| } | ||
| /// Dispose of `self` (same as drop) | ||
| #[deprecated="Use std::mem::drop instead, if at all needed."] | ||
| pub fn dispose(mut self) { | ||
| self.clear(); | ||
| mem::forget(self); | ||
| } | ||
| /// Return a slice containing all elements of the vector. | ||
| pub fn as_slice(&self) -> &[A::Item] { | ||
| self | ||
| } | ||
| /// Return a mutable slice containing all elements of the vector. | ||
| pub fn as_mut_slice(&mut self) -> &mut [A::Item] { | ||
| self | ||
| } | ||
| /// Return a raw pointer to the vector's buffer. | ||
| pub fn as_ptr(&self) -> *const A::Item { | ||
| self.xs.ptr() | ||
| } | ||
| /// Return a raw mutable pointer to the vector's buffer. | ||
| pub fn as_mut_ptr(&mut self) -> *mut A::Item { | ||
| self.xs.ptr_mut() | ||
| } | ||
| } | ||
| impl<A: Array> Deref for ArrayVec<A> { | ||
| type Target = [A::Item]; | ||
| #[inline] | ||
| fn deref(&self) -> &[A::Item] { | ||
| unsafe { | ||
| slice::from_raw_parts(self.xs.ptr(), self.len()) | ||
| } | ||
| } | ||
| } | ||
| impl<A: Array> DerefMut for ArrayVec<A> { | ||
| #[inline] | ||
| fn deref_mut(&mut self) -> &mut [A::Item] { | ||
| let len = self.len(); | ||
| unsafe { | ||
| slice::from_raw_parts_mut(self.xs.ptr_mut(), 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<A: Array> From<A> for ArrayVec<A> { | ||
| fn from(array: A) -> Self { | ||
| ArrayVec { xs: MaybeUninit::from(array), len: Index::from(A::CAPACITY) } | ||
| } | ||
| } | ||
| /// Try to create an `ArrayVec` from a slice. This will return an error if the slice was too big to | ||
| /// fit. | ||
| /// | ||
| /// ``` | ||
| /// use arrayvec::ArrayVec; | ||
| /// use std::convert::TryInto as _; | ||
| /// | ||
| /// let array: ArrayVec<[_; 4]> = (&[1, 2, 3] as &[_]).try_into().unwrap(); | ||
| /// assert_eq!(array.len(), 3); | ||
| /// assert_eq!(array.capacity(), 4); | ||
| /// ``` | ||
| impl<A: Array> std::convert::TryFrom<&[A::Item]> for ArrayVec<A> | ||
| where | ||
| A::Item: Clone, | ||
| { | ||
| type Error = CapacityError; | ||
| fn try_from(slice: &[A::Item]) -> Result<Self, Self::Error> { | ||
| if A::CAPACITY < slice.len() { | ||
| Err(CapacityError::new(())) | ||
| } else { | ||
| let mut array = Self::new(); | ||
| array.extend(slice.iter().cloned()); | ||
| Ok(array) | ||
| } | ||
| } | ||
| } | ||
| /// 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<A> { | ||
| 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<A> { | ||
| 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<A: Array> IntoIterator for ArrayVec<A> { | ||
| type Item = A::Item; | ||
| type IntoIter = IntoIter<A>; | ||
| fn into_iter(self) -> IntoIter<A> { | ||
| IntoIter { index: Index::from(0), v: self, } | ||
| } | ||
| } | ||
| /// By-value iterator for `ArrayVec`. | ||
| pub struct IntoIter<A: Array> { | ||
| index: A::Index, | ||
| v: ArrayVec<A>, | ||
| } | ||
| impl<A: Array> Iterator for IntoIter<A> { | ||
| type Item = A::Item; | ||
| fn next(&mut self) -> Option<A::Item> { | ||
| 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_ptr(index))) | ||
| } | ||
| } | ||
| } | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| let len = self.v.len() - self.index.to_usize(); | ||
| (len, Some(len)) | ||
| } | ||
| } | ||
| impl<A: Array> DoubleEndedIterator for IntoIter<A> { | ||
| fn next_back(&mut self) -> Option<A::Item> { | ||
| 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_ptr(new_len))) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| impl<A: Array> ExactSizeIterator for IntoIter<A> { } | ||
| impl<A: Array> Drop for IntoIter<A> { | ||
| 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_mut( | ||
| self.v.get_unchecked_ptr(index), | ||
| len - index); | ||
| ptr::drop_in_place(elements); | ||
| } | ||
| } | ||
| } | ||
| impl<A: Array> Clone for IntoIter<A> | ||
| where | ||
| A::Item: Clone, | ||
| { | ||
| fn clone(&self) -> IntoIter<A> { | ||
| self.v[self.index.to_usize()..] | ||
| .iter() | ||
| .cloned() | ||
| .collect::<ArrayVec<A>>() | ||
| .into_iter() | ||
| } | ||
| } | ||
| impl<A: Array> fmt::Debug for IntoIter<A> | ||
| where | ||
| A::Item: fmt::Debug, | ||
| { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| f.debug_list() | ||
| .entries(&self.v[self.index.to_usize()..]) | ||
| .finish() | ||
| } | ||
| } | ||
| /// 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<A>, | ||
| } | ||
| 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; | ||
| fn next(&mut self) -> Option<Self::Item> { | ||
| self.iter.next().map(|elt| | ||
| unsafe { | ||
| ptr::read(elt as *const _) | ||
| } | ||
| ) | ||
| } | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| self.iter.size_hint() | ||
| } | ||
| } | ||
| impl<'a, A: Array> DoubleEndedIterator for Drain<'a, A> | ||
| where A::Item: 'a, | ||
| { | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
| 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().add(tail); | ||
| let dst = source_vec.as_mut_ptr().add(start); | ||
| ptr::copy(src, dst, self.tail_len); | ||
| source_vec.set_len(start + self.tail_len); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| struct ScopeExitGuard<T, Data, F> | ||
| where F: FnMut(&Data, &mut T) | ||
| { | ||
| value: T, | ||
| data: Data, | ||
| f: F, | ||
| } | ||
| impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F> | ||
| where F: FnMut(&Data, &mut T) | ||
| { | ||
| fn drop(&mut self) { | ||
| (self.f)(&self.data, &mut self.value) | ||
| } | ||
| } | ||
| /// 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<A: Array> Extend<A::Item> for ArrayVec<A> { | ||
| fn extend<T: IntoIterator<Item=A::Item>>(&mut self, iter: T) { | ||
| let take = self.capacity() - self.len(); | ||
| unsafe { | ||
| let len = self.len(); | ||
| let mut ptr = raw_ptr_add(self.as_mut_ptr(), len); | ||
| let end_ptr = raw_ptr_add(ptr, take); | ||
| // Keep the length in a separate variable, write it back on scope | ||
| // exit. To help the compiler with alias analysis and stuff. | ||
| // We update the length to handle panic in the iteration of the | ||
| // user's iterator, without dropping any elements on the floor. | ||
| let mut guard = ScopeExitGuard { | ||
| value: &mut self.len, | ||
| data: len, | ||
| f: move |&len, self_len| { | ||
| **self_len = Index::from(len); | ||
| } | ||
| }; | ||
| let mut iter = iter.into_iter(); | ||
| loop { | ||
| if ptr == end_ptr { break; } | ||
| if let Some(elt) = iter.next() { | ||
| raw_ptr_write(ptr, elt); | ||
| ptr = raw_ptr_add(ptr, 1); | ||
| guard.data += 1; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /// Rawptr add but uses arithmetic distance for ZST | ||
| unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T { | ||
| if mem::size_of::<T>() == 0 { | ||
| // Special case for ZST | ||
| (ptr as usize).wrapping_add(offset) as _ | ||
| } else { | ||
| ptr.add(offset) | ||
| } | ||
| } | ||
| unsafe fn raw_ptr_write<T>(ptr: *mut T, value: T) { | ||
| if mem::size_of::<T>() == 0 { | ||
| /* nothing */ | ||
| } else { | ||
| ptr::write(ptr, value) | ||
| } | ||
| } | ||
| /// 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<A: Array> iter::FromIterator<A::Item> for ArrayVec<A> { | ||
| fn from_iter<T: IntoIterator<Item=A::Item>>(iter: T) -> Self { | ||
| let mut array = ArrayVec::new(); | ||
| array.extend(iter); | ||
| array | ||
| } | ||
| } | ||
| impl<A: Array> Clone for ArrayVec<A> | ||
| where A::Item: Clone | ||
| { | ||
| fn clone(&self) -> Self { | ||
| self.iter().cloned().collect() | ||
| } | ||
| fn clone_from(&mut self, rhs: &Self) { | ||
| // recursive case for the common prefix | ||
| let prefix = cmp::min(self.len(), rhs.len()); | ||
| self[..prefix].clone_from_slice(&rhs[..prefix]); | ||
| if prefix < self.len() { | ||
| // rhs was shorter | ||
| for _ in 0..self.len() - prefix { | ||
| self.pop(); | ||
| } | ||
| } else { | ||
| let rhs_elems = rhs[self.len()..].iter().cloned(); | ||
| self.extend(rhs_elems); | ||
| } | ||
| } | ||
| } | ||
| impl<A: Array> Hash for ArrayVec<A> | ||
| where A::Item: Hash | ||
| { | ||
| fn hash<H: Hasher>(&self, state: &mut H) { | ||
| Hash::hash(&**self, state) | ||
| } | ||
| } | ||
| impl<A: Array> PartialEq for ArrayVec<A> | ||
| where A::Item: PartialEq | ||
| { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| **self == **other | ||
| } | ||
| } | ||
| impl<A: Array> PartialEq<[A::Item]> for ArrayVec<A> | ||
| where A::Item: PartialEq | ||
| { | ||
| fn eq(&self, other: &[A::Item]) -> bool { | ||
| **self == *other | ||
| } | ||
| } | ||
| impl<A: Array> Eq for ArrayVec<A> where A::Item: Eq { } | ||
| impl<A: Array> Borrow<[A::Item]> for ArrayVec<A> { | ||
| fn borrow(&self) -> &[A::Item] { self } | ||
| } | ||
| impl<A: Array> BorrowMut<[A::Item]> for ArrayVec<A> { | ||
| fn borrow_mut(&mut self) -> &mut [A::Item] { self } | ||
| } | ||
| impl<A: Array> AsRef<[A::Item]> for ArrayVec<A> { | ||
| fn as_ref(&self) -> &[A::Item] { self } | ||
| } | ||
| impl<A: Array> AsMut<[A::Item]> for ArrayVec<A> { | ||
| fn as_mut(&mut self) -> &mut [A::Item] { self } | ||
| } | ||
| impl<A: Array> fmt::Debug for ArrayVec<A> where A::Item: fmt::Debug { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } | ||
| } | ||
| impl<A: Array> Default for ArrayVec<A> { | ||
| /// Return an empty array | ||
| fn default() -> ArrayVec<A> { | ||
| ArrayVec::new() | ||
| } | ||
| } | ||
| impl<A: Array> PartialOrd for ArrayVec<A> where A::Item: PartialOrd { | ||
| fn partial_cmp(&self, other: &ArrayVec<A>) -> Option<cmp::Ordering> { | ||
| (**self).partial_cmp(other) | ||
| } | ||
| fn lt(&self, other: &Self) -> bool { | ||
| (**self).lt(other) | ||
| } | ||
| fn le(&self, other: &Self) -> bool { | ||
| (**self).le(other) | ||
| } | ||
| fn ge(&self, other: &Self) -> bool { | ||
| (**self).ge(other) | ||
| } | ||
| fn gt(&self, other: &Self) -> bool { | ||
| (**self).gt(other) | ||
| } | ||
| } | ||
| impl<A: Array> Ord for ArrayVec<A> where A::Item: Ord { | ||
| fn cmp(&self, other: &ArrayVec<A>) -> cmp::Ordering { | ||
| (**self).cmp(other) | ||
| } | ||
| } | ||
| #[cfg(feature="std")] | ||
| /// `Write` appends written data to the end of the vector. | ||
| /// | ||
| /// Requires `features="std"`. | ||
| impl<A: Array<Item=u8>> io::Write for ArrayVec<A> { | ||
| fn write(&mut self, data: &[u8]) -> io::Result<usize> { | ||
| let len = cmp::min(self.remaining_capacity(), data.len()); | ||
| let _result = self.try_extend_from_slice(&data[..len]); | ||
| debug_assert!(_result.is_ok()); | ||
| Ok(len) | ||
| } | ||
| fn flush(&mut self) -> io::Result<()> { Ok(()) } | ||
| } | ||
| #[cfg(feature="serde")] | ||
| /// Requires crate feature `"serde"` | ||
| impl<T: Serialize, A: Array<Item=T>> Serialize for ArrayVec<A> { | ||
| fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
| where S: Serializer | ||
| { | ||
| serializer.collect_seq(self) | ||
| } | ||
| } | ||
| #[cfg(feature="serde")] | ||
| /// Requires crate feature `"serde"` | ||
| impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Deserialize<'de> for ArrayVec<A> { | ||
| fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
| where D: Deserializer<'de> | ||
| { | ||
| use serde::de::{Visitor, SeqAccess, Error}; | ||
| use std::marker::PhantomData; | ||
| struct ArrayVecVisitor<'de, T: Deserialize<'de>, A: Array<Item=T>>(PhantomData<(&'de (), T, A)>); | ||
| impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Visitor<'de> for ArrayVecVisitor<'de, T, A> { | ||
| type Value = ArrayVec<A>; | ||
| fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
| write!(formatter, "an array with no more than {} items", A::CAPACITY) | ||
| } | ||
| fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error> | ||
| where SA: SeqAccess<'de>, | ||
| { | ||
| let mut values = ArrayVec::<A>::new(); | ||
| while let Some(value) = seq.next_element()? { | ||
| if let Err(_) = values.try_push(value) { | ||
| return Err(SA::Error::invalid_length(A::CAPACITY + 1, &self)); | ||
| } | ||
| } | ||
| Ok(values) | ||
| } | ||
| } | ||
| deserializer.deserialize_seq(ArrayVecVisitor::<T, A>(PhantomData)) | ||
| } | ||
| } | ||
| pub use crate::arrayvec::{ArrayVec, IntoIter, Drain}; |
+6
-6
@@ -12,3 +12,3 @@ #![cfg(feature = "serde")] | ||
| fn test_ser_de_empty() { | ||
| let vec = ArrayVec::<[u32; 0]>::new(); | ||
| let vec = ArrayVec::<u32, 0>::new(); | ||
@@ -24,3 +24,3 @@ assert_tokens(&vec, &[ | ||
| fn test_ser_de() { | ||
| let mut vec = ArrayVec::<[u32; 3]>::new(); | ||
| let mut vec = ArrayVec::<u32, 3>::new(); | ||
| vec.push(20); | ||
@@ -41,3 +41,3 @@ vec.push(55); | ||
| fn test_de_too_large() { | ||
| assert_de_tokens_error::<ArrayVec<[u32; 2]>>(&[ | ||
| assert_de_tokens_error::<ArrayVec<u32, 2>>(&[ | ||
| Token::Seq { len: Some(3) }, | ||
@@ -58,3 +58,3 @@ Token::U32(13), | ||
| fn test_ser_de_empty() { | ||
| let string = ArrayString::<[u8; 0]>::new(); | ||
| let string = ArrayString::<0>::new(); | ||
@@ -69,3 +69,3 @@ assert_tokens(&string, &[ | ||
| fn test_ser_de() { | ||
| let string = ArrayString::<[u8; 9]>::from("1234 abcd") | ||
| let string = ArrayString::<9>::from("1234 abcd") | ||
| .expect("expected exact specified capacity to be enough"); | ||
@@ -80,3 +80,3 @@ | ||
| fn test_de_too_large() { | ||
| assert_de_tokens_error::<ArrayString<[u8; 2]>>(&[ | ||
| assert_de_tokens_error::<ArrayString<2>>(&[ | ||
| Token::Str("afd") | ||
@@ -83,0 +83,0 @@ ], "invalid length 3, expected a string no more than 2 bytes long"); |
+101
-60
@@ -16,3 +16,3 @@ extern crate arrayvec; | ||
| let mut vec: ArrayVec<[Vec<i32>; 3]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<Vec<i32>, 3> = ArrayVec::new(); | ||
@@ -33,3 +33,3 @@ vec.push(vec![1, 2, 3, 4]); | ||
| fn test_capacity_left() { | ||
| let mut vec: ArrayVec<[usize; 4]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<usize, 4> = ArrayVec::new(); | ||
| assert_eq!(vec.remaining_capacity(), 4); | ||
@@ -48,3 +48,3 @@ vec.push(1); | ||
| fn test_extend_from_slice() { | ||
| let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<usize, 10> = ArrayVec::new(); | ||
@@ -60,3 +60,3 @@ vec.try_extend_from_slice(&[1, 2, 3]).unwrap(); | ||
| fn test_extend_from_slice_error() { | ||
| let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<usize, 10> = ArrayVec::new(); | ||
@@ -67,3 +67,3 @@ vec.try_extend_from_slice(&[1, 2, 3]).unwrap(); | ||
| let mut vec: ArrayVec<[usize; 0]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<usize, 0> = ArrayVec::new(); | ||
| let res = vec.try_extend_from_slice(&[0; 1]); | ||
@@ -78,3 +78,3 @@ assert_matches!(res, Err(_)); | ||
| let res: Result<ArrayVec<[_; 2]>, _> = (&[1, 2, 3] as &[_]).try_into(); | ||
| let res: Result<ArrayVec<_, 2>, _> = (&[1, 2, 3] as &[_]).try_into(); | ||
| assert_matches!(res, Err(_)); | ||
@@ -86,3 +86,3 @@ } | ||
| const N: usize = 4096; | ||
| let mut vec: ArrayVec<[_; N]> = ArrayVec::new(); | ||
| let mut vec: ArrayVec<_, N> = ArrayVec::new(); | ||
| for _ in 0..N { | ||
@@ -123,3 +123,3 @@ assert!(vec.try_push(1u8).is_ok()); | ||
| { | ||
| let mut array = ArrayVec::<[Bump; 128]>::new(); | ||
| let mut array = ArrayVec::<Bump, 128>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -134,3 +134,3 @@ array.push(Bump(flag)); | ||
| { | ||
| let mut array = ArrayVec::<[_; 3]>::new(); | ||
| let mut array = ArrayVec::<_, 3>::new(); | ||
| array.push(vec![Bump(flag)]); | ||
@@ -154,3 +154,3 @@ array.push(vec![Bump(flag), Bump(flag)]); | ||
| { | ||
| let mut array = ArrayVec::<[_; 3]>::new(); | ||
| let mut array = ArrayVec::<_, 3>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -169,3 +169,3 @@ array.push(Bump(flag)); | ||
| { | ||
| let mut array = ArrayVec::<[_; 3]>::new(); | ||
| let mut array = ArrayVec::<_, 3>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -224,3 +224,3 @@ array.push(Bump(flag)); | ||
| { | ||
| let mut array = ArrayVec::<[Bump; 128]>::new(); | ||
| let mut array = ArrayVec::<Bump, 128>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -241,3 +241,3 @@ array.push(Bump(flag)); | ||
| { | ||
| let mut array = ArrayVec::<[Bump; 16]>::new(); | ||
| let mut array = ArrayVec::<Bump, 16>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -267,10 +267,10 @@ array.push(Bump(flag)); | ||
| let mut array: ArrayVec<[_; 5]> = range.by_ref().collect(); | ||
| let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); | ||
| assert_eq!(&array[..], &[0, 1, 2, 3, 4]); | ||
| assert_eq!(range.next(), Some(5)); | ||
| array.extend(range.by_ref()); | ||
| array.extend(range.by_ref().take(0)); | ||
| assert_eq!(range.next(), Some(6)); | ||
| let mut array: ArrayVec<[_; 10]> = (0..3).collect(); | ||
| let mut array: ArrayVec<_, 10> = (0..3).collect(); | ||
| assert_eq!(&array[..], &[0, 1, 2]); | ||
@@ -281,5 +281,24 @@ array.extend(3..5); | ||
| #[should_panic] | ||
| #[test] | ||
| fn test_extend_capacity_panic_1() { | ||
| let mut range = 0..10; | ||
| let _: ArrayVec<_, 5> = range.by_ref().collect(); | ||
| } | ||
| #[should_panic] | ||
| #[test] | ||
| fn test_extend_capacity_panic_2() { | ||
| let mut range = 0..10; | ||
| let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect(); | ||
| assert_eq!(&array[..], &[0, 1, 2, 3, 4]); | ||
| assert_eq!(range.next(), Some(5)); | ||
| array.extend(range.by_ref().take(1)); | ||
| } | ||
| #[test] | ||
| fn test_is_send_sync() { | ||
| let data = ArrayVec::<[Vec<i32>; 5]>::new(); | ||
| let data = ArrayVec::<Vec<i32>, 5>::new(); | ||
| &data as &dyn Send; | ||
@@ -291,17 +310,16 @@ &data as &dyn Sync; | ||
| fn test_compact_size() { | ||
| // Future rust will kill these drop flags! | ||
| // 4 elements size + 1 len + 1 enum tag + [1 drop flag] | ||
| type ByteArray = ArrayVec<[u8; 4]>; | ||
| // 4 bytes + padding + length | ||
| type ByteArray = ArrayVec<u8, 4>; | ||
| println!("{}", mem::size_of::<ByteArray>()); | ||
| assert!(mem::size_of::<ByteArray>() <= 8); | ||
| assert!(mem::size_of::<ByteArray>() <= 2 * mem::size_of::<u32>()); | ||
| // 1 enum tag + 1 drop flag | ||
| type EmptyArray = ArrayVec<[u8; 0]>; | ||
| // just length | ||
| type EmptyArray = ArrayVec<u8, 0>; | ||
| println!("{}", mem::size_of::<EmptyArray>()); | ||
| assert!(mem::size_of::<EmptyArray>() <= 2); | ||
| assert!(mem::size_of::<EmptyArray>() <= mem::size_of::<u32>()); | ||
| // 12 element size + 1 enum tag + 3 padding + 1 len + 1 drop flag + 2 padding | ||
| type QuadArray = ArrayVec<[u32; 3]>; | ||
| // 3 elements + padding + length | ||
| type QuadArray = ArrayVec<u32, 3>; | ||
| println!("{}", mem::size_of::<QuadArray>()); | ||
| assert!(mem::size_of::<QuadArray>() <= 24); | ||
| assert!(mem::size_of::<QuadArray>() <= 4 * 4 + mem::size_of::<u32>()); | ||
| } | ||
@@ -311,3 +329,3 @@ | ||
| fn test_still_works_with_option_arrayvec() { | ||
| type RefArray = ArrayVec<[&'static i32; 2]>; | ||
| type RefArray = ArrayVec<&'static i32, 2>; | ||
| let array = Some(RefArray::new()); | ||
@@ -325,6 +343,6 @@ assert!(array.is_some()); | ||
| v.extend(0..); | ||
| v.extend(0..8); | ||
| v.drain(1..4); | ||
| assert_eq!(&v[..], &[0, 4, 5, 6, 7]); | ||
| let u: ArrayVec<[_; 3]> = v.drain(1..4).rev().collect(); | ||
| let u: ArrayVec<_, 3> = v.drain(1..4).rev().collect(); | ||
| assert_eq!(&u[..], &[6, 5, 4]); | ||
@@ -342,6 +360,6 @@ assert_eq!(&v[..], &[0, 7]); | ||
| v.extend(0..); | ||
| v.extend(0..8); | ||
| v.drain(1..=4); | ||
| assert_eq!(&v[..], &[0, 5, 6, 7]); | ||
| let u: ArrayVec<[_; 3]> = v.drain(1..=2).rev().collect(); | ||
| let u: ArrayVec<_, 3> = v.drain(1..=2).rev().collect(); | ||
| assert_eq!(&u[..], &[6, 5]); | ||
@@ -396,3 +414,3 @@ assert_eq!(&v[..], &[0, 7]); | ||
| let mut array = ArrayVec::<[DropPanic; 1]>::new(); | ||
| let mut array = ArrayVec::<DropPanic, 1>::new(); | ||
| array.push(DropPanic); | ||
@@ -412,3 +430,3 @@ } | ||
| let mut array = ArrayVec::<[DropPanic; 1]>::new(); | ||
| let mut array = ArrayVec::<DropPanic, 1>::new(); | ||
| array.push(DropPanic); | ||
@@ -423,3 +441,3 @@ array.into_iter(); | ||
| let mut v = ArrayVec::<[_; 3]>::new(); | ||
| let mut v = ArrayVec::<_, 3>::new(); | ||
| v.insert(0, 0); | ||
@@ -453,3 +471,3 @@ v.insert(1, 1); | ||
| fn test_into_inner_2() { | ||
| let mut v = ArrayVec::<[String; 4]>::new(); | ||
| let mut v = ArrayVec::<String, 4>::new(); | ||
| v.push("a".into()); | ||
@@ -463,5 +481,5 @@ v.push("b".into()); | ||
| #[test] | ||
| fn test_into_inner_3_() { | ||
| let mut v = ArrayVec::<[i32; 4]>::new(); | ||
| v.extend(1..); | ||
| fn test_into_inner_3() { | ||
| let mut v = ArrayVec::<i32, 4>::new(); | ||
| v.extend(1..=4); | ||
| assert_eq!(v.into_inner().unwrap(), [1, 2, 3, 4]); | ||
@@ -474,3 +492,3 @@ } | ||
| use std::io::Write; | ||
| let mut v = ArrayVec::<[_; 8]>::new(); | ||
| let mut v = ArrayVec::<_, 8>::new(); | ||
| write!(&mut v, "\x01\x02\x03").unwrap(); | ||
@@ -485,3 +503,3 @@ assert_eq!(&v[..], &[1, 2, 3]); | ||
| fn array_clone_from() { | ||
| let mut v = ArrayVec::<[_; 4]>::new(); | ||
| let mut v = ArrayVec::<_, 4>::new(); | ||
| v.push(vec![1, 2]); | ||
@@ -491,7 +509,7 @@ v.push(vec![3, 4, 5]); | ||
| let reference = v.to_vec(); | ||
| let mut u = ArrayVec::<[_; 4]>::new(); | ||
| let mut u = ArrayVec::<_, 4>::new(); | ||
| u.clone_from(&v); | ||
| assert_eq!(&u, &reference[..]); | ||
| let mut t = ArrayVec::<[_; 4]>::new(); | ||
| let mut t = ArrayVec::<_, 4>::new(); | ||
| t.push(vec![97]); | ||
@@ -514,3 +532,3 @@ t.push(vec![]); | ||
| let text = "hello world"; | ||
| let mut s = ArrayString::<[_; 16]>::new(); | ||
| let mut s = ArrayString::<16>::new(); | ||
| s.try_push_str(text).unwrap(); | ||
@@ -525,3 +543,3 @@ assert_eq!(&s, text); | ||
| let mut t = ArrayString::<[_; 2]>::new(); | ||
| let mut t = ArrayString::<2>::new(); | ||
| assert!(t.try_push_str(text).is_err()); | ||
@@ -537,3 +555,3 @@ assert_eq!(&t, ""); | ||
| let t = || -> Result<(), Box<dyn Error>> { | ||
| let mut t = ArrayString::<[_; 2]>::new(); | ||
| let mut t = ArrayString::<2>::new(); | ||
| t.try_push_str(text)?; | ||
@@ -549,3 +567,3 @@ Ok(()) | ||
| // Test `from` constructor | ||
| let u = ArrayString::<[_; 11]>::from(text).unwrap(); | ||
| let u = ArrayString::<11>::from(text).unwrap(); | ||
| assert_eq!(&u, text); | ||
@@ -558,3 +576,3 @@ assert_eq!(u.len(), text.len()); | ||
| let text = "hello world"; | ||
| let u: ArrayString<[_; 11]> = text.parse().unwrap(); | ||
| let u: ArrayString<11> = text.parse().unwrap(); | ||
| assert_eq!(&u, text); | ||
@@ -575,5 +593,5 @@ assert_eq!(u.len(), text.len()); | ||
| let text = "hi"; | ||
| let mut s = ArrayString::<[_; 4]>::new(); | ||
| let mut s = ArrayString::<4>::new(); | ||
| s.push_str("abcd"); | ||
| let t = ArrayString::<[_; 4]>::from(text).unwrap(); | ||
| let t = ArrayString::<4>::from(text).unwrap(); | ||
| s.clone_from(&t); | ||
@@ -586,3 +604,3 @@ assert_eq!(&t, &s); | ||
| let text = "abcαβγ"; | ||
| let mut s = ArrayString::<[_; 8]>::new(); | ||
| let mut s = ArrayString::<8>::new(); | ||
| for c in text.chars() { | ||
@@ -602,3 +620,3 @@ if let Err(_) = s.try_push(c) { | ||
| fn test_insert_at_length() { | ||
| let mut v = ArrayVec::<[_; 8]>::new(); | ||
| let mut v = ArrayVec::<_, 8>::new(); | ||
| let result1 = v.try_insert(0, "a"); | ||
@@ -613,3 +631,3 @@ let result2 = v.try_insert(1, "b"); | ||
| fn test_insert_out_of_bounds() { | ||
| let mut v = ArrayVec::<[_; 8]>::new(); | ||
| let mut v = ArrayVec::<_, 8>::new(); | ||
| let _ = v.try_insert(1, "test"); | ||
@@ -647,3 +665,3 @@ } | ||
| { | ||
| let mut array = ArrayVec::<[_; 2]>::new(); | ||
| let mut array = ArrayVec::<_, 2>::new(); | ||
| array.push(Bump(flag)); | ||
@@ -663,3 +681,3 @@ array.insert(0, Bump(flag)); | ||
| fn test_pop_at() { | ||
| let mut v = ArrayVec::<[String; 4]>::new(); | ||
| let mut v = ArrayVec::<String, 4>::new(); | ||
| let s = String::from; | ||
@@ -687,5 +705,5 @@ v.push(s("a")); | ||
| use std::net; | ||
| let s: ArrayString<[u8; 4]> = Default::default(); | ||
| let s: ArrayString<4> = Default::default(); | ||
| // Something without `Default` implementation. | ||
| let v: ArrayVec<[net::TcpStream; 4]> = Default::default(); | ||
| let v: ArrayVec<net::TcpStream, 4> = Default::default(); | ||
| assert_eq!(s.len(), 0); | ||
@@ -715,10 +733,10 @@ assert_eq!(v.len(), 0); | ||
| let mut array: ArrayVec<[_; 5]> = range.by_ref().map(|_| Z).collect(); | ||
| let mut array: ArrayVec<_, 5> = range.by_ref().take(5).map(|_| Z).collect(); | ||
| assert_eq!(&array[..], &[Z; 5]); | ||
| assert_eq!(range.next(), Some(5)); | ||
| array.extend(range.by_ref().map(|_| Z)); | ||
| array.extend(range.by_ref().take(0).map(|_| Z)); | ||
| assert_eq!(range.next(), Some(6)); | ||
| let mut array: ArrayVec<[_; 10]> = (0..3).map(|_| Z).collect(); | ||
| let mut array: ArrayVec<_, 10> = (0..3).map(|_| Z).collect(); | ||
| assert_eq!(&array[..], &[Z; 3]); | ||
@@ -729,1 +747,24 @@ array.extend((3..5).map(|_| Z)); | ||
| } | ||
| #[test] | ||
| fn test_try_from_argument() { | ||
| use core::convert::TryFrom; | ||
| let v = ArrayString::<16>::try_from(format_args!("Hello {}", 123)).unwrap(); | ||
| assert_eq!(&v, "Hello 123"); | ||
| } | ||
| #[test] | ||
| fn allow_max_capacity_arrayvec_type() { | ||
| // this type is allowed to be used (but can't be constructed) | ||
| let _v: ArrayVec<(), {usize::MAX}>; | ||
| } | ||
| #[should_panic(expected="ArrayVec: largest supported")] | ||
| #[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. 'ArrayVec: largest supported'"); | ||
| } | ||
| // this type is allowed to be used (but can't be constructed) | ||
| let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new(); | ||
| } |
-43
| language: rust | ||
| sudo: false | ||
| env: | ||
| - FEATURES='serde' | ||
| matrix: | ||
| include: | ||
| - rust: 1.36.0 | ||
| env: | ||
| - FEATURES='array-sizes-33-128 array-sizes-129-255' | ||
| - rust: stable | ||
| - rust: stable | ||
| env: | ||
| - FEATURES='serde' | ||
| - rust: stable | ||
| env: | ||
| - FEATURES='array-sizes-33-128 array-sizes-129-255' | ||
| - rust: beta | ||
| - rust: nightly | ||
| - rust: nightly | ||
| env: | ||
| - FEATURES='serde' | ||
| - rust: nightly | ||
| env: | ||
| - FEATURES='array-sizes-33-128 array-sizes-129-255' | ||
| - rust: nightly | ||
| env: | ||
| - FEATURES='unstable-const-fn' | ||
| - name: "miri" | ||
| script: sh ci/miri.sh | ||
| branches: | ||
| only: | ||
| - master | ||
| - 0.4 | ||
| script: | ||
| - | | ||
| cargo build -v --no-default-features && | ||
| cargo build -v --features "$FEATURES" && | ||
| cargo test -v --features "$FEATURES" && | ||
| cargo test -v --release --features "$FEATURES" && | ||
| cargo bench -v --features "$FEATURES" --no-run && | ||
| cargo doc -v --features "$FEATURES" && | ||
| cargo build -v --manifest-path=nodrop/Cargo.toml && | ||
| cargo test -v --manifest-path=nodrop/Cargo.toml |
-151
| /// Trait for fixed size arrays. | ||
| /// | ||
| /// This trait is implemented for some specific array sizes, see | ||
| /// the implementor list below. At the current state of Rust we can't | ||
| /// make this fully general for every array size. | ||
| /// | ||
| /// The following crate features add more array sizes (and they are not | ||
| /// enabled by default due to their impact on compliation speed). | ||
| /// | ||
| /// - `array-sizes-33-128`: All sizes 33 to 128 are implemented | ||
| /// (a few in this range are included by default). | ||
| /// - `array-sizes-129-255`: All sizes 129 to 255 are implemented | ||
| /// (a few in this range are included by default). | ||
| /// | ||
| /// ## Safety | ||
| /// | ||
| /// This trait can *only* be implemented by fixed-size arrays or types with | ||
| /// *exactly* the representation of a fixed size array (of the right element | ||
| /// type and capacity). | ||
| /// | ||
| /// Normally this trait is an implementation detail of arrayvec and doesn’t | ||
| /// need implementing. | ||
| pub unsafe trait Array { | ||
| /// The array’s element type | ||
| type Item; | ||
| /// The smallest type that can index and tell the length of the array. | ||
| #[doc(hidden)] | ||
| type Index: Index; | ||
| /// The array's element capacity | ||
| const CAPACITY: usize; | ||
| fn as_slice(&self) -> &[Self::Item]; | ||
| fn as_mut_slice(&mut self) -> &mut [Self::Item]; | ||
| } | ||
| pub trait Index : PartialEq + Copy { | ||
| const ZERO: Self; | ||
| fn to_usize(self) -> usize; | ||
| fn from(_: usize) -> Self; | ||
| } | ||
| impl Index for () { | ||
| const ZERO: Self = (); | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { 0 } | ||
| #[inline(always)] | ||
| fn from(_ix: usize) -> Self { () } | ||
| } | ||
| impl Index for bool { | ||
| const ZERO: Self = false; | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { self as usize } | ||
| #[inline(always)] | ||
| fn from(ix: usize) -> Self { ix != 0 } | ||
| } | ||
| impl Index for u8 { | ||
| const ZERO: Self = 0; | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { self as usize } | ||
| #[inline(always)] | ||
| fn from(ix: usize) -> Self { ix as u8 } | ||
| } | ||
| impl Index for u16 { | ||
| const ZERO: Self = 0; | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { self as usize } | ||
| #[inline(always)] | ||
| fn from(ix: usize) -> Self { ix as u16 } | ||
| } | ||
| impl Index for u32 { | ||
| const ZERO: Self = 0; | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { self as usize } | ||
| #[inline(always)] | ||
| fn from(ix: usize) -> Self { ix as u32 } | ||
| } | ||
| impl Index for usize { | ||
| const ZERO: Self = 0; | ||
| #[inline(always)] | ||
| fn to_usize(self) -> usize { self } | ||
| #[inline(always)] | ||
| fn from(ix: usize) -> Self { ix } | ||
| } | ||
| macro_rules! fix_array_impl { | ||
| ($index_type:ty, $len:expr ) => ( | ||
| unsafe impl<T> Array for [T; $len] { | ||
| type Item = T; | ||
| type Index = $index_type; | ||
| const CAPACITY: usize = $len; | ||
| #[doc(hidden)] | ||
| fn as_slice(&self) -> &[Self::Item] { self } | ||
| #[doc(hidden)] | ||
| fn as_mut_slice(&mut self) -> &mut [Self::Item] { self } | ||
| } | ||
| ) | ||
| } | ||
| macro_rules! fix_array_impl_recursive { | ||
| ($index_type:ty, ) => (); | ||
| ($index_type:ty, $($len:expr,)*) => ( | ||
| $(fix_array_impl!($index_type, $len);)* | ||
| ); | ||
| } | ||
| fix_array_impl_recursive!((), 0,); | ||
| fix_array_impl_recursive!(bool, 1,); | ||
| fix_array_impl_recursive!(u8, 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, ); | ||
| #[cfg(not(feature="array-sizes-33-128"))] | ||
| fix_array_impl_recursive!(u8, 32, 40, 48, 50, 56, 64, 72, 96, 100, 128, ); | ||
| #[cfg(feature="array-sizes-33-128")] | ||
| fix_array_impl_recursive!(u8, | ||
| 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, | ||
| 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, | ||
| 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, | ||
| 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, | ||
| 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, | ||
| 125, 126, 127, 128, | ||
| ); | ||
| #[cfg(not(feature="array-sizes-129-255"))] | ||
| fix_array_impl_recursive!(u8, 160, 192, 200, 224,); | ||
| #[cfg(feature="array-sizes-129-255")] | ||
| fix_array_impl_recursive!(u8, | ||
| 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, | ||
| 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, | ||
| 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, | ||
| 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, | ||
| 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, | ||
| 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, | ||
| 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, | ||
| 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, | ||
| 253, 254, 255, | ||
| ); | ||
| fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,); | ||
| // This array size doesn't exist on 16-bit | ||
| #[cfg(any(target_pointer_width="32", target_pointer_width="64"))] | ||
| fix_array_impl_recursive!(u32, 1 << 16,); | ||
| use crate::array::Array; | ||
| use std::mem::MaybeUninit as StdMaybeUninit; | ||
| #[derive(Copy)] | ||
| pub struct MaybeUninit<T> { | ||
| inner: StdMaybeUninit<T>, | ||
| } | ||
| impl<T> Clone for MaybeUninit<T> | ||
| where T: Copy | ||
| { | ||
| fn clone(&self) -> Self { *self } | ||
| } | ||
| impl<T> MaybeUninit<T> { | ||
| /// Create a new MaybeUninit with uninitialized interior | ||
| pub const unsafe fn uninitialized() -> Self { | ||
| MaybeUninit { inner: StdMaybeUninit::uninit() } | ||
| } | ||
| /// Create a new MaybeUninit from the value `v`. | ||
| pub fn from(v: T) -> Self { | ||
| MaybeUninit { inner: StdMaybeUninit::new(v) } | ||
| } | ||
| // Raw pointer casts written so that we don't reference or access the | ||
| // uninitialized interior value | ||
| /// Return a raw pointer to the start of the interior array | ||
| pub fn ptr(&self) -> *const T::Item | ||
| where T: Array | ||
| { | ||
| self.inner.as_ptr() as *const T::Item | ||
| } | ||
| /// Return a mut raw pointer to the start of the interior array | ||
| pub fn ptr_mut(&mut self) -> *mut T::Item | ||
| where T: Array | ||
| { | ||
| self.inner.as_mut_ptr() as *mut T::Item | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet