FIX: Remake extend_from_slice to try_extend_from_slice

Do nothing and return an error, if the slice doesn't fit in the
remaining capacity.
This commit is contained in:
bluss
2018-11-28 15:59:11 +01:00
parent 8e5ff2d0fb
commit 47827e4843
3 changed files with 12 additions and 9 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ fn extend_with_slice_fn(b: &mut Bencher) {
let data = [1; 512]; let data = [1; 512];
b.iter(|| { b.iter(|| {
v.clear(); v.clear();
black_box(v.extend_from_slice(&data)); black_box(v.try_extend_from_slice(&data));
v[0] v[0]
}); });
b.bytes = v.capacity() as u64; b.bytes = v.capacity() as u64;
+10 -7
View File
@@ -543,21 +543,22 @@ impl<A: Array> ArrayVec<A> {
/// ///
/// let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); /// let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new();
/// vec.push(1); /// vec.push(1);
/// vec.extend_from_slice(&[2, 3]); /// vec.try_extend_from_slice(&[2, 3]).unwrap();
/// assert_eq!(&vec[..], &[1, 2, 3]); /// assert_eq!(&vec[..], &[1, 2, 3]);
/// ``` /// ```
/// ///
/// # Panics /// # Errors
/// ///
/// This method will panic if the capacity left (see [`remaining_capacity`]) is /// This method will return an error if the capacity left (see
/// smaller then the length of the provided slice. /// [`remaining_capacity`]) is smaller then the length of the provided
/// slice.
/// ///
/// [`remaining_capacity`]: #method.remaining_capacity /// [`remaining_capacity`]: #method.remaining_capacity
pub fn extend_from_slice(&mut self, other: &[A::Item]) pub fn try_extend_from_slice(&mut self, other: &[A::Item]) -> Result<(), CapacityError>
where A::Item: Copy, where A::Item: Copy,
{ {
if self.remaining_capacity() < other.len() { if self.remaining_capacity() < other.len() {
panic!("ArrayVec::extend_from_slice: slice is larger then capacity left"); return Err(CapacityError::new(()));
} }
let self_len = self.len(); let self_len = self.len();
@@ -568,6 +569,7 @@ impl<A: Array> ArrayVec<A> {
ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len); ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len);
self.set_len(self_len + other_len); self.set_len(self_len + other_len);
} }
Ok(())
} }
/// Create a draining iterator that removes the specified range in the vector /// Create a draining iterator that removes the specified range in the vector
@@ -1080,7 +1082,8 @@ impl<A: Array> Ord for ArrayVec<A> where A::Item: Ord {
impl<A: Array<Item=u8>> io::Write for ArrayVec<A> { impl<A: Array<Item=u8>> io::Write for ArrayVec<A> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> { fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let len = cmp::min(self.remaining_capacity(), data.len()); let len = cmp::min(self.remaining_capacity(), data.len());
self.extend_from_slice(&data[..len]); let _result = self.try_extend_from_slice(&data[..len]);
debug_assert!(_result.is_ok());
Ok(len) Ok(len)
} }
fn flush(&mut self) -> io::Result<()> { Ok(()) } fn flush(&mut self) -> io::Result<()> { Ok(()) }
+1 -1
View File
@@ -45,7 +45,7 @@ fn test_capacity_left() {
fn test_extend_from_slice() { fn test_extend_from_slice() {
let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new();
vec.extend_from_slice(&[1, 2, 3]); vec.try_extend_from_slice(&[1, 2, 3]);
assert_eq!(vec.len(), 3); assert_eq!(vec.len(), 3);
assert_eq!(&vec[..], &[1, 2, 3]); assert_eq!(&vec[..], &[1, 2, 3]);
assert_eq!(vec.pop(), Some(3)); assert_eq!(vec.pop(), Some(3));