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()

`