Merge pull request #39 from bluss/insert
Fix bounds checking in ArrayVec::insert(index, element)
This commit is contained in:
+5
-1
@@ -179,6 +179,10 @@ impl<A: Array> ArrayVec<A> {
|
|||||||
///
|
///
|
||||||
/// Return `None` if no element is shifted out.
|
/// Return `None` if no element is shifted out.
|
||||||
///
|
///
|
||||||
|
/// `index` must be <= `self.len()` and < `self.capacity()`. Note that any
|
||||||
|
/// out of bounds index insert results in the element being "shifted out"
|
||||||
|
/// and returned directly.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use arrayvec::ArrayVec;
|
/// use arrayvec::ArrayVec;
|
||||||
///
|
///
|
||||||
@@ -192,7 +196,7 @@ impl<A: Array> ArrayVec<A> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn insert(&mut self, index: usize, element: A::Item) -> Option<A::Item> {
|
pub fn insert(&mut self, index: usize, element: A::Item) -> Option<A::Item> {
|
||||||
if index >= self.capacity() {
|
if index > self.len() || index == self.capacity() {
|
||||||
return Some(element);
|
return Some(element);
|
||||||
}
|
}
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
|
|||||||
@@ -355,3 +355,60 @@ fn test_string_clone() {
|
|||||||
s.clone_from(&t);
|
s.clone_from(&t);
|
||||||
assert_eq!(&t, &s);
|
assert_eq!(&t, &s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_insert_at_length() {
|
||||||
|
let mut v = ArrayVec::<[_; 8]>::new();
|
||||||
|
let result1 = v.insert(0, "a");
|
||||||
|
let result2 = v.insert(1, "b");
|
||||||
|
assert!(result1.is_none() && result2.is_none());
|
||||||
|
assert_eq!(&v[..], &["a", "b"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_insert_out_of_bounds() {
|
||||||
|
let mut v = ArrayVec::<[_; 8]>::new();
|
||||||
|
let result = v.insert(1, "test");
|
||||||
|
assert_eq!(result, Some("test"));
|
||||||
|
assert_eq!(v.len(), 0);
|
||||||
|
|
||||||
|
let mut u = ArrayVec::from([1, 2, 3, 4]);
|
||||||
|
let ret = u.insert(3, 99);
|
||||||
|
assert_eq!(&u[..], &[1, 2, 3, 99]);
|
||||||
|
assert_eq!(ret, Some(4));
|
||||||
|
let ret = u.insert(4, 77);
|
||||||
|
assert_eq!(&u[..], &[1, 2, 3, 99]);
|
||||||
|
assert_eq!(ret, Some(77));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop_in_insert() {
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
let flag = &Cell::new(0);
|
||||||
|
|
||||||
|
struct Bump<'a>(&'a Cell<i32>);
|
||||||
|
|
||||||
|
impl<'a> Drop for Bump<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let n = self.0.get();
|
||||||
|
self.0.set(n + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.set(0);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut array = ArrayVec::<[_; 2]>::new();
|
||||||
|
array.push(Bump(flag));
|
||||||
|
array.insert(0, Bump(flag));
|
||||||
|
assert_eq!(flag.get(), 0);
|
||||||
|
let ret = array.insert(1, Bump(flag));
|
||||||
|
assert_eq!(flag.get(), 0);
|
||||||
|
assert!(ret.is_some());
|
||||||
|
drop(ret);
|
||||||
|
assert_eq!(flag.get(), 1);
|
||||||
|
}
|
||||||
|
assert_eq!(flag.get(), 3);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user