331: Relax trait requirements on IndexMap/IndexSet. r=korken89 a=jeandudey

Some requirements are not necessary and the specification can be removed/simplified. This makes these types a bit more ergonomic when using them in a trait or function definition as not all traits need to be specified for some cases.

Co-authored-by: Jean-Pierre De Jesus DIAZ <me@jeandudey.tech>
This commit is contained in:
bors[bot] 2023-01-10 14:07:18 +00:00 committed by GitHub
commit 44a609fe75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 118 deletions

View File

@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- renamed `pool::singleton::arc::Pool` to `ArcPool` and moved it into the `pool::arc` module
- [breaking-change] changed the target support of memory pool API to only support 32-bit x86 and a
subset of ARM targets. See the module level documentation of the `pool` module for details
- relax trait requirements on `IndexMap` and `IndexSet`.
- [breaking-change] this crate now depends on `atomic-polyfill` v1.0.1, meaning that targets that
require a polyfill need a `critical-section` **v1.x.x** implementation.

View File

@ -313,7 +313,7 @@ where
impl<K, V, const N: usize> Clone for CoreMap<K, V, N>
where
K: Eq + Hash + Clone,
K: Clone,
V: Clone,
{
fn clone(&self) -> Self {
@ -499,12 +499,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, BuildHasherDefault<S>, N> {
}
}
impl<K, V, S, const N: usize> IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher,
{
/* Public API */
impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Returns the number of elements the map can hold
pub fn capacity(&self) -> usize {
N
@ -652,39 +647,6 @@ where
.map(|bucket| (&bucket.key, &mut bucket.value))
}
/// Returns an entry for the corresponding key
/// ```
/// use heapless::FnvIndexMap;
/// use heapless::Entry;
/// let mut map = FnvIndexMap::<_, _, 16>::new();
/// if let Entry::Vacant(v) = map.entry("a") {
/// v.insert(1).unwrap();
/// }
/// if let Entry::Occupied(mut o) = map.entry("a") {
/// println!("found {}", *o.get()); // Prints 1
/// o.insert(2);
/// }
/// // Prints 2
/// println!("val: {}", *map.get("a").unwrap());
/// ```
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
let hash_val = hash_with(&key, &self.build_hasher);
if let Some((probe, pos)) = self.core.find(hash_val, &key) {
Entry::Occupied(OccupiedEntry {
key,
probe,
pos,
core: &mut self.core,
})
} else {
Entry::Vacant(VacantEntry {
key,
hash_val,
core: &mut self.core,
})
}
}
/// Return the number of key-value pairs in the map.
///
/// Computes in **O(1)** time.
@ -735,6 +697,46 @@ where
*pos = None;
}
}
}
impl<K, V, S, const N: usize> IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher,
{
/* Public API */
/// Returns an entry for the corresponding key
/// ```
/// use heapless::FnvIndexMap;
/// use heapless::Entry;
/// let mut map = FnvIndexMap::<_, _, 16>::new();
/// if let Entry::Vacant(v) = map.entry("a") {
/// v.insert(1).unwrap();
/// }
/// if let Entry::Occupied(mut o) = map.entry("a") {
/// println!("found {}", *o.get()); // Prints 1
/// o.insert(2);
/// }
/// // Prints 2
/// println!("val: {}", *map.get("a").unwrap());
/// ```
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
let hash_val = hash_with(&key, &self.build_hasher);
if let Some((probe, pos)) = self.core.find(hash_val, &key) {
Entry::Occupied(OccupiedEntry {
key,
probe,
pos,
core: &mut self.core,
})
} else {
Entry::Vacant(VacantEntry {
key,
hash_val,
core: &mut self.core,
})
}
}
/// Returns a reference to the value corresponding to the key.
///
@ -931,7 +933,7 @@ where
impl<K, V, S, const N: usize> Clone for IndexMap<K, V, S, N>
where
K: Eq + Hash + Clone,
K: Clone,
V: Clone,
S: Clone,
{
@ -945,9 +947,8 @@ where
impl<K, V, S, const N: usize> fmt::Debug for IndexMap<K, V, S, N>
where
K: Eq + Hash + fmt::Debug,
K: fmt::Debug,
V: fmt::Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
@ -956,8 +957,7 @@ where
impl<K, V, S, const N: usize> Default for IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher + Default,
S: Default,
{
fn default() -> Self {
// Const assert
@ -1052,11 +1052,7 @@ impl<K, V, const N: usize> Iterator for IntoIter<K, V, N> {
}
}
impl<K, V, S, const N: usize> IntoIterator for IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher,
{
impl<K, V, S, const N: usize> IntoIterator for IndexMap<K, V, S, N> {
type Item = (K, V);
type IntoIter = IntoIter<K, V, N>;
@ -1067,11 +1063,7 @@ where
}
}
impl<'a, K, V, S, const N: usize> IntoIterator for &'a IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher,
{
impl<'a, K, V, S, const N: usize> IntoIterator for &'a IndexMap<K, V, S, N> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
@ -1080,11 +1072,7 @@ where
}
}
impl<'a, K, V, S, const N: usize> IntoIterator for &'a mut IndexMap<K, V, S, N>
where
K: Eq + Hash,
S: BuildHasher,
{
impl<'a, K, V, S, const N: usize> IntoIterator for &'a mut IndexMap<K, V, S, N> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;

View File

@ -92,11 +92,7 @@ impl<T, S, const N: usize> IndexSet<T, BuildHasherDefault<S>, N> {
}
}
impl<T, S, const N: usize> IndexSet<T, S, N>
where
T: Eq + Hash,
S: BuildHasher,
{
impl<T, S, const N: usize> IndexSet<T, S, N> {
/// Returns the number of elements the set can hold
///
/// # Examples
@ -147,6 +143,60 @@ where
self.map.last().map(|(k, _v)| k)
}
/// Returns the number of elements in the set.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert_eq!(v.len(), 0);
/// v.insert(1).unwrap();
/// assert_eq!(v.len(), 1);
/// ```
pub fn len(&self) -> usize {
self.map.len()
}
/// Returns `true` if the set contains no elements.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert!(v.is_empty());
/// v.insert(1).unwrap();
/// assert!(!v.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
/// Clears the set, removing all values.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// v.insert(1).unwrap();
/// v.clear();
/// assert!(v.is_empty());
/// ```
pub fn clear(&mut self) {
self.map.clear()
}
}
impl<T, S, const N: usize> IndexSet<T, S, N>
where
T: Eq + Hash,
S: BuildHasher,
{
/// Visits the values representing the difference, i.e. the values that are in `self` but not in
/// `other`.
///
@ -277,54 +327,6 @@ where
self.iter().chain(other.difference(self))
}
/// Returns the number of elements in the set.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert_eq!(v.len(), 0);
/// v.insert(1).unwrap();
/// assert_eq!(v.len(), 1);
/// ```
pub fn len(&self) -> usize {
self.map.len()
}
/// Returns `true` if the set contains no elements.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert!(v.is_empty());
/// v.insert(1).unwrap();
/// assert!(!v.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
/// Clears the set, removing all values.
///
/// # Examples
///
/// ```
/// use heapless::FnvIndexSet;
///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// v.insert(1).unwrap();
/// v.clear();
/// assert!(v.is_empty());
/// ```
pub fn clear(&mut self) {
self.map.clear()
}
/// Returns `true` if the set contains a value.
///
/// The value may be any borrowed form of the set's value type, but `Hash` and `Eq` on the
@ -473,7 +475,7 @@ where
impl<T, S, const N: usize> Clone for IndexSet<T, S, N>
where
T: Eq + Hash + Clone,
T: Clone,
S: Clone,
{
fn clone(&self) -> Self {
@ -485,8 +487,7 @@ where
impl<T, S, const N: usize> fmt::Debug for IndexSet<T, S, N>
where
T: Eq + Hash + fmt::Debug,
S: BuildHasher,
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
@ -495,8 +496,7 @@ where
impl<T, S, const N: usize> Default for IndexSet<T, S, N>
where
T: Eq + Hash,
S: BuildHasher + Default,
S: Default,
{
fn default() -> Self {
IndexSet {