Auto merge of #79319 - m-ou-se:rollup-d9n5viq, r=m-ou-se

Rollup of 10 pull requests

Successful merges:

 - #76941 (Add f{32,64}::is_subnormal)
 - #77697 (Split each iterator adapter and source into individual modules)
 - #78305 (Stabilize alloc::Layout const functions)
 - #78608 (Stabilize refcell_take)
 - #78793 (Clean up `StructuralEq` docs)
 - #79267 (BTreeMap: address namespace conflicts)
 - #79293 (Add test for eval order for a+=b)
 - #79295 (BTreeMap: fix minor testing mistakes in #78903)
 - #79297 (BTreeMap: swap the names of NodeRef::new and Root::new_leaf)
 - #79299 (Stabilise `then`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2020-11-22 23:59:48 +00:00
commit 32da90b431
53 changed files with 3778 additions and 3551 deletions

View File

@ -1,5 +1,4 @@
#![feature(allow_internal_unstable)]
#![feature(bool_to_option)]
#![feature(const_fn)]
#![feature(const_panic)]
#![feature(extend_one)]

View File

@ -1,5 +1,4 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(bool_to_option)]
#![feature(core_intrinsics)]
#![feature(crate_visibility_modifier)]
#![feature(drain_filter)]

View File

@ -1,6 +1,5 @@
//! The main parser interface.
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(bindings_after_at)]
#![feature(iter_order_by)]

View File

