Skip to content

Commit 8d1fa53

Browse files
committed
Implement clone_from to reuse allocations
1 parent adedee6 commit 8d1fa53

File tree

4 files changed

+76
-6
lines changed

4 files changed

+76
-6
lines changed

src/lib.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,33 @@ impl HashValue {
107107
}
108108
}
109109

110-
#[derive(Copy, Clone, Debug)]
110+
#[derive(Copy, Debug)]
111111
struct Bucket<K, V> {
112112
hash: HashValue,
113113
key: K,
114114
value: V,
115115
}
116116

117+
impl<K, V> Clone for Bucket<K, V>
118+
where
119+
K: Clone,
120+
V: Clone,
121+
{
122+
fn clone(&self) -> Self {
123+
Bucket {
124+
hash: self.hash,
125+
key: self.key.clone(),
126+
value: self.value.clone(),
127+
}
128+
}
129+
130+
fn clone_from(&mut self, other: &Self) {
131+
self.hash = other.hash;
132+
self.key.clone_from(&other.key);
133+
self.value.clone_from(&other.value);
134+
}
135+
}
136+
117137
impl<K, V> Bucket<K, V> {
118138
// field accessors -- used for `f` instead of closures in `.map(f)`
119139
fn key_ref(&self) -> &K {

src/map.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,36 @@ fn hash_elem_using<B: BuildHasher, K: ?Sized + Hash>(build: &B, k: &K) -> HashVa
7777
/// assert_eq!(letters[&'u'], 1);
7878
/// assert_eq!(letters.get(&'y'), None);
7979
/// ```
80-
#[derive(Clone)]
8180
#[cfg(has_std)]
8281
pub struct IndexMap<K, V, S = RandomState> {
8382
core: IndexMapCore<K, V>,
8483
hash_builder: S,
8584
}
86-
#[derive(Clone)]
8785
#[cfg(not(has_std))]
8886
pub struct IndexMap<K, V, S> {
8987
core: IndexMapCore<K, V>,
9088
hash_builder: S,
9189
}
9290

91+
impl<K, V, S> Clone for IndexMap<K, V, S>
92+
where
93+
K: Clone,
94+
V: Clone,
95+
S: Clone,
96+
{
97+
fn clone(&self) -> Self {
98+
IndexMap {
99+
core: self.core.clone(),
100+
hash_builder: self.hash_builder.clone(),
101+
}
102+
}
103+
104+
fn clone_from(&mut self, other: &Self) {
105+
self.core.clone_from(&other.core);
106+
self.hash_builder.clone_from(&other.hash_builder);
107+
}
108+
}
109+
93110
impl<K, V, S> Entries for IndexMap<K, V, S> {
94111
type Entry = Bucket<K, V>;
95112

src/map_core.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,6 @@ enum Inserted<V> {
368368
}
369369

370370
/// Core of the map that does not depend on S
371-
#[derive(Clone)]
372371
pub(crate) struct IndexMapCore<K, V> {
373372
mask: usize,
374373
/// indices are the buckets. indices.len() == raw capacity
@@ -377,6 +376,26 @@ pub(crate) struct IndexMapCore<K, V> {
377376
entries: Vec<Bucket<K, V>>,
378377
}
379378

379+
impl<K, V> Clone for IndexMapCore<K, V>
380+
where
381+
K: Clone,
382+
V: Clone,
383+
{
384+
fn clone(&self) -> Self {
385+
IndexMapCore {
386+
mask: self.mask,
387+
indices: self.indices.clone(),
388+
entries: self.entries.clone(),
389+
}
390+
}
391+
392+
fn clone_from(&mut self, other: &Self) {
393+
self.mask = other.mask;
394+
self.indices.clone_from(&other.indices);
395+
self.entries.clone_from(&other.entries);
396+
}
397+
}
398+
380399
impl<K, V> Entries for IndexMapCore<K, V> {
381400
type Entry = Bucket<K, V>;
382401

src/set.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,31 @@ type Bucket<T> = super::Bucket<T, ()>;
6363
/// assert!(letters.contains(&'u'));
6464
/// assert!(!letters.contains(&'y'));
6565
/// ```
66-
#[derive(Clone)]
6766
#[cfg(has_std)]
6867
pub struct IndexSet<T, S = RandomState> {
6968
map: IndexMap<T, (), S>,
7069
}
7170
#[cfg(not(has_std))]
72-
#[derive(Clone)]
7371
pub struct IndexSet<T, S> {
7472
map: IndexMap<T, (), S>,
7573
}
7674

75+
impl<T, S> Clone for IndexSet<T, S>
76+
where
77+
T: Clone,
78+
S: Clone,
79+
{
80+
fn clone(&self) -> Self {
81+
IndexSet {
82+
map: self.map.clone(),
83+
}
84+
}
85+
86+
fn clone_from(&mut self, other: &Self) {
87+
self.map.clone_from(&other.map);
88+
}
89+
}
90+
7791
impl<T, S> Entries for IndexSet<T, S> {
7892
type Entry = Bucket<T>;
7993

0 commit comments

Comments
 (0)