1- use crate :: size_hint;
21use std:: iter:: { Fuse , FusedIterator } ;
32
43/// An iterator adaptor that pads a sequence to a minimum length by filling
@@ -11,28 +10,36 @@ use std::iter::{Fuse, FusedIterator};
1110#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
1211pub struct PadUsing < I , F > {
1312 iter : Fuse < I > ,
14- min : usize ,
15- pos : usize ,
13+ elements_from_next : usize ,
14+ elements_from_next_back : usize ,
15+ elements_required : usize ,
1616 filler : F ,
1717}
1818
1919impl < I , F > std:: fmt:: Debug for PadUsing < I , F >
2020where
2121 I : std:: fmt:: Debug ,
2222{
23- debug_fmt_fields ! ( PadUsing , iter, min, pos) ;
23+ debug_fmt_fields ! (
24+ PadUsing ,
25+ iter,
26+ elements_from_next,
27+ elements_from_next_back,
28+ elements_required
29+ ) ;
2430}
2531
2632/// Create a new `PadUsing` iterator.
27- pub fn pad_using < I , F > ( iter : I , min : usize , filler : F ) -> PadUsing < I , F >
33+ pub fn pad_using < I , F > ( iter : I , elements_required : usize , filler : F ) -> PadUsing < I , F >
2834where
2935 I : Iterator ,
3036 F : FnMut ( usize ) -> I :: Item ,
3137{
3238 PadUsing {
3339 iter : iter. fuse ( ) ,
34- min,
35- pos : 0 ,
40+ elements_from_next : 0 ,
41+ elements_from_next_back : 0 ,
42+ elements_required,
3643 filler,
3744 }
3845}
@@ -46,38 +53,34 @@ where
4653
4754 #[ inline]
4855 fn next ( & mut self ) -> Option < Self :: Item > {
49- match self . iter . next ( ) {
50- None => {
51- if self . pos < self . min {
52- let e = Some ( ( self . filler ) ( self . pos ) ) ;
53- self . pos += 1 ;
54- e
55- } else {
56- None
57- }
58- }
59- e => {
60- self . pos += 1 ;
61- e
62- }
56+ let total_consumed = self . elements_from_next + self . elements_from_next_back ;
57+
58+ if total_consumed >= self . elements_required {
59+ self . iter . next ( )
60+ } else if let Some ( e) = self . iter . next ( ) {
61+ self . elements_from_next += 1 ;
62+ Some ( e)
63+ } else {
64+ let e = ( self . filler ) ( self . elements_from_next ) ;
65+ self . elements_from_next += 1 ;
66+ Some ( e)
6367 }
6468 }
6569
6670 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
67- let tail = self . min . saturating_sub ( self . pos ) ;
68- size_hint:: max ( self . iter . size_hint ( ) , ( tail, Some ( tail) ) )
69- }
71+ let total_consumed = self . elements_from_next + self . elements_from_next_back ;
72+
73+ if total_consumed >= self . elements_required {
74+ return self . iter . size_hint ( ) ;
75+ }
76+
77+ let elements_remaining = self . elements_required - total_consumed;
78+ let ( low, high) = self . iter . size_hint ( ) ;
79+
80+ let lower_bound = low. max ( elements_remaining) ;
81+ let upper_bound = high. map ( |h| h. max ( elements_remaining) ) ;
7082
71- fn fold < B , G > ( self , mut init : B , mut f : G ) -> B
72- where
73- G : FnMut ( B , Self :: Item ) -> B ,
74- {
75- let mut pos = self . pos ;
76- init = self . iter . fold ( init, |acc, item| {
77- pos += 1 ;
78- f ( acc, item)
79- } ) ;
80- ( pos..self . min ) . map ( self . filler ) . fold ( init, f)
83+ ( lower_bound, upper_bound)
8184 }
8285}
8386
@@ -87,25 +90,24 @@ where
8790 F : FnMut ( usize ) -> I :: Item ,
8891{
8992 fn next_back ( & mut self ) -> Option < Self :: Item > {
90- if self . min == 0 {
91- self . iter . next_back ( )
92- } else if self . iter . len ( ) >= self . min {
93- self . min -= 1 ;
94- self . iter . next_back ( )
95- } else {
96- self . min -= 1 ;
97- Some ( ( self . filler ) ( self . min ) )
93+ let total_consumed = self . elements_from_next + self . elements_from_next_back ;
94+
95+ if total_consumed >= self . elements_required {
96+ return self . iter . next_back ( ) ;
9897 }
99- }
10098
101- fn rfold < B , G > ( self , mut init : B , mut f : G ) -> B
102- where
103- G : FnMut ( B , Self :: Item ) -> B ,
104- {
105- init = ( self . iter . len ( ) ..self . min )
106- . map ( self . filler )
107- . rfold ( init, & mut f) ;
108- self . iter . rfold ( init, f)
99+ let elements_remaining = self . elements_required - total_consumed;
100+ self . elements_from_next_back += 1 ;
101+
102+ if self . iter . len ( ) < elements_remaining {
103+ Some ( ( self . filler ) (
104+ self . elements_required - self . elements_from_next_back ,
105+ ) )
106+ } else {
107+ let item = self . iter . next_back ( ) ;
108+ debug_assert ! ( item. is_some( ) ) ; // If this triggers, we should not have incremented elements_from_next_back, and the input iterator mistakenly reported that it would be able to produce at least elements_remaining items.
109+ item
110+ }
109111 }
110112}
111113
0 commit comments