@ -67,7 +67,7 @@ impl<K, V> Root<K, V> {
// Push key-value pair and new right subtree.
let tree_height = open_node.height() - 1;
let mut right_tree = Root::new_leaf();
let mut right_tree = Root::new();
for _ in 0..tree_height {
right_tree.push_internal_level();
}

View File

@ -9,7 +9,7 @@ use core::ops::{Index, RangeBounds};
use core::ptr;
use super::borrow::DormantMutRef;
use super::node::{self, marker, ForceResult::*, Handle, NodeRef};
use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
use super::search::{self, SearchResult::*};
use super::unwrap_unchecked;
@ -128,7 +128,7 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BTreeMap<K, V> {
root: Option<node::Root<K, V>>,
root: Option<Root<K, V>>,
length: usize,
}
@ -145,7 +145,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
fn clone(&self) -> BTreeMap<K, V> {
fn clone_subtree<'a, K: Clone, V: Clone>(
node: node::NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>,
node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>,
) -> BTreeMap<K, V>
where
K: 'a,
@ -153,7 +153,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
{
match node.force() {
Leaf(leaf) => {
let mut out_tree = BTreeMap { root: Some(node::Root::new_leaf()), length: 0 };
let mut out_tree = BTreeMap { root: Some(Root::new()), length: 0 };
{
let root = out_tree.root.as_mut().unwrap(); // unwrap succeeds because we just wrapped
@ -198,7 +198,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
(root, length)
};
out_node.push(k, v, subroot.unwrap_or_else(node::Root::new_leaf));
out_node.push(k, v, subroot.unwrap_or_else(Root::new));
out_tree.length += 1 + sublength;
}
}
@ -1558,7 +1558,7 @@ pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> {
length: &'a mut usize,
/// Burried reference to the root field in the borrowed map.
/// Wrapped in `Option` to allow drop handler to `take` it.
dormant_root: Option<DormantMutRef<'a, node::Root<K, V>>>,
dormant_root: Option<DormantMutRef<'a, Root<K, V>>>,
/// Contains a leaf edge preceding the next element to be returned, or the last leaf edge.
/// Empty if the map has no root, if iteration went beyond the last leaf edge,
/// or if a panic occurred in the predicate.
@ -2160,8 +2160,8 @@ impl<K, V> BTreeMap<K, V> {
/// If the root node is the empty (non-allocated) root node, allocate our
/// own node. Is an associated function to avoid borrowing the entire BTreeMap.
fn ensure_is_owned(root: &mut Option<node::Root<K, V>>) -> &mut node::Root<K, V> {
root.get_or_insert_with(node::Root::new_leaf)
fn ensure_is_owned(root: &mut Option<Root<K, V>>) -> &mut Root<K, V> {
root.get_or_insert_with(Root::new)
}
}

View File

@ -6,13 +6,14 @@ use crate::fmt::Debug;
use crate::rc::Rc;
use crate::string::{String, ToString};
use crate::vec::Vec;
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::iter::{self, FromIterator};
use std::mem;
use std::ops::Bound::{self, Excluded, Included, Unbounded};
use std::ops::RangeBounds;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
mod ord_chaos;
use ord_chaos::{Cyclic3, Governed, Governor};
@ -56,24 +57,23 @@ impl<K, V> BTreeMap<K, V> {
assert!(root_node.ascend().is_err());
root_node.assert_back_pointers();
// Check consistenty of `length` and some of the navigation.
// Check consistency of `length` with what navigation code encounters.
assert_eq!(self.length, root_node.calc_length());
assert_eq!(self.length, self.keys().count());
// Lastly, check the invariant causing the least harm.
root_node.assert_min_len(if root_node.height() > 0 { 1 } else { 0 });
} else {
// Check consistenty of `length` and some of the navigation.
assert_eq!(self.length, 0);
assert_eq!(self.length, self.keys().count());
}
// Check that `assert_strictly_ascending` will encounter all keys.
assert_eq!(self.length, self.keys().count());
}
// Panics if the map is corrupted or if the keys are not in strictly
// ascending order, in the current opinion of the `Ord` implementation.
// If the `Ord` implementation does not honor transitivity, this method
// does not guarantee that all the keys are unique, just that adjacent
// keys are unique.
// If the `Ord` implementation violates transitivity, this method does not
// guarantee that all keys are unique, just that adjacent keys are unique.
fn check(&self)
where
K: Debug + Ord,
@ -879,6 +879,7 @@ mod test_drain_filter {
map.check();
}
// Explicitly consumes the iterator, where most test cases drop it instantly.
#[test]
fn consumed_keeping_all() {
let pairs = (0..3).map(|i| (i, i));
@ -887,6 +888,7 @@ mod test_drain_filter {
map.check();
}
// Explicitly consumes the iterator, where most test cases drop it instantly.
#[test]
fn consumed_removing_all() {
let pairs = (0..3).map(|i| (i, i));
@ -896,15 +898,7 @@ mod test_drain_filter {
map.check();
}
#[test]
fn dropped_removing_all() {
let pairs = (0..3).map(|i| (i, i));
let mut map: BTreeMap<_, _> = pairs.collect();
map.drain_filter(|_, _| true);
assert!(map.is_empty());
map.check();
}
// Explicitly consumes the iterator and modifies values through it.
#[test]
fn mutating_and_keeping() {
let pairs = (0..3).map(|i| (i, i));
@ -921,6 +915,7 @@ mod test_drain_filter {
map.check();
}
// Explicitly consumes the iterator and modifies values through it.
#[test]
fn mutating_and_removing() {
let pairs = (0..3).map(|i| (i, i));
@ -1094,7 +1089,7 @@ mod test_drain_filter {
struct D;
impl Drop for D {
fn drop(&mut self) {
if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
if DROPS.fetch_add(1, SeqCst) == 1 {
panic!("panic in `drop`");
}
}
@ -1105,14 +1100,14 @@ mod test_drain_filter {
catch_unwind(move || {
drop(map.drain_filter(|i, _| {
PREDS.fetch_add(1usize << i, Ordering::SeqCst);
PREDS.fetch_add(1usize << i, SeqCst);
true
}))
})
.unwrap_err();
assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
assert_eq!(PREDS.load(SeqCst), 0x011);
assert_eq!(DROPS.load(SeqCst), 3);
}
#[test]
@ -1123,7 +1118,7 @@ mod test_drain_filter {
struct D;
impl Drop for D {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
DROPS.fetch_add(1, SeqCst);
}
}
@ -1132,7 +1127,7 @@ mod test_drain_filter {
catch_unwind(AssertUnwindSafe(|| {
drop(map.drain_filter(|i, _| {
PREDS.fetch_add(1usize << i, Ordering::SeqCst);
PREDS.fetch_add(1usize << i, SeqCst);
match i {
0 => true,
_ => panic!(),
@ -1141,8 +1136,8 @@ mod test_drain_filter {
}))
.unwrap_err();
assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 1);
assert_eq!(PREDS.load(SeqCst), 0x011);
assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(map.len(), 2);
assert_eq!(map.first_entry().unwrap().key(), &4);
assert_eq!(map.last_entry().unwrap().key(), &8);
@ -1158,7 +1153,7 @@ mod test_drain_filter {
struct D;
impl Drop for D {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
DROPS.fetch_add(1, SeqCst);
}
}
@ -1167,7 +1162,7 @@ mod test_drain_filter {
{
let mut it = map.drain_filter(|i, _| {
PREDS.fetch_add(1usize << i, Ordering::SeqCst);
PREDS.fetch_add(1usize << i, SeqCst);
match i {
0 => true,
_ => panic!(),
@ -1180,8 +1175,8 @@ mod test_drain_filter {
assert!(matches!(result, Ok(None)));
}
assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 1);
assert_eq!(PREDS.load(SeqCst), 0x011);
assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(map.len(), 2);
assert_eq!(map.first_entry().unwrap().key(), &4);
assert_eq!(map.last_entry().unwrap().key(), &8);
@ -1315,8 +1310,6 @@ fn test_zst() {
// undefined.
#[test]
fn test_bad_zst() {
use std::cmp::Ordering;
#[derive(Clone, Copy, Debug)]
struct Bad;
@ -1763,7 +1756,7 @@ fn test_append_drop_leak() {
impl Drop for D {
fn drop(&mut self) {
if DROPS.fetch_add(1, Ordering::SeqCst) == 0 {
if DROPS.fetch_add(1, SeqCst) == 0 {
panic!("panic in `drop`");
}
}
@ -1779,7 +1772,7 @@ fn test_append_drop_leak() {
catch_unwind(move || left.append(&mut right)).unwrap_err();
assert_eq!(DROPS.load(Ordering::SeqCst), 4); // Rust issue #47949 ate one little piggy
assert_eq!(DROPS.load(SeqCst), 4); // Rust issue #47949 ate one little piggy
}
#[test]
@ -1894,7 +1887,7 @@ fn test_into_iter_drop_leak_height_0() {
impl Drop for D {
fn drop(&mut self) {
if DROPS.fetch_add(1, Ordering::SeqCst) == 3 {
if DROPS.fetch_add(1, SeqCst) == 3 {
panic!("panic in `drop`");
}
}
@ -1909,7 +1902,7 @@ fn test_into_iter_drop_leak_height_0() {
catch_unwind(move || drop(map.into_iter())).unwrap_err();
assert_eq!(DROPS.load(Ordering::SeqCst), 5);
assert_eq!(DROPS.load(SeqCst), 5);
}
#[test]
@ -1921,18 +1914,18 @@ fn test_into_iter_drop_leak_height_1() {
struct D;
impl Drop for D {
fn drop(&mut self) {
if DROPS.fetch_add(1, Ordering::SeqCst) == PANIC_POINT.load(Ordering::SeqCst) {
if DROPS.fetch_add(1, SeqCst) == PANIC_POINT.load(SeqCst) {
panic!("panic in `drop`");
}
}
}
for panic_point in vec![0, 1, size - 2, size - 1] {
DROPS.store(0, Ordering::SeqCst);
PANIC_POINT.store(panic_point, Ordering::SeqCst);
DROPS.store(0, SeqCst);
PANIC_POINT.store(panic_point, SeqCst);
let map: BTreeMap<_, _> = (0..size).map(|i| (i, D)).collect();
catch_unwind(move || drop(map.into_iter())).unwrap_err();
assert_eq!(DROPS.load(Ordering::SeqCst), size);
assert_eq!(DROPS.load(SeqCst), size);
}
}

View File

@ -2,6 +2,7 @@ use std::cell::Cell;
use std::cmp::Ordering::{self, *};
use std::ptr;
// Minimal type with an `Ord` implementation violating transitivity.
#[derive(Debug)]
pub enum Cyclic3 {
A,
@ -34,6 +35,7 @@ impl PartialEq for Cyclic3 {
impl Eq for Cyclic3 {}
// Controls the ordering of values wrapped by `Governed`.
#[derive(Debug)]
pub struct Governor {
flipped: Cell<bool>,
@ -49,6 +51,9 @@ impl Governor {
}
}
// Type with an `Ord` implementation that forms a total order at any moment
// (assuming that `T` respects total order), but can suddenly be made to invert
// that total order.
#[derive(Debug)]
pub struct Governed<'a, T>(pub T, pub &'a Governor);

View File

@ -134,13 +134,13 @@ pub type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
impl<K, V> Root<K, V> {
/// Returns a new owned tree, with its own root node that is initially empty.
pub fn new_leaf() -> Self {
NodeRef::new().forget_type()
pub fn new() -> Self {
NodeRef::new_leaf().forget_type()
}
}
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
fn new() -> Self {
fn new_leaf() -> Self {
Self::from_new_leaf(Box::new(unsafe { LeafNode::new() }))
}

View File

@ -74,12 +74,12 @@ fn test_splitpoint() {
#[test]
fn test_partial_cmp_eq() {
let mut root1 = NodeRef::new();
let mut root1 = NodeRef::new_leaf();
let mut leaf1 = root1.borrow_mut();
leaf1.push(1, ());
let mut root1 = root1.forget_type();
root1.push_internal_level();
let root2 = Root::new_leaf();
let root2 = Root::new();
root1.reborrow().assert_back_pointers();
root2.reborrow().assert_back_pointers();

View File

@ -50,7 +50,7 @@ where
{
match search_linear(&node, key) {
(idx, true) => Found(unsafe { Handle::new_kv(node, idx) }),
(idx, false) => SearchResult::GoDown(unsafe { Handle::new_edge(node, idx) }),
(idx, false) => GoDown(unsafe { Handle::new_edge(node, idx) }),
}
}

View File

@ -1,9 +1,10 @@
use super::super::DeterministicRng;
use super::*;
use crate::vec::Vec;
use std::cmp::Ordering;
use std::iter::FromIterator;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::atomic::{AtomicU32, Ordering::SeqCst};
#[test]
fn test_clone_eq() {
@ -355,7 +356,7 @@ fn test_drain_filter_drop_panic_leak() {
struct D(i32);
impl Drop for D {
fn drop(&mut self) {
if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
if DROPS.fetch_add(1, SeqCst) == 1 {
panic!("panic in `drop`");
}
}
@ -368,14 +369,14 @@ fn test_drain_filter_drop_panic_leak() {
catch_unwind(move || {
drop(set.drain_filter(|d| {
PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
PREDS.fetch_add(1u32 << d.0, SeqCst);
true
}))
})
.ok();
assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 3);
assert_eq!(PREDS.load(SeqCst), 0x011);
assert_eq!(DROPS.load(SeqCst), 3);
}
#[test]
@ -387,7 +388,7 @@ fn test_drain_filter_pred_panic_leak() {
struct D(i32);
impl Drop for D {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
DROPS.fetch_add(1, SeqCst);
}
}
@ -398,7 +399,7 @@ fn test_drain_filter_pred_panic_leak() {
catch_unwind(AssertUnwindSafe(|| {
drop(set.drain_filter(|d| {
PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
PREDS.fetch_add(1u32 << d.0, SeqCst);
match d.0 {
0 => true,
_ => panic!(),
@ -407,8 +408,8 @@ fn test_drain_filter_pred_panic_leak() {
}))
.ok();
assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
assert_eq!(DROPS.load(Ordering::SeqCst), 1);
assert_eq!(PREDS.load(SeqCst), 0x011);
assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(set.len(), 2);
assert_eq!(set.first().unwrap().0, 4);
assert_eq!(set.last().unwrap().0, 8);
@ -498,8 +499,6 @@ fn test_extend_ref() {
#[test]
fn test_recovery() {
use std::cmp::Ordering;
#[derive(Debug)]
struct Foo(&'static str, i32);

View File

@ -50,7 +50,7 @@ impl Layout {
/// must not overflow (i.e., the rounded value must be less than
/// or equal to `usize::MAX`).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
if !align.is_power_of_two() {
@ -96,7 +96,7 @@ impl Layout {
/// The minimum size in bytes for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn size(&self) -> usize {
self.size_
@ -104,7 +104,7 @@ impl Layout {
/// The minimum byte alignment for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
#[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn align(&self) -> usize {
self.align_.get()

View File

@ -23,12 +23,10 @@ impl bool {
/// # Examples
///
/// ```
/// #![feature(bool_to_option)]
///
/// assert_eq!(false.then(|| 0), None);
/// assert_eq!(true.then(|| 0), Some(0));
/// ```
#[unstable(feature = "bool_to_option", issue = "64260")]
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
#[inline]
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
if self { Some(f()) } else { None }

View File

@ -1027,7 +1027,6 @@ impl<T: Default> RefCell<T> {
/// # Examples
///
/// ```
/// #![feature(refcell_take)]
/// use std::cell::RefCell;
///
/// let c = RefCell::new(5);
@ -1036,7 +1035,7 @@ impl<T: Default> RefCell<T> {
/// assert_eq!(five, 5);
/// assert_eq!(c.into_inner(), 0);
/// ```
#[unstable(feature = "refcell_take", issue = "71395")]
#[stable(feature = "refcell_take", since = "1.50.0")]
pub fn take(&self) -> T {
self.replace(Default::default())
}

View File

@ -1,6 +1,5 @@
use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
use crate::ops::Try;
use crate::usize;
use crate::{ops::Try, usize};
/// An iterator that links two iterators together, in a chain.
///

View File

@ -0,0 +1,139 @@
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
use crate::iter::{FusedIterator, TrustedLen};
use crate::ops::Try;
/// An iterator that clones the elements of an underlying iterator.
///
/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`cloned`]: Iterator::cloned
/// [`Iterator`]: trait.Iterator.html
#[stable(feature = "iter_cloned", since = "1.1.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct Cloned<I> {
it: I,
}
impl<I> Cloned<I> {
pub(in crate::iter) fn new(it: I) -> Cloned<I> {
Cloned { it }
}
}
fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
move |acc, elt| f(acc, elt.clone())
}
#[stable(feature = "iter_cloned", since = "1.1.0")]
impl<'a, I, T: 'a> Iterator for Cloned<I>
where
I: Iterator<Item = &'a T>,
T: Clone,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.it.next().cloned()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.it.try_fold(init, clone_try_fold(f))
}
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.it.map(T::clone).fold(init, f)
}
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
unsafe { try_get_unchecked(&mut self.it, idx).clone() }
}
}
#[stable(feature = "iter_cloned", since = "1.1.0")]
impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
where
I: DoubleEndedIterator<Item = &'a T>,
T: Clone,
{
fn next_back(&mut self) -> Option<T> {
self.it.next_back().cloned()
}
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.it.try_rfold(init, clone_try_fold(f))
}
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.it.map(T::clone).rfold(init, f)
}
}
#[stable(feature = "iter_cloned", since = "1.1.0")]
impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
where
I: ExactSizeIterator<Item = &'a T>,
T: Clone,
{
fn len(&self) -> usize {
self.it.len()
}
fn is_empty(&self) -> bool {
self.it.is_empty()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<'a, I, T: 'a> FusedIterator for Cloned<I>
where
I: FusedIterator<Item = &'a T>,
T: Clone,
{
}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Cloned<I>
where
I: TrustedRandomAccess,
{
#[inline]
fn may_have_side_effect() -> bool {
true
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
where
I: TrustedLen<Item = &'a T>,
T: Clone,
{
}

View File

@ -0,0 +1,155 @@
use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
use crate::iter::{FusedIterator, TrustedLen};
use crate::ops::Try;
/// An iterator that copies the elements of an underlying iterator.
///
/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`copied`]: Iterator::copied
/// [`Iterator`]: trait.Iterator.html
#[stable(feature = "iter_copied", since = "1.36.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct Copied<I> {
it: I,
}
impl<I> Copied<I> {
pub(in crate::iter) fn new(it: I) -> Copied<I> {
Copied { it }
}
}
fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
move |acc, &elt| f(acc, elt)
}
fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
move |acc, &elt| f(acc, elt)
}
#[stable(feature = "iter_copied", since = "1.36.0")]
impl<'a, I, T: 'a> Iterator for Copied<I>
where
I: Iterator<Item = &'a T>,
T: Copy,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.it.next().copied()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.it.try_fold(init, copy_try_fold(f))
}
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.it.fold(init, copy_fold(f))
}
fn nth(&mut self, n: usize) -> Option<T> {
self.it.nth(n).copied()
}
fn last(self) -> Option<T> {
self.it.last().copied()
}
fn count(self) -> usize {
self.it.count()
}
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
*unsafe { try_get_unchecked(&mut self.it, idx) }
}
}
#[stable(feature = "iter_copied", since = "1.36.0")]
impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
where
I: DoubleEndedIterator<Item = &'a T>,
T: Copy,
{
fn next_back(&mut self) -> Option<T> {
self.it.next_back().copied()
}
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.it.try_rfold(init, copy_try_fold(f))
}
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.it.rfold(init, copy_fold(f))
}
}
#[stable(feature = "iter_copied", since = "1.36.0")]
impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
where
I: ExactSizeIterator<Item = &'a T>,
T: Copy,
{
fn len(&self) -> usize {
self.it.len()
}
fn is_empty(&self) -> bool {
self.it.is_empty()
}
}
#[stable(feature = "iter_copied", since = "1.36.0")]
impl<'a, I, T: 'a> FusedIterator for Copied<I>
where
I: FusedIterator<Item = &'a T>,
T: Copy,
{
}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Copied<I>
where
I: TrustedRandomAccess,
{
#[inline]
fn may_have_side_effect() -> bool {
I::may_have_side_effect()
}
}
#[stable(feature = "iter_copied", since = "1.36.0")]
unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
where
I: TrustedLen<Item = &'a T>,
T: Copy,
{
}

View File

@ -0,0 +1,87 @@
use crate::{iter::FusedIterator, ops::Try};
/// An iterator that repeats endlessly.
///
/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`cycle`]: Iterator::cycle
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Cycle<I> {
orig: I,
iter: I,
}
impl<I: Clone> Cycle<I> {
pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
Cycle { orig: iter.clone(), iter }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Cycle<I>
where
I: Clone + Iterator,
{
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
match self.iter.next() {
None => {
self.iter = self.orig.clone();
self.iter.next()
}
y => y,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
// the cycle iterator is either empty or infinite
match self.orig.size_hint() {
sz @ (0, Some(0)) => sz,
(0, _) => (0, None),
_ => (usize::MAX, None),
}
}
#[inline]
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
where
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
// fully iterate the current iterator. this is necessary because
// `self.iter` may be empty even when `self.orig` isn't
acc = self.iter.try_fold(acc, &mut f)?;
self.iter = self.orig.clone();
// complete a full cycle, keeping track of whether the cycled
// iterator is empty or not. we need to return early in case
// of an empty iterator to prevent an infinite loop
let mut is_empty = true;
acc = self.iter.try_fold(acc, |acc, x| {
is_empty = false;
f(acc, x)
})?;
if is_empty {
return try { acc };
}
loop {
self.iter = self.orig.clone();
acc = self.iter.try_fold(acc, &mut f)?;
}
}
// No `fold` override, because `fold` doesn't make much sense for `Cycle`,
// and we can't do anything better than the default.
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}

View File

@ -0,0 +1,238 @@
use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::{Add, AddAssign, Try};
/// An iterator that yields the current count and the element during iteration.
///
/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`enumerate`]: Iterator::enumerate
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Enumerate<I> {
iter: I,
count: usize,
}
impl<I> Enumerate<I> {
pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
Enumerate { iter, count: 0 }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Enumerate<I>
where
I: Iterator,
{
type Item = (usize, <I as Iterator>::Item);
/// # Overflow Behavior
///
/// The method does no guarding against overflows, so enumerating more than
/// `usize::MAX` elements either produces the wrong result or panics. If
/// debug assertions are enabled, a panic is guaranteed.
///
/// # Panics
///
/// Might panic if the index of the element overflows a `usize`.
#[inline]
fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
let a = self.iter.next()?;
let i = self.count;
// Possible undefined overflow.
AddAssign::add_assign(&mut self.count, 1);
Some((i, a))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
let a = self.iter.nth(n)?;
// Possible undefined overflow.
let i = Add::add(self.count, n);
self.count = Add::add(i, 1);
Some((i, a))
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
#[inline]
fn enumerate<'a, T, Acc, R>(
count: &'a mut usize,
mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, item| {
let acc = fold(acc, (*count, item));
// Possible undefined overflow.
AddAssign::add_assign(count, 1);
acc
}
}
self.iter.try_fold(init, enumerate(&mut self.count, fold))
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn enumerate<T, Acc>(
mut count: usize,
mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| {
let acc = fold(acc, (count, item));
// Possible undefined overflow.
AddAssign::add_assign(&mut count, 1);
acc
}
}
self.iter.fold(init, enumerate(self.count, fold))
}
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
(Add::add(self.count, idx), value)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Enumerate<I>
where
I: ExactSizeIterator + DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
let a = self.iter.next_back()?;
let len = self.iter.len();
// Can safely add, `ExactSizeIterator` promises that the number of
// elements fits into a `usize`.
Some((self.count + len, a))
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
let a = self.iter.nth_back(n)?;
let len = self.iter.len();
// Can safely add, `ExactSizeIterator` promises that the number of
// elements fits into a `usize`.
Some((self.count + len, a))
}
#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
// Can safely add and subtract the count, as `ExactSizeIterator` promises
// that the number of elements fits into a `usize`.
fn enumerate<T, Acc, R>(
mut count: usize,
mut fold: impl FnMut(Acc, (usize, T)) -> R,
) -> impl FnMut(Acc, T) -> R {
move |acc, item| {
count -= 1;
fold(acc, (count, item))
}
}
let count = self.count + self.iter.len();
self.iter.try_rfold(init, enumerate(count, fold))
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
// Can safely add and subtract the count, as `ExactSizeIterator` promises
// that the number of elements fits into a `usize`.
fn enumerate<T, Acc>(
mut count: usize,
mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| {
count -= 1;
fold(acc, (count, item))
}
}
let count = self.count + self.iter.len();
self.iter.rfold(init, enumerate(count, fold))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Enumerate<I>
where
I: ExactSizeIterator,
{
fn len(&self) -> usize {
self.iter.len()
}
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Enumerate<I>
where
I: TrustedRandomAccess,
{
fn may_have_side_effect() -> bool {
I::may_have_side_effect()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}

View File

@ -0,0 +1,152 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::Try;
/// An iterator that filters the elements of `iter` with `predicate`.
///
/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`filter`]: Iterator::filter
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Filter<I, P> {
iter: I,
predicate: P,
}
impl<I, P> Filter<I, P> {
pub(in crate::iter) fn new(iter: I, predicate: P) -> Filter<I, P> {
Filter { iter, predicate }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Filter").field("iter", &self.iter).finish()
}
}
fn filter_fold<T, Acc>(
mut predicate: impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
}
fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
predicate: &'a mut impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, item| if predicate(&item) { fold(acc, item) } else { try { acc } }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, P> Iterator for Filter<I, P>
where
P: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
self.iter.find(&mut self.predicate)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
// this special case allows the compiler to make `.filter(_).count()`
// branchless. Barring perfect branch prediction (which is unattainable in
// the general case), this will be much faster in >90% of cases (containing
// virtually all real workloads) and only a tiny bit slower in the rest.
//
// Having this specialization thus allows us to write `.filter(p).count()`
// where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is
// less readable and also less backwards-compatible to Rust before 1.10.
//
// Using the branchless version will also simplify the LLVM byte code, thus
// leaving more budget for LLVM optimizations.
#[inline]
fn count(self) -> usize {
#[inline]
fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
move |x| predicate(&x) as usize
}
self.iter.map(to_usize(self.predicate)).sum()
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, filter_fold(self.predicate, fold))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
where
P: FnMut(&I::Item) -> bool,
{
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
self.iter.rfind(&mut self.predicate)
}
#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, filter_fold(self.predicate, fold))
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P>
where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}

View File

@ -0,0 +1,150 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::{ControlFlow, Try};
/// An iterator that uses `f` to both filter and map elements from `iter`.
///
/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`filter_map`]: Iterator::filter_map
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct FilterMap<I, F> {
iter: I,
f: F,
}
impl<I, F> FilterMap<I, F> {
pub(in crate::iter) fn new(iter: I, f: F) -> FilterMap<I, F> {
FilterMap { iter, f }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FilterMap").field("iter", &self.iter).finish()
}
}
fn filter_map_fold<T, B, Acc>(
mut f: impl FnMut(T) -> Option<B>,
mut fold: impl FnMut(Acc, B) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| match f(item) {
Some(x) => fold(acc, x),
None => acc,
}
}
fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
f: &'a mut impl FnMut(T) -> Option<B>,
mut fold: impl FnMut(Acc, B) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, item| match f(item) {
Some(x) => fold(acc, x),
None => try { acc },
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
where
F: FnMut(I::Item) -> Option<B>,
{
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
self.iter.find_map(&mut self.f)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, filter_map_fold(self.f, fold))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
where
F: FnMut(I::Item) -> Option<B>,
{
#[inline]
fn next_back(&mut self) -> Option<B> {
#[inline]
fn find<T, B>(
f: &mut impl FnMut(T) -> Option<B>,
) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
move |(), x| match f(x) {
Some(x) => ControlFlow::Break(x),
None => ControlFlow::CONTINUE,
}
}
self.iter.try_rfold((), find(&mut self.f)).break_value()
}
#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, filter_map_fold(self.f, fold))
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F>
where
F: FnMut(I::Item) -> Option<B>,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where
F: FnMut(I::Item) -> Option<B>
{
}

View File

@ -1,9 +1,7 @@
use crate::fmt;
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
use crate::ops::Try;
use super::super::{DoubleEndedIterator, Fuse, FusedIterator, Iterator};
use super::Map;
/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
@ -14,8 +12,9 @@ use super::Map;
pub struct FlatMap<I, U: IntoIterator, F> {
inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
}
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
pub(in super::super) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
FlatMap { inner: FlattenCompat::new(iter.map(f)) }
}
}

View File

@ -1,9 +1,6 @@
use super::InPlaceIterable;
use crate::intrinsics;
use crate::iter::adapters::zip::try_get_unchecked;
use crate::iter::adapters::SourceIter;
use crate::iter::TrustedRandomAccess;
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter};
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedRandomAccess};
use crate::ops::Try;
/// An iterator that yields `None` forever after the underlying iterator

View File

@ -0,0 +1,167 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::Try;
/// An iterator that calls a function with a reference to each element before
/// yielding it.
///
/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`inspect`]: Iterator::inspect
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Inspect<I, F> {
iter: I,
f: F,
}
impl<I, F> Inspect<I, F> {
pub(in crate::iter) fn new(iter: I, f: F) -> Inspect<I, F> {
Inspect { iter, f }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Inspect").field("iter", &self.iter).finish()
}
}
impl<I: Iterator, F> Inspect<I, F>
where
F: FnMut(&I::Item),
{
#[inline]
fn do_inspect(&mut self, elt: Option<I::Item>) -> Option<I::Item> {
if let Some(ref a) = elt {
(self.f)(a);
}
elt
}
}
fn inspect_fold<T, Acc>(
mut f: impl FnMut(&T),
mut fold: impl FnMut(Acc, T) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| {
f(&item);
fold(acc, item)
}
}
fn inspect_try_fold<'a, T, Acc, R>(
f: &'a mut impl FnMut(&T),
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, item| {
f(&item);
fold(acc, item)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, F> Iterator for Inspect<I, F>
where
F: FnMut(&I::Item),
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
let next = self.iter.next();
self.do_inspect(next)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_fold(init, inspect_try_fold(&mut self.f, fold))
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, inspect_fold(self.f, fold))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
where
F: FnMut(&I::Item),
{
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
let next = self.iter.next_back();
self.do_inspect(next)
}
#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_rfold(init, inspect_try_fold(&mut self.f, fold))
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, inspect_fold(self.f, fold))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
where
F: FnMut(&I::Item),
{
fn len(&self) -> usize {
self.iter.len()
}
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F>
where
F: FnMut(&I::Item),
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}

View File

@ -0,0 +1,213 @@
use crate::fmt;
use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::Try;
/// An iterator that maps the values of `iter` with `f`.
///
/// This `struct` is created by the [`map`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`map`]: Iterator::map
/// [`Iterator`]: trait.Iterator.html
///
/// # Notes about side effects
///
/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that
/// you can also [`map`] backwards:
///
/// ```rust
/// let v: Vec<i32> = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect();
///
/// assert_eq!(v, [4, 3, 2]);
/// ```
///
/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
///
/// But if your closure has state, iterating backwards may act in a way you do
/// not expect. Let's go through an example. First, in the forward direction:
///
/// ```rust
/// let mut c = 0;
///
/// for pair in vec!['a', 'b', 'c'].into_iter()
/// .map(|letter| { c += 1; (letter, c) }) {
/// println!("{:?}", pair);
/// }
/// ```
///
/// This will print "('a', 1), ('b', 2), ('c', 3)".
///
/// Now consider this twist where we add a call to `rev`. This version will
/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
/// but the values of the counter still go in order. This is because `map()` is
/// still being called lazily on each item, but we are popping items off the
/// back of the vector now, instead of shifting them from the front.
///
/// ```rust
/// let mut c = 0;
///
/// for pair in vec!['a', 'b', 'c'].into_iter()
/// .map(|letter| { c += 1; (letter, c) })
/// .rev() {
/// println!("{:?}", pair);
/// }
/// ```
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Map<I, F> {
iter: I,
f: F,
}
impl<I, F> Map<I, F> {
pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
Map { iter, f }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Map").field("iter", &self.iter).finish()
}
}
fn map_fold<T, B, Acc>(
mut f: impl FnMut(T) -> B,
mut g: impl FnMut(Acc, B) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, elt| g(acc, f(elt))
}
fn map_try_fold<'a, T, B, Acc, R>(
f: &'a mut impl FnMut(T) -> B,
mut g: impl FnMut(Acc, B) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, elt| g(acc, f(elt))
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: Iterator, F> Iterator for Map<I, F>
where
F: FnMut(I::Item) -> B,
{
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
self.iter.next().map(&mut self.f)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
where
Self: Sized,
G: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_fold(init, map_try_fold(&mut self.f, g))
}
fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
where
G: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, map_fold(self.f, g))
}
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>
where
F: FnMut(I::Item) -> B,
{
#[inline]
fn next_back(&mut self) -> Option<B> {
self.iter.next_back().map(&mut self.f)
}
fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
where
Self: Sized,
G: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_rfold(init, map_try_fold(&mut self.f, g))
}
fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
where
G: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, map_fold(self.f, g))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
where
F: FnMut(I::Item) -> B,
{
fn len(&self) -> usize {
self.iter.len()
}
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<B, I: FusedIterator, F> FusedIterator for Map<I, F> where F: FnMut(I::Item) -> B {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<B, I, F> TrustedLen for Map<I, F>
where
I: TrustedLen,
F: FnMut(I::Item) -> B,
{
}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
where
I: TrustedRandomAccess,
{
#[inline]
fn may_have_side_effect() -> bool {
true
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for Map<I, F>
where
F: FnMut(I::Item) -> B,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for Map<I, F> where F: FnMut(I::Item) -> B {}

View File

@ -0,0 +1,101 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, InPlaceIterable};
use crate::ops::{ControlFlow, Try};
/// An iterator that only accepts elements while `predicate` returns `Some(_)`.
///
/// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`map_while`]: Iterator::map_while
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
#[derive(Clone)]
pub struct MapWhile<I, P> {
iter: I,
predicate: P,
}
impl<I, P> MapWhile<I, P> {
pub(in crate::iter) fn new(iter: I, predicate: P) -> MapWhile<I, P> {
MapWhile { iter, predicate }
}
}
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MapWhile").field("iter", &self.iter).finish()
}
}
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
where
P: FnMut(I::Item) -> Option<B>,
{
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
let x = self.iter.next()?;
(self.predicate)(x)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
let Self { iter, predicate } = self;
iter.try_fold(init, |acc, x| match predicate(x) {
Some(item) => ControlFlow::from_try(fold(acc, item)),
None => ControlFlow::Break(try { acc }),
})
.into_try()
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}
self.try_fold(init, ok(fold)).unwrap()
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, B, I: Iterator, P> SourceIter for MapWhile<I, P>
where
P: FnMut(I::Item) -> Option<B>,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<B, I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> where
P: FnMut(I::Item) -> Option<B>
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,301 @@
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::Try;
/// An iterator with a `peek()` that returns an optional reference to the next
/// element.
///
/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`peekable`]: Iterator::peekable
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Peekable<I: Iterator> {
iter: I,
/// Remember a peeked value, even if it was None.
peeked: Option<Option<I::Item>>,
}
impl<I: Iterator> Peekable<I> {
pub(in crate::iter) fn new(iter: I) -> Peekable<I> {
Peekable { iter, peeked: None }
}
}
// Peekable must remember if a None has been seen in the `.peek()` method.
// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the
// underlying iterator at most once. This does not by itself make the iterator
// fused.
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> Iterator for Peekable<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
match self.peeked.take() {
Some(v) => v,
None => self.iter.next(),
}
}
#[inline]
#[rustc_inherit_overflow_checks]
fn count(mut self) -> usize {
match self.peeked.take() {
Some(None) => 0,
Some(Some(_)) => 1 + self.iter.count(),
None => self.iter.count(),
}
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
match self.peeked.take() {
Some(None) => None,
Some(v @ Some(_)) if n == 0 => v,
Some(Some(_)) => self.iter.nth(n - 1),
None => self.iter.nth(n),
}
}
#[inline]
fn last(mut self) -> Option<I::Item> {
let peek_opt = match self.peeked.take() {
Some(None) => return None,
Some(v) => v,
None => None,
};
self.iter.last().or(peek_opt)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let peek_len = match self.peeked {
Some(None) => return (0, Some(0)),
Some(Some(_)) => 1,
None => 0,
};
let (lo, hi) = self.iter.size_hint();
let lo = lo.saturating_add(peek_len);
let hi = match hi {
Some(x) => x.checked_add(peek_len),
None => None,
};
(lo, hi)
}
#[inline]
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
let acc = match self.peeked.take() {
Some(None) => return try { init },
Some(Some(v)) => f(init, v)?,
None => init,
};
self.iter.try_fold(acc, f)
}
#[inline]
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
let acc = match self.peeked {
Some(None) => return init,
Some(Some(v)) => fold(init, v),
None => init,
};
self.iter.fold(acc, fold)
}
}
#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Peekable<I>
where
I: DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
match self.peeked.as_mut() {
Some(v @ Some(_)) => self.iter.next_back().or_else(|| v.take()),
Some(None) => None,
None => self.iter.next_back(),
}
}
#[inline]
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
match self.peeked.take() {
Some(None) => try { init },
Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
Ok(acc) => f(acc, v),
Err(e) => {
self.peeked = Some(Some(v));
Try::from_error(e)
}
},
None => self.iter.try_rfold(init, f),
}
}
#[inline]
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
match self.peeked {
Some(None) => init,
Some(Some(v)) => {
let acc = self.iter.rfold(init, &mut fold);
fold(acc, v)
}
None => self.iter.rfold(init, fold),
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator> FusedIterator for Peekable<I> {}
impl<I: Iterator> Peekable<I> {
/// Returns a reference to the next() value without advancing the iterator.
///
/// Like [`next`], if there is a value, it is wrapped in a `Some(T)`.
/// But if the iteration is over, `None` is returned.
///
/// [`next`]: Iterator::next
///
/// Because `peek()` returns a reference, and many iterators iterate over
/// references, there can be a possibly confusing situation where the
/// return value is a double reference. You can see this effect in the
/// examples below.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let xs = [1, 2, 3];
///
/// let mut iter = xs.iter().peekable();
///
/// // peek() lets us see into the future
/// assert_eq!(iter.peek(), Some(&&1));
/// assert_eq!(iter.next(), Some(&1));
///
/// assert_eq!(iter.next(), Some(&2));
///
/// // The iterator does not advance even if we `peek` multiple times
/// assert_eq!(iter.peek(), Some(&&3));
/// assert_eq!(iter.peek(), Some(&&3));
///
/// assert_eq!(iter.next(), Some(&3));
///
/// // After the iterator is finished, so is `peek()`
/// assert_eq!(iter.peek(), None);
/// assert_eq!(iter.next(), None);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn peek(&mut self) -> Option<&I::Item> {
let iter = &mut self.iter;
self.peeked.get_or_insert_with(|| iter.next()).as_ref()
}
/// Consume and return the next value of this iterator if a condition is true.
///
/// If `func` returns `true` for the next value of this iterator, consume and return it.
/// Otherwise, return `None`.
///
/// # Examples
/// Consume a number if it's equal to 0.
/// ```
/// #![feature(peekable_next_if)]
/// let mut iter = (0..5).peekable();
/// // The first item of the iterator is 0; consume it.
/// assert_eq!(iter.next_if(|&x| x == 0), Some(0));
/// // The next item returned is now 1, so `consume` will return `false`.
/// assert_eq!(iter.next_if(|&x| x == 0), None);
/// // `next_if` saves the value of the next item if it was not equal to `expected`.
/// assert_eq!(iter.next(), Some(1));
/// ```
///
/// Consume any number less than 10.
/// ```
/// #![feature(peekable_next_if)]
/// let mut iter = (1..20).peekable();
/// // Consume all numbers less than 10
/// while iter.next_if(|&x| x < 10).is_some() {}
/// // The next value returned will be 10
/// assert_eq!(iter.next(), Some(10));
/// ```
#[unstable(feature = "peekable_next_if", issue = "72480")]
pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
match self.next() {
Some(matched) if func(&matched) => Some(matched),
other => {
// Since we called `self.next()`, we consumed `self.peeked`.
assert!(self.peeked.is_none());
self.peeked = Some(other);
None
}
}
}
/// Consume and return the next item if it is equal to `expected`.
///
/// # Example
/// Consume a number if it's equal to 0.
/// ```
/// #![feature(peekable_next_if)]
/// let mut iter = (0..5).peekable();
/// // The first item of the iterator is 0; consume it.
/// assert_eq!(iter.next_if_eq(&0), Some(0));
/// // The next item returned is now 1, so `consume` will return `false`.
/// assert_eq!(iter.next_if_eq(&0), None);
/// // `next_if_eq` saves the value of the next item if it was not equal to `expected`.
/// assert_eq!(iter.next(), Some(1));
/// ```
#[unstable(feature = "peekable_next_if", issue = "72480")]
pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
where
T: ?Sized,
I::Item: PartialEq<T>,
{
self.next_if(|next| next == expected)
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Peekable<I>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}

View File

@ -0,0 +1,137 @@
use crate::iter::{FusedIterator, TrustedLen};
use crate::ops::Try;
/// A double-ended iterator with the direction inverted.
///
/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`rev`]: Iterator::rev
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rev<T> {
iter: T,
}
impl<T> Rev<T> {
pub(in crate::iter) fn new(iter: T) -> Rev<T> {
Rev { iter }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Rev<I>
where
I: DoubleEndedIterator,
{
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next_back()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
self.iter.advance_back_by(n)
}
#[inline]
fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
self.iter.nth_back(n)
}
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.iter.try_rfold(init, f)
}
fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, f)
}
#[inline]
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
P: FnMut(&Self::Item) -> bool,
{
self.iter.rfind(predicate)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Rev<I>
where
I: DoubleEndedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next()
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
self.iter.advance_by(n)
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
self.iter.nth(n)
}
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
self.iter.try_fold(init, f)
}
fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, f)
}
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
where
P: FnMut(&Self::Item) -> bool,
{
self.iter.find(predicate)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Rev<I>
where
I: ExactSizeIterator + DoubleEndedIterator,
{
fn len(&self) -> usize {
self.iter.len()
}
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[stable(feature = "fused", since = "1.26.0")]
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 {}

View File

@ -0,0 +1,111 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, InPlaceIterable};
use crate::ops::{ControlFlow, Try};
/// An iterator to maintain state while iterating another iterator.
///
/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`scan`]: Iterator::scan
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct Scan<I, St, F> {
iter: I,
f: F,
state: St,
}
impl<I, St, F> Scan<I, St, F> {
pub(in crate::iter) fn new(iter: I, state: St, f: F) -> Scan<I, St, F> {
Scan { iter, state, f }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, St: fmt::Debug, F> fmt::Debug for Scan<I, St, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Scan").field("iter", &self.iter).field("state", &self.state).finish()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I, St, F> Iterator for Scan<I, St, F>
where
I: Iterator,
F: FnMut(&mut St, I::Item) -> Option<B>,
{
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
let a = self.iter.next()?;
(self.f)(&mut self.state, a)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the scan function
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
fn scan<'a, T, St, B, Acc, R: Try<Ok = Acc>>(
state: &'a mut St,
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
mut fold: impl FnMut(Acc, B) -> R + 'a,
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| match f(state, x) {
None => ControlFlow::Break(try { acc }),
Some(x) => ControlFlow::from_try(fold(acc, x)),
}
}
let state = &mut self.state;
let f = &mut self.f;
self.iter.try_fold(init, scan(state, f, fold)).into_try()
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}
self.try_fold(init, ok(fold)).unwrap()
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
where
I: SourceIter<Source = S>,
F: FnMut(&mut St, I::Item) -> Option<B>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> where
F: FnMut(&mut St, I::Item) -> Option<B>
{
}

View File

@ -0,0 +1,199 @@
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::{ControlFlow, Try};
/// An iterator that skips over `n` elements of `iter`.
///
/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`skip`]: Iterator::skip
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Skip<I> {
iter: I,
n: usize,
}
impl<I> Skip<I> {
pub(in crate::iter) fn new(iter: I, n: usize) -> Skip<I> {
Skip { iter, n }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Skip<I>
where
I: Iterator,
{
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.n == 0 {
self.iter.next()
} else {
let old_n = self.n;
self.n = 0;
self.iter.nth(old_n)
}
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
// Can't just add n + self.n due to overflow.
if self.n > 0 {
let to_skip = self.n;
self.n = 0;
// nth(n) skips n+1
self.iter.nth(to_skip - 1)?;
}
self.iter.nth(n)
}
#[inline]
fn count(mut self) -> usize {
if self.n > 0 {
// nth(n) skips n+1
if self.iter.nth(self.n - 1).is_none() {
return 0;
}
}
self.iter.count()
}
#[inline]
fn last(mut self) -> Option<I::Item> {
if self.n > 0 {
// nth(n) skips n+1
self.iter.nth(self.n - 1)?;
}
self.iter.last()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.iter.size_hint();
let lower = lower.saturating_sub(self.n);
let upper = match upper {
Some(x) => Some(x.saturating_sub(self.n)),
None => None,
};
(lower, upper)
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
let n = self.n;
self.n = 0;
if n > 0 {
// nth(n) skips n+1
if self.iter.nth(n - 1).is_none() {
return try { init };
}
}
self.iter.try_fold(init, fold)
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
if self.n > 0 {
// nth(n) skips n+1
if self.iter.nth(self.n - 1).is_none() {
return init;
}
}
self.iter.fold(init, fold)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")]
impl<I> DoubleEndedIterator for Skip<I>
where
I: DoubleEndedIterator + ExactSizeIterator,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.len() > 0 { self.iter.next_back() } else { None }
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
let len = self.len();
if n < len {
self.iter.nth_back(n)
} else {
if len > 0 {
// consume the original iterator
self.iter.nth_back(len - 1);
}
None
}
}
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
fn check<T, Acc, R: Try<Ok = Acc>>(
mut n: usize,
mut fold: impl FnMut(Acc, T) -> R,
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
move |acc, x| {
n -= 1;
let r = fold(acc, x);
if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}
let n = self.len();
if n == 0 { try { init } } else { self.iter.try_rfold(init, check(n, fold)).into_try() }
}
fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<Acc, T>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, T) -> Result<Acc, !> {
move |acc, x| Ok(f(acc, x))
}
self.try_rfold(init, ok(fold)).unwrap()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Skip<I>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {}

View File

@ -0,0 +1,126 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::Try;
/// An iterator that rejects elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`skip_while`]: Iterator::skip_while
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct SkipWhile<I, P> {
iter: I,
flag: bool,
predicate: P,
}
impl<I, P> SkipWhile<I, P> {
pub(in crate::iter) fn new(iter: I, predicate: P) -> SkipWhile<I, P> {
SkipWhile { iter, flag: false, predicate }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SkipWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, P> Iterator for SkipWhile<I, P>
where
P: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
fn check<'a, T>(
flag: &'a mut bool,
pred: &'a mut impl FnMut(&T) -> bool,
) -> impl FnMut(&T) -> bool + 'a {
move |x| {
if *flag || !pred(x) {
*flag = true;
true
} else {
false
}
}
}
let flag = &mut self.flag;
let pred = &mut self.predicate;
self.iter.find(check(flag, pred))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
if !self.flag {
match self.next() {
Some(v) => init = fold(init, v)?,
None => return try { init },
}
}
self.iter.try_fold(init, fold)
}
#[inline]
fn fold<Acc, Fold>(mut self, mut init: Acc, mut fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
if !self.flag {
match self.next() {
Some(v) => init = fold(init, v),
None => return init,
}
}
self.iter.fold(init, fold)
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I, P> FusedIterator for SkipWhile<I, P>
where
I: FusedIterator,
P: FnMut(&I::Item) -> bool,
{
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P>
where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where
F: FnMut(&I::Item) -> bool
{
}

View File

@ -0,0 +1,235 @@
use crate::{intrinsics, iter::from_fn, ops::Try};
/// An iterator for stepping iterators by a custom amount.
///
/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See
/// its documentation for more.
///
/// [`step_by`]: Iterator::step_by
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "iterator_step_by", since = "1.28.0")]
#[derive(Clone, Debug)]
pub struct StepBy<I> {
iter: I,
step: usize,
first_take: bool,
}
impl<I> StepBy<I> {
pub(in crate::iter) fn new(iter: I, step: usize) -> StepBy<I> {
assert!(step != 0);
StepBy { iter, step: step - 1, first_take: true }
}
}
#[stable(feature = "iterator_step_by", since = "1.28.0")]
impl<I> Iterator for StepBy<I>
where
I: Iterator,
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.first_take {
self.first_take = false;
self.iter.next()
} else {
self.iter.nth(self.step)
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
#[inline]
fn first_size(step: usize) -> impl Fn(usize) -> usize {
move |n| if n == 0 { 0 } else { 1 + (n - 1) / (step + 1) }
}
#[inline]
fn other_size(step: usize) -> impl Fn(usize) -> usize {
move |n| n / (step + 1)
}
let (low, high) = self.iter.size_hint();
if self.first_take {
let f = first_size(self.step);
(f(low), high.map(f))
} else {
let f = other_size(self.step);
(f(low), high.map(f))
}
}
#[inline]
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
if self.first_take {
self.first_take = false;
let first = self.iter.next();
if n == 0 {
return first;
}
n -= 1;
}
// n and self.step are indices, we need to add 1 to get the amount of elements
// When calling `.nth`, we need to subtract 1 again to convert back to an index
// step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1`
let mut step = self.step + 1;
// n + 1 could overflow
// thus, if n is usize::MAX, instead of adding one, we call .nth(step)
if n == usize::MAX {
self.iter.nth(step - 1);
} else {
n += 1;
}
// overflow handling
loop {
let mul = n.checked_mul(step);
{
if intrinsics::likely(mul.is_some()) {
return self.iter.nth(mul.unwrap() - 1);
}
}
let div_n = usize::MAX / n;
let div_step = usize::MAX / step;
let nth_n = div_n * n;
let nth_step = div_step * step;
let nth = if nth_n > nth_step {
step -= div_n;
nth_n
} else {
n -= div_step;
nth_step
};
self.iter.nth(nth - 1);
}
}
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
where
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
#[inline]
fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
move || iter.nth(step)
}
if self.first_take {
self.first_take = false;
match self.iter.next() {
None => return try { acc },
Some(x) => acc = f(acc, x)?,
}
}
from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
}
fn fold<Acc, F>(mut self, mut acc: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
move || iter.nth(step)
}
if self.first_take {
self.first_take = false;
match self.iter.next() {
None => return acc,
Some(x) => acc = f(acc, x),
}
}
from_fn(nth(&mut self.iter, self.step)).fold(acc, f)
}
}
impl<I> StepBy<I>
where
I: ExactSizeIterator,
{
// The zero-based index starting from the end of the iterator of the
// last element. Used in the `DoubleEndedIterator` implementation.
fn next_back_index(&self) -> usize {
let rem = self.iter.len() % (self.step + 1);
if self.first_take {
if rem == 0 { self.step } else { rem - 1 }
} else {
rem
}
}
}
#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for StepBy<I>
where
I: DoubleEndedIterator + ExactSizeIterator,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.nth_back(self.next_back_index())
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
// `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
// is out of bounds because the length of `self.iter` does not exceed
// `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
// zero-indexed
let n = n.saturating_mul(self.step + 1).saturating_add(self.next_back_index());
self.iter.nth_back(n)
}
fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
where
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
#[inline]
fn nth_back<I: DoubleEndedIterator>(
iter: &mut I,
step: usize,
) -> impl FnMut() -> Option<I::Item> + '_ {
move || iter.nth_back(step)
}
match self.next_back() {
None => try { init },
Some(x) => {
let acc = f(init, x)?;
from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
}
}
}
#[inline]
fn rfold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc
where
Self: Sized,
F: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn nth_back<I: DoubleEndedIterator>(
iter: &mut I,
step: usize,
) -> impl FnMut() -> Option<I::Item> + '_ {
move || iter.nth_back(step)
}
match self.next_back() {
None => init,
Some(x) => {
let acc = f(init, x);
from_fn(nth_back(&mut self.iter, self.step)).fold(acc, f)
}
}
}
}
// StepBy can only make the iterator shorter, so the len will still fit.
#[stable(feature = "iterator_step_by", since = "1.28.0")]
impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}

