11// ignore-tidy-filelength
2+ // This file almost exclusively consists of the definition of `Iterator`. We
3+ // can't split that into multiple files.
24
35use crate :: cmp:: { self , Ordering } ;
46use crate :: ops:: { Add , Try } ;
@@ -7,7 +9,9 @@ use super::super::LoopState;
79use super :: super :: { Chain , Cloned , Copied , Cycle , Enumerate , Filter , FilterMap , Fuse } ;
810use super :: super :: { FlatMap , Flatten } ;
911use super :: super :: { FromIterator , Product , Sum , Zip } ;
10- use super :: super :: { Inspect , Map , Peekable , Rev , Scan , Skip , SkipWhile , StepBy , Take , TakeWhile } ;
12+ use super :: super :: {
13+ Inspect , Map , MapWhile , Peekable , Rev , Scan , Skip , SkipWhile , StepBy , Take , TakeWhile ,
14+ } ;
1115
1216fn _assert_is_object_safe ( _: & dyn Iterator < Item = ( ) > ) { }
1317
@@ -1026,6 +1030,102 @@ pub trait Iterator {
10261030 TakeWhile :: new ( self , predicate)
10271031 }
10281032
1033+ /// Creates an iterator that both yields elements based on a predicate and maps.
1034+ ///
1035+ /// `map_while()` takes a closure as an argument. It will call this
1036+ /// closure on each element of the iterator, and yield elements
1037+ /// while it returns [`Some(_)`][`Some`].
1038+ ///
1039+ /// After [`None`] is returned, `map_while()`'s job is over, and the
1040+ /// rest of the elements are ignored.
1041+ ///
1042+ /// # Examples
1043+ ///
1044+ /// Basic usage:
1045+ ///
1046+ /// ```
1047+ /// #![feature(iter_map_while)]
1048+ /// let a = [-1i32, 4, 0, 1];
1049+ ///
1050+ /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));
1051+ ///
1052+ /// assert_eq!(iter.next(), Some(-16));
1053+ /// assert_eq!(iter.next(), Some(4));
1054+ /// assert_eq!(iter.next(), None);
1055+ /// ```
1056+ ///
1057+ /// Here's the same example, but with [`take_while`] and [`map`]:
1058+ ///
1059+ /// [`take_while`]: #method.take_while
1060+ /// [`map`]: #method.map
1061+ ///
1062+ /// ```
1063+ /// let a = [-1i32, 4, 0, 1];
1064+ ///
1065+ /// let mut iter = a.iter()
1066+ /// .map(|x| 16i32.checked_div(*x))
1067+ /// .take_while(|x| x.is_some())
1068+ /// .map(|x| x.unwrap());
1069+ ///
1070+ /// assert_eq!(iter.next(), Some(-16));
1071+ /// assert_eq!(iter.next(), Some(4));
1072+ /// assert_eq!(iter.next(), None);
1073+ /// ```
1074+ ///
1075+ /// Stopping after an initial [`None`]:
1076+ ///
1077+ /// ```
1078+ /// #![feature(iter_map_while)]
1079+ /// use std::convert::TryFrom;
1080+ ///
1081+ /// let a = [0, -1, 1, -2];
1082+ ///
1083+ /// let mut iter = a.iter().map_while(|x| u32::try_from(*x).ok());
1084+ ///
1085+ /// assert_eq!(iter.next(), Some(0u32));
1086+ ///
1087+ /// // We have more elements that are fit in u32, but since we already
1088+ /// // got a None, map_while() isn't used any more
1089+ /// assert_eq!(iter.next(), None);
1090+ /// ```
1091+ ///
1092+ /// Because `map_while()` needs to look at the value in order to see if it
1093+ /// should be included or not, consuming iterators will see that it is
1094+ /// removed:
1095+ ///
1096+ /// ```
1097+ /// #![feature(iter_map_while)]
1098+ /// use std::convert::TryFrom;
1099+ ///
1100+ /// let a = [1, 2, -3, 4];
1101+ /// let mut iter = a.iter();
1102+ ///
1103+ /// let result: Vec<u32> = iter.by_ref()
1104+ /// .map_while(|n| u32::try_from(*n).ok())
1105+ /// .collect();
1106+ ///
1107+ /// assert_eq!(result, &[1, 2]);
1108+ ///
1109+ /// let result: Vec<i32> = iter.cloned().collect();
1110+ ///
1111+ /// assert_eq!(result, &[4]);
1112+ /// ```
1113+ ///
1114+ /// The `-3` is no longer there, because it was consumed in order to see if
1115+ /// the iteration should stop, but wasn't placed back into the iterator.
1116+ ///
1117+ /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
1118+ /// [`None`]: ../../std/option/enum.Option.html#variant.None
1119+ #[ inline]
1120+ #[ unstable( feature = "iter_map_while" , reason = "recently added" , issue = "none" ) ]
1121+ fn map_while < B , P > ( self , predicate : P ) -> MapWhile < Self , P >
1122+ where
1123+ Self : Sized ,
1124+ P : FnMut ( Self :: Item ) -> Option < B > ,
1125+ {
1126+ MapWhile :: new ( self , predicate)
1127+ }
1128+
10291129 /// Creates an iterator that skips the first `n` elements.
10301130 ///
10311131 /// After they have been consumed, the rest of the elements are yielded.
0 commit comments