From 07b2ca2e1f32807faf00af1285566fdb38fb6658 Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 17 Feb 2016 23:08:46 +0100 Subject: [PATCH 1/3] Edit docs for methods returning Result --- src/array_string.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) 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; From 49be63d9b8e40546644207ffc7e69a2d559ff39c Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 17 Feb 2016 23:08:46 +0100 Subject: [PATCH 2/3] arrayvec: Reorder method pop --- src/lib.rs | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d627f9a..9fd9886 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). From c5589aecdf748a682eb8080180049c6559ea85f7 Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 17 Feb 2016 23:08:46 +0100 Subject: [PATCH 3/3] Add .retain() method Based on "retain_mut" as discussed for vec: we can provide &mut to the element to remove effortlessly. --- src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ tests/tests.rs | 17 +++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 9fd9886..11c710a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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() {