From eed52fb5e2d90c25ba25b1fe071f8d2091305201 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 15:42:04 -0700 Subject: [PATCH 1/8] Use double_ended_iterator_methods! --- src/map.rs | 32 ++++++++------------------------ src/set.rs | 8 ++------ 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/map.rs b/src/map.rs index aa8d06a0..9b833c35 100644 --- a/src/map.rs +++ b/src/map.rs @@ -813,9 +813,7 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { } impl DoubleEndedIterator for Keys<'_, K, V> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::key_ref) - } + double_ended_iterator_methods!(Bucket::key_ref); } impl ExactSizeIterator for Keys<'_, K, V> { @@ -857,9 +855,7 @@ impl Iterator for IntoKeys { } impl DoubleEndedIterator for IntoKeys { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::key) - } + double_ended_iterator_methods!(Bucket::key); } impl ExactSizeIterator for IntoKeys { @@ -893,9 +889,7 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { } impl DoubleEndedIterator for Values<'_, K, V> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::value_ref) - } + double_ended_iterator_methods!(Bucket::value_ref); } impl ExactSizeIterator for Values<'_, K, V> { @@ -937,9 +931,7 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { } impl DoubleEndedIterator for ValuesMut<'_, K, V> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::value_mut) - } + double_ended_iterator_methods!(Bucket::value_mut); } impl ExactSizeIterator for ValuesMut<'_, K, V> { @@ -966,9 +958,7 @@ impl Iterator for IntoValues { } impl DoubleEndedIterator for IntoValues { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::value) - } + double_ended_iterator_methods!(Bucket::value); } impl ExactSizeIterator for IntoValues { @@ -1002,9 +992,7 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { } impl DoubleEndedIterator for Iter<'_, K, V> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::refs) - } + double_ended_iterator_methods!(Bucket::refs); } impl ExactSizeIterator for Iter<'_, K, V> { @@ -1046,9 +1034,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { } impl DoubleEndedIterator for IterMut<'_, K, V> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::ref_mut) - } + double_ended_iterator_methods!(Bucket::ref_mut); } impl ExactSizeIterator for IterMut<'_, K, V> { @@ -1075,9 +1061,7 @@ impl Iterator for IntoIter { } impl DoubleEndedIterator for IntoIter { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::key_value) - } + double_ended_iterator_methods!(Bucket::key_value); } impl ExactSizeIterator for IntoIter { diff --git a/src/set.rs b/src/set.rs index 66c3da4d..f7f3232e 100644 --- a/src/set.rs +++ b/src/set.rs @@ -708,9 +708,7 @@ impl Iterator for IntoIter { } impl DoubleEndedIterator for IntoIter { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::key) - } + double_ended_iterator_methods!(Bucket::key); } impl ExactSizeIterator for IntoIter { @@ -744,9 +742,7 @@ impl<'a, T> Iterator for Iter<'a, T> { } impl DoubleEndedIterator for Iter<'_, T> { - fn next_back(&mut self) -> Option { - self.iter.next_back().map(Bucket::key_ref) - } + double_ended_iterator_methods!(Bucket::key_ref); } impl ExactSizeIterator for Iter<'_, T> { From d5c6269dadba2025022c653acf1d0cade3039113 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 15:48:39 -0700 Subject: [PATCH 2/8] Specialize nth_back just like nth --- src/macros.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/macros.rs b/src/macros.rs index c4d84217..a7b33508 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -116,5 +116,9 @@ macro_rules! double_ended_iterator_methods { fn next_back(&mut self) -> Option { self.iter.next_back().map($map_elt) } + + fn nth_back(&mut self, n: usize) -> Option { + self.iter.nth_back(n).map($map_elt) + } }; } From 306d6b11603cac5dcb2552941ff7465ef6756a13 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 15:48:43 -0700 Subject: [PATCH 3/8] Add rfold for iterators built on Chain --- src/set.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/set.rs b/src/set.rs index f7f3232e..f559999a 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1083,6 +1083,13 @@ where fn next_back(&mut self) -> Option { self.iter.next_back() } + + fn rfold(self, init: B, f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + self.iter.rfold(init, f) + } } impl Clone for SymmetricDifference<'_, T, S1, S2> { @@ -1146,6 +1153,13 @@ where fn next_back(&mut self) -> Option { self.iter.next_back() } + + fn rfold(self, init: B, f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + self.iter.rfold(init, f) + } } impl Clone for Union<'_, T, S> { From 3a44f893241a52f3fd71b6aac520017e8a2f6c29 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 16:07:38 -0700 Subject: [PATCH 4/8] impl ExactSizeIterator for Drain --- src/map.rs | 6 ++++++ src/set.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/map.rs b/src/map.rs index 9b833c35..fad30cf6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1098,6 +1098,12 @@ impl DoubleEndedIterator for Drain<'_, K, V> { double_ended_iterator_methods!(Bucket::key_value); } +impl ExactSizeIterator for Drain<'_, K, V> { + fn len(&self) -> usize { + self.iter.len() + } +} + impl<'a, K, V, S> IntoIterator for &'a IndexMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; diff --git a/src/set.rs b/src/set.rs index f559999a..404af274 100644 --- a/src/set.rs +++ b/src/set.rs @@ -786,6 +786,12 @@ impl DoubleEndedIterator for Drain<'_, T> { double_ended_iterator_methods!(Bucket::key); } +impl ExactSizeIterator for Drain<'_, T> { + fn len(&self) -> usize { + self.iter.len() + } +} + impl<'a, T, S> IntoIterator for &'a IndexSet { type Item = &'a T; type IntoIter = Iter<'a, T>; From 7423210e0e0575c8df578b51d95c17bb5630f5ed Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 16:08:29 -0700 Subject: [PATCH 5/8] impl FusedIterator for all iterators --- src/map.rs | 20 +++++++++++++++++++- src/set.rs | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/map.rs b/src/map.rs index fad30cf6..3d0536a1 100644 --- a/src/map.rs +++ b/src/map.rs @@ -12,7 +12,7 @@ use crate::vec::{self, Vec}; use ::core::cmp::Ordering; use ::core::fmt; use ::core::hash::{BuildHasher, Hash, Hasher}; -use ::core::iter::FromIterator; +use ::core::iter::{FromIterator, FusedIterator}; use ::core::ops::{Index, IndexMut, RangeBounds}; use ::core::slice::{Iter as SliceIter, IterMut as SliceIterMut}; @@ -822,6 +822,8 @@ impl ExactSizeIterator for Keys<'_, K, V> { } } +impl FusedIterator for Keys<'_, K, V> {} + // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Keys<'_, K, V> { fn clone(&self) -> Self { @@ -864,6 +866,8 @@ impl ExactSizeIterator for IntoKeys { } } +impl FusedIterator for IntoKeys {} + impl fmt::Debug for IntoKeys { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::key_ref); @@ -898,6 +902,8 @@ impl ExactSizeIterator for Values<'_, K, V> { } } +impl FusedIterator for Values<'_, K, V> {} + // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Values<'_, K, V> { fn clone(&self) -> Self { @@ -940,6 +946,8 @@ impl ExactSizeIterator for ValuesMut<'_, K, V> { } } +impl FusedIterator for ValuesMut<'_, K, V> {} + /// An owning iterator over the values of a `IndexMap`. /// /// This `struct` is created by the [`into_values`] method on [`IndexMap`]. @@ -967,6 +975,8 @@ impl ExactSizeIterator for IntoValues { } } +impl FusedIterator for IntoValues {} + impl fmt::Debug for IntoValues { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::value_ref); @@ -1001,6 +1011,8 @@ impl ExactSizeIterator for Iter<'_, K, V> { } } +impl FusedIterator for Iter<'_, K, V> {} + // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Iter<'_, K, V> { fn clone(&self) -> Self { @@ -1043,6 +1055,8 @@ impl ExactSizeIterator for IterMut<'_, K, V> { } } +impl FusedIterator for IterMut<'_, K, V> {} + /// An owning iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`into_iter`] method on [`IndexMap`] @@ -1070,6 +1084,8 @@ impl ExactSizeIterator for IntoIter { } } +impl FusedIterator for IntoIter {} + impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::refs); @@ -1104,6 +1120,8 @@ impl ExactSizeIterator for Drain<'_, K, V> { } } +impl FusedIterator for Drain<'_, K, V> {} + impl<'a, K, V, S> IntoIterator for &'a IndexMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; diff --git a/src/set.rs b/src/set.rs index 404af274..e17163e7 100644 --- a/src/set.rs +++ b/src/set.rs @@ -10,7 +10,7 @@ use crate::vec::{self, Vec}; use core::cmp::Ordering; use core::fmt; use core::hash::{BuildHasher, Hash}; -use core::iter::{Chain, FromIterator}; +use core::iter::{Chain, FromIterator, FusedIterator}; use core::ops::{BitAnd, BitOr, BitXor, Index, RangeBounds, Sub}; use core::slice; @@ -717,6 +717,8 @@ impl ExactSizeIterator for IntoIter { } } +impl FusedIterator for IntoIter {} + impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::key_ref); @@ -751,6 +753,8 @@ impl ExactSizeIterator for Iter<'_, T> { } } +impl FusedIterator for Iter<'_, T> {} + impl Clone for Iter<'_, T> { fn clone(&self) -> Self { Iter { @@ -792,6 +796,8 @@ impl ExactSizeIterator for Drain<'_, T> { } } +impl FusedIterator for Drain<'_, T> {} + impl<'a, T, S> IntoIterator for &'a IndexSet { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -959,6 +965,13 @@ where } } +impl FusedIterator for Difference<'_, T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ +} + impl Clone for Difference<'_, T, S> { fn clone(&self) -> Self { Difference { @@ -1026,6 +1039,13 @@ where } } +impl FusedIterator for Intersection<'_, T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ +} + impl Clone for Intersection<'_, T, S> { fn clone(&self) -> Self { Intersection { @@ -1098,6 +1118,14 @@ where } } +impl FusedIterator for SymmetricDifference<'_, T, S1, S2> +where + T: Eq + Hash, + S1: BuildHasher, + S2: BuildHasher, +{ +} + impl Clone for SymmetricDifference<'_, T, S1, S2> { fn clone(&self) -> Self { SymmetricDifference { @@ -1168,6 +1196,13 @@ where } } +impl FusedIterator for Union<'_, T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ +} + impl Clone for Union<'_, T, S> { fn clone(&self) -> Self { Union { From 2b9cbea4a185f9bc4ca89b7c7ff005d5f4f030be Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 16:23:23 -0700 Subject: [PATCH 6/8] impl Debug for Drain --- src/map.rs | 7 +++++++ src/set.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/map.rs b/src/map.rs index 3d0536a1..a2d8122d 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1122,6 +1122,13 @@ impl ExactSizeIterator for Drain<'_, K, V> { impl FusedIterator for Drain<'_, K, V> {} +impl fmt::Debug for Drain<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let iter = self.iter.as_slice().iter().map(Bucket::refs); + f.debug_list().entries(iter).finish() + } +} + impl<'a, K, V, S> IntoIterator for &'a IndexMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; diff --git a/src/set.rs b/src/set.rs index e17163e7..134c9045 100644 --- a/src/set.rs +++ b/src/set.rs @@ -798,6 +798,13 @@ impl ExactSizeIterator for Drain<'_, T> { impl FusedIterator for Drain<'_, T> {} +impl fmt::Debug for Drain<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let iter = self.iter.as_slice().iter().map(Bucket::key_ref); + f.debug_list().entries(iter).finish() + } +} + impl<'a, T, S> IntoIterator for &'a IndexSet { type Item = &'a T; type IntoIter = Iter<'a, T>; From 19789dcb537964e47cc88646a8eb9739d1064a25 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 16:25:08 -0700 Subject: [PATCH 7/8] impl Debug for ParIterMut --- src/map.rs | 2 ++ src/rayon/map.rs | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/map.rs b/src/map.rs index a2d8122d..4beb5f44 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1057,6 +1057,8 @@ impl ExactSizeIterator for IterMut<'_, K, V> { impl FusedIterator for IterMut<'_, K, V> {} +// TODO: `impl Debug for IterMut` once we have MSRV 1.53 for `slice::IterMut::as_slice` + /// An owning iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`into_iter`] method on [`IndexMap`] diff --git a/src/rayon/map.rs b/src/rayon/map.rs index ed2da3ef..1bfce60c 100644 --- a/src/rayon/map.rs +++ b/src/rayon/map.rs @@ -139,6 +139,13 @@ pub struct ParIterMut<'a, K, V> { entries: &'a mut [Bucket], } +impl fmt::Debug for ParIterMut<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let iter = self.entries.iter().map(Bucket::refs); + f.debug_list().entries(iter).finish() + } +} + impl<'a, K: Sync + Send, V: Send> ParallelIterator for ParIterMut<'a, K, V> { type Item = (&'a K, &'a mut V); From e594967b47b9f1dedbf8b9693b61a38f2994aa69 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 30 Jul 2021 16:25:23 -0700 Subject: [PATCH 8/8] impl Debug for ParValuesMut --- src/map.rs | 2 ++ src/rayon/map.rs | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/map.rs b/src/map.rs index 4beb5f44..3a43a79b 100644 --- a/src/map.rs +++ b/src/map.rs @@ -948,6 +948,8 @@ impl ExactSizeIterator for ValuesMut<'_, K, V> { impl FusedIterator for ValuesMut<'_, K, V> {} +// TODO: `impl Debug for ValuesMut` once we have MSRV 1.53 for `slice::IterMut::as_slice` + /// An owning iterator over the values of a `IndexMap`. /// /// This `struct` is created by the [`into_values`] method on [`IndexMap`]. diff --git a/src/rayon/map.rs b/src/rayon/map.rs index 1bfce60c..bedad3c4 100644 --- a/src/rayon/map.rs +++ b/src/rayon/map.rs @@ -346,6 +346,13 @@ pub struct ParValuesMut<'a, K, V> { entries: &'a mut [Bucket], } +impl fmt::Debug for ParValuesMut<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let iter = self.entries.iter().map(Bucket::value_ref); + f.debug_list().entries(iter).finish() + } +} + impl<'a, K: Send, V: Send> ParallelIterator for ParValuesMut<'a, K, V> { type Item = &'a mut V;