1 use crate::fmt; 2 use crate::hash::Hash; 3 4 /// An unbounded range (`..`). 5 /// 6 /// `RangeFull` is primarily used as a [slicing index], its shorthand is `..`. 7 /// It cannot serve as an [`Iterator`] because it doesn't have a starting point. 8 /// 9 /// # Examples 10 /// 11 /// The `..` syntax is a `RangeFull`: 12 /// 13 /// ``` 14 /// assert_eq!((..), std::ops::RangeFull); 15 /// ``` 16 /// 17 /// It does not have an [`IntoIterator`] implementation, so you can't use it in 18 /// a `for` loop directly. This won't compile: 19 /// 20 /// ```compile_fail,E0277 21 /// for i in .. { 22 /// // ... 23 /// } 24 /// ``` 25 /// 26 /// Used as a [slicing index], `RangeFull` produces the full array as a slice. 27 /// 28 /// ``` 29 /// let arr = [0, 1, 2, 3, 4]; 30 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); // This is the `RangeFull` 31 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); 32 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); 33 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); 34 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); 35 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); 36 /// ``` 37 /// 38 /// [slicing index]: crate::slice::SliceIndex 39 #[lang = "RangeFull"] 40 #[doc(alias = "..")] 41 #[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] 42 #[stable(feature = "rust1", since = "1.0.0")] 43 pub struct RangeFull; 44 45 #[stable(feature = "rust1", since = "1.0.0")] 46 impl fmt::Debug for RangeFull { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result47 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 48 write!(fmt, "..") 49 } 50 } 51 52 /// A (half-open) range bounded inclusively below and exclusively above 53 /// (`start..end`). 54 /// 55 /// The range `start..end` contains all values with `start <= x < end`. 56 /// It is empty if `start >= end`. 57 /// 58 /// # Examples 59 /// 60 /// The `start..end` syntax is a `Range`: 61 /// 62 /// ``` 63 /// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 }); 64 /// assert_eq!(3 + 4 + 5, (3..6).sum()); 65 /// ``` 66 /// 67 /// ``` 68 /// let arr = [0, 1, 2, 3, 4]; 69 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); 70 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); 71 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); 72 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); 73 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); // This is a `Range` 74 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); 75 /// ``` 76 #[lang = "Range"] 77 #[doc(alias = "..")] 78 #[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186 79 #[stable(feature = "rust1", since = "1.0.0")] 80 pub struct Range<Idx> { 81 /// The lower bound of the range (inclusive). 82 #[stable(feature = "rust1", since = "1.0.0")] 83 pub start: Idx, 84 /// The upper bound of the range (exclusive). 85 #[stable(feature = "rust1", since = "1.0.0")] 86 pub end: Idx, 87 } 88 89 #[stable(feature = "rust1", since = "1.0.0")] 90 impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result91 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 92 self.start.fmt(fmt)?; 93 write!(fmt, "..")?; 94 self.end.fmt(fmt)?; 95 Ok(()) 96 } 97 } 98 99 impl<Idx: PartialOrd<Idx>> Range<Idx> { 100 /// Returns `true` if `item` is contained in the range. 101 /// 102 /// # Examples 103 /// 104 /// ``` 105 /// assert!(!(3..5).contains(&2)); 106 /// assert!( (3..5).contains(&3)); 107 /// assert!( (3..5).contains(&4)); 108 /// assert!(!(3..5).contains(&5)); 109 /// 110 /// assert!(!(3..3).contains(&3)); 111 /// assert!(!(3..2).contains(&3)); 112 /// 113 /// assert!( (0.0..1.0).contains(&0.5)); 114 /// assert!(!(0.0..1.0).contains(&f32::NAN)); 115 /// assert!(!(0.0..f32::NAN).contains(&0.5)); 116 /// assert!(!(f32::NAN..1.0).contains(&0.5)); 117 /// ``` 118 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where Idx: PartialOrd<U>, U: ?Sized + PartialOrd<Idx>,119 pub fn contains<U>(&self, item: &U) -> bool 120 where 121 Idx: PartialOrd<U>, 122 U: ?Sized + PartialOrd<Idx>, 123 { 124 <Self as RangeBounds<Idx>>::contains(self, item) 125 } 126 127 /// Returns `true` if the range contains no items. 128 /// 129 /// # Examples 130 /// 131 /// ``` 132 /// assert!(!(3..5).is_empty()); 133 /// assert!( (3..3).is_empty()); 134 /// assert!( (3..2).is_empty()); 135 /// ``` 136 /// 137 /// The range is empty if either side is incomparable: 138 /// 139 /// ``` 140 /// assert!(!(3.0..5.0).is_empty()); 141 /// assert!( (3.0..f32::NAN).is_empty()); 142 /// assert!( (f32::NAN..5.0).is_empty()); 143 /// ``` 144 #[stable(feature = "range_is_empty", since = "1.47.0")] is_empty(&self) -> bool145 pub fn is_empty(&self) -> bool { 146 !(self.start < self.end) 147 } 148 } 149 150 /// A range only bounded inclusively below (`start..`). 151 /// 152 /// The `RangeFrom` `start..` contains all values with `x >= start`. 153 /// 154 /// *Note*: Overflow in the [`Iterator`] implementation (when the contained 155 /// data type reaches its numerical limit) is allowed to panic, wrap, or 156 /// saturate. This behavior is defined by the implementation of the [`Step`] 157 /// trait. For primitive integers, this follows the normal rules, and respects 158 /// the overflow checks profile (panic in debug, wrap in release). Note also 159 /// that overflow happens earlier than you might assume: the overflow happens 160 /// in the call to `next` that yields the maximum value, as the range must be 161 /// set to a state to yield the next value. 162 /// 163 /// [`Step`]: crate::iter::Step 164 /// 165 /// # Examples 166 /// 167 /// The `start..` syntax is a `RangeFrom`: 168 /// 169 /// ``` 170 /// assert_eq!((2..), std::ops::RangeFrom { start: 2 }); 171 /// assert_eq!(2 + 3 + 4, (2..).take(3).sum()); 172 /// ``` 173 /// 174 /// ``` 175 /// let arr = [0, 1, 2, 3, 4]; 176 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); 177 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); 178 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); 179 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); // This is a `RangeFrom` 180 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); 181 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); 182 /// ``` 183 #[lang = "RangeFrom"] 184 #[doc(alias = "..")] 185 #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 186 #[stable(feature = "rust1", since = "1.0.0")] 187 pub struct RangeFrom<Idx> { 188 /// The lower bound of the range (inclusive). 189 #[stable(feature = "rust1", since = "1.0.0")] 190 pub start: Idx, 191 } 192 193 #[stable(feature = "rust1", since = "1.0.0")] 194 impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result195 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 196 self.start.fmt(fmt)?; 197 write!(fmt, "..")?; 198 Ok(()) 199 } 200 } 201 202 impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { 203 /// Returns `true` if `item` is contained in the range. 204 /// 205 /// # Examples 206 /// 207 /// ``` 208 /// assert!(!(3..).contains(&2)); 209 /// assert!( (3..).contains(&3)); 210 /// assert!( (3..).contains(&1_000_000_000)); 211 /// 212 /// assert!( (0.0..).contains(&0.5)); 213 /// assert!(!(0.0..).contains(&f32::NAN)); 214 /// assert!(!(f32::NAN..).contains(&0.5)); 215 /// ``` 216 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where Idx: PartialOrd<U>, U: ?Sized + PartialOrd<Idx>,217 pub fn contains<U>(&self, item: &U) -> bool 218 where 219 Idx: PartialOrd<U>, 220 U: ?Sized + PartialOrd<Idx>, 221 { 222 <Self as RangeBounds<Idx>>::contains(self, item) 223 } 224 } 225 226 /// A range only bounded exclusively above (`..end`). 227 /// 228 /// The `RangeTo` `..end` contains all values with `x < end`. 229 /// It cannot serve as an [`Iterator`] because it doesn't have a starting point. 230 /// 231 /// # Examples 232 /// 233 /// The `..end` syntax is a `RangeTo`: 234 /// 235 /// ``` 236 /// assert_eq!((..5), std::ops::RangeTo { end: 5 }); 237 /// ``` 238 /// 239 /// It does not have an [`IntoIterator`] implementation, so you can't use it in 240 /// a `for` loop directly. This won't compile: 241 /// 242 /// ```compile_fail,E0277 243 /// // error[E0277]: the trait bound `std::ops::RangeTo<{integer}>: 244 /// // std::iter::Iterator` is not satisfied 245 /// for i in ..5 { 246 /// // ... 247 /// } 248 /// ``` 249 /// 250 /// When used as a [slicing index], `RangeTo` produces a slice of all array 251 /// elements before the index indicated by `end`. 252 /// 253 /// ``` 254 /// let arr = [0, 1, 2, 3, 4]; 255 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); 256 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); // This is a `RangeTo` 257 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); 258 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); 259 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); 260 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); 261 /// ``` 262 /// 263 /// [slicing index]: crate::slice::SliceIndex 264 #[lang = "RangeTo"] 265 #[doc(alias = "..")] 266 #[derive(Copy, Clone, PartialEq, Eq, Hash)] 267 #[stable(feature = "rust1", since = "1.0.0")] 268 pub struct RangeTo<Idx> { 269 /// The upper bound of the range (exclusive). 270 #[stable(feature = "rust1", since = "1.0.0")] 271 pub end: Idx, 272 } 273 274 #[stable(feature = "rust1", since = "1.0.0")] 275 impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result276 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 277 write!(fmt, "..")?; 278 self.end.fmt(fmt)?; 279 Ok(()) 280 } 281 } 282 283 impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { 284 /// Returns `true` if `item` is contained in the range. 285 /// 286 /// # Examples 287 /// 288 /// ``` 289 /// assert!( (..5).contains(&-1_000_000_000)); 290 /// assert!( (..5).contains(&4)); 291 /// assert!(!(..5).contains(&5)); 292 /// 293 /// assert!( (..1.0).contains(&0.5)); 294 /// assert!(!(..1.0).contains(&f32::NAN)); 295 /// assert!(!(..f32::NAN).contains(&0.5)); 296 /// ``` 297 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where Idx: PartialOrd<U>, U: ?Sized + PartialOrd<Idx>,298 pub fn contains<U>(&self, item: &U) -> bool 299 where 300 Idx: PartialOrd<U>, 301 U: ?Sized + PartialOrd<Idx>, 302 { 303 <Self as RangeBounds<Idx>>::contains(self, item) 304 } 305 } 306 307 /// A range bounded inclusively below and above (`start..=end`). 308 /// 309 /// The `RangeInclusive` `start..=end` contains all values with `x >= start` 310 /// and `x <= end`. It is empty unless `start <= end`. 311 /// 312 /// This iterator is [fused], but the specific values of `start` and `end` after 313 /// iteration has finished are **unspecified** other than that [`.is_empty()`] 314 /// will return `true` once no more values will be produced. 315 /// 316 /// [fused]: crate::iter::FusedIterator 317 /// [`.is_empty()`]: RangeInclusive::is_empty 318 /// 319 /// # Examples 320 /// 321 /// The `start..=end` syntax is a `RangeInclusive`: 322 /// 323 /// ``` 324 /// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5)); 325 /// assert_eq!(3 + 4 + 5, (3..=5).sum()); 326 /// ``` 327 /// 328 /// ``` 329 /// let arr = [0, 1, 2, 3, 4]; 330 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); 331 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); 332 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); 333 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); 334 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); 335 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); // This is a `RangeInclusive` 336 /// ``` 337 #[lang = "RangeInclusive"] 338 #[doc(alias = "..=")] 339 #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 340 #[stable(feature = "inclusive_range", since = "1.26.0")] 341 pub struct RangeInclusive<Idx> { 342 // Note that the fields here are not public to allow changing the 343 // representation in the future; in particular, while we could plausibly 344 // expose start/end, modifying them without changing (future/current) 345 // private fields may lead to incorrect behavior, so we don't want to 346 // support that mode. 347 pub(crate) start: Idx, 348 pub(crate) end: Idx, 349 350 // This field is: 351 // - `false` upon construction 352 // - `false` when iteration has yielded an element and the iterator is not exhausted 353 // - `true` when iteration has been used to exhaust the iterator 354 // 355 // This is required to support PartialEq and Hash without a PartialOrd bound or specialization. 356 pub(crate) exhausted: bool, 357 } 358 359 impl<Idx> RangeInclusive<Idx> { 360 /// Creates a new inclusive range. Equivalent to writing `start..=end`. 361 /// 362 /// # Examples 363 /// 364 /// ``` 365 /// use std::ops::RangeInclusive; 366 /// 367 /// assert_eq!(3..=5, RangeInclusive::new(3, 5)); 368 /// ``` 369 #[lang = "range_inclusive_new"] 370 #[stable(feature = "inclusive_range_methods", since = "1.27.0")] 371 #[inline] 372 #[rustc_promotable] 373 #[rustc_const_stable(feature = "const_range_new", since = "1.32.0")] new(start: Idx, end: Idx) -> Self374 pub const fn new(start: Idx, end: Idx) -> Self { 375 Self { start, end, exhausted: false } 376 } 377 378 /// Returns the lower bound of the range (inclusive). 379 /// 380 /// When using an inclusive range for iteration, the values of `start()` and 381 /// [`end()`] are unspecified after the iteration ended. To determine 382 /// whether the inclusive range is empty, use the [`is_empty()`] method 383 /// instead of comparing `start() > end()`. 384 /// 385 /// Note: the value returned by this method is unspecified after the range 386 /// has been iterated to exhaustion. 387 /// 388 /// [`end()`]: RangeInclusive::end 389 /// [`is_empty()`]: RangeInclusive::is_empty 390 /// 391 /// # Examples 392 /// 393 /// ``` 394 /// assert_eq!((3..=5).start(), &3); 395 /// ``` 396 #[stable(feature = "inclusive_range_methods", since = "1.27.0")] 397 #[rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0")] 398 #[inline] start(&self) -> &Idx399 pub const fn start(&self) -> &Idx { 400 &self.start 401 } 402 403 /// Returns the upper bound of the range (inclusive). 404 /// 405 /// When using an inclusive range for iteration, the values of [`start()`] 406 /// and `end()` are unspecified after the iteration ended. To determine 407 /// whether the inclusive range is empty, use the [`is_empty()`] method 408 /// instead of comparing `start() > end()`. 409 /// 410 /// Note: the value returned by this method is unspecified after the range 411 /// has been iterated to exhaustion. 412 /// 413 /// [`start()`]: RangeInclusive::start 414 /// [`is_empty()`]: RangeInclusive::is_empty 415 /// 416 /// # Examples 417 /// 418 /// ``` 419 /// assert_eq!((3..=5).end(), &5); 420 /// ``` 421 #[stable(feature = "inclusive_range_methods", since = "1.27.0")] 422 #[rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0")] 423 #[inline] end(&self) -> &Idx424 pub const fn end(&self) -> &Idx { 425 &self.end 426 } 427 428 /// Destructures the `RangeInclusive` into (lower bound, upper (inclusive) bound). 429 /// 430 /// Note: the value returned by this method is unspecified after the range 431 /// has been iterated to exhaustion. 432 /// 433 /// # Examples 434 /// 435 /// ``` 436 /// assert_eq!((3..=5).into_inner(), (3, 5)); 437 /// ``` 438 #[stable(feature = "inclusive_range_methods", since = "1.27.0")] 439 #[inline] into_inner(self) -> (Idx, Idx)440 pub fn into_inner(self) -> (Idx, Idx) { 441 (self.start, self.end) 442 } 443 } 444 445 impl RangeInclusive<usize> { 446 /// Converts to an exclusive `Range` for `SliceIndex` implementations. 447 /// The caller is responsible for dealing with `end == usize::MAX`. 448 #[inline] into_slice_range(self) -> Range<usize>449 pub(crate) fn into_slice_range(self) -> Range<usize> { 450 // If we're not exhausted, we want to simply slice `start..end + 1`. 451 // If we are exhausted, then slicing with `end + 1..end + 1` gives us an 452 // empty range that is still subject to bounds-checks for that endpoint. 453 let exclusive_end = self.end + 1; 454 let start = if self.exhausted { exclusive_end } else { self.start }; 455 start..exclusive_end 456 } 457 } 458 459 #[stable(feature = "inclusive_range", since = "1.26.0")] 460 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result461 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 462 self.start.fmt(fmt)?; 463 write!(fmt, "..=")?; 464 self.end.fmt(fmt)?; 465 if self.exhausted { 466 write!(fmt, " (exhausted)")?; 467 } 468 Ok(()) 469 } 470 } 471 472 impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { 473 /// Returns `true` if `item` is contained in the range. 474 /// 475 /// # Examples 476 /// 477 /// ``` 478 /// assert!(!(3..=5).contains(&2)); 479 /// assert!( (3..=5).contains(&3)); 480 /// assert!( (3..=5).contains(&4)); 481 /// assert!( (3..=5).contains(&5)); 482 /// assert!(!(3..=5).contains(&6)); 483 /// 484 /// assert!( (3..=3).contains(&3)); 485 /// assert!(!(3..=2).contains(&3)); 486 /// 487 /// assert!( (0.0..=1.0).contains(&1.0)); 488 /// assert!(!(0.0..=1.0).contains(&f32::NAN)); 489 /// assert!(!(0.0..=f32::NAN).contains(&0.0)); 490 /// assert!(!(f32::NAN..=1.0).contains(&1.0)); 491 /// ``` 492 /// 493 /// This method always returns `false` after iteration has finished: 494 /// 495 /// ``` 496 /// let mut r = 3..=5; 497 /// assert!(r.contains(&3) && r.contains(&5)); 498 /// for _ in r.by_ref() {} 499 /// // Precise field values are unspecified here 500 /// assert!(!r.contains(&3) && !r.contains(&5)); 501 /// ``` 502 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where Idx: PartialOrd<U>, U: ?Sized + PartialOrd<Idx>,503 pub fn contains<U>(&self, item: &U) -> bool 504 where 505 Idx: PartialOrd<U>, 506 U: ?Sized + PartialOrd<Idx>, 507 { 508 <Self as RangeBounds<Idx>>::contains(self, item) 509 } 510 511 /// Returns `true` if the range contains no items. 512 /// 513 /// # Examples 514 /// 515 /// ``` 516 /// assert!(!(3..=5).is_empty()); 517 /// assert!(!(3..=3).is_empty()); 518 /// assert!( (3..=2).is_empty()); 519 /// ``` 520 /// 521 /// The range is empty if either side is incomparable: 522 /// 523 /// ``` 524 /// assert!(!(3.0..=5.0).is_empty()); 525 /// assert!( (3.0..=f32::NAN).is_empty()); 526 /// assert!( (f32::NAN..=5.0).is_empty()); 527 /// ``` 528 /// 529 /// This method returns `true` after iteration has finished: 530 /// 531 /// ``` 532 /// let mut r = 3..=5; 533 /// for _ in r.by_ref() {} 534 /// // Precise field values are unspecified here 535 /// assert!(r.is_empty()); 536 /// ``` 537 #[stable(feature = "range_is_empty", since = "1.47.0")] 538 #[inline] is_empty(&self) -> bool539 pub fn is_empty(&self) -> bool { 540 self.exhausted || !(self.start <= self.end) 541 } 542 } 543 544 /// A range only bounded inclusively above (`..=end`). 545 /// 546 /// The `RangeToInclusive` `..=end` contains all values with `x <= end`. 547 /// It cannot serve as an [`Iterator`] because it doesn't have a starting point. 548 /// 549 /// # Examples 550 /// 551 /// The `..=end` syntax is a `RangeToInclusive`: 552 /// 553 /// ``` 554 /// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 }); 555 /// ``` 556 /// 557 /// It does not have an [`IntoIterator`] implementation, so you can't use it in a 558 /// `for` loop directly. This won't compile: 559 /// 560 /// ```compile_fail,E0277 561 /// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>: 562 /// // std::iter::Iterator` is not satisfied 563 /// for i in ..=5 { 564 /// // ... 565 /// } 566 /// ``` 567 /// 568 /// When used as a [slicing index], `RangeToInclusive` produces a slice of all 569 /// array elements up to and including the index indicated by `end`. 570 /// 571 /// ``` 572 /// let arr = [0, 1, 2, 3, 4]; 573 /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); 574 /// assert_eq!(arr[ .. 3], [0, 1, 2 ]); 575 /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive` 576 /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); 577 /// assert_eq!(arr[1.. 3], [ 1, 2 ]); 578 /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); 579 /// ``` 580 /// 581 /// [slicing index]: crate::slice::SliceIndex 582 #[lang = "RangeToInclusive"] 583 #[doc(alias = "..=")] 584 #[derive(Copy, Clone, PartialEq, Eq, Hash)] 585 #[stable(feature = "inclusive_range", since = "1.26.0")] 586 pub struct RangeToInclusive<Idx> { 587 /// The upper bound of the range (inclusive) 588 #[stable(feature = "inclusive_range", since = "1.26.0")] 589 pub end: Idx, 590 } 591 592 #[stable(feature = "inclusive_range", since = "1.26.0")] 593 impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result594 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 595 write!(fmt, "..=")?; 596 self.end.fmt(fmt)?; 597 Ok(()) 598 } 599 } 600 601 impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> { 602 /// Returns `true` if `item` is contained in the range. 603 /// 604 /// # Examples 605 /// 606 /// ``` 607 /// assert!( (..=5).contains(&-1_000_000_000)); 608 /// assert!( (..=5).contains(&5)); 609 /// assert!(!(..=5).contains(&6)); 610 /// 611 /// assert!( (..=1.0).contains(&1.0)); 612 /// assert!(!(..=1.0).contains(&f32::NAN)); 613 /// assert!(!(..=f32::NAN).contains(&0.5)); 614 /// ``` 615 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where Idx: PartialOrd<U>, U: ?Sized + PartialOrd<Idx>,616 pub fn contains<U>(&self, item: &U) -> bool 617 where 618 Idx: PartialOrd<U>, 619 U: ?Sized + PartialOrd<Idx>, 620 { 621 <Self as RangeBounds<Idx>>::contains(self, item) 622 } 623 } 624 625 // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>> 626 // because underflow would be possible with (..0).into() 627 628 /// An endpoint of a range of keys. 629 /// 630 /// # Examples 631 /// 632 /// `Bound`s are range endpoints: 633 /// 634 /// ``` 635 /// use std::ops::Bound::*; 636 /// use std::ops::RangeBounds; 637 /// 638 /// assert_eq!((..100).start_bound(), Unbounded); 639 /// assert_eq!((1..12).start_bound(), Included(&1)); 640 /// assert_eq!((1..12).end_bound(), Excluded(&12)); 641 /// ``` 642 /// 643 /// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`]. 644 /// Note that in most cases, it's better to use range syntax (`1..5`) instead. 645 /// 646 /// ``` 647 /// use std::collections::BTreeMap; 648 /// use std::ops::Bound::{Excluded, Included, Unbounded}; 649 /// 650 /// let mut map = BTreeMap::new(); 651 /// map.insert(3, "a"); 652 /// map.insert(5, "b"); 653 /// map.insert(8, "c"); 654 /// 655 /// for (key, value) in map.range((Excluded(3), Included(8))) { 656 /// println!("{}: {}", key, value); 657 /// } 658 /// 659 /// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next()); 660 /// ``` 661 /// 662 /// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range 663 #[stable(feature = "collections_bound", since = "1.17.0")] 664 #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] 665 pub enum Bound<T> { 666 /// An inclusive bound. 667 #[stable(feature = "collections_bound", since = "1.17.0")] 668 Included(#[stable(feature = "collections_bound", since = "1.17.0")] T), 669 /// An exclusive bound. 670 #[stable(feature = "collections_bound", since = "1.17.0")] 671 Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T), 672 /// An infinite endpoint. Indicates that there is no bound in this direction. 673 #[stable(feature = "collections_bound", since = "1.17.0")] 674 Unbounded, 675 } 676 677 impl<T> Bound<T> { 678 /// Converts from `&Bound<T>` to `Bound<&T>`. 679 #[inline] 680 #[unstable(feature = "bound_as_ref", issue = "80996")] as_ref(&self) -> Bound<&T>681 pub fn as_ref(&self) -> Bound<&T> { 682 match *self { 683 Included(ref x) => Included(x), 684 Excluded(ref x) => Excluded(x), 685 Unbounded => Unbounded, 686 } 687 } 688 689 /// Converts from `&mut Bound<T>` to `Bound<&mut T>`. 690 #[inline] 691 #[unstable(feature = "bound_as_ref", issue = "80996")] as_mut(&mut self) -> Bound<&mut T>692 pub fn as_mut(&mut self) -> Bound<&mut T> { 693 match *self { 694 Included(ref mut x) => Included(x), 695 Excluded(ref mut x) => Excluded(x), 696 Unbounded => Unbounded, 697 } 698 } 699 700 /// Maps a `Bound<T>` to a `Bound<U>` by applying a function to the contained value (including 701 /// both `Included` and `Excluded`), returning a `Bound` of the same kind. 702 /// 703 /// # Examples 704 /// 705 /// ``` 706 /// #![feature(bound_map)] 707 /// use std::ops::Bound::*; 708 /// 709 /// let bound_string = Included("Hello, World!"); 710 /// 711 /// assert_eq!(bound_string.map(|s| s.len()), Included(13)); 712 /// ``` 713 /// 714 /// ``` 715 /// #![feature(bound_map)] 716 /// use std::ops::Bound; 717 /// use Bound::*; 718 /// 719 /// let unbounded_string: Bound<String> = Unbounded; 720 /// 721 /// assert_eq!(unbounded_string.map(|s| s.len()), Unbounded); 722 /// ``` 723 #[inline] 724 #[unstable(feature = "bound_map", issue = "86026")] map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U>725 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> { 726 match self { 727 Unbounded => Unbounded, 728 Included(x) => Included(f(x)), 729 Excluded(x) => Excluded(f(x)), 730 } 731 } 732 } 733 734 impl<T: Clone> Bound<&T> { 735 /// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound. 736 /// 737 /// # Examples 738 /// 739 /// ``` 740 /// use std::ops::Bound::*; 741 /// use std::ops::RangeBounds; 742 /// 743 /// assert_eq!((1..12).start_bound(), Included(&1)); 744 /// assert_eq!((1..12).start_bound().cloned(), Included(1)); 745 /// ``` 746 #[must_use = "`self` will be dropped if the result is not used"] 747 #[stable(feature = "bound_cloned", since = "1.55.0")] cloned(self) -> Bound<T>748 pub fn cloned(self) -> Bound<T> { 749 match self { 750 Bound::Unbounded => Bound::Unbounded, 751 Bound::Included(x) => Bound::Included(x.clone()), 752 Bound::Excluded(x) => Bound::Excluded(x.clone()), 753 } 754 } 755 } 756 757 /// `RangeBounds` is implemented by Rust's built-in range types, produced 758 /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. 759 #[stable(feature = "collections_range", since = "1.28.0")] 760 pub trait RangeBounds<T: ?Sized> { 761 /// Start index bound. 762 /// 763 /// Returns the start value as a `Bound`. 764 /// 765 /// # Examples 766 /// 767 /// ``` 768 /// # fn main() { 769 /// use std::ops::Bound::*; 770 /// use std::ops::RangeBounds; 771 /// 772 /// assert_eq!((..10).start_bound(), Unbounded); 773 /// assert_eq!((3..10).start_bound(), Included(&3)); 774 /// # } 775 /// ``` 776 #[stable(feature = "collections_range", since = "1.28.0")] start_bound(&self) -> Bound<&T>777 fn start_bound(&self) -> Bound<&T>; 778 779 /// End index bound. 780 /// 781 /// Returns the end value as a `Bound`. 782 /// 783 /// # Examples 784 /// 785 /// ``` 786 /// # fn main() { 787 /// use std::ops::Bound::*; 788 /// use std::ops::RangeBounds; 789 /// 790 /// assert_eq!((3..).end_bound(), Unbounded); 791 /// assert_eq!((3..10).end_bound(), Excluded(&10)); 792 /// # } 793 /// ``` 794 #[stable(feature = "collections_range", since = "1.28.0")] end_bound(&self) -> Bound<&T>795 fn end_bound(&self) -> Bound<&T>; 796 797 /// Returns `true` if `item` is contained in the range. 798 /// 799 /// # Examples 800 /// 801 /// ``` 802 /// assert!( (3..5).contains(&4)); 803 /// assert!(!(3..5).contains(&2)); 804 /// 805 /// assert!( (0.0..1.0).contains(&0.5)); 806 /// assert!(!(0.0..1.0).contains(&f32::NAN)); 807 /// assert!(!(0.0..f32::NAN).contains(&0.5)); 808 /// assert!(!(f32::NAN..1.0).contains(&0.5)); 809 #[stable(feature = "range_contains", since = "1.35.0")] contains<U>(&self, item: &U) -> bool where T: PartialOrd<U>, U: ?Sized + PartialOrd<T>,810 fn contains<U>(&self, item: &U) -> bool 811 where 812 T: PartialOrd<U>, 813 U: ?Sized + PartialOrd<T>, 814 { 815 (match self.start_bound() { 816 Included(start) => start <= item, 817 Excluded(start) => start < item, 818 Unbounded => true, 819 }) && (match self.end_bound() { 820 Included(end) => item <= end, 821 Excluded(end) => item < end, 822 Unbounded => true, 823 }) 824 } 825 } 826 827 use self::Bound::{Excluded, Included, Unbounded}; 828 829 #[stable(feature = "collections_range", since = "1.28.0")] 830 impl<T: ?Sized> RangeBounds<T> for RangeFull { start_bound(&self) -> Bound<&T>831 fn start_bound(&self) -> Bound<&T> { 832 Unbounded 833 } end_bound(&self) -> Bound<&T>834 fn end_bound(&self) -> Bound<&T> { 835 Unbounded 836 } 837 } 838 839 #[stable(feature = "collections_range", since = "1.28.0")] 840 impl<T> RangeBounds<T> for RangeFrom<T> { start_bound(&self) -> Bound<&T>841 fn start_bound(&self) -> Bound<&T> { 842 Included(&self.start) 843 } end_bound(&self) -> Bound<&T>844 fn end_bound(&self) -> Bound<&T> { 845 Unbounded 846 } 847 } 848 849 #[stable(feature = "collections_range", since = "1.28.0")] 850 impl<T> RangeBounds<T> for RangeTo<T> { start_bound(&self) -> Bound<&T>851 fn start_bound(&self) -> Bound<&T> { 852 Unbounded 853 } end_bound(&self) -> Bound<&T>854 fn end_bound(&self) -> Bound<&T> { 855 Excluded(&self.end) 856 } 857 } 858 859 #[stable(feature = "collections_range", since = "1.28.0")] 860 impl<T> RangeBounds<T> for Range<T> { start_bound(&self) -> Bound<&T>861 fn start_bound(&self) -> Bound<&T> { 862 Included(&self.start) 863 } end_bound(&self) -> Bound<&T>864 fn end_bound(&self) -> Bound<&T> { 865 Excluded(&self.end) 866 } 867 } 868 869 #[stable(feature = "collections_range", since = "1.28.0")] 870 impl<T> RangeBounds<T> for RangeInclusive<T> { start_bound(&self) -> Bound<&T>871 fn start_bound(&self) -> Bound<&T> { 872 Included(&self.start) 873 } end_bound(&self) -> Bound<&T>874 fn end_bound(&self) -> Bound<&T> { 875 if self.exhausted { 876 // When the iterator is exhausted, we usually have start == end, 877 // but we want the range to appear empty, containing nothing. 878 Excluded(&self.end) 879 } else { 880 Included(&self.end) 881 } 882 } 883 } 884 885 #[stable(feature = "collections_range", since = "1.28.0")] 886 impl<T> RangeBounds<T> for RangeToInclusive<T> { start_bound(&self) -> Bound<&T>887 fn start_bound(&self) -> Bound<&T> { 888 Unbounded 889 } end_bound(&self) -> Bound<&T>890 fn end_bound(&self) -> Bound<&T> { 891 Included(&self.end) 892 } 893 } 894 895 #[stable(feature = "collections_range", since = "1.28.0")] 896 impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) { start_bound(&self) -> Bound<&T>897 fn start_bound(&self) -> Bound<&T> { 898 match *self { 899 (Included(ref start), _) => Included(start), 900 (Excluded(ref start), _) => Excluded(start), 901 (Unbounded, _) => Unbounded, 902 } 903 } 904 end_bound(&self) -> Bound<&T>905 fn end_bound(&self) -> Bound<&T> { 906 match *self { 907 (_, Included(ref end)) => Included(end), 908 (_, Excluded(ref end)) => Excluded(end), 909 (_, Unbounded) => Unbounded, 910 } 911 } 912 } 913 914 #[stable(feature = "collections_range", since = "1.28.0")] 915 impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { start_bound(&self) -> Bound<&T>916 fn start_bound(&self) -> Bound<&T> { 917 self.0 918 } 919 end_bound(&self) -> Bound<&T>920 fn end_bound(&self) -> Bound<&T> { 921 self.1 922 } 923 } 924 925 #[stable(feature = "collections_range", since = "1.28.0")] 926 impl<T> RangeBounds<T> for RangeFrom<&T> { start_bound(&self) -> Bound<&T>927 fn start_bound(&self) -> Bound<&T> { 928 Included(self.start) 929 } end_bound(&self) -> Bound<&T>930 fn end_bound(&self) -> Bound<&T> { 931 Unbounded 932 } 933 } 934 935 #[stable(feature = "collections_range", since = "1.28.0")] 936 impl<T> RangeBounds<T> for RangeTo<&T> { start_bound(&self) -> Bound<&T>937 fn start_bound(&self) -> Bound<&T> { 938 Unbounded 939 } end_bound(&self) -> Bound<&T>940 fn end_bound(&self) -> Bound<&T> { 941 Excluded(self.end) 942 } 943 } 944 945 #[stable(feature = "collections_range", since = "1.28.0")] 946 impl<T> RangeBounds<T> for Range<&T> { start_bound(&self) -> Bound<&T>947 fn start_bound(&self) -> Bound<&T> { 948 Included(self.start) 949 } end_bound(&self) -> Bound<&T>950 fn end_bound(&self) -> Bound<&T> { 951 Excluded(self.end) 952 } 953 } 954 955 #[stable(feature = "collections_range", since = "1.28.0")] 956 impl<T> RangeBounds<T> for RangeInclusive<&T> { start_bound(&self) -> Bound<&T>957 fn start_bound(&self) -> Bound<&T> { 958 Included(self.start) 959 } end_bound(&self) -> Bound<&T>960 fn end_bound(&self) -> Bound<&T> { 961 Included(self.end) 962 } 963 } 964 965 #[stable(feature = "collections_range", since = "1.28.0")] 966 impl<T> RangeBounds<T> for RangeToInclusive<&T> { start_bound(&self) -> Bound<&T>967 fn start_bound(&self) -> Bound<&T> { 968 Unbounded 969 } end_bound(&self) -> Bound<&T>970 fn end_bound(&self) -> Bound<&T> { 971 Included(self.end) 972 } 973 } 974