1 use std
::iter
::Peekable
;
3 #[cfg(feature = "use_std")]
6 /// An iterator that allows peeking at an element before deciding to accept it.
8 /// See [`.peeking_take_while()`](trait.Itertools.html#method.peeking_take_while)
9 /// for more information.
11 /// This is implemented by peeking adaptors like peekable and put back,
12 /// but also by a few iterators that can be peeked natively, like the slice’s
13 /// by reference iterator (`std::slice::Iter`).
14 pub trait PeekingNext
: Iterator
{
15 /// Pass a reference to the next iterator element to the closure `accept`;
16 /// if `accept` returns true, return it as the next element,
18 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
19 where F
: FnOnce(&Self::Item
) -> bool
;
22 impl<I
> PeekingNext
for Peekable
<I
>
25 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
26 where F
: FnOnce(&Self::Item
) -> bool
28 if let Some(r
) = self.peek() {
37 impl<I
> PeekingNext
for PutBack
<I
>
40 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
41 where F
: FnOnce(&Self::Item
) -> bool
43 if let Some(r
) = self.next() {
55 #[cfg(feature = "use_std")]
56 impl<I
> PeekingNext
for PutBackN
<I
>
59 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
60 where F
: FnOnce(&Self::Item
) -> bool
62 if let Some(r
) = self.next() {
74 /// An iterator adaptor that takes items while a closure returns `true`.
76 /// See [`.peeking_take_while()`](../trait.Itertools.html#method.peeking_take_while)
77 /// for more information.
78 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
79 pub struct PeekingTakeWhile
<'a
, I
: 'a
, F
>
86 /// Create a PeekingTakeWhile
87 pub fn peeking_take_while
<I
, F
>(iter
: &mut I
, f
: F
) -> PeekingTakeWhile
<I
, F
>
96 impl<'a
, I
, F
> Iterator
for PeekingTakeWhile
<'a
, I
, F
>
98 F
: FnMut(&I
::Item
) -> bool
,
102 fn next(&mut self) -> Option
<Self::Item
> {
103 self.iter
.peeking_next(&mut self.f
)
106 fn size_hint(&self) -> (usize, Option
<usize>) {
107 let (_
, hi
) = self.iter
.size_hint();
112 // Some iterators are so lightweight we can simply clone them to save their
113 // state and use that for peeking.
114 macro_rules
! peeking_next_by_clone
{
115 ([$
($typarm
:tt
)*] $type_
:ty
) => {
116 impl<$
($typarm
)*> PeekingNext
for $type_
{
117 fn peeking_next
<F
>(&mut self, accept
: F
) -> Option
<Self::Item
>
118 where F
: FnOnce(&Self::Item
) -> bool
120 let saved_state
= self.clone();
121 if let Some(r
) = self.next() {
134 peeking_next_by_clone
! { ['a, T] ::std::slice::Iter<'a, T> }
135 peeking_next_by_clone
! { ['a] ::std::str::Chars<'a> }
136 peeking_next_by_clone
! { ['a] ::std::str::CharIndices<'a> }
137 peeking_next_by_clone
! { ['a] ::std::str::Bytes<'a> }
138 peeking_next_by_clone
! { ['a, T] ::std::option::Iter<'a, T> }
139 peeking_next_by_clone
! { ['a, T] ::std::result::Iter<'a, T> }
140 peeking_next_by_clone
! { [T] ::std::iter::Empty<T> }
141 #[cfg(feature = "use_std")]
142 peeking_next_by_clone
! { ['a, T] ::std::collections::linked_list::Iter<'a, T> }
143 #[cfg(feature = "use_std")]
144 peeking_next_by_clone
! { ['a, T] ::std::collections::vec_deque::Iter<'a, T> }
146 // cloning a Rev has no extra overhead; peekable and put backs are never DEI.
147 peeking_next_by_clone
! { [I
: Clone
+ PeekingNext
+ DoubleEndedIterator
]
148 ::std
::iter
::Rev
<I
> }