diff --git a/src/array_string.rs b/src/array_string.rs index a9b9f1a..a6410c2 100644 --- a/src/array_string.rs +++ b/src/array_string.rs @@ -50,6 +50,8 @@ impl> ArrayString { /// /// Capacity is inferred from the type parameter. /// + /// **Errors** if the backing array is not large enough to fit the string. + /// /// ``` /// use arrayvec::ArrayString; /// @@ -77,8 +79,9 @@ impl> ArrayString { /// Adds the given char to the end of the string. /// - /// Returns `Ok` if the push succeeds, and returns `Err` if the backing - /// array is not large enough to fit the additional char. + /// Returns `Ok` if the push succeeds. + /// + /// **Errors** if the backing array is not large enough to fit the additional char. /// /// ``` /// use arrayvec::ArrayString; @@ -99,8 +102,9 @@ impl> ArrayString { /// Adds the given string slice to the end of the string. /// - /// Returns `Ok` if the push succeeds, and returns `Err` if the - /// backing array is not large enough to fit the string. + /// Returns `Ok` if the push succeeds. + /// + /// **Errors** if the backing array is not large enough to fit the string. /// /// ``` /// use arrayvec::ArrayString; diff --git a/src/lib.rs b/src/lib.rs index d627f9a..11c710a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -155,31 +155,6 @@ impl ArrayVec { } } - /// Remove the last element in the vector. - /// - /// Return `Some(` *element* `)` if the vector is non-empty, else `None`. - /// - /// ``` - /// use arrayvec::ArrayVec; - /// - /// let mut array = ArrayVec::<[_; 2]>::new(); - /// - /// array.push(1); - /// - /// assert_eq!(array.pop(), Some(1)); - /// assert_eq!(array.pop(), None); - /// ``` - pub fn pop(&mut self) -> Option { - if self.len() == 0 { - return None - } - unsafe { - let new_len = self.len() - 1; - self.set_len(new_len); - Some(ptr::read(self.get_unchecked_mut(new_len))) - } - } - /// Insert `element` in position `index`. /// /// Shift up all elements after `index`. If any is pushed out, it is returned. @@ -225,6 +200,31 @@ impl ArrayVec { ret } + /// Remove the last element in the vector. + /// + /// Return `Some(` *element* `)` if the vector is non-empty, else `None`. + /// + /// ``` + /// use arrayvec::ArrayVec; + /// + /// let mut array = ArrayVec::<[_; 2]>::new(); + /// + /// array.push(1); + /// + /// assert_eq!(array.pop(), Some(1)); + /// assert_eq!(array.pop(), None); + /// ``` + pub fn pop(&mut self) -> Option { + if self.len() == 0 { + return None + } + unsafe { + let new_len = self.len() - 1; + self.set_len(new_len); + Some(ptr::read(self.get_unchecked_mut(new_len))) + } + } + /// Remove the element at `index` and swap the last element into its place. /// /// This operation is O(1). @@ -277,6 +277,40 @@ impl ArrayVec { while let Some(_) = self.pop() { } } + /// 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(&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 /// /// May panic if `length` is greater than the capacity. diff --git a/tests/tests.rs b/tests/tests.rs index aa5b80d..aadacce 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -158,6 +158,23 @@ fn test_drain() { assert_eq!(&v[..], &[]); } +#[test] +fn test_retain() { + let mut v = ArrayVec::from([0; 8]); + for (i, elt) in v.iter_mut().enumerate() { + *elt = i; + } + v.retain(|_| true); + assert_eq!(&v[..], &[0, 1, 2, 3, 4, 5, 6, 7]); + v.retain(|elt| { + *elt /= 2; + *elt % 2 == 0 + }); + assert_eq!(&v[..], &[0, 0, 2, 2]); + v.retain(|_| false); + assert_eq!(&v[..], &[]); +} + #[test] #[should_panic] fn test_drain_oob() {