diff --git a/src/raw/mod.rs b/src/raw/mod.rs
index 58a0a9178..2c6392181 100644
--- a/src/raw/mod.rs
+++ b/src/raw/mod.rs
@@ -163,6 +163,7 @@ fn h2(hash: u64) -> u8 {
///
/// Proof that the probe will visit every group in the table:
///
+#[derive(Clone)]
struct ProbeSeq {
pos: usize,
stride: usize,
@@ -4070,6 +4071,7 @@ pub struct RawIterHash {
_marker: PhantomData,
}
+#[derive(Clone)]
struct RawIterHashInner {
// See `RawTableInner`'s corresponding fields for details.
// We can't store a `*const RawTableInner` as it would get
@@ -4099,6 +4101,27 @@ impl RawIterHash {
}
}
+impl Clone for RawIterHash {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn clone(&self) -> Self {
+ Self {
+ inner: self.inner.clone(),
+ _marker: PhantomData,
+ }
+ }
+}
+
+impl Default for RawIterHash {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn default() -> Self {
+ Self {
+ // SAFETY: Because the table is static, it always outlives the iter.
+ inner: unsafe { RawIterHashInner::new(&RawTableInner::NEW, 0) },
+ _marker: PhantomData,
+ }
+ }
+}
+
impl RawIterHashInner {
#[cfg_attr(feature = "inline-more", inline)]
unsafe fn new(table: &RawTableInner, hash: u64) -> Self {
diff --git a/src/table.rs b/src/table.rs
index 0b8b66424..8f9530404 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -776,7 +776,7 @@ where
pub fn iter_hash(&self, hash: u64) -> IterHash<'_, T> {
IterHash {
inner: unsafe { self.raw.iter_hash(hash) },
- _marker: PhantomData,
+ marker: PhantomData,
}
}
@@ -829,7 +829,7 @@ where
pub fn iter_hash_mut(&mut self, hash: u64) -> IterHashMut<'_, T> {
IterHashMut {
inner: unsafe { self.raw.iter_hash(hash) },
- _marker: PhantomData,
+ marker: PhantomData,
}
}
@@ -1946,6 +1946,7 @@ impl<'a, T> Default for Iter<'a, T> {
}
}
}
+
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
@@ -2051,6 +2052,20 @@ impl ExactSizeIterator for IterMut<'_, T> {
impl FusedIterator for IterMut<'_, T> {}
+impl fmt::Debug for IterMut<'_, T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list()
+ .entries(Iter {
+ inner: self.inner.clone(),
+ marker: PhantomData,
+ })
+ .finish()
+ }
+}
+
/// An iterator over the entries of a `HashTable` that could match a given hash.
/// The iterator element type is `&'a T`.
///
@@ -2061,7 +2076,17 @@ impl FusedIterator for IterMut<'_, T> {}
/// [`HashTable`]: struct.HashTable.html
pub struct IterHash<'a, T> {
inner: RawIterHash,
- _marker: PhantomData<&'a T>,
+ marker: PhantomData<&'a T>,
+}
+
+impl<'a, T> Default for IterHash<'a, T> {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn default() -> Self {
+ IterHash {
+ inner: Default::default(),
+ marker: PhantomData,
+ }
+ }
}
impl<'a, T> Iterator for IterHash<'a, T> {
@@ -2074,6 +2099,37 @@ impl<'a, T> Iterator for IterHash<'a, T> {
None => None,
}
}
+
+ fn fold(self, init: B, mut f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.inner
+ .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
+ }
+}
+
+impl FusedIterator for IterHash<'_, T> {}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+impl<'a, T> Clone for IterHash<'a, T> {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn clone(&self) -> IterHash<'a, T> {
+ IterHash {
+ inner: self.inner.clone(),
+ marker: PhantomData,
+ }
+ }
+}
+
+impl fmt::Debug for IterHash<'_, T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
}
/// A mutable iterator over the entries of a `HashTable` that could match a given hash.
@@ -2086,7 +2142,17 @@ impl<'a, T> Iterator for IterHash<'a, T> {
/// [`HashTable`]: struct.HashTable.html
pub struct IterHashMut<'a, T> {
inner: RawIterHash,
- _marker: PhantomData<&'a mut T>,
+ marker: PhantomData<&'a mut T>,
+}
+
+impl<'a, T> Default for IterHashMut<'a, T> {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn default() -> Self {
+ IterHashMut {
+ inner: Default::default(),
+ marker: PhantomData,
+ }
+ }
}
impl<'a, T> Iterator for IterHashMut<'a, T> {
@@ -2099,6 +2165,31 @@ impl<'a, T> Iterator for IterHashMut<'a, T> {
None => None,
}
}
+
+ fn fold(self, init: B, mut f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.inner
+ .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
+ }
+}
+
+impl FusedIterator for IterHashMut<'_, T> {}
+
+impl fmt::Debug for IterHashMut<'_, T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list()
+ .entries(IterHash {
+ inner: self.inner.clone(),
+ marker: PhantomData,
+ })
+ .finish()
+ }
}
/// An owning iterator over the entries of a `HashTable` in arbitrary order.
@@ -2126,6 +2217,7 @@ impl Default for IntoIter {
}
}
}
+
impl Iterator for IntoIter
where
A: Allocator,
@@ -2160,6 +2252,21 @@ where
impl FusedIterator for IntoIter where A: Allocator {}
+impl fmt::Debug for IntoIter
+where
+ T: fmt::Debug,
+ A: Allocator,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list()
+ .entries(Iter {
+ inner: self.inner.iter(),
+ marker: PhantomData,
+ })
+ .finish()
+ }
+}
+
/// A draining iterator over the items of a `HashTable`.
///
/// This `struct` is created by the [`drain`] method on [`HashTable`].
@@ -2171,36 +2278,42 @@ pub struct Drain<'a, T, A: Allocator = Global> {
inner: RawDrain<'a, T, A>,
}
-impl Drain<'_, T, A> {
- /// Returns a iterator of references over the remaining items.
- fn iter(&self) -> Iter<'_, T> {
- Iter {
- inner: self.inner.iter(),
- marker: PhantomData,
- }
- }
-}
-
impl Iterator for Drain<'_, T, A> {
type Item = T;
fn next(&mut self) -> Option {
self.inner.next()
}
+
fn size_hint(&self) -> (usize, Option) {
self.inner.size_hint()
}
+
+ fn fold(self, init: B, f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.inner.fold(init, f)
+ }
}
+
impl ExactSizeIterator for Drain<'_, T, A> {
fn len(&self) -> usize {
self.inner.len()
}
}
+
impl FusedIterator for Drain<'_, T, A> {}
impl fmt::Debug for Drain<'_, T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_list().entries(self.iter()).finish()
+ f.debug_list()
+ .entries(Iter {
+ inner: self.inner.iter(),
+ marker: PhantomData,
+ })
+ .finish()
}
}