View File

@ -0,0 +1,209 @@
use crate::cmp;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::{ControlFlow, Try};
/// An iterator that only iterates over the first `n` iterations of `iter`.
///
/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`take`]: Iterator::take
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Take<I> {
iter: I,
n: usize,
}
impl<I> Take<I> {
pub(in crate::iter) fn new(iter: I, n: usize) -> Take<I> {
Take { iter, n }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Take<I>
where
I: Iterator,
{
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
if self.n != 0 {
self.n -= 1;
self.iter.next()
} else {
None
}
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
if self.n > n {
self.n -= n + 1;
self.iter.nth(n)
} else {
if self.n > 0 {
self.iter.nth(self.n - 1);
self.n = 0;
}
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.n == 0 {
return (0, Some(0));
}
let (lower, upper) = self.iter.size_hint();
let lower = cmp::min(lower, self.n);
let upper = match upper {
Some(x) if x < self.n => Some(x),
_ => Some(self.n),
};
(lower, upper)
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
n: &'a mut usize,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| {
*n -= 1;
let r = fold(acc, x);
if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}
if self.n == 0 {
try { init }
} else {
let n = &mut self.n;
self.iter.try_fold(init, check(n, fold)).into_try()
}
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}
self.try_fold(init, ok(fold)).unwrap()
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I>
where
I: DoubleEndedIterator + ExactSizeIterator,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.n == 0 {
None
} else {
let n = self.n;
self.n -= 1;
self.iter.nth_back(self.iter.len().saturating_sub(n))
}
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.iter.len();
if self.n > n {
let m = len.saturating_sub(self.n) + n;
self.n -= n + 1;
self.iter.nth_back(m)
} else {
if len > 0 {
self.iter.nth_back(len - 1);
}
None
}
}
#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
if self.n == 0 {
try { init }
} else {
let len = self.iter.len();
if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
try { init }
} else {
self.iter.try_rfold(init, fold)
}
}
}
#[inline]
fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
if self.n == 0 {
init
} else {
let len = self.iter.len();
if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
init
} else {
self.iter.rfold(init, fold)
}
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}

