This works, but take_one_item seems too verbose. Can it be done in a better way?
I'm not sure there is a more concise way... but I'm also uncertain what the utility is. The item removed won't be random, but iteration order also isn't specified. What would you like to use this for?
If verbosity is your main concern then this should do the trick, though note that it will probably unnecessarily hash the item when removing it.
fn take_one_item<T>(set: &mut HashSet::<T>) -> Option<T> where T: Eq, T: Hash, T: Copy {
let item = *set.iter().next()?;
set.take(&item)
}
Or if you are open to using nightly features, you can abuse HashSet::extract_if
to get the job done.
#![feature(hash_extract_if)]
fn take_one_item<T>(set: &mut HashSet::<T>) -> Option<T> where T: Eq, T: Hash, T: Copy {
set.extract_if(|_| true).next()
}
uncertain what the utility is.
The application is debugging code in something that allocates slots in an array. (Not my code; I'm fixing a crate.) I'm temporarily replacing a free list with a map, so I can catch attempts to put the same empty slot in the free list twice. Seems to be a race condition. Happens about once in 3 to 6 hours of run time.
Okay, I was just wondering if it was a situation where you couldn't simply iterate over the set directly.
Have you considered using BTreeSet? It provides pop_first()
and pop_last()
right out of the box.