Skip to content

Commit 4f47f49

Browse files
committed
Implement clone_from to reuse allocations
1 parent 01bb540 commit 4f47f49

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
@@ -362,7 +362,6 @@ where
362362
}
363363

364364
/// Core of the map that does not depend on S
365-
#[derive(Clone)]
366365
pub(crate) struct IndexMapCore<K, V> {
367366
mask: usize,
368367
/// indices are the buckets. indices.len() == raw capacity
@@ -371,6 +370,26 @@ pub(crate) struct IndexMapCore<K, V> {
371370
entries: Vec<Bucket<K, V>>,
372371
}
373372

373+
impl<K, V> Clone for IndexMapCore<K, V>
374+
where
375+
K: Clone,
376+
V: Clone,
377+
{
378+
fn clone(&self) -> Self {
379+
IndexMapCore {
380+
mask: self.mask,
381+
indices: self.indices.clone(),
382+
entries: self.entries.clone(),
383+
}
384+
}
385+
386+
fn clone_from(&mut self, other: &Self) {
387+
self.mask = other.mask;
388+
self.indices.clone_from(&other.indices);
389+
self.entries.clone_from(&other.entries);
390+
}
391+
}
392+
374393
impl<K, V> Entries for IndexMapCore<K, V> {
375394
type Entry = Bucket<K, V>;
376395

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)