Skip to content

Commit dac6212

Browse files
committed
Auto merge of #136718 - the8472:const-dispatch-slice-iter, r=<try>
[perf experiment] try const dispatch instead of macros for slice::iter::next
2 parents a9e7b30 + 505e294 commit dac6212

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

library/core/src/slice/iter/macros.rs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,36 @@ macro_rules! iterator {
133133
},
134134
)
135135
}
136+
137+
unsafe fn iter_next_zst(&mut self) -> Option<$elem> {
138+
// SAFETY: todo
139+
let len_ref = unsafe { &mut *(&raw mut self.end_or_len).cast::<usize>() };
140+
if *len_ref == 0 {
141+
None
142+
} else {
143+
// SAFETY: todo
144+
Some(unsafe {
145+
*len_ref = crate::intrinsics::unchecked_sub(*len_ref, 1);
146+
self.ptr.$into_ref()
147+
})
148+
}
149+
}
150+
151+
unsafe fn iter_next_pst(&mut self) -> Option<$elem> {
152+
// SAFETY: todo
153+
let end_ref = unsafe { &mut *(&raw mut self.end_or_len).cast::<NonNull<T>>() };
154+
if self.ptr == *end_ref {
155+
None
156+
} else {
157+
// SAFETY: todo
158+
Some(unsafe {
159+
let $( $mut_ )? old = self.ptr;
160+
self.ptr = self.ptr.add(1);
161+
old.$into_ref()
162+
})
163+
}
164+
}
165+
136166
}
137167

138168
#[stable(feature = "rust1", since = "1.0.0")]
@@ -154,17 +184,9 @@ macro_rules! iterator {
154184

155185
#[inline]
156186
fn next(&mut self) -> Option<$elem> {
157-
// could be implemented with slices, but this avoids bounds checks
158-
159-
// SAFETY: The call to `next_unchecked` is
160-
// safe since we check if the iterator is empty first.
161-
unsafe {
162-
if is_empty!(self) {
163-
None
164-
} else {
165-
Some(self.next_unchecked())
166-
}
167-
}
187+
let fun = const { if T::IS_ZST { Self::iter_next_zst } else { Self::iter_next_pst } };
188+
// SAFETY: todo
189+
unsafe { fun(self) }
168190
}
169191

170192
#[inline]

0 commit comments

Comments
 (0)