1
1
use crate :: fmt;
2
2
use crate :: iter:: { FusedIterator , TrustedLen , UncheckedIterator } ;
3
- use crate :: mem:: { self , MaybeUninit } ;
4
3
use crate :: num:: NonZero ;
5
4
6
5
/// Creates a new iterator that repeats a single element a given number of times.
@@ -59,78 +58,48 @@ use crate::num::NonZero;
59
58
#[ inline]
60
59
#[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
61
60
pub fn repeat_n < T : Clone > ( element : T , count : usize ) -> RepeatN < T > {
62
- let element = if count == 0 {
63
- // `element` gets dropped eagerly.
64
- MaybeUninit :: uninit ( )
65
- } else {
66
- MaybeUninit :: new ( element)
67
- } ;
68
-
69
- RepeatN { element, count }
61
+ RepeatN { inner : RepeatNInner :: new ( element, count) }
62
+ }
63
+
64
+ #[ derive( Clone ) ]
65
+ struct RepeatNInner < T > {
66
+ element : T ,
67
+ count : NonZero < usize > ,
68
+ }
69
+
70
+ impl < T > RepeatNInner < T > {
71
+ fn new ( element : T , count : usize ) -> Option < Self > {
72
+ let count = NonZero :: < usize > :: new ( count) ?;
73
+ Some ( Self { element, count } )
74
+ }
70
75
}
71
76
72
77
/// An iterator that repeats an element an exact number of times.
73
78
///
74
79
/// This `struct` is created by the [`repeat_n()`] function.
75
80
/// See its documentation for more.
76
81
#[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
82
+ #[ derive( Clone ) ]
77
83
pub struct RepeatN < A > {
78
- count : usize ,
79
- // Invariant: uninit iff count == 0.
80
- element : MaybeUninit < A > ,
84
+ inner : Option < RepeatNInner < A > > ,
81
85
}
82
86
83
87
impl < A > RepeatN < A > {
84
- /// Returns the element if it hasn't been dropped already.
85
- fn element_ref ( & self ) -> Option < & A > {
86
- if self . count > 0 {
87
- // SAFETY: The count is non-zero, so it must be initialized.
88
- Some ( unsafe { self . element . assume_init_ref ( ) } )
89
- } else {
90
- None
91
- }
92
- }
93
88
/// If we haven't already dropped the element, return it in an option.
94
- ///
95
- /// Clears the count so it won't be dropped again later.
96
89
#[ inline]
97
90
fn take_element ( & mut self ) -> Option < A > {
98
- if self . count > 0 {
99
- self . count = 0 ;
100
- let element = mem:: replace ( & mut self . element , MaybeUninit :: uninit ( ) ) ;
101
- // SAFETY: We just set count to zero so it won't be dropped again,
102
- // and it used to be non-zero so it hasn't already been dropped.
103
- unsafe { Some ( element. assume_init ( ) ) }
104
- } else {
105
- None
106
- }
107
- }
108
- }
109
-
110
- #[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
111
- impl < A : Clone > Clone for RepeatN < A > {
112
- fn clone ( & self ) -> RepeatN < A > {
113
- RepeatN {
114
- count : self . count ,
115
- element : self . element_ref ( ) . cloned ( ) . map_or_else ( MaybeUninit :: uninit, MaybeUninit :: new) ,
116
- }
91
+ self . inner . take ( ) . map ( |inner| inner. element )
117
92
}
118
93
}
119
94
120
95
#[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
121
96
impl < A : fmt:: Debug > fmt:: Debug for RepeatN < A > {
122
97
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
123
- f. debug_struct ( "RepeatN" )
124
- . field ( "count" , & self . count )
125
- . field ( "element" , & self . element_ref ( ) )
126
- . finish ( )
127
- }
128
- }
129
-
130
- #[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
131
- impl < A > Drop for RepeatN < A > {
132
- fn drop ( & mut self ) {
133
- self . take_element ( ) ;
98
+ let ( count, element) = match self . inner . as_ref ( ) {
99
+ Some ( inner) => ( inner. count . get ( ) , Some ( & inner. element ) ) ,
100
+ None => ( 0 , None ) ,
101
+ } ;
102
+ f. debug_struct ( "RepeatN" ) . field ( "count" , & count) . field ( "element" , & element) . finish ( )
134
103
}
135
104
}
136
105
@@ -140,12 +109,15 @@ impl<A: Clone> Iterator for RepeatN<A> {
140
109
141
110
#[ inline]
142
111
fn next ( & mut self ) -> Option < A > {
143
- if self . count > 0 {
144
- // SAFETY: Just checked it's not empty
145
- unsafe { Some ( self . next_unchecked ( ) ) }
146
- } else {
147
- None
112
+ let inner = self . inner . as_mut ( ) ?;
113
+ let count = inner. count . get ( ) ;
114
+
115
+ if let Some ( decremented) = NonZero :: < usize > :: new ( count - 1 ) {
116
+ inner. count = decremented;
117
+ return Some ( inner. element . clone ( ) ) ;
148
118
}
119
+
120
+ return self . take_element ( ) ;
149
121
}
150
122
151
123
#[ inline]
@@ -156,19 +128,19 @@ impl<A: Clone> Iterator for RepeatN<A> {
156
128
157
129
#[ inline]
158
130
fn advance_by ( & mut self , skip : usize ) -> Result < ( ) , NonZero < usize > > {
159
- let len = self . count ;
131
+ let Some ( inner) = self . inner . as_mut ( ) else {
132
+ return NonZero :: < usize > :: new ( skip) . map ( Err ) . unwrap_or ( Ok ( ( ) ) ) ;
133
+ } ;
160
134
161
- if skip >= len {
162
- self . take_element ( ) ;
163
- }
135
+ let len = inner. count . get ( ) ;
164
136
165
- if skip > len {
166
- // SAFETY: we just checked that the difference is positive
167
- Err ( unsafe { NonZero :: new_unchecked ( skip - len) } )
168
- } else {
169
- self . count = len - skip;
170
- Ok ( ( ) )
137
+ if let Some ( new_len) = len. checked_sub ( skip) . and_then ( NonZero :: < usize > :: new) {
138
+ inner. count = new_len;
139
+ return Ok ( ( ) ) ;
171
140
}
141
+
142
+ self . inner = None ;
143
+ return NonZero :: < usize > :: new ( skip - len) . map ( Err ) . unwrap_or ( Ok ( ( ) ) ) ;
172
144
}
173
145
174
146
#[ inline]
@@ -185,7 +157,7 @@ impl<A: Clone> Iterator for RepeatN<A> {
185
157
#[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
186
158
impl < A : Clone > ExactSizeIterator for RepeatN < A > {
187
159
fn len ( & self ) -> usize {
188
- self . count
160
+ self . inner . as_ref ( ) . map ( |inner| inner . count . get ( ) ) . unwrap_or ( 0 )
189
161
}
190
162
}
191
163
@@ -213,20 +185,4 @@ impl<A: Clone> FusedIterator for RepeatN<A> {}
213
185
#[ unstable( feature = "trusted_len" , issue = "37572" ) ]
214
186
unsafe impl < A : Clone > TrustedLen for RepeatN < A > { }
215
187
#[ stable( feature = "iter_repeat_n" , since = "1.82.0" ) ]
216
- impl < A : Clone > UncheckedIterator for RepeatN < A > {
217
- #[ inline]
218
- unsafe fn next_unchecked ( & mut self ) -> Self :: Item {
219
- // SAFETY: The caller promised the iterator isn't empty
220
- self . count = unsafe { self . count . unchecked_sub ( 1 ) } ;
221
- if self . count == 0 {
222
- // SAFETY: the check above ensured that the count used to be non-zero,
223
- // so element hasn't been dropped yet, and we just lowered the count to
224
- // zero so it won't be dropped later, and thus it's okay to take it here.
225
- unsafe { mem:: replace ( & mut self . element , MaybeUninit :: uninit ( ) ) . assume_init ( ) }
226
- } else {
227
- // SAFETY: the count is non-zero, so it must have not been dropped yet.
228
- let element = unsafe { self . element . assume_init_ref ( ) } ;
229
- A :: clone ( element)
230
- }
231
- }
232
- }
188
+ impl < A : Clone > UncheckedIterator for RepeatN < A > { }
0 commit comments