View File

@ -0,0 +1,139 @@
use crate::fmt;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
use crate::ops::{ControlFlow, Try};
/// An iterator that only accepts elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`take_while`]: Iterator::take_while
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct TakeWhile<I, P> {
iter: I,
flag: bool,
predicate: P,
}
impl<I, P> TakeWhile<I, P> {
pub(in crate::iter) fn new(iter: I, predicate: P) -> TakeWhile<I, P> {
TakeWhile { iter, flag: false, predicate }
}
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TakeWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, P> Iterator for TakeWhile<I, P>
where
P: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.flag {
None
} else {
let x = self.iter.next()?;
if (self.predicate)(&x) {
Some(x)
} else {
self.flag = true;
None
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.flag {
(0, Some(0))
} else {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
}
#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
flag: &'a mut bool,
p: &'a mut impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| {
if p(&x) {
ControlFlow::from_try(fold(acc, x))
} else {
*flag = true;
ControlFlow::Break(try { acc })
}
}
}
if self.flag {
try { init }
} else {
let flag = &mut self.flag;
let p = &mut self.predicate;
self.iter.try_fold(init, check(flag, p, fold)).into_try()
}
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}
self.try_fold(init, ok(fold)).unwrap()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I, P> FusedIterator for TakeWhile<I, P>
where
I: FusedIterator,
P: FnMut(&I::Item) -> bool,
{
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P>
where
P: FnMut(&I::Item) -> bool,
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where
F: FnMut(&I::Item) -> bool
{
}

View File

@ -1,10 +1,7 @@
use crate::cmp;
use crate::fmt::{self, Debug};
use super::super::{
DoubleEndedIterator, ExactSizeIterator, FusedIterator, InPlaceIterable, Iterator, SourceIter,
TrustedLen,
};
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
use crate::iter::{InPlaceIterable, SourceIter, TrustedLen};
/// An iterator that iterates two other iterators simultaneously.
///
@ -21,7 +18,7 @@ pub struct Zip<A, B> {
len: usize,
}
impl<A: Iterator, B: Iterator> Zip<A, B> {
pub(in super::super) fn new(a: A, b: B) -> Zip<A, B> {
pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {
ZipImpl::new(a, b)
}
fn super_nth(&mut self, mut n: usize) -> Option<(A::Item, B::Item)> {

View File

@ -335,15 +335,14 @@ pub use self::sources::{successors, Successors};
#[stable(feature = "fused", since = "1.26.0")]
pub use self::traits::FusedIterator;
#[unstable(issue = "none", feature = "inplace_iteration")]
pub use self::traits::InPlaceIterable;
#[unstable(feature = "trusted_len", issue = "37572")]
pub use self::traits::TrustedLen;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{DoubleEndedIterator, Extend, FromIterator, IntoIterator};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{ExactSizeIterator, Product, Sum};
#[unstable(issue = "none", feature = "inplace_iteration")]
pub use self::traits::InPlaceIterable;
pub use self::traits::{
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
};
#[stable(feature = "iter_cloned", since = "1.1.0")]
pub use self::adapters::Cloned;
@ -351,21 +350,19 @@ pub use self::adapters::Cloned;
pub use self::adapters::Copied;
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::adapters::Flatten;
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::adapters::MapWhile;
#[unstable(issue = "none", feature = "inplace_iteration")]
#[unstable(feature = "inplace_iteration", issue = "none")]
pub use self::adapters::SourceIter;
#[stable(feature = "iterator_step_by", since = "1.28.0")]
pub use self::adapters::StepBy;
#[unstable(feature = "trusted_random_access", issue = "none")]
pub use self::adapters::TrustedRandomAccess;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::adapters::{Chain, Cycle, Enumerate, Filter, FilterMap, Map, Rev, Zip};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::adapters::{FlatMap, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::adapters::{Fuse, Inspect};
pub use self::adapters::{
Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
Skip, SkipWhile, Take, TakeWhile, Zip,
};
pub(crate) use self::adapters::process_results;

View File

@ -1,625 +1,27 @@
use crate::fmt;
use crate::marker;
mod empty;
mod from_fn;
mod once;
mod once_with;
mod repeat;
mod repeat_with;
mod successors;
use super::{FusedIterator, TrustedLen};
pub use self::repeat::{repeat, Repeat};
/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
element: A,
}
#[stable(feature = "iter_empty", since = "1.2.0")]
pub use self::empty::{empty, Empty};
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
Some(self.element.clone())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
Some(self.element.clone())
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<A: Clone> FusedIterator for Repeat<A> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with()`] function.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`Iterator::take()`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
Repeat { element: elt }
}
/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`repeat_with()`] function.
/// See its documentation for more.
#[derive(Copy, Clone, Debug)]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub struct RepeatWith<F> {
repeater: F,
}
#[stable(feature = "iter_once", since = "1.2.0")]
pub use self::once::{once, Once};
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
Some((self.repeater)())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}
/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
/// The `repeat_with()` function calls the repeater over and over again.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need implements [`Clone`], and
/// it is OK to keep the source element in memory, you should instead use
/// the [`repeat()`] function.
///
/// An iterator produced by `repeat_with()` is not a [`DoubleEndedIterator`].
/// If you need `repeat_with()` to return a [`DoubleEndedIterator`],
/// please open a GitHub issue explaining your use case.
///
/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // let's assume we have some value of a type that is not `Clone`
/// // or which don't want to have in memory just yet because it is expensive:
/// #[derive(PartialEq, Debug)]
/// struct Expensive;
///
/// // a particular value forever:
/// let mut things = iter::repeat_with(|| Expensive);
///
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// ```
///
/// Using mutation and going finite:
///
/// ```rust
/// use std::iter;
///
/// // From the zeroth to the third power of two:
/// let mut curr = 1;
/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
/// .take(4);
///
/// assert_eq!(Some(1), pow2.next());
/// assert_eq!(Some(2), pow2.next());
/// assert_eq!(Some(4), pow2.next());
/// assert_eq!(Some(8), pow2.next());
///
/// // ... and now we're done
/// assert_eq!(None, pow2.next());
/// ```
#[inline]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
RepeatWith { repeater }
}
/// An iterator that yields nothing.
///
/// This `struct` is created by the [`empty()`] function. See its documentation for more.
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);
#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
unsafe impl<T> Send for Empty<T> {}
#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
unsafe impl<T> Sync for Empty<T> {}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<T> fmt::Debug for Empty<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("Empty")
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Iterator for Empty<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> DoubleEndedIterator for Empty<T> {
fn next_back(&mut self) -> Option<T> {
None
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> ExactSizeIterator for Empty<T> {
fn len(&self) -> usize {
0
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Empty<T> {}
#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Empty<T> {}
// not #[derive] because that adds a Clone bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Clone for Empty<T> {
fn clone(&self) -> Empty<T> {
Empty(marker::PhantomData)
}
}
// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Default for Empty<T> {
fn default() -> Empty<T> {
Empty(marker::PhantomData)
}
}
/// Creates an iterator that yields nothing.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // this could have been an iterator over i32, but alas, it's just not.
/// let mut nope = iter::empty::<i32>();
///
/// assert_eq!(None, nope.next());
/// ```
#[stable(feature = "iter_empty", since = "1.2.0")]
#[rustc_const_stable(feature = "const_iter_empty", since = "1.32.0")]
pub const fn empty<T>() -> Empty<T> {
Empty(marker::PhantomData)
}
/// An iterator that yields an element exactly once.
///
/// This `struct` is created by the [`once()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
inner: crate::option::IntoIter<T>,
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> Iterator for Once<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> DoubleEndedIterator for Once<T> {
fn next_back(&mut self) -> Option<T> {
self.inner.next_back()
}
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> ExactSizeIterator for Once<T> {
fn len(&self) -> usize {
self.inner.len()
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Once<T> {}
#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Once<T> {}
/// Creates an iterator that yields an element exactly once.
///
/// This is commonly used to adapt a single value into a [`chain()`] of other
/// kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// [`chain()`]: Iterator::chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once(1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once(PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[stable(feature = "iter_once", since = "1.2.0")]
pub fn once<T>(value: T) -> Once<T> {
Once { inner: Some(value).into_iter() }
}
/// An iterator that yields a single element of type `A` by
/// applying the provided closure `F: FnOnce() -> A`.
///
/// This `struct` is created by the [`once_with()`] function.
/// See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub struct OnceWith<F> {
gen: Option<F>,
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
let f = self.gen.take()?;
Some(f())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.gen.iter().size_hint()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
fn next_back(&mut self) -> Option<A> {
self.next()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
fn len(&self) -> usize {
self.gen.iter().len()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
#[stable(feature = "iter_once_with", since = "1.43.0")]
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
/// Creates an iterator that lazily generates a value exactly once by invoking
/// the provided closure.
///
/// This is commonly used to adapt a single value generator into a [`chain()`] of
/// other kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// Unlike [`once()`], this function will lazily generate the value on request.
///
/// [`chain()`]: Iterator::chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once_with(|| 1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[inline]
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
OnceWith { gen: Some(gen) }
}
/// Creates a new iterator where each iteration calls the provided closure
/// `F: FnMut() -> Option<T>`.
///
/// This allows creating a custom iterator with any behavior
/// without using the more verbose syntax of creating a dedicated type
/// and implementing the [`Iterator`] trait for it.
///
/// Note that the `FromFn` iterator doesnt make assumptions about the behavior of the closure,
/// and therefore conservatively does not implement [`FusedIterator`],
/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
///
/// The closure can use captures and its environment to track state across iterations. Depending on
/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
///
/// [`move`]: ../../std/keyword.move.html
///
/// # Examples
///
/// Lets re-implement the counter iterator from the [module-level documentation]:
///
/// [module-level documentation]: super
///
/// ```
/// let mut count = 0;
/// let counter = std::iter::from_fn(move || {
/// // Increment our count. This is why we started at zero.
/// count += 1;
///
/// // Check to see if we've finished counting or not.
/// if count < 6 {
/// Some(count)
/// } else {
/// None
/// }
/// });
/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
/// ```
#[inline]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub fn from_fn<T, F>(f: F) -> FromFn<F>
where
F: FnMut() -> Option<T>,
{
FromFn(f)
}
/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
///
/// This `struct` is created by the [`iter::from_fn()`] function.
/// See its documentation for more.
///
/// [`iter::from_fn()`]: from_fn
#[derive(Clone)]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub struct FromFn<F>(F);
pub use self::repeat_with::{repeat_with, RepeatWith};
#[stable(feature = "iter_from_fn", since = "1.34.0")]
impl<T, F> Iterator for FromFn<F>
where
F: FnMut() -> Option<T>,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
(self.0)()
}
}
#[stable(feature = "iter_from_fn", since = "1.34.0")]
impl<F> fmt::Debug for FromFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FromFn").finish()
}
}
/// Creates a new iterator where each successive item is computed based on the preceding one.
///
/// The iterator starts with the given first item (if any)
/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each items successor.
///
/// ```
/// use std::iter::successors;
///
/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
/// ```
#[stable(feature = "iter_successors", since = "1.34.0")]
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
where
F: FnMut(&T) -> Option<T>,
{
// If this function returned `impl Iterator<Item=T>`
// it could be based on `unfold` and not need a dedicated type.
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
Successors { next: first, succ }
}
/// An new iterator where each successive item is computed based on the preceding one.
///
/// This `struct` is created by the [`iter::successors()`] function.
/// See its documentation for more.
///
/// [`iter::successors()`]: successors
#[derive(Clone)]
#[stable(feature = "iter_successors", since = "1.34.0")]
pub struct Successors<T, F> {
next: Option<T>,
succ: F,
}
pub use self::from_fn::{from_fn, FromFn};
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T, F> Iterator for Successors<T, F>
where
F: FnMut(&T) -> Option<T>,
{
type Item = T;
pub use self::successors::{successors, Successors};
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let item = self.next.take()?;
self.next = (self.succ)(&item);
Some(item)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.next.is_some() { (1, None) } else { (0, Some(0)) }
}
}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Successors").field("next", &self.next).finish()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub use self::once_with::{once_with, OnceWith};

View File

@ -0,0 +1,92 @@
use crate::fmt;
use crate::iter::{FusedIterator, TrustedLen};
use crate::marker;
/// Creates an iterator that yields nothing.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // this could have been an iterator over i32, but alas, it's just not.
/// let mut nope = iter::empty::<i32>();
///
/// assert_eq!(None, nope.next());
/// ```
#[stable(feature = "iter_empty", since = "1.2.0")]
#[rustc_const_stable(feature = "const_iter_empty", since = "1.32.0")]
pub const fn empty<T>() -> Empty<T> {
Empty(marker::PhantomData)
}
/// An iterator that yields nothing.
///
/// This `struct` is created by the [`empty()`] function. See its documentation for more.
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);
#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
unsafe impl<T> Send for Empty<T> {}
#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
unsafe impl<T> Sync for Empty<T> {}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<T> fmt::Debug for Empty<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("Empty")
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Iterator for Empty<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> DoubleEndedIterator for Empty<T> {
fn next_back(&mut self) -> Option<T> {
None
}
}
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> ExactSizeIterator for Empty<T> {
fn len(&self) -> usize {
0
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Empty<T> {}
#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Empty<T> {}
// not #[derive] because that adds a Clone bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Clone for Empty<T> {
fn clone(&self) -> Empty<T> {
Empty(marker::PhantomData)
}
}
// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Default for Empty<T> {
fn default() -> Empty<T> {
Empty(marker::PhantomData)
}
}

View File

@ -0,0 +1,78 @@
use crate::fmt;
/// Creates a new iterator where each iteration calls the provided closure
/// `F: FnMut() -> Option<T>`.
///
/// This allows creating a custom iterator with any behavior
/// without using the more verbose syntax of creating a dedicated type
/// and implementing the [`Iterator`] trait for it.
///
/// Note that the `FromFn` iterator doesnt make assumptions about the behavior of the closure,
/// and therefore conservatively does not implement [`FusedIterator`],
/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
///
/// The closure can use captures and its environment to track state across iterations. Depending on
/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
///
/// [`move`]: ../../std/keyword.move.html
/// [`FusedIterator`]: crate::iter::FusedIterator
///
/// # Examples
///
/// Lets re-implement the counter iterator from [module-level documentation]:
///
/// [module-level documentation]: crate::iter
///
/// ```
/// let mut count = 0;
/// let counter = std::iter::from_fn(move || {
/// // Increment our count. This is why we started at zero.
/// count += 1;
///
/// // Check to see if we've finished counting or not.
/// if count < 6 {
/// Some(count)
/// } else {
/// None
/// }
/// });
/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
/// ```
#[inline]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub fn from_fn<T, F>(f: F) -> FromFn<F>
where
F: FnMut() -> Option<T>,
{
FromFn(f)
}
/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
///
/// This `struct` is created by the [`iter::from_fn()`] function.
/// See its documentation for more.
///
/// [`iter::from_fn()`]: from_fn
#[derive(Clone)]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub struct FromFn<F>(F);
#[stable(feature = "iter_from_fn", since = "1.34.0")]
impl<T, F> Iterator for FromFn<F>
where
F: FnMut() -> Option<T>,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
(self.0)()
}
}
#[stable(feature = "iter_from_fn", since = "1.34.0")]
impl<F> fmt::Debug for FromFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FromFn").finish()
}
}

