diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fb8a0c3c26554..eb1c74b264c65 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1518,6 +1518,12 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn fold(self, init: B, f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.inner.fold(init, f) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { @@ -1542,6 +1548,12 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn fold(self, init: B, f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.inner.fold(init, f) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { @@ -1588,6 +1600,12 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.inner.fold(init, move |acc, (k, _)| f(acc, k)) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { @@ -1611,6 +1629,12 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.inner.fold(init, move |acc, (_, v)| f(acc, v)) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { @@ -1634,6 +1658,12 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.inner.fold(init, move |acc, (_, v)| f(acc, v)) + } } #[stable(feature = "map_values_mut", since = "1.10.0")] impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 1ec7a4a7b639b..6037e5ee1068f 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -942,6 +942,12 @@ impl<'a, K> Iterator for Iter<'a, K> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn fold(self, init: B, f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.iter.fold(init, f) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K> ExactSizeIterator for Iter<'a, K> { diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index b357bc3552a5e..df2c025842f4b 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -795,6 +795,24 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> { None } + + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + let mut acc = init; + let RawBuckets { mut raw, hashes_end, .. } = self; + while raw.hash != hashes_end { + unsafe { + // We are swapping out the pointer to a bucket and replacing + // it with the pointer to the next one. + let prev = ptr::replace(&mut raw, raw.offset(1)); + if *prev.hash != EMPTY_BUCKET { + acc = f(acc, prev) + } + } + } + acc + } } /// An iterator that moves out buckets in reverse order. It leaves the table @@ -899,6 +917,15 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.elems_left, Some(self.elems_left)) } + + #[inline] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.iter.fold(init, move |acc, bucket| { + f(acc, unsafe { (&(*bucket.pair).0, &(*bucket.pair).1) }) + }) + } } impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { fn len(&self) -> usize { @@ -920,6 +947,16 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.elems_left, Some(self.elems_left)) } + + #[inline] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + self.iter.fold(init, move |acc, bucket| { + let pair_mut = bucket.pair as *mut (K, V); + f(acc, unsafe { (&(*pair_mut).0, &mut (*pair_mut).1) }) + }) + } } impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { fn len(&self) -> usize {