1
1
// ignore-tidy-filelength
2
+ // This file almost exclusively consists of the definition of `Iterator`. We
3
+ // can't split that into multiple files.
2
4
3
5
use crate :: cmp:: { self , Ordering } ;
4
6
use crate :: ops:: { Add , Try } ;
@@ -7,7 +9,9 @@ use super::super::LoopState;
7
9
use super :: super :: { Chain , Cloned , Copied , Cycle , Enumerate , Filter , FilterMap , Fuse } ;
8
10
use super :: super :: { FlatMap , Flatten } ;
9
11
use 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
+ } ;
11
15
12
16
fn _assert_is_object_safe ( _: & dyn Iterator < Item = ( ) > ) { }
13
17
@@ -1026,6 +1030,102 @@ pub trait Iterator {
1026
1030
TakeWhile :: new ( self , predicate)
1027
1031
}
1028
1032
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
+
1029
1129
/// Creates an iterator that skips the first `n` elements.
1030
1130
///
1031
1131
/// After they have been consumed, the rest of the elements are yielded.
0 commit comments