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) + } }; } diff --git a/src/map.rs b/src/map.rs index aa8d06a0..3a43a79b 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}; @@ -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> { @@ -824,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 { @@ -857,9 +857,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 { @@ -868,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); @@ -893,9 +893,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> { @@ -904,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 { @@ -937,9 +937,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> { @@ -948,6 +946,10 @@ 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`]. @@ -966,9 +968,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 { @@ -977,6 +977,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); @@ -1002,9 +1004,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> { @@ -1013,6 +1013,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 { @@ -1046,9 +1048,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> { @@ -1057,6 +1057,10 @@ 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`] @@ -1075,9 +1079,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 { @@ -1086,6 +1088,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); @@ -1114,6 +1118,21 @@ 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 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/rayon/map.rs b/src/rayon/map.rs index ed2da3ef..bedad3c4 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); @@ -339,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; diff --git a/src/set.rs b/src/set.rs index 66c3da4d..134c9045 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; @@ -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 { @@ -719,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); @@ -744,9 +744,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> { @@ -755,6 +753,8 @@ impl ExactSizeIterator for Iter<'_, T> { } } +impl FusedIterator for Iter<'_, T> {} + impl Clone for Iter<'_, T> { fn clone(&self) -> Self { Iter { @@ -790,6 +790,21 @@ impl DoubleEndedIterator for Drain<'_, T> { double_ended_iterator_methods!(Bucket::key); } +impl ExactSizeIterator for Drain<'_, T> { + fn len(&self) -> usize { + self.iter.len() + } +} + +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>; @@ -957,6 +972,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 { @@ -1024,6 +1046,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 { @@ -1087,6 +1116,21 @@ 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 FusedIterator for SymmetricDifference<'_, T, S1, S2> +where + T: Eq + Hash, + S1: BuildHasher, + S2: BuildHasher, +{ } impl Clone for SymmetricDifference<'_, T, S1, S2> { @@ -1150,6 +1194,20 @@ 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 FusedIterator for Union<'_, T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ } impl Clone for Union<'_, T, S> {