Skip to content

Commit

Permalink
Add a try_remove method (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
aym-v authored Jun 7, 2021
1 parent 6c5fe73 commit eb0ad4e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 9 deletions.
39 changes: 30 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,15 +953,12 @@ impl<T> Slab<T> {
}
}

/// Remove and return the value associated with the given key.
/// Tries to remove the value associated with the given key,
/// returning the value if the key existed.
///
/// The key is then released and may be associated with future stored
/// values.
///
/// # Panics
///
/// Panics if `key` is not associated with a value.
///
/// # Examples
///
/// ```
Expand All @@ -970,10 +967,10 @@ impl<T> Slab<T> {
///
/// let hello = slab.insert("hello");
///
/// assert_eq!(slab.remove(hello), "hello");
/// assert_eq!(slab.try_remove(hello), Some("hello"));
/// assert!(!slab.contains(hello));
/// ```
pub fn remove(&mut self, key: usize) -> T {
pub fn try_remove(&mut self, key: usize) -> Option<T> {
if let Some(entry) = self.entries.get_mut(key) {
// Swap the entry at the provided value
let prev = mem::replace(entry, Entry::Vacant(self.next));
Expand All @@ -982,15 +979,39 @@ impl<T> Slab<T> {
Entry::Occupied(val) => {
self.len -= 1;
self.next = key;
return val;
return val.into();
}
_ => {
// Woops, the entry is actually vacant, restore the state
*entry = prev;
}
}
}
panic!("invalid key");
None
}

/// Remove and return the value associated with the given key.
///
/// The key is then released and may be associated with future stored
/// values.
///
/// # Panics
///
/// Panics if `key` is not associated with a value.
///
/// # Examples
///
/// ```
/// # use slab::*;
/// let mut slab = Slab::new();
///
/// let hello = slab.insert("hello");
///
/// assert_eq!(slab.remove(hello), "hello");
/// assert!(!slab.contains(hello));
/// ```
pub fn remove(&mut self, key: usize) -> T {
self.try_remove(key).expect("invalid key")
}

/// Return `true` if a value is associated with the given key.
Expand Down
11 changes: 11 additions & 0 deletions tests/slab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,3 +659,14 @@ fn drain_rev() {
let vals: Vec<u64> = slab.drain().rev().collect();
assert_eq!(vals, (0..9).rev().collect::<Vec<u64>>());
}

#[test]
fn try_remove() {
let mut slab = Slab::new();

let key = slab.insert(1);

assert_eq!(slab.try_remove(key), Some(1));
assert_eq!(slab.try_remove(key), None);
assert_eq!(slab.get(key), None);
}

0 comments on commit eb0ad4e

Please sign in to comment.