View File

@ -0,0 +1,99 @@
use crate::iter::{FusedIterator, TrustedLen};
/// Creates an iterator that yields an element exactly once.
///
/// This is commonly used to adapt a single value into a [`chain()`] of other
/// kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// [`chain()`]: Iterator::chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once(1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once(PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[stable(feature = "iter_once", since = "1.2.0")]
pub fn once<T>(value: T) -> Once<T> {
Once { inner: Some(value).into_iter() }
}
/// An iterator that yields an element exactly once.
///
/// This `struct` is created by the [`once()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
inner: crate::option::IntoIter<T>,
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> Iterator for Once<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> DoubleEndedIterator for Once<T> {
fn next_back(&mut self) -> Option<T> {
self.inner.next_back()
}
}
#[stable(feature = "iter_once", since = "1.2.0")]
impl<T> ExactSizeIterator for Once<T> {
fn len(&self) -> usize {
self.inner.len()
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Once<T> {}
#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Once<T> {}

View File

@ -0,0 +1,109 @@
use crate::iter::{FusedIterator, TrustedLen};
/// Creates an iterator that lazily generates a value exactly once by invoking
/// the provided closure.
///
/// This is commonly used to adapt a single value generator into a [`chain()`] of
/// other kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// Unlike [`once()`], this function will lazily generate the value on request.
///
/// [`chain()`]: Iterator::chain
/// [`once()`]: crate::iter::once
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once_with(|| 1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[inline]
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
OnceWith { gen: Some(gen) }
}
/// An iterator that yields a single element of type `A` by
/// applying the provided closure `F: FnOnce() -> A`.
///
/// This `struct` is created by the [`once_with()`] function.
/// See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub struct OnceWith<F> {
gen: Option<F>,
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
let f = self.gen.take()?;
Some(f())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.gen.iter().size_hint()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
fn next_back(&mut self) -> Option<A> {
self.next()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
fn len(&self) -> usize {
self.gen.iter().len()
}
}
#[stable(feature = "iter_once_with", since = "1.43.0")]
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
#[stable(feature = "iter_once_with", since = "1.43.0")]
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}

View File

@ -0,0 +1,93 @@
use crate::iter::{FusedIterator, TrustedLen};
/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with()`] function.
///
/// [`repeat_with()`]: crate::iter::repeat_with
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`Iterator::take()`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
Repeat { element: elt }
}
/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
element: A,
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
Some(self.element.clone())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
Some(self.element.clone())
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<A: Clone> FusedIterator for Repeat<A> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}

View File

@ -0,0 +1,98 @@
use crate::iter::{FusedIterator, TrustedLen};
/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
/// The `repeat_with()` function calls the repeater over and over again.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need implements [`Clone`], and
/// it is OK to keep the source element in memory, you should instead use
/// the [`repeat()`] function.
///
/// An iterator produced by `repeat_with()` is not a [`DoubleEndedIterator`].
/// If you need `repeat_with()` to return a [`DoubleEndedIterator`],
/// please open a GitHub issue explaining your use case.
///
/// [`repeat()`]: crate::iter::repeat
/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // let's assume we have some value of a type that is not `Clone`
/// // or which don't want to have in memory just yet because it is expensive:
/// #[derive(PartialEq, Debug)]
/// struct Expensive;
///
/// // a particular value forever:
/// let mut things = iter::repeat_with(|| Expensive);
///
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// assert_eq!(Some(Expensive), things.next());
/// ```
///
/// Using mutation and going finite:
///
/// ```rust
/// use std::iter;
///
/// // From the zeroth to the third power of two:
/// let mut curr = 1;
/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
/// .take(4);
///
/// assert_eq!(Some(1), pow2.next());
/// assert_eq!(Some(2), pow2.next());
/// assert_eq!(Some(4), pow2.next());
/// assert_eq!(Some(8), pow2.next());
///
/// // ... and now we're done
/// assert_eq!(None, pow2.next());
/// ```
#[inline]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
RepeatWith { repeater }
}
/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`repeat_with()`] function.
/// See its documentation for more.
#[derive(Copy, Clone, Debug)]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub struct RepeatWith<F> {
repeater: F,
}
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
Some((self.repeater)())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}

