Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: New implementation of the slice iterators
Reimplement the slice iterators using `NonZero` where possible. 1. Iter, IterMut now have a non-nullable field a. The usual enum layout optimizations apply b. Automatic and more principled nonnull metadata for that pointer 2. Big change for zero sized elements. The end field is a counter. The produced pointer value is equivalent to `slice.as_ptr()` and thus `&slice[i]` for each index `i` in this case. * Implementation Notes ** Regular case, T is not zero-sized (Nothing changes in this case, but this is the documentation in the code.) The iterator represents a contiguous range of elements. `ptr` is a pointer to the start of the range. `end` is a pointer to one past the end of the range. Initial values are ptr = slice.as_ptr() and end = ptr.offset(slice.len()) The iterator is empty when ptr == end. The iterator is stepped at the front by incrementing ptr, the yielded element is the old value of ptr ("post increment" semantic). The iterator is stepped at the back by decrementing end, the yielded element is the new value of end ("pre decrement" semantic). ** When T is a Zero-sized type (ZST) `ptr` is a pointer to the start of the range. `end` is used as an integer: the count of elements in the range. Initial values are ptr = slice.as_ptr() and end = self.len() as *const T The iterator is empty when end == 0 The iterator is stepped at the front by decrementing end. The iterator is stepped at the back by decrementing end. For both front and back, the yielded element is `ptr`, which does not change during the iteration. ** NonZero `ptr` is derived from `slice.as_ptr()` and just like it is is non-null. `end` is allowed to be null (used by the ZST implementation); this is required since for iterating a [(); usize::MAX] all values of usize (and equivalently the raw pointer) are used, including zero.
- Loading branch information