Skip to content

Commit 7cf51ea

Browse files
committed
Auto merge of #561 - Amanieu:debug-iter, r=cuviper
Implement `Debug`, `FusedIterator` and `Iterator::fold` for all `HashTable` iterators
2 parents a25cd3b + 7af86ab commit 7cf51ea

File tree

2 files changed

+151
-15
lines changed

2 files changed

+151
-15
lines changed

src/raw/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ fn h2(hash: u64) -> u8 {
163163
///
164164
/// Proof that the probe will visit every group in the table:
165165
/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
166+
#[derive(Clone)]
166167
struct ProbeSeq {
167168
pos: usize,
168169
stride: usize,
@@ -4070,6 +4071,7 @@ pub struct RawIterHash<T> {
40704071
_marker: PhantomData<T>,
40714072
}
40724073

4074+
#[derive(Clone)]
40734075
struct RawIterHashInner {
40744076
// See `RawTableInner`'s corresponding fields for details.
40754077
// We can't store a `*const RawTableInner` as it would get
@@ -4099,6 +4101,27 @@ impl<T> RawIterHash<T> {
40994101
}
41004102
}
41014103

4104+
impl<T> Clone for RawIterHash<T> {
4105+
#[cfg_attr(feature = "inline-more", inline)]
4106+
fn clone(&self) -> Self {
4107+
Self {
4108+
inner: self.inner.clone(),
4109+
_marker: PhantomData,
4110+
}
4111+
}
4112+
}
4113+
4114+
impl<T> Default for RawIterHash<T> {
4115+
#[cfg_attr(feature = "inline-more", inline)]
4116+
fn default() -> Self {
4117+
Self {
4118+
// SAFETY: Because the table is static, it always outlives the iter.
4119+
inner: unsafe { RawIterHashInner::new(&RawTableInner::NEW, 0) },
4120+
_marker: PhantomData,
4121+
}
4122+
}
4123+
}
4124+
41024125
impl RawIterHashInner {
41034126
#[cfg_attr(feature = "inline-more", inline)]
41044127
unsafe fn new(table: &RawTableInner, hash: u64) -> Self {

src/table.rs

Lines changed: 128 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ where
776776
pub fn iter_hash(&self, hash: u64) -> IterHash<'_, T> {
777777
IterHash {
778778
inner: unsafe { self.raw.iter_hash(hash) },
779-
_marker: PhantomData,
779+
marker: PhantomData,
780780
}
781781
}
782782

@@ -829,7 +829,7 @@ where
829829
pub fn iter_hash_mut(&mut self, hash: u64) -> IterHashMut<'_, T> {
830830
IterHashMut {
831831
inner: unsafe { self.raw.iter_hash(hash) },
832-
_marker: PhantomData,
832+
marker: PhantomData,
833833
}
834834
}
835835

@@ -1946,6 +1946,7 @@ impl<'a, T> Default for Iter<'a, T> {
19461946
}
19471947
}
19481948
}
1949+
19491950
impl<'a, T> Iterator for Iter<'a, T> {
19501951
type Item = &'a T;
19511952

@@ -2051,6 +2052,20 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {
20512052

20522053
impl<T> FusedIterator for IterMut<'_, T> {}
20532054

2055+
impl<T> fmt::Debug for IterMut<'_, T>
2056+
where
2057+
T: fmt::Debug,
2058+
{
2059+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2060+
f.debug_list()
2061+
.entries(Iter {
2062+
inner: self.inner.clone(),
2063+
marker: PhantomData,
2064+
})
2065+
.finish()
2066+
}
2067+
}
2068+
20542069
/// An iterator over the entries of a `HashTable` that could match a given hash.
20552070
/// The iterator element type is `&'a T`.
20562071
///
@@ -2061,7 +2076,17 @@ impl<T> FusedIterator for IterMut<'_, T> {}
20612076
/// [`HashTable`]: struct.HashTable.html
20622077
pub struct IterHash<'a, T> {
20632078
inner: RawIterHash<T>,
2064-
_marker: PhantomData<&'a T>,
2079+
marker: PhantomData<&'a T>,
2080+
}
2081+
2082+
impl<'a, T> Default for IterHash<'a, T> {
2083+
#[cfg_attr(feature = "inline-more", inline)]
2084+
fn default() -> Self {
2085+
IterHash {
2086+
inner: Default::default(),
2087+
marker: PhantomData,
2088+
}
2089+
}
20652090
}
20662091

