diff options
| author | The 8472 <git@infinite-source.de> | 2022-07-30 01:48:16 +0200 |
|---|---|---|
| committer | The 8472 <git@infinite-source.de> | 2023-02-28 21:00:00 +0100 |
| commit | 05c7330ca03650bbcb6a55f5fa490b3bb03c1940 (patch) | |
| tree | b7ace4e112ca9e379342f60cd877fbb40211b400 | |
| parent | 31f858d9a511f24fedb8ed997b28304fec809630 (diff) | |
| download | rust-05c7330ca03650bbcb6a55f5fa490b3bb03c1940.tar.gz rust-05c7330ca03650bbcb6a55f5fa490b3bb03c1940.zip | |
Implement Default for some alloc/core iterators
This way one can `mem::take()` them out of structs or #[derive(Default)] on structs containing them. These changes will be insta-stable.
| -rw-r--r-- | library/alloc/src/collections/binary_heap/mod.rs | 7 | ||||
| -rw-r--r-- | library/alloc/src/collections/btree/map.rs | 56 | ||||
| -rw-r--r-- | library/alloc/src/collections/btree/map/tests.rs | 16 | ||||
| -rw-r--r-- | library/alloc/src/collections/btree/navigate.rs | 12 | ||||
| -rw-r--r-- | library/alloc/src/collections/btree/set.rs | 22 | ||||
| -rw-r--r-- | library/alloc/src/collections/linked_list.rs | 21 | ||||
| -rw-r--r-- | library/alloc/src/collections/linked_list/tests.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/vec/into_iter.rs | 7 | ||||
| -rw-r--r-- | library/alloc/tests/vec.rs | 10 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/chain.rs | 11 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/cloned.rs | 11 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/copied.rs | 11 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/enumerate.rs | 10 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/flatten.rs | 11 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/fuse.rs | 7 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/rev.rs | 10 | ||||
| -rw-r--r-- | library/core/src/slice/iter/macros.rs | 7 | ||||
| -rw-r--r-- | library/core/tests/slice.rs | 10 |
18 files changed, 243 insertions, 2 deletions
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index f1d0a305d99..b0ec70ad565 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1468,6 +1468,13 @@ impl<T> ExactSizeIterator for IntoIter<T> { #[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for IntoIter<T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for IntoIter<T> { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + // In addition to the SAFETY invariants of the following three unsafe traits // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 386cd1a1657..c1e8a84969a 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -362,6 +362,13 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { + fn default() -> Self { + Iter { range: Default::default(), length: 0 } + } +} + /// A mutable iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`BTreeMap`]. See its @@ -386,6 +393,13 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { + fn default() -> Self { + IterMut { range: Default::default(), length: 0, _marker: PhantomData {} } + } +} + /// An owning iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`into_iter`] method on [`BTreeMap`] @@ -421,6 +435,13 @@ impl<K: Debug, V: Debug, A: Allocator + Clone> Debug for IntoIter<K, V, A> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for IntoIter<K, V> { + fn default() -> Self { + IntoIter { range: Default::default(), length: 0, alloc: Global } + } +} + /// An iterator over the keys of a `BTreeMap`. /// /// This `struct` is created by the [`keys`] method on [`BTreeMap`]. See its @@ -1768,6 +1789,13 @@ impl<K, V> Clone for Keys<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for Keys<'_, K, V> { + fn default() -> Self { + Keys { inner: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; @@ -1809,6 +1837,13 @@ impl<K, V> Clone for Values<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for Values<'_, K, V> { + fn default() -> Self { + Values { inner: Default::default() } + } +} + /// An iterator produced by calling `drain_filter` on BTreeMap. #[unstable(feature = "btree_drain_filter", issue = "70530")] pub struct DrainFilter< @@ -1945,6 +1980,13 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for Range<'_, K, V> { + fn default() -> Self { + Range { inner: Default::default() } + } +} + #[stable(feature = "map_values_mut", since = "1.10.0")] impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; @@ -2021,6 +2063,13 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoKeys<K, V, A> { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl<K, V, A: Allocator + Clone> FusedIterator for IntoKeys<K, V, A> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for IntoKeys<K, V> { + fn default() -> Self { + IntoKeys { inner: Default::default() } + } +} + #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl<K, V, A: Allocator + Clone> Iterator for IntoValues<K, V, A> { type Item = V; @@ -2055,6 +2104,13 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoValues<K, V, A> { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl<K, V, A: Allocator + Clone> FusedIterator for IntoValues<K, V, A> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<K, V> Default for IntoValues<K, V> { + fn default() -> Self { + IntoValues { inner: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 76c2f27b466..4d011195936 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -563,6 +563,22 @@ fn test_iter_min_max() { a.check(); } +#[test] +fn test_iters_default() { + let iter: Keys<'_, u8, u8> = Keys::default(); + assert_eq!(iter.len(), 0); + let iter: Values<'_, u8, u8> = Values::default(); + assert_eq!(iter.len(), 0); + let iter: Range<'_, u8, u8> = Range::default(); + assert_eq!(iter.count(), 0); + let iter: IntoIter<u8, u8> = IntoIter::default(); + assert_eq!(iter.len(), 0); + let iter: IntoKeys<u8, u8> = IntoKeys::default(); + assert_eq!(iter.len(), 0); + let iter: IntoValues<u8, u8> = IntoValues::default(); + assert_eq!(iter.len(), 0); +} + fn range_keys(map: &BTreeMap<i32, i32>, range: impl RangeBounds<i32>) -> Vec<i32> { Vec::from_iter(map.range(range).map(|(&k, &v)| { assert_eq!(k, v); diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index b890717e50b..a85a3162451 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -19,6 +19,12 @@ impl<'a, K: 'a, V: 'a> Clone for LeafRange<marker::Immut<'a>, K, V> { } } +impl<B, K, V> Default for LeafRange<B, K, V> { + fn default() -> Self { + LeafRange { front: None, back: None } + } +} + impl<BorrowType, K, V> LeafRange<BorrowType, K, V> { pub fn none() -> Self { LeafRange { front: None, back: None } @@ -124,6 +130,12 @@ pub struct LazyLeafRange<BorrowType, K, V> { back: Option<LazyLeafHandle<BorrowType, K, V>>, } +impl<B, K, V> Default for LazyLeafRange<B, K, V> { + fn default() -> Self { + LazyLeafRange { front: None, back: None } + } +} + impl<'a, K: 'a, V: 'a> Clone for LazyLeafRange<marker::Immut<'a>, K, V> { fn clone(&self) -> Self { LazyLeafRange { front: self.front.clone(), back: self.back.clone() } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 4ddb2119252..897499db429 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1544,6 +1544,14 @@ impl<T, A: Allocator + Clone> Iterator for IntoIter<T, A> { self.iter.size_hint() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for Iter<'_, T> { + fn default() -> Self { + Iter { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T, A: Allocator + Clone> DoubleEndedIterator for IntoIter<T, A> { fn next_back(&mut self) -> Option<T> { @@ -1560,6 +1568,13 @@ impl<T, A: Allocator + Clone> ExactSizeIterator for IntoIter<T, A> { #[stable(feature = "fused", since = "1.26.0")] impl<T, A: Allocator + Clone> FusedIterator for IntoIter<T, A> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for IntoIter<T> { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl<T> Clone for Range<'_, T> { fn clone(&self) -> Self { @@ -1598,6 +1613,13 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> { #[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for Range<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for Range<'_, T> { + fn default() -> Self { + Range { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T, A: Allocator + Clone> Clone for Difference<'_, T, A> { fn clone(&self) -> Self { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index f2f5dffc25d..dae7fc48b1f 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1075,6 +1075,13 @@ impl<T> ExactSizeIterator for Iter<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for Iter<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for Iter<'_, T> { + fn default() -> Self { + Iter { head: None, tail: None, len: 0, marker: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; @@ -1129,6 +1136,13 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for IterMut<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for IterMut<'_, T> { + fn default() -> Self { + IterMut { head: None, tail: None, len: 0, marker: Default::default() } + } +} + /// A cursor over a `LinkedList`. /// /// A `Cursor` is like an iterator, except that it can freely seek back-and-forth. @@ -1808,6 +1822,13 @@ impl<T> ExactSizeIterator for IntoIter<T> {} #[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for IntoIter<T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for IntoIter<T> { + fn default() -> Self { + LinkedList::new().into_iter() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T> FromIterator<T> for LinkedList<T> { fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 04594d55b6a..075c68f7241 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -173,6 +173,12 @@ fn test_iterator() { } #[test] +fn test_default() { + let iter: IntoIter<u8> = Default::default(); + assert_eq!(iter.len(), 0); +} + +#[test] fn test_iterator_clone() { let mut n = LinkedList::new(); n.push_back(2); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 37966007eb7..2be484c3dd4 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -347,6 +347,13 @@ impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<T> Default for IntoIter<T> { + fn default() -> Self { + super::Vec::new().into_iter() + } +} + #[doc(hidden)] #[unstable(issue = "none", feature = "std_internals")] #[rustc_unsafe_specialization_marker] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 2f07c2911a5..782b150681c 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,5 +1,6 @@ use core::alloc::{Allocator, Layout}; -use core::iter::IntoIterator; +use core::assert_eq; +use core::iter::{ExactSizeIterator, IntoIterator}; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1036,6 +1037,13 @@ fn test_into_iter_clone() { } #[test] +fn test_into_iter_default() { + let iter: IntoIter<u8> = Default::default(); + assert_eq!(iter.len(), 0); + assert_eq!(iter.as_slice(), &[]); +} + +#[test] fn test_into_iter_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 60eb3a6da3a..21fc3bc6f6f 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -282,6 +282,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<A, B> Default for Chain<A, B> +where + A: Iterator + Default, + B: Iterator + Default, +{ + fn default() -> Self { + Chain::new(Default::default(), Default::default()) + } +} + #[inline] fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> { let x = f(opt.as_mut()?); diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 914ff86c1a9..d22a6e721f5 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -153,3 +153,14 @@ where item.clone() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Cloned<I> +where + I: Default + Iterator<Item = &'a T>, + T: Clone, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 62d3afb8160..d5e579834ee 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -240,3 +240,14 @@ where } } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Copied<I> +where + I: Default + Iterator<Item = &'a T>, + T: Copy, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 14a12695111..0b44139a83b 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -264,3 +264,13 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<I> Default for Enumerate<I> +where + I: Iterator + Default, +{ + fn default() -> Self { + Enumerate::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index b040a0ea901..c0a347a7c1d 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -302,6 +302,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<I> Default for Flatten<I> +where + I: Iterator + Default, + <I as Iterator>::Item: IntoIterator, +{ + fn default() -> Self { + Flatten::new(Default::default()) + } +} + /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index c9314454203..87275fa3951 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -181,6 +181,13 @@ where } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<I: Default> Default for Fuse<I> { + fn default() -> Self { + Fuse { iter: Default::default() } + } +} + #[unstable(feature = "trusted_len", issue = "37572")] // SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse` // is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 139fb7bbdd9..4ad75ec0ea2 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -135,3 +135,13 @@ impl<I> FusedIterator for Rev<I> where I: FusedIterator + DoubleEndedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<I> Default for Rev<I> +where + I: Default + Iterator, +{ + fn default() -> Self { + Rev::new(Default::default()) + } +} diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 89b92a7d597..57754182c4e 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -393,6 +393,13 @@ macro_rules! iterator { } } } + + #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] + impl<T> Default for $name<'_, T> { + fn default() -> Self { + (& $( $mut_ )? []).into_iter() + } + } } } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 39559cdbb5e..294de77a6b0 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,8 +1,10 @@ use core::cell::Cell; use core::cmp::Ordering; +use core::iter::ExactSizeIterator; use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; -use core::slice; +use core::slice::Iter; +use core::{assert_eq, slice}; #[test] fn test_position() { @@ -225,6 +227,12 @@ fn test_iterator_count() { } #[test] +fn test_iterator_default() { + let iter: Iter<'_, u8> = Iter::default(); + assert_eq!(iter.len(), 0); +} + +#[test] fn test_chunks_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let c = v.chunks(3); |
