1 use crate::convert::TryFrom; 2 use crate::mem; 3 use crate::num::NonZeroUsize; 4 use crate::ops::{self, Try}; 5 6 use super::{ 7 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep, 8 }; 9 10 // Safety: All invariants are upheld. 11 macro_rules! unsafe_impl_trusted_step { 12 ($($type:ty)*) => {$( 13 #[unstable(feature = "trusted_step", issue = "85731")] 14 unsafe impl TrustedStep for $type {} 15 )*}; 16 } 17 unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize]; 18 19 /// Objects that have a notion of *successor* and *predecessor* operations. 20 /// 21 /// The *successor* operation moves towards values that compare greater. 22 /// The *predecessor* operation moves towards values that compare lesser. 23 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 24 pub trait Step: Clone + PartialOrd + Sized { 25 /// Returns the number of *successor* steps required to get from `start` to `end`. 26 /// 27 /// Returns `None` if the number of steps would overflow `usize` 28 /// (or is infinite, or if `end` would never be reached). 29 /// 30 /// # Invariants 31 /// 32 /// For any `a`, `b`, and `n`: 33 /// 34 /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)` 35 /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)` 36 /// * `steps_between(&a, &b) == Some(n)` only if `a <= b` 37 /// * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b` 38 /// * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`; 39 /// this is the case when it would require more than `usize::MAX` steps to get to `b` 40 /// * `steps_between(&a, &b) == None` if `a > b` steps_between(start: &Self, end: &Self) -> Option<usize>41 fn steps_between(start: &Self, end: &Self) -> Option<usize>; 42 43 /// Returns the value that would be obtained by taking the *successor* 44 /// of `self` `count` times. 45 /// 46 /// If this would overflow the range of values supported by `Self`, returns `None`. 47 /// 48 /// # Invariants 49 /// 50 /// For any `a`, `n`, and `m`: 51 /// 52 /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, m).and_then(|x| Step::forward_checked(x, n))` 53 /// 54 /// For any `a`, `n`, and `m` where `n + m` does not overflow: 55 /// 56 /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, n + m)` 57 /// 58 /// For any `a` and `n`: 59 /// 60 /// * `Step::forward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::forward_checked(&x, 1))` 61 /// * Corollary: `Step::forward_checked(&a, 0) == Some(a)` forward_checked(start: Self, count: usize) -> Option<Self>62 fn forward_checked(start: Self, count: usize) -> Option<Self>; 63 64 /// Returns the value that would be obtained by taking the *successor* 65 /// of `self` `count` times. 66 /// 67 /// If this would overflow the range of values supported by `Self`, 68 /// this function is allowed to panic, wrap, or saturate. 69 /// The suggested behavior is to panic when debug assertions are enabled, 70 /// and to wrap or saturate otherwise. 71 /// 72 /// Unsafe code should not rely on the correctness of behavior after overflow. 73 /// 74 /// # Invariants 75 /// 76 /// For any `a`, `n`, and `m`, where no overflow occurs: 77 /// 78 /// * `Step::forward(Step::forward(a, n), m) == Step::forward(a, n + m)` 79 /// 80 /// For any `a` and `n`, where no overflow occurs: 81 /// 82 /// * `Step::forward_checked(a, n) == Some(Step::forward(a, n))` 83 /// * `Step::forward(a, n) == (0..n).fold(a, |x, _| Step::forward(x, 1))` 84 /// * Corollary: `Step::forward(a, 0) == a` 85 /// * `Step::forward(a, n) >= a` 86 /// * `Step::backward(Step::forward(a, n), n) == a` forward(start: Self, count: usize) -> Self87 fn forward(start: Self, count: usize) -> Self { 88 Step::forward_checked(start, count).expect("overflow in `Step::forward`") 89 } 90 91 /// Returns the value that would be obtained by taking the *successor* 92 /// of `self` `count` times. 93 /// 94 /// # Safety 95 /// 96 /// It is undefined behavior for this operation to overflow the 97 /// range of values supported by `Self`. If you cannot guarantee that this 98 /// will not overflow, use `forward` or `forward_checked` instead. 99 /// 100 /// # Invariants 101 /// 102 /// For any `a`: 103 /// 104 /// * if there exists `b` such that `b > a`, it is safe to call `Step::forward_unchecked(a, 1)` 105 /// * if there exists `b`, `n` such that `steps_between(&a, &b) == Some(n)`, 106 /// it is safe to call `Step::forward_unchecked(a, m)` for any `m <= n`. 107 /// 108 /// For any `a` and `n`, where no overflow occurs: 109 /// 110 /// * `Step::forward_unchecked(a, n)` is equivalent to `Step::forward(a, n)` forward_unchecked(start: Self, count: usize) -> Self111 unsafe fn forward_unchecked(start: Self, count: usize) -> Self { 112 Step::forward(start, count) 113 } 114 115 /// Returns the value that would be obtained by taking the *predecessor* 116 /// of `self` `count` times. 117 /// 118 /// If this would overflow the range of values supported by `Self`, returns `None`. 119 /// 120 /// # Invariants 121 /// 122 /// For any `a`, `n`, and `m`: 123 /// 124 /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == n.checked_add(m).and_then(|x| Step::backward_checked(a, x))` 125 /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == try { Step::backward_checked(a, n.checked_add(m)?) }` 126 /// 127 /// For any `a` and `n`: 128 /// 129 /// * `Step::backward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::backward_checked(&x, 1))` 130 /// * Corollary: `Step::backward_checked(&a, 0) == Some(a)` backward_checked(start: Self, count: usize) -> Option<Self>131 fn backward_checked(start: Self, count: usize) -> Option<Self>; 132 133 /// Returns the value that would be obtained by taking the *predecessor* 134 /// of `self` `count` times. 135 /// 136 /// If this would overflow the range of values supported by `Self`, 137 /// this function is allowed to panic, wrap, or saturate. 138 /// The suggested behavior is to panic when debug assertions are enabled, 139 /// and to wrap or saturate otherwise. 140 /// 141 /// Unsafe code should not rely on the correctness of behavior after overflow. 142 /// 143 /// # Invariants 144 /// 145 /// For any `a`, `n`, and `m`, where no overflow occurs: 146 /// 147 /// * `Step::backward(Step::backward(a, n), m) == Step::backward(a, n + m)` 148 /// 149 /// For any `a` and `n`, where no overflow occurs: 150 /// 151 /// * `Step::backward_checked(a, n) == Some(Step::backward(a, n))` 152 /// * `Step::backward(a, n) == (0..n).fold(a, |x, _| Step::backward(x, 1))` 153 /// * Corollary: `Step::backward(a, 0) == a` 154 /// * `Step::backward(a, n) <= a` 155 /// * `Step::forward(Step::backward(a, n), n) == a` backward(start: Self, count: usize) -> Self156 fn backward(start: Self, count: usize) -> Self { 157 Step::backward_checked(start, count).expect("overflow in `Step::backward`") 158 } 159 160 /// Returns the value that would be obtained by taking the *predecessor* 161 /// of `self` `count` times. 162 /// 163 /// # Safety 164 /// 165 /// It is undefined behavior for this operation to overflow the 166 /// range of values supported by `Self`. If you cannot guarantee that this 167 /// will not overflow, use `backward` or `backward_checked` instead. 168 /// 169 /// # Invariants 170 /// 171 /// For any `a`: 172 /// 173 /// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)` 174 /// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`, 175 /// it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`. 176 /// 177 /// For any `a` and `n`, where no overflow occurs: 178 /// 179 /// * `Step::backward_unchecked(a, n)` is equivalent to `Step::backward(a, n)` backward_unchecked(start: Self, count: usize) -> Self180 unsafe fn backward_unchecked(start: Self, count: usize) -> Self { 181 Step::backward(start, count) 182 } 183 } 184 185 // These are still macro-generated because the integer literals resolve to different types. 186 macro_rules! step_identical_methods { 187 () => { 188 #[inline] 189 unsafe fn forward_unchecked(start: Self, n: usize) -> Self { 190 // SAFETY: the caller has to guarantee that `start + n` doesn't overflow. 191 unsafe { start.unchecked_add(n as Self) } 192 } 193 194 #[inline] 195 unsafe fn backward_unchecked(start: Self, n: usize) -> Self { 196 // SAFETY: the caller has to guarantee that `start - n` doesn't overflow. 197 unsafe { start.unchecked_sub(n as Self) } 198 } 199 200 #[inline] 201 #[allow(arithmetic_overflow)] 202 #[rustc_inherit_overflow_checks] 203 fn forward(start: Self, n: usize) -> Self { 204 // In debug builds, trigger a panic on overflow. 205 // This should optimize completely out in release builds. 206 if Self::forward_checked(start, n).is_none() { 207 let _ = Self::MAX + 1; 208 } 209 // Do wrapping math to allow e.g. `Step::forward(-128i8, 255)`. 210 start.wrapping_add(n as Self) 211 } 212 213 #[inline] 214 #[allow(arithmetic_overflow)] 215 #[rustc_inherit_overflow_checks] 216 fn backward(start: Self, n: usize) -> Self { 217 // In debug builds, trigger a panic on overflow. 218 // This should optimize completely out in release builds. 219 if Self::backward_checked(start, n).is_none() { 220 let _ = Self::MIN - 1; 221 } 222 // Do wrapping math to allow e.g. `Step::backward(127i8, 255)`. 223 start.wrapping_sub(n as Self) 224 } 225 }; 226 } 227 228 macro_rules! step_integer_impls { 229 { 230 narrower than or same width as usize: 231 $( [ $u_narrower:ident $i_narrower:ident ] ),+; 232 wider than usize: 233 $( [ $u_wider:ident $i_wider:ident ] ),+; 234 } => { 235 $( 236 #[allow(unreachable_patterns)] 237 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 238 impl Step for $u_narrower { 239 step_identical_methods!(); 240 241 #[inline] 242 fn steps_between(start: &Self, end: &Self) -> Option<usize> { 243 if *start <= *end { 244 // This relies on $u_narrower <= usize 245 Some((*end - *start) as usize) 246 } else { 247 None 248 } 249 } 250 251 #[inline] 252 fn forward_checked(start: Self, n: usize) -> Option<Self> { 253 match Self::try_from(n) { 254 Ok(n) => start.checked_add(n), 255 Err(_) => None, // if n is out of range, `unsigned_start + n` is too 256 } 257 } 258 259 #[inline] 260 fn backward_checked(start: Self, n: usize) -> Option<Self> { 261 match Self::try_from(n) { 262 Ok(n) => start.checked_sub(n), 263 Err(_) => None, // if n is out of range, `unsigned_start - n` is too 264 } 265 } 266 } 267 268 #[allow(unreachable_patterns)] 269 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 270 impl Step for $i_narrower { 271 step_identical_methods!(); 272 273 #[inline] 274 fn steps_between(start: &Self, end: &Self) -> Option<usize> { 275 if *start <= *end { 276 // This relies on $i_narrower <= usize 277 // 278 // Casting to isize extends the width but preserves the sign. 279 // Use wrapping_sub in isize space and cast to usize to compute 280 // the difference that might not fit inside the range of isize. 281 Some((*end as isize).wrapping_sub(*start as isize) as usize) 282 } else { 283 None 284 } 285 } 286 287 #[inline] 288 fn forward_checked(start: Self, n: usize) -> Option<Self> { 289 match $u_narrower::try_from(n) { 290 Ok(n) => { 291 // Wrapping handles cases like 292 // `Step::forward(-120_i8, 200) == Some(80_i8)`, 293 // even though 200 is out of range for i8. 294 let wrapped = start.wrapping_add(n as Self); 295 if wrapped >= start { 296 Some(wrapped) 297 } else { 298 None // Addition overflowed 299 } 300 } 301 // If n is out of range of e.g. u8, 302 // then it is bigger than the entire range for i8 is wide 303 // so `any_i8 + n` necessarily overflows i8. 304 Err(_) => None, 305 } 306 } 307 308 #[inline] 309 fn backward_checked(start: Self, n: usize) -> Option<Self> { 310 match $u_narrower::try_from(n) { 311 Ok(n) => { 312 // Wrapping handles cases like 313 // `Step::forward(-120_i8, 200) == Some(80_i8)`, 314 // even though 200 is out of range for i8. 315 let wrapped = start.wrapping_sub(n as Self); 316 if wrapped <= start { 317 Some(wrapped) 318 } else { 319 None // Subtraction overflowed 320 } 321 } 322 // If n is out of range of e.g. u8, 323 // then it is bigger than the entire range for i8 is wide 324 // so `any_i8 - n` necessarily overflows i8. 325 Err(_) => None, 326 } 327 } 328 } 329 )+ 330 331 $( 332 #[allow(unreachable_patterns)] 333 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 334 impl Step for $u_wider { 335 step_identical_methods!(); 336 337 #[inline] 338 fn steps_between(start: &Self, end: &Self) -> Option<usize> { 339 if *start <= *end { 340 usize::try_from(*end - *start).ok() 341 } else { 342 None 343 } 344 } 345 346 #[inline] 347 fn forward_checked(start: Self, n: usize) -> Option<Self> { 348 start.checked_add(n as Self) 349 } 350 351 #[inline] 352 fn backward_checked(start: Self, n: usize) -> Option<Self> { 353 start.checked_sub(n as Self) 354 } 355 } 356 357 #[allow(unreachable_patterns)] 358 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 359 impl Step for $i_wider { 360 step_identical_methods!(); 361 362 #[inline] 363 fn steps_between(start: &Self, end: &Self) -> Option<usize> { 364 if *start <= *end { 365 match end.checked_sub(*start) { 366 Some(result) => usize::try_from(result).ok(), 367 // If the difference is too big for e.g. i128, 368 // it's also gonna be too big for usize with fewer bits. 369 None => None, 370 } 371 } else { 372 None 373 } 374 } 375 376 #[inline] 377 fn forward_checked(start: Self, n: usize) -> Option<Self> { 378 start.checked_add(n as Self) 379 } 380 381 #[inline] 382 fn backward_checked(start: Self, n: usize) -> Option<Self> { 383 start.checked_sub(n as Self) 384 } 385 } 386 )+ 387 }; 388 } 389 390 #[cfg(target_pointer_width = "64")] 391 step_integer_impls! { 392 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize]; 393 wider than usize: [u128 i128]; 394 } 395 396 #[cfg(target_pointer_width = "32")] 397 step_integer_impls! { 398 narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize]; 399 wider than usize: [u64 i64], [u128 i128]; 400 } 401 402 #[cfg(target_pointer_width = "16")] 403 step_integer_impls! { 404 narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize]; 405 wider than usize: [u32 i32], [u64 i64], [u128 i128]; 406 } 407 408 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] 409 impl Step for char { 410 #[inline] steps_between(&start: &char, &end: &char) -> Option<usize>411 fn steps_between(&start: &char, &end: &char) -> Option<usize> { 412 let start = start as u32; 413 let end = end as u32; 414 if start <= end { 415 let count = end - start; 416 if start < 0xD800 && 0xE000 <= end { 417 usize::try_from(count - 0x800).ok() 418 } else { 419 usize::try_from(count).ok() 420 } 421 } else { 422 None 423 } 424 } 425 426 #[inline] forward_checked(start: char, count: usize) -> Option<char>427 fn forward_checked(start: char, count: usize) -> Option<char> { 428 let start = start as u32; 429 let mut res = Step::forward_checked(start, count)?; 430 if start < 0xD800 && 0xD800 <= res { 431 res = Step::forward_checked(res, 0x800)?; 432 } 433 if res <= char::MAX as u32 { 434 // SAFETY: res is a valid unicode scalar 435 // (below 0x110000 and not in 0xD800..0xE000) 436 Some(unsafe { char::from_u32_unchecked(res) }) 437 } else { 438 None 439 } 440 } 441 442 #[inline] backward_checked(start: char, count: usize) -> Option<char>443 fn backward_checked(start: char, count: usize) -> Option<char> { 444 let start = start as u32; 445 let mut res = Step::backward_checked(start, count)?; 446 if start >= 0xE000 && 0xE000 > res { 447 res = Step::backward_checked(res, 0x800)?; 448 } 449 // SAFETY: res is a valid unicode scalar 450 // (below 0x110000 and not in 0xD800..0xE000) 451 Some(unsafe { char::from_u32_unchecked(res) }) 452 } 453 454 #[inline] forward_unchecked(start: char, count: usize) -> char455 unsafe fn forward_unchecked(start: char, count: usize) -> char { 456 let start = start as u32; 457 // SAFETY: the caller must guarantee that this doesn't overflow 458 // the range of values for a char. 459 let mut res = unsafe { Step::forward_unchecked(start, count) }; 460 if start < 0xD800 && 0xD800 <= res { 461 // SAFETY: the caller must guarantee that this doesn't overflow 462 // the range of values for a char. 463 res = unsafe { Step::forward_unchecked(res, 0x800) }; 464 } 465 // SAFETY: because of the previous contract, this is guaranteed 466 // by the caller to be a valid char. 467 unsafe { char::from_u32_unchecked(res) } 468 } 469 470 #[inline] backward_unchecked(start: char, count: usize) -> char471 unsafe fn backward_unchecked(start: char, count: usize) -> char { 472 let start = start as u32; 473 // SAFETY: the caller must guarantee that this doesn't overflow 474 // the range of values for a char. 475 let mut res = unsafe { Step::backward_unchecked(start, count) }; 476 if start >= 0xE000 && 0xE000 > res { 477 // SAFETY: the caller must guarantee that this doesn't overflow 478 // the range of values for a char. 479 res = unsafe { Step::backward_unchecked(res, 0x800) }; 480 } 481 // SAFETY: because of the previous contract, this is guaranteed 482 // by the caller to be a valid char. 483 unsafe { char::from_u32_unchecked(res) } 484 } 485 } 486 487 macro_rules! range_exact_iter_impl { 488 ($($t:ty)*) => ($( 489 #[stable(feature = "rust1", since = "1.0.0")] 490 impl ExactSizeIterator for ops::Range<$t> { } 491 )*) 492 } 493 494 /// Safety: This macro must only be used on types that are `Copy` and result in ranges 495 /// which have an exact `size_hint()` where the upper bound must not be `None`. 496 macro_rules! unsafe_range_trusted_random_access_impl { 497 ($($t:ty)*) => ($( 498 #[doc(hidden)] 499 #[unstable(feature = "trusted_random_access", issue = "none")] 500 unsafe impl TrustedRandomAccess for ops::Range<$t> {} 501 502 #[doc(hidden)] 503 #[unstable(feature = "trusted_random_access", issue = "none")] 504 unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> { 505 const MAY_HAVE_SIDE_EFFECT: bool = false; 506 } 507 )*) 508 } 509 510 macro_rules! range_incl_exact_iter_impl { 511 ($($t:ty)*) => ($( 512 #[stable(feature = "inclusive_range", since = "1.26.0")] 513 impl ExactSizeIterator for ops::RangeInclusive<$t> { } 514 )*) 515 } 516 517 /// Specialization implementations for `Range`. 518 trait RangeIteratorImpl { 519 type Item; 520 521 // Iterator spec_next(&mut self) -> Option<Self::Item>522 fn spec_next(&mut self) -> Option<Self::Item>; spec_nth(&mut self, n: usize) -> Option<Self::Item>523 fn spec_nth(&mut self, n: usize) -> Option<Self::Item>; spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>524 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>; 525 526 // DoubleEndedIterator spec_next_back(&mut self) -> Option<Self::Item>527 fn spec_next_back(&mut self) -> Option<Self::Item>; spec_nth_back(&mut self, n: usize) -> Option<Self::Item>528 fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>; spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>529 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>; 530 } 531 532 impl<A: Step> RangeIteratorImpl for ops::Range<A> { 533 type Item = A; 534 535 #[inline] spec_next(&mut self) -> Option<A>536 default fn spec_next(&mut self) -> Option<A> { 537 if self.start < self.end { 538 let n = 539 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld"); 540 Some(mem::replace(&mut self.start, n)) 541 } else { 542 None 543 } 544 } 545 546 #[inline] spec_nth(&mut self, n: usize) -> Option<A>547 default fn spec_nth(&mut self, n: usize) -> Option<A> { 548 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) { 549 if plus_n < self.end { 550 self.start = 551 Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld"); 552 return Some(plus_n); 553 } 554 } 555 556 self.start = self.end.clone(); 557 None 558 } 559 560 #[inline] spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>561 default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 562 let available = if self.start <= self.end { 563 Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) 564 } else { 565 0 566 }; 567 568 let taken = available.min(n); 569 570 self.start = 571 Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld"); 572 573 NonZeroUsize::new(n - taken).map_or(Ok(()), Err) 574 } 575 576 #[inline] spec_next_back(&mut self) -> Option<A>577 default fn spec_next_back(&mut self) -> Option<A> { 578 if self.start < self.end { 579 self.end = 580 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld"); 581 Some(self.end.clone()) 582 } else { 583 None 584 } 585 } 586 587 #[inline] spec_nth_back(&mut self, n: usize) -> Option<A>588 default fn spec_nth_back(&mut self, n: usize) -> Option<A> { 589 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) { 590 if minus_n > self.start { 591 self.end = 592 Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld"); 593 return Some(self.end.clone()); 594 } 595 } 596 597 self.end = self.start.clone(); 598 None 599 } 600 601 #[inline] spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>602 default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 603 let available = if self.start <= self.end { 604 Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) 605 } else { 606 0 607 }; 608 609 let taken = available.min(n); 610 611 self.end = 612 Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld"); 613 614 NonZeroUsize::new(n - taken).map_or(Ok(()), Err) 615 } 616 } 617 618 impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> { 619 #[inline] spec_next(&mut self) -> Option<T>620 fn spec_next(&mut self) -> Option<T> { 621 if self.start < self.end { 622 let old = self.start; 623 // SAFETY: just checked precondition 624 self.start = unsafe { Step::forward_unchecked(old, 1) }; 625 Some(old) 626 } else { 627 None 628 } 629 } 630 631 #[inline] spec_nth(&mut self, n: usize) -> Option<T>632 fn spec_nth(&mut self, n: usize) -> Option<T> { 633 if let Some(plus_n) = Step::forward_checked(self.start, n) { 634 if plus_n < self.end { 635 // SAFETY: just checked precondition 636 self.start = unsafe { Step::forward_unchecked(plus_n, 1) }; 637 return Some(plus_n); 638 } 639 } 640 641 self.start = self.end; 642 None 643 } 644 645 #[inline] spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>646 fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 647 let available = if self.start <= self.end { 648 Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) 649 } else { 650 0 651 }; 652 653 let taken = available.min(n); 654 655 // SAFETY: the conditions above ensure that the count is in bounds. If start <= end 656 // then steps_between either returns a bound to which we clamp or returns None which 657 // together with the initial inequality implies more than usize::MAX steps. 658 // Otherwise 0 is returned which always safe to use. 659 self.start = unsafe { Step::forward_unchecked(self.start, taken) }; 660 661 NonZeroUsize::new(n - taken).map_or(Ok(()), Err) 662 } 663 664 #[inline] spec_next_back(&mut self) -> Option<T>665 fn spec_next_back(&mut self) -> Option<T> { 666 if self.start < self.end { 667 // SAFETY: just checked precondition 668 self.end = unsafe { Step::backward_unchecked(self.end, 1) }; 669 Some(self.end) 670 } else { 671 None 672 } 673 } 674 675 #[inline] spec_nth_back(&mut self, n: usize) -> Option<T>676 fn spec_nth_back(&mut self, n: usize) -> Option<T> { 677 if let Some(minus_n) = Step::backward_checked(self.end, n) { 678 if minus_n > self.start { 679 // SAFETY: just checked precondition 680 self.end = unsafe { Step::backward_unchecked(minus_n, 1) }; 681 return Some(self.end); 682 } 683 } 684 685 self.end = self.start; 686 None 687 } 688 689 #[inline] spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>690 fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 691 let available = if self.start <= self.end { 692 Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) 693 } else { 694 0 695 }; 696 697 let taken = available.min(n); 698 699 // SAFETY: same as the spec_advance_by() implementation 700 self.end = unsafe { Step::backward_unchecked(self.end, taken) }; 701 702 NonZeroUsize::new(n - taken).map_or(Ok(()), Err) 703 } 704 } 705 706 #[stable(feature = "rust1", since = "1.0.0")] 707 impl<A: Step> Iterator for ops::Range<A> { 708 type Item = A; 709 710 #[inline] next(&mut self) -> Option<A>711 fn next(&mut self) -> Option<A> { 712 self.spec_next() 713 } 714 715 #[inline] size_hint(&self) -> (usize, Option<usize>)716 fn size_hint(&self) -> (usize, Option<usize>) { 717 if self.start < self.end { 718 let hint = Step::steps_between(&self.start, &self.end); 719 (hint.unwrap_or(usize::MAX), hint) 720 } else { 721 (0, Some(0)) 722 } 723 } 724 725 #[inline] nth(&mut self, n: usize) -> Option<A>726 fn nth(&mut self, n: usize) -> Option<A> { 727 self.spec_nth(n) 728 } 729 730 #[inline] last(mut self) -> Option<A>731 fn last(mut self) -> Option<A> { 732 self.next_back() 733 } 734 735 #[inline] min(mut self) -> Option<A> where A: Ord,736 fn min(mut self) -> Option<A> 737 where 738 A: Ord, 739 { 740 self.next() 741 } 742 743 #[inline] max(mut self) -> Option<A> where A: Ord,744 fn max(mut self) -> Option<A> 745 where 746 A: Ord, 747 { 748 self.next_back() 749 } 750 751 #[inline] is_sorted(self) -> bool752 fn is_sorted(self) -> bool { 753 true 754 } 755 756 #[inline] advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>757 fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 758 self.spec_advance_by(n) 759 } 760 761 #[inline] __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce,762 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item 763 where 764 Self: TrustedRandomAccessNoCoerce, 765 { 766 // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index 767 // that is in bounds. 768 // Additionally Self: TrustedRandomAccess is only implemented for Copy types 769 // which means even repeated reads of the same index would be safe. 770 unsafe { Step::forward_unchecked(self.start.clone(), idx) } 771 } 772 } 773 774 // These macros generate `ExactSizeIterator` impls for various range types. 775 // 776 // * `ExactSizeIterator::len` is required to always return an exact `usize`, 777 // so no range can be longer than `usize::MAX`. 778 // * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`. 779 // For integer types in `RangeInclusive<_>` 780 // this is the case for types *strictly narrower* than `usize` 781 // since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. 782 range_exact_iter_impl! { 783 usize u8 u16 784 isize i8 i16 785 786 // These are incorrect per the reasoning above, 787 // but removing them would be a breaking change as they were stabilized in Rust 1.0.0. 788 // So e.g. `(0..66_000_u32).len()` for example will compile without error or warnings 789 // on 16-bit platforms, but continue to give a wrong result. 790 u32 791 i32 792 } 793 794 unsafe_range_trusted_random_access_impl! { 795 usize u8 u16 796 isize i8 i16 797 } 798 799 #[cfg(target_pointer_width = "32")] 800 unsafe_range_trusted_random_access_impl! { 801 u32 i32 802 } 803 804 #[cfg(target_pointer_width = "64")] 805 unsafe_range_trusted_random_access_impl! { 806 u32 i32 807 u64 i64 808 } 809 810 range_incl_exact_iter_impl! { 811 u8 812 i8 813 814 // These are incorrect per the reasoning above, 815 // but removing them would be a breaking change as they were stabilized in Rust 1.26.0. 816 // So e.g. `(0..=u16::MAX).len()` for example will compile without error or warnings 817 // on 16-bit platforms, but continue to give a wrong result. 818 u16 819 i16 820 } 821 822 #[stable(feature = "rust1", since = "1.0.0")] 823 impl<A: Step> DoubleEndedIterator for ops::Range<A> { 824 #[inline] next_back(&mut self) -> Option<A>825 fn next_back(&mut self) -> Option<A> { 826 self.spec_next_back() 827 } 828 829 #[inline] nth_back(&mut self, n: usize) -> Option<A>830 fn nth_back(&mut self, n: usize) -> Option<A> { 831 self.spec_nth_back(n) 832 } 833 834 #[inline] advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>835 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 836 self.spec_advance_back_by(n) 837 } 838 } 839 840 // Safety: 841 // The following invariants for `Step::steps_between` exist: 842 // 843 // > * `steps_between(&a, &b) == Some(n)` only if `a <= b` 844 // > * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`; 845 // > this is the case when it would require more than `usize::MAX` steps to 846 // > get to `b` 847 // > * `steps_between(&a, &b) == None` if `a > b` 848 // 849 // The first invariant is what is generally required for `TrustedLen` to be 850 // sound. The note addendum satisfies an additional `TrustedLen` invariant. 851 // 852 // > The upper bound must only be `None` if the actual iterator length is larger 853 // > than `usize::MAX` 854 // 855 // The second invariant logically follows the first so long as the `PartialOrd` 856 // implementation is correct; regardless it is explicitly stated. If `a < b` 857 // then `(0, Some(0))` is returned by `ops::Range<A: Step>::size_hint`. As such 858 // the second invariant is upheld. 859 #[unstable(feature = "trusted_len", issue = "37572")] 860 unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {} 861 862 #[stable(feature = "fused", since = "1.26.0")] 863 impl<A: Step> FusedIterator for ops::Range<A> {} 864 865 #[stable(feature = "rust1", since = "1.0.0")] 866 impl<A: Step> Iterator for ops::RangeFrom<A> { 867 type Item = A; 868 869 #[inline] next(&mut self) -> Option<A>870 fn next(&mut self) -> Option<A> { 871 let n = Step::forward(self.start.clone(), 1); 872 Some(mem::replace(&mut self.start, n)) 873 } 874 875 #[inline] size_hint(&self) -> (usize, Option<usize>)876 fn size_hint(&self) -> (usize, Option<usize>) { 877 (usize::MAX, None) 878 } 879 880 #[inline] nth(&mut self, n: usize) -> Option<A>881 fn nth(&mut self, n: usize) -> Option<A> { 882 let plus_n = Step::forward(self.start.clone(), n); 883 self.start = Step::forward(plus_n.clone(), 1); 884 Some(plus_n) 885 } 886 } 887 888 // Safety: See above implementation for `ops::Range<A>` 889 #[unstable(feature = "trusted_len", issue = "37572")] 890 unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {} 891 892 #[stable(feature = "fused", since = "1.26.0")] 893 impl<A: Step> FusedIterator for ops::RangeFrom<A> {} 894 895 trait RangeInclusiveIteratorImpl { 896 type Item; 897 898 // Iterator spec_next(&mut self) -> Option<Self::Item>899 fn spec_next(&mut self) -> Option<Self::Item>; spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>900 fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R 901 where 902 Self: Sized, 903 F: FnMut(B, Self::Item) -> R, 904 R: Try<Output = B>; 905 906 // DoubleEndedIterator spec_next_back(&mut self) -> Option<Self::Item>907 fn spec_next_back(&mut self) -> Option<Self::Item>; spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>908 fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R 909 where 910 Self: Sized, 911 F: FnMut(B, Self::Item) -> R, 912 R: Try<Output = B>; 913 } 914 915 impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> { 916 type Item = A; 917 918 #[inline] spec_next(&mut self) -> Option<A>919 default fn spec_next(&mut self) -> Option<A> { 920 if self.is_empty() { 921 return None; 922 } 923 let is_iterating = self.start < self.end; 924 Some(if is_iterating { 925 let n = 926 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld"); 927 mem::replace(&mut self.start, n) 928 } else { 929 self.exhausted = true; 930 self.start.clone() 931 }) 932 } 933 934 #[inline] spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, A) -> R, R: Try<Output = B>,935 default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R 936 where 937 Self: Sized, 938 F: FnMut(B, A) -> R, 939 R: Try<Output = B>, 940 { 941 if self.is_empty() { 942 return try { init }; 943 } 944 945 let mut accum = init; 946 947 while self.start < self.end { 948 let n = 949 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld"); 950 let n = mem::replace(&mut self.start, n); 951 accum = f(accum, n)?; 952 } 953 954 self.exhausted = true; 955 956 if self.start == self.end { 957 accum = f(accum, self.start.clone())?; 958 } 959 960 try { accum } 961 } 962 963 #[inline] spec_next_back(&mut self) -> Option<A>964 default fn spec_next_back(&mut self) -> Option<A> { 965 if self.is_empty() { 966 return None; 967 } 968 let is_iterating = self.start < self.end; 969 Some(if is_iterating { 970 let n = 971 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld"); 972 mem::replace(&mut self.end, n) 973 } else { 974 self.exhausted = true; 975 self.end.clone() 976 }) 977 } 978 979 #[inline] spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, A) -> R, R: Try<Output = B>,980 default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R 981 where 982 Self: Sized, 983 F: FnMut(B, A) -> R, 984 R: Try<Output = B>, 985 { 986 if self.is_empty() { 987 return try { init }; 988 } 989 990 let mut accum = init; 991 992 while self.start < self.end { 993 let n = 994 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld"); 995 let n = mem::replace(&mut self.end, n); 996 accum = f(accum, n)?; 997 } 998 999 self.exhausted = true; 1000 1001 if self.start == self.end { 1002 accum = f(accum, self.start.clone())?; 1003 } 1004 1005 try { accum } 1006 } 1007 } 1008 1009 impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { 1010 #[inline] spec_next(&mut self) -> Option<T>1011 fn spec_next(&mut self) -> Option<T> { 1012 if self.is_empty() { 1013 return None; 1014 } 1015 let is_iterating = self.start < self.end; 1016 Some(if is_iterating { 1017 // SAFETY: just checked precondition 1018 let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; 1019 mem::replace(&mut self.start, n) 1020 } else { 1021 self.exhausted = true; 1022 self.start.clone() 1023 }) 1024 } 1025 1026 #[inline] spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, T) -> R, R: Try<Output = B>,1027 fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R 1028 where 1029 Self: Sized, 1030 F: FnMut(B, T) -> R, 1031 R: Try<Output = B>, 1032 { 1033 if self.is_empty() { 1034 return try { init }; 1035 } 1036 1037 let mut accum = init; 1038 1039 while self.start < self.end { 1040 // SAFETY: just checked precondition 1041 let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; 1042 let n = mem::replace(&mut self.start, n); 1043 accum = f(accum, n)?; 1044 } 1045 1046 self.exhausted = true; 1047 1048 if self.start == self.end { 1049 accum = f(accum, self.start.clone())?; 1050 } 1051 1052 try { accum } 1053 } 1054 1055 #[inline] spec_next_back(&mut self) -> Option<T>1056 fn spec_next_back(&mut self) -> Option<T> { 1057 if self.is_empty() { 1058 return None; 1059 } 1060 let is_iterating = self.start < self.end; 1061 Some(if is_iterating { 1062 // SAFETY: just checked precondition 1063 let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; 1064 mem::replace(&mut self.end, n) 1065 } else { 1066 self.exhausted = true; 1067 self.end.clone() 1068 }) 1069 } 1070 1071 #[inline] spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, T) -> R, R: Try<Output = B>,1072 fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R 1073 where 1074 Self: Sized, 1075 F: FnMut(B, T) -> R, 1076 R: Try<Output = B>, 1077 { 1078 if self.is_empty() { 1079 return try { init }; 1080 } 1081 1082 let mut accum = init; 1083 1084 while self.start < self.end { 1085 // SAFETY: just checked precondition 1086 let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; 1087 let n = mem::replace(&mut self.end, n); 1088 accum = f(accum, n)?; 1089 } 1090 1091 self.exhausted = true; 1092 1093 if self.start == self.end { 1094 accum = f(accum, self.start.clone())?; 1095 } 1096 1097 try { accum } 1098 } 1099 } 1100 1101 #[stable(feature = "inclusive_range", since = "1.26.0")] 1102 impl<A: Step> Iterator for ops::RangeInclusive<A> { 1103 type Item = A; 1104 1105 #[inline] next(&mut self) -> Option<A>1106 fn next(&mut self) -> Option<A> { 1107 self.spec_next() 1108 } 1109 1110 #[inline] size_hint(&self) -> (usize, Option<usize>)1111 fn size_hint(&self) -> (usize, Option<usize>) { 1112 if self.is_empty() { 1113 return (0, Some(0)); 1114 } 1115 1116 match Step::steps_between(&self.start, &self.end) { 1117 Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), 1118 None => (usize::MAX, None), 1119 } 1120 } 1121 1122 #[inline] nth(&mut self, n: usize) -> Option<A>1123 fn nth(&mut self, n: usize) -> Option<A> { 1124 if self.is_empty() { 1125 return None; 1126 } 1127 1128 if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) { 1129 use crate::cmp::Ordering::*; 1130 1131 match plus_n.partial_cmp(&self.end) { 1132 Some(Less) => { 1133 self.start = Step::forward(plus_n.clone(), 1); 1134 return Some(plus_n); 1135 } 1136 Some(Equal) => { 1137 self.start = plus_n.clone(); 1138 self.exhausted = true; 1139 return Some(plus_n); 1140 } 1141 _ => {} 1142 } 1143 } 1144 1145 self.start = self.end.clone(); 1146 self.exhausted = true; 1147 None 1148 } 1149 1150 #[inline] try_fold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,1151 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R 1152 where 1153 Self: Sized, 1154 F: FnMut(B, Self::Item) -> R, 1155 R: Try<Output = B>, 1156 { 1157 self.spec_try_fold(init, f) 1158 } 1159 1160 impl_fold_via_try_fold! { fold -> try_fold } 1161 1162 #[inline] last(mut self) -> Option<A>1163 fn last(mut self) -> Option<A> { 1164 self.next_back() 1165 } 1166 1167 #[inline] min(mut self) -> Option<A> where A: Ord,1168 fn min(mut self) -> Option<A> 1169 where 1170 A: Ord, 1171 { 1172 self.next() 1173 } 1174 1175 #[inline] max(mut self) -> Option<A> where A: Ord,1176 fn max(mut self) -> Option<A> 1177 where 1178 A: Ord, 1179 { 1180 self.next_back() 1181 } 1182 1183 #[inline] is_sorted(self) -> bool1184 fn is_sorted(self) -> bool { 1185 true 1186 } 1187 } 1188 1189 #[stable(feature = "inclusive_range", since = "1.26.0")] 1190 impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> { 1191 #[inline] next_back(&mut self) -> Option<A>1192 fn next_back(&mut self) -> Option<A> { 1193 self.spec_next_back() 1194 } 1195 1196 #[inline] nth_back(&mut self, n: usize) -> Option<A>1197 fn nth_back(&mut self, n: usize) -> Option<A> { 1198 if self.is_empty() { 1199 return None; 1200 } 1201 1202 if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) { 1203 use crate::cmp::Ordering::*; 1204 1205 match minus_n.partial_cmp(&self.start) { 1206 Some(Greater) => { 1207 self.end = Step::backward(minus_n.clone(), 1); 1208 return Some(minus_n); 1209 } 1210 Some(Equal) => { 1211 self.end = minus_n.clone(); 1212 self.exhausted = true; 1213 return Some(minus_n); 1214 } 1215 _ => {} 1216 } 1217 } 1218 1219 self.end = self.start.clone(); 1220 self.exhausted = true; 1221 None 1222 } 1223 1224 #[inline] try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,1225 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R 1226 where 1227 Self: Sized, 1228 F: FnMut(B, Self::Item) -> R, 1229 R: Try<Output = B>, 1230 { 1231 self.spec_try_rfold(init, f) 1232 } 1233 1234 impl_fold_via_try_fold! { rfold -> try_rfold } 1235 } 1236 1237 // Safety: See above implementation for `ops::Range<A>` 1238 #[unstable(feature = "trusted_len", issue = "37572")] 1239 unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {} 1240 1241 #[stable(feature = "fused", since = "1.26.0")] 1242 impl<A: Step> FusedIterator for ops::RangeInclusive<A> {} 1243