Auto merge of #120050 - scottmcm:vec-resize-memset, r= · rust-lang/rust@27371af (original) (raw)
`@@ -110,6 +110,58 @@ impl Drop for RepeatN {
`
110
110
`}
`
111
111
`}
`
112
112
``
``
113
`+
trait SpecRepeatN {
`
``
114
`+
unsafe fn spec_next_unchecked(&mut self) -> A;
`
``
115
`+
fn spec_fold<B, F: FnMut(B, A) -> B>(self, b: B, f: F) -> B;
`
``
116
`+
}
`
``
117
+
``
118
`+
impl<A: Clone> SpecRepeatN for RepeatN {
`
``
119
`+
default unsafe fn spec_next_unchecked(&mut self) -> A {
`
``
120
`+
self.count -= 1;
`
``
121
+
``
122
`+
if self.count == 0 {
`
``
123
`+
// SAFETY: we just lowered the count to zero so it won't be dropped
`
``
124
`+
// later, and thus it's okay to take it here.
`
``
125
`+
unsafe { ManuallyDrop::take(&mut self.element) }
`
``
126
`+
} else {
`
``
127
`+
A::clone(&self.element)
`
``
128
`+
}
`
``
129
`+
}
`
``
130
+
``
131
`+
default fn spec_fold<B, F: FnMut(B, A) -> B>(mut self, mut b: B, mut f: F) -> B {
`
``
132
`+
let mut count = self.count;
`
``
133
`+
if let Some(element) = self.take_element() {
`
``
134
`+
while count > 1 {
`
``
135
`+
count -= 1;
`
``
136
`+
b = f(b, element.clone());
`
``
137
`+
}
`
``
138
`+
b = f(b, element);
`
``
139
`+
}
`
``
140
`+
b
`
``
141
`+
}
`
``
142
`+
}
`
``
143
+
``
144
`+
impl<A: Copy> SpecRepeatN for RepeatN {
`
``
145
`+
unsafe fn spec_next_unchecked(&mut self) -> A {
`
``
146
`+
self.count -= 1;
`
``
147
+
``
148
`` +
// For Copy
types, we can always just read the item directly,
``
``
149
`+
// so skip having a branch that would need to be optimized out.
`
``
150
`+
*self.element
`
``
151
`+
}
`
``
152
+
``
153
`+
fn spec_fold<B, F: FnMut(B, A) -> B>(self, mut b: B, mut f: F) -> B {
`
``
154
`+
let mut count = self.count;
`
``
155
`+
let element = *self.element;
`
``
156
+
``
157
`+
while count > 0 {
`
``
158
`+
count -= 1;
`
``
159
`+
b = f(b, element);
`
``
160
`+
}
`
``
161
`+
b
`
``
162
`+
}
`
``
163
`+
}
`
``
164
+
113
165
`#[unstable(feature = "iter_repeat_n", issue = "104434")]
`
114
166
`impl<A: Clone> Iterator for RepeatN {
`
115
167
`type Item = A;
`
`@@ -120,15 +172,8 @@ impl<A: Clone> Iterator for RepeatN {
`
120
172
`return None;
`
121
173
`}
`
122
174
``
123
``
`-
self.count -= 1;
`
124
``
`-
Some(if self.count == 0 {
`
125
``
`-
// SAFETY: the check above ensured that the count used to be non-zero,
`
126
``
`-
// so element hasn't been dropped yet, and we just lowered the count to
`
127
``
`-
// zero so it won't be dropped later, and thus it's okay to take it here.
`
128
``
`-
unsafe { ManuallyDrop::take(&mut self.element) }
`
129
``
`-
} else {
`
130
``
`-
A::clone(&self.element)
`
131
``
`-
})
`
``
175
`+
// SAFETY: Just confirmed above that the iterator is non-empty
`
``
176
`+
unsafe { Some(self.spec_next_unchecked()) }
`
132
177
`}
`
133
178
``
134
179
`#[inline]
`
`@@ -154,6 +199,11 @@ impl<A: Clone> Iterator for RepeatN {
`
154
199
`}
`
155
200
`}
`
156
201
``
``
202
`+
#[inline]
`
``
203
`+
fn fold<B, F: FnMut(B, A) -> B>(self, init: B, f: F) -> B {
`
``
204
`+
self.spec_fold(init, f)
`
``
205
`+
}
`
``
206
+
157
207
`#[inline]
`
158
208
`fn last(mut self) -> Option {
`
159
209
`self.take_element()
`