Skip to content

Commit 87de8b6

Browse files
Generic container: new Map private trait
Note: `BTreeMap::remove<Q>` and `BTreeMap::remove<Q>` both accept a more general `Q` rather than just `Self::Key`. If ever needed, `Map<Q>` would be possible (with the same bound on `Q` than `Self::Key`: `Ord` or `Eq + Hash`). Implement `Map` for simple unordered `Vec<(_, _)>`. Note it uses `swap_remove`.
1 parent 4d96da1 commit 87de8b6

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/generic_containers.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//! **Private** generalizations of containers:
2+
//! - `Map`: `BTreeMap`, `HashMap` (any hasher) and _unordered_ `Vec`.
3+
4+
#![cfg(feature = "use_alloc")]
5+
6+
use alloc::collections::BTreeMap;
7+
use alloc::vec::Vec;
8+
#[cfg(feature = "use_std")]
9+
use core::hash::{BuildHasher, Hash};
10+
#[cfg(feature = "use_std")]
11+
use std::collections::HashMap;
12+
13+
pub trait Map {
14+
type Key;
15+
type Value;
16+
fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
17+
fn remove(&mut self, key: &Self::Key) -> Option<Self::Value>;
18+
fn entry_or_default(&mut self, key: Self::Key) -> &mut Self::Value
19+
where
20+
Self::Value: Default;
21+
}
22+
23+
impl<K, V> Map for BTreeMap<K, V>
24+
where
25+
K: Ord,
26+
{
27+
type Key = K;
28+
type Value = V;
29+
fn insert(&mut self, key: K, value: V) -> Option<V> {
30+
self.insert(key, value)
31+
}
32+
fn remove(&mut self, key: &K) -> Option<V> {
33+
self.remove(key)
34+
}
35+
fn entry_or_default(&mut self, key: K) -> &mut V
36+
where
37+
V: Default,
38+
{
39+
self.entry(key).or_default()
40+
}
41+
}
42+
43+
#[cfg(feature = "use_std")]
44+
impl<K, V, S> Map for HashMap<K, V, S>
45+
where
46+
K: Eq + Hash,
47+
S: BuildHasher,
48+
{
49+
type Key = K;
50+
type Value = V;
51+
fn insert(&mut self, key: K, value: V) -> Option<V> {
52+
self.insert(key, value)
53+
}
54+
fn remove(&mut self, key: &K) -> Option<V> {
55+
self.remove(key)
56+
}
57+
fn entry_or_default(&mut self, key: K) -> &mut V
58+
where
59+
V: Default,
60+
{
61+
self.entry(key).or_default()
62+
}
63+
}
64+
65+
impl<K, V> Map for Vec<(K, V)>
66+
where
67+
K: Eq,
68+
{
69+
type Key = K;
70+
type Value = V;
71+
fn insert(&mut self, key: K, value: V) -> Option<V> {
72+
match self.iter_mut().find(|(k, _)| k == &key) {
73+
Some((_, v)) => Some(core::mem::replace(v, value)),
74+
None => {
75+
self.push((key, value));
76+
None
77+
}
78+
}
79+
}
80+
fn remove(&mut self, key: &K) -> Option<V> {
81+
let index = self.iter().position(|(k, _)| k == key)?;
82+
Some(self.swap_remove(index).1)
83+
}
84+
fn entry_or_default(&mut self, key: K) -> &mut V
85+
where
86+
V: Default,
87+
{
88+
let index = self.iter().position(|(k, _)| k == &key).unwrap_or_else(|| {
89+
self.push((key, V::default()));
90+
self.len() - 1
91+
});
92+
&mut self[index].1
93+
}
94+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ mod extrema_set;
188188
mod flatten_ok;
189189
mod format;
190190
#[cfg(feature = "use_alloc")]
191+
mod generic_containers;
192+
#[cfg(feature = "use_alloc")]
191193
mod group_map;
192194
#[cfg(feature = "use_alloc")]
193195
mod groupbylazy;

0 commit comments

Comments
 (0)