View File

@ -0,0 +1,66 @@
use crate::{fmt, iter::FusedIterator};
/// Creates a new iterator where each successive item is computed based on the preceding one.
///
/// The iterator starts with the given first item (if any)
/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each items successor.
///
/// ```
/// use std::iter::successors;
///
/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
/// ```
#[stable(feature = "iter_successors", since = "1.34.0")]
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
where
F: FnMut(&T) -> Option<T>,
{
// If this function returned `impl Iterator<Item=T>`
// it could be based on `unfold` and not need a dedicated type.
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
Successors { next: first, succ }
}
/// An new iterator where each successive item is computed based on the preceding one.
///
/// This `struct` is created by the [`iter::successors()`] function.
/// See its documentation for more.
///
/// [`iter::successors()`]: successors
#[derive(Clone)]
#[stable(feature = "iter_successors", since = "1.34.0")]
pub struct Successors<T, F> {
next: Option<T>,
succ: F,
}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T, F> Iterator for Successors<T, F>
where
F: FnMut(&T) -> Option<T>,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let item = self.next.take()?;
self.next = (self.succ)(&item);
Some(item)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.next.is_some() { (1, None) } else { (0, Some(0)) }
}
}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
#[stable(feature = "iter_successors", since = "1.34.0")]
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Successors").field("next", &self.next).finish()
}
}