20672092
impl<'a, T> Iterator for IterHash<'a, T> {
@@ -2074,6 +2099,37 @@ impl<'a, T> Iterator for IterHash<'a, T> {
20742099
None => None,
20752100
}
20762101
}
2102+
2103+
fn fold<B, F>(self, init: B, mut f: F) -> B
2104+
where
2105+
Self: Sized,
2106+
F: FnMut(B, Self::Item) -> B,
2107+
{
2108+
self.inner
2109+
.fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
2110+
}
2111+
}
2112+
2113+
impl<T> FusedIterator for IterHash<'_, T> {}
2114+
2115+
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2116+
impl<'a, T> Clone for IterHash<'a, T> {
2117+
#[cfg_attr(feature = "inline-more", inline)]
2118+
fn clone(&self) -> IterHash<'a, T> {
2119+
IterHash {
2120+
inner: self.inner.clone(),
2121+
marker: PhantomData,
2122+
}
2123+
}
2124+
}
2125+
2126+
impl<T> fmt::Debug for IterHash<'_, T>
2127+
where
2128+
T: fmt::Debug,
2129+
{
2130+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2131+
f.debug_list().entries(self.clone()).finish()
2132+
}
20772133
}
20782134

20792135
/// 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> {
20862142
/// [`HashTable`]: struct.HashTable.html
20872143
pub struct IterHashMut<'a, T> {
20882144
inner: RawIterHash<T>,
2089-
_marker: PhantomData<&'a mut T>,
2145+
marker: PhantomData<&'a mut T>,
2146+
}
2147+
2148+
impl<'a, T> Default for IterHashMut<'a, T> {
2149+
#[cfg_attr(feature = "inline-more", inline)]
2150+
fn default() -> Self {
2151+
IterHashMut {
2152+
inner: Default::default(),
2153+
marker: PhantomData,
2154+
}
2155+
}
20902156
}
20912157

20922158
impl<'a, T> Iterator for IterHashMut<'a, T> {
@@ -2099,6 +2165,31 @@ impl<'a, T> Iterator for IterHashMut<'a, T> {
20992165
None => None,
21002166
}
21012167
}
2168+
2169+
fn fold<B, F>(self, init: B, mut f: F) -> B
2170+
where
2171+
Self: Sized,
2172+
F: FnMut(B, Self::Item) -> B,
2173+
{
2174+
self.inner
2175+
.fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
2176+
}
2177+
}
2178+
2179+
impl<T> FusedIterator for IterHashMut<'_, T> {}
2180+
2181+
impl<T> fmt::Debug for IterHashMut<'_, T>
2182+
where
2183+
T: fmt::Debug,
2184+
{
2185+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2186+
f.debug_list()
2187+
.entries(IterHash {
2188+
inner: self.inner.clone(),
2189+
marker: PhantomData,
2190+
})
2191+
.finish()
2192+
}
21022193
}
21032194

21042195
/// An owning iterator over the entries of a `HashTable` in arbitrary order.
@@ -2126,6 +2217,7 @@ impl<T, A: Allocator> Default for IntoIter<T, A> {
21262217
}
21272218
}
21282219
}
2220+
21292221
impl<T, A> Iterator for IntoIter<T, A>
21302222
where
21312223
A: Allocator,
@@ -2160,6 +2252,21 @@ where
21602252

21612253
impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}
21622254

2255+
impl<T, A> fmt::Debug for IntoIter<T, A>
2256+
where
2257+
T: fmt::Debug,
2258+
A: Allocator,
2259+
{
2260+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2261+
f.debug_list()
2262+
.entries(Iter {
2263+
inner: self.inner.iter(),
2264+
marker: PhantomData,
2265+
})
2266+
.finish()
2267+
}
2268+
}
2269+
21632270
/// A draining iterator over the items of a `HashTable`.
21642271
///
21652272
/// This `struct` is created by the [`drain`] method on [`HashTable`].
@@ -2171,36 +2278,42 @@ pub struct Drain<'a, T, A: Allocator = Global> {
21712278
inner: RawDrain<'a, T, A>,
21722279
}
21732280

2174-
impl<T, A: Allocator> Drain<'_, T, A> {
2175-
/// Returns a iterator of references over the remaining items.
2176-
fn iter(&self) -> Iter<'_, T> {
2177-
Iter {
2178-
inner: self.inner.iter(),
2179-
marker: PhantomData,
2180-
}
2181-
}
2182-
}
2183-
21842281
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
21852282
type Item = T;
21862283

21872284
fn next(&mut self) -> Option<T> {
21882285
self.inner.next()
21892286
}
2287+
21902288
fn size_hint(&self) -> (usize, Option<usize>) {
21912289
self.inner.size_hint()
21922290
}
2291+
2292+
fn fold<B, F>(self, init: B, f: F) -> B
2293+
where
2294+
Self: Sized,
2295+
F: FnMut(B, Self::Item) -> B,
2296+
{
2297+
self.inner.fold(init, f)
2298+
}
21932299
}
2300+
21942301
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
21952302
fn len(&self) -> usize {
21962303
self.inner.len()
21972304
}
21982305
}
2306+
21992307
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
22002308

22012309
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
22022310
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2203-
f.debug_list().entries(self.iter()).finish()
2311+
f.debug_list()
2312+
.entries(Iter {
2313+
inner: self.inner.iter(),
2314+
marker: PhantomData,
2315+
})
2316+
.finish()
22042317
}
22052318
}
22062319

0 commit comments

Comments
 (0)