diff options
| author | The8472 <git@infinite-source.de> | 2021-01-31 21:15:18 +0100 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2021-03-21 20:43:48 +0100 |
| commit | 895d7a9a096aab4690a032cee28f57f4b8a0e9ac (patch) | |
| tree | 5611608833cb39148a23f13aafc164ebc12c1259 | |
| parent | 1438207c3d150ce42804e857537b12082c68c79b (diff) | |
| download | rust-895d7a9a096aab4690a032cee28f57f4b8a0e9ac.tar.gz rust-895d7a9a096aab4690a032cee28f57f4b8a0e9ac.zip | |
implement TrustedRandomAccess for Ranges over int types
| -rw-r--r-- | library/core/src/iter/range.rs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index cc80e06decd..4b293c596e7 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -3,7 +3,7 @@ use crate::convert::TryFrom; use crate::mem; use crate::ops::{self, Try}; -use super::{FusedIterator, TrustedLen}; +use super::{FusedIterator, TrustedLen, TrustedRandomAccess}; /// Objects that have a notion of *successor* and *predecessor* operations. /// @@ -493,6 +493,18 @@ macro_rules! range_exact_iter_impl { )*) } +/// Safety: This macro must only be used on types that are `Copy` and result in ranges +/// which have an exact `size_hint()` where the upper bound must not be `None`. +macro_rules! unsafe_range_trusted_random_access_impl { + ($($t:ty)*) => ($( + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccess for ops::Range<$t> { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + )*) +} + macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( #[stable(feature = "inclusive_range", since = "1.26.0")] @@ -553,6 +565,18 @@ impl<A: Step> Iterator for ops::Range<A> { fn max(mut self) -> Option<A> { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for Copy types + // which means even repeated reads of the same index would be safe. + unsafe { Step::forward_unchecked(self.start.clone(), idx) } + } } // These macros generate `ExactSizeIterator` impls for various range types. @@ -574,6 +598,23 @@ range_exact_iter_impl! { u32 i32 } + +unsafe_range_trusted_random_access_impl! { + usize u8 u16 + isize i8 i16 +} + +#[cfg(target_pointer_width = "32")] +unsafe_range_trusted_random_access_impl! { + u32 i32 +} + +#[cfg(target_pointer_width = "64")] +unsafe_range_trusted_random_access_impl! { + u32 i32 + u64 i64 +} + range_incl_exact_iter_impl! { u8 i8 |
