2 use std
::iter
::Peekable
;
4 #[cfg(feature = "use_std")]
7 /// An iterator that allows peeking at an element before deciding to accept it.
9 /// See [`.peeking_take_while()`](trait.Itertools.html#method.peeking_take_while)
10 /// for more information.
12 /// This is implemented by peeking adaptors like peekable and put back,
13 /// but also by a few iterators that can be peeked natively, like the slice’s
14 /// by reference iterator (`std::slice::Iter`).
15 pub trait PeekingNext
: Iterator
{
16 /// Pass a reference to the next iterator element to the closure `accept`;
17 /// if `accept` returns true, return it as the next element,
19 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
20 where F
: FnOnce(&Self::Item
) -> bool
;
23 impl<I
> PeekingNext
for Peekable
<I
>
26 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
27 where F
: FnOnce(&Self::Item
) -> bool
29 if let Some(r
) = self.peek() {
38 impl<I
> PeekingNext
for PutBack
<I
>
41 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
42 where F
: FnOnce(&Self::Item
) -> bool
44 if let Some(r
) = self.next() {
56 #[cfg(feature = "use_std")]
57 impl<I
> PeekingNext
for PutBackN
<I
>
60 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
61 where F
: FnOnce(&Self::Item
) -> bool
63 if let Some(r
) = self.next() {
75 /// An iterator adaptor that takes items while a closure returns `true`.
77 /// See [`.peeking_take_while()`](../trait.Itertools.html#method.peeking_take_while)
78 /// for more information.
79 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
80 pub struct PeekingTakeWhile
<'a
, I
: 'a
, F
>
87 /// Create a PeekingTakeWhile
88 pub fn peeking_take_while
<I
, F
>(iter
: &mut I
, f
: F
) -> PeekingTakeWhile
<I
, F
>
97 impl<'a
, I
, F
> Iterator
for PeekingTakeWhile
<'a
, I
, F
>
99 F
: FnMut(&I
::Item
) -> bool
,
103 fn next(&mut self) -> Option
<Self::Item
> {
104 self.iter
.peeking_next(&mut self.f
)
107 fn size_hint(&self) -> (usize, Option
<usize>) {
108 let (_
, hi
) = self.iter
.size_hint();
113 // Some iterators are so lightweight we can simply clone them to save their
114 // state and use that for peeking.
115 macro_rules
! peeking_next_by_clone
{
116 ([$
($typarm
:tt
)*] $type_
:ty
) => {
117 impl<$
($typarm
)*> PeekingNext
for $type_
{
118 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
119 where F
: FnOnce(&Self::Item
) -> bool
121 let saved_state
= self.clone();
122 if let Some(r
) = self.next() {
135 peeking_next_by_clone
! { ['a, T] ::std::slice::Iter<'a, T> }
136 peeking_next_by_clone
! { ['a] ::std::str::Chars<'a> }
137 peeking_next_by_clone
! { ['a] ::std::str::CharIndices<'a> }
138 peeking_next_by_clone
! { ['a] ::std::str::Bytes<'a> }
139 peeking_next_by_clone
! { ['a, T] ::std::option::Iter<'a, T> }
140 peeking_next_by_clone
! { ['a, T] ::std::result::Iter<'a, T> }
141 peeking_next_by_clone
! { [T] ::std::iter::Empty<T> }
142 #[cfg(feature = "use_std")]
143 peeking_next_by_clone
! { ['a, T] ::std::collections::linked_list::Iter<'a, T> }
144 #[cfg(feature = "use_std")]
145 peeking_next_by_clone
! { ['a, T] ::std::collections::vec_deque::Iter<'a, T> }
147 // cloning a Rev has no extra overhead; peekable and put backs are never DEI.
148 peeking_next_by_clone
! { [I
: Clone
+ PeekingNext
+ DoubleEndedIterator
]
149 ::std
::iter
::Rev
<I
> }