View File

@ -156,18 +156,18 @@ pub trait StructuralPartialEq {
/// Required trait for constants used in pattern matches.
///
/// Any type that derives `Eq` automatically implements this trait, *regardless*
/// of whether its type-parameters implement `Eq`.
/// of whether its type parameters implement `Eq`.
///
/// This is a hack to workaround a limitation in our type-system.
/// This is a hack to work around a limitation in our type system.
///
/// Background:
/// # Background
///
/// We want to require that types of consts used in pattern matches
/// have the attribute `#[derive(PartialEq, Eq)]`.
///
/// In a more ideal world, we could check that requirement by just checking that
/// the given type implements both (1.) the `StructuralPartialEq` trait *and*
/// (2.) the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
/// the given type implements both the `StructuralPartialEq` trait *and*
/// the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
/// and be a case that we want the compiler to accept, and yet the constant's
/// type fails to implement `Eq`.
///
@ -176,8 +176,11 @@ pub trait StructuralPartialEq {
/// ```rust
/// #[derive(PartialEq, Eq)]
/// struct Wrap<X>(X);
///
/// fn higher_order(_: &()) { }
///
/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
///
/// fn main() {
/// match CFN {
/// CFN => {}

View File

@ -441,6 +441,32 @@ impl f32 {
self.abs_private() < Self::INFINITY
}
/// Returns `true` if the number is [subnormal].
///
/// ```
/// #![feature(is_subnormal)]
/// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
/// let max = f32::MAX;
/// let lower_than_min = 1.0e-40_f32;
/// let zero = 0.0_f32;
///
/// assert!(!min.is_subnormal());
/// assert!(!max.is_subnormal());
///
/// assert!(!zero.is_subnormal());
/// assert!(!f32::NAN.is_subnormal());
/// assert!(!f32::INFINITY.is_subnormal());
/// // Values between `0` and `min` are Subnormal.
/// assert!(lower_than_min.is_subnormal());
/// ```
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[unstable(feature = "is_subnormal", issue = "79288")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[inline]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
}
/// Returns `true` if the number is neither zero, infinite,
/// [subnormal], or `NaN`.
///

View File

@ -440,6 +440,32 @@ impl f64 {
self.abs_private() < Self::INFINITY
}
/// Returns `true` if the number is [subnormal].
///
/// ```
/// #![feature(is_subnormal)]
/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
/// let max = f64::MAX;
/// let lower_than_min = 1.0e-308_f64;
/// let zero = 0.0_f64;
///
/// assert!(!min.is_subnormal());
/// assert!(!max.is_subnormal());
///
/// assert!(!zero.is_subnormal());
/// assert!(!f64::NAN.is_subnormal());
/// assert!(!f64::INFINITY.is_subnormal());
/// // Values between `0` and `min` are Subnormal.
/// assert!(lower_than_min.is_subnormal());
/// ```
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[unstable(feature = "is_subnormal", issue = "79288")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[inline]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
}
/// Returns `true` if the number is neither zero, infinite,
/// [subnormal], or `NaN`.
///

View File

@ -227,7 +227,6 @@
#![feature(asm)]
#![feature(associated_type_bounds)]
#![feature(atomic_mut_ptr)]
#![feature(bool_to_option)]
#![feature(box_syntax)]
#![feature(c_variadic)]
#![feature(cfg_accessible)]
@ -297,7 +296,6 @@
#![feature(raw)]
#![feature(raw_ref_macros)]
#![feature(ready_macro)]
#![feature(refcell_take)]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
#![feature(shrink_to)]

View File

@ -23,7 +23,6 @@
#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
#![feature(rustc_private)]
#![feature(nll)]
#![feature(bool_to_option)]
#![feature(available_concurrency)]
#![feature(internal_output_capture)]
#![feature(panic_unwind)]

View File

@ -0,0 +1,76 @@
// Test evaluation order of operands of the compound assignment operators
// run-pass
use std::ops::AddAssign;
enum Side {
Lhs,
Rhs,
}
// In the following tests, we place our value into a wrapper type so that we
// can do an element access as the outer place expression. If we just had the
// block expression, it'd be a value expression and not compile.
struct Wrapper<T>(T);
// Evaluation order for `a op= b` where typeof(a) and typeof(b) are primitives
// is first `b` then `a`.
fn primitive_compound() {
let mut side_order = vec![];
let mut int = Wrapper(0);
{
side_order.push(Side::Lhs);
int
}.0 += {
side_order.push(Side::Rhs);
0
};
assert!(matches!(side_order[..], [Side::Rhs, Side::Lhs]));
}
// Evaluation order for `a op=b` otherwise is first `a` then `b`.
fn generic_compound<T: AddAssign<T> + Default>() {
let mut side_order = vec![];
let mut add_assignable: Wrapper<T> = Wrapper(Default::default());
{
side_order.push(Side::Lhs);
add_assignable
}.0 += {
side_order.push(Side::Rhs);
Default::default()
};
assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs]));
}
fn custom_compound() {
struct Custom;
impl AddAssign<()> for Custom {
fn add_assign(&mut self, _: ()) {
// this block purposely left blank
}
}
let mut side_order = vec![];
let mut custom = Wrapper(Custom);
{
side_order.push(Side::Lhs);
custom
}.0 += {
side_order.push(Side::Rhs);
};
assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs]));
}
fn main() {
primitive_compound();
generic_compound::<i32>();
custom_compound();
}

View File

@ -13,11 +13,13 @@ error[E0599]: no method named `collect` found for struct `Cloned<TakeWhile<&mut
LL | .collect();
| ^^^^^^^ method not found in `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6]>>`
|
::: $SRC_DIR/core/src/iter/adapters/mod.rs:LL:COL
::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
|
LL | pub struct Cloned<I> {
| -------------------- doesn't satisfy `_: Iterator`
...
|
::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
|
LL | pub struct TakeWhile<I, P> {
| -------------------------- doesn't satisfy `<_ as Iterator>::Item = &_`
|

View File

@ -15,7 +15,7 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
| doesn't satisfy `_: FnMut<(&&str,)>`
|
::: $SRC_DIR/core/src/iter/adapters/mod.rs:LL:COL
::: $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
|
LL | pub struct Filter<I, P> {
| ----------------------- doesn't satisfy `_: Iterator`