core/range.rs
1//! # Experimental replacement range types
2//!
3//! The types within this module are meant to replace the existing
4//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition.
5//!
6//! ```
7//! #![feature(new_range_api)]
8//! use core::range::{Range, RangeFrom, RangeInclusive};
9//!
10//! let arr = [0, 1, 2, 3, 4];
11//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]);
12//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]);
13//! assert_eq!(arr[ ..=3 ], [0, 1, 2, 3 ]);
14//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]);
15//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]);
16//! assert_eq!(arr[RangeInclusive::from(1..=3)], [ 1, 2, 3 ]);
17//! ```
18
19use crate::fmt;
20use crate::hash::Hash;
21
22mod iter;
23
24#[unstable(feature = "new_range_api", issue = "125687")]
25pub mod legacy;
26
27use Bound::{Excluded, Included, Unbounded};
28#[doc(inline)]
29pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
30
31#[doc(inline)]
32pub use crate::iter::Step;
33#[doc(inline)]
34pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo};
35
36/// A (half-open) range bounded inclusively below and exclusively above
37/// (`start..end` in a future edition).
38///
39/// The range `start..end` contains all values with `start <= x < end`.
40/// It is empty if `start >= end`.
41///
42/// # Examples
43///
44/// ```
45/// #![feature(new_range_api)]
46/// use core::range::Range;
47///
48/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 });
49/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
50/// ```
51#[lang = "RangeCopy"]
52#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
53#[unstable(feature = "new_range_api", issue = "125687")]
54pub struct Range<Idx> {
55 /// The lower bound of the range (inclusive).
56 #[unstable(feature = "new_range_api", issue = "125687")]
57 pub start: Idx,
58 /// The upper bound of the range (exclusive).
59 #[unstable(feature = "new_range_api", issue = "125687")]
60 pub end: Idx,
61}
62
63#[unstable(feature = "new_range_api", issue = "125687")]
64impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
65 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
66 self.start.fmt(fmt)?;
67 write!(fmt, "..")?;
68 self.end.fmt(fmt)?;
69 Ok(())
70 }
71}
72
73impl<Idx: Step> Range<Idx> {
74 /// Creates an iterator over the elements within this range.
75 ///
76 /// Shorthand for `.clone().into_iter()`
77 ///
78 /// # Examples
79 ///
80 /// ```
81 /// #![feature(new_range_api)]
82 /// use core::range::Range;
83 ///
84 /// let mut i = Range::from(3..9).iter().map(|n| n*n);
85 /// assert_eq!(i.next(), Some(9));
86 /// assert_eq!(i.next(), Some(16));
87 /// assert_eq!(i.next(), Some(25));
88 /// ```
89 #[unstable(feature = "new_range_api", issue = "125687")]
90 #[inline]
91 pub fn iter(&self) -> IterRange<Idx> {
92 self.clone().into_iter()
93 }
94}
95
96impl<Idx: PartialOrd<Idx>> Range<Idx> {
97 /// Returns `true` if `item` is contained in the range.
98 ///
99 /// # Examples
100 ///
101 /// ```
102 /// #![feature(new_range_api)]
103 /// use core::range::Range;
104 ///
105 /// assert!(!Range::from(3..5).contains(&2));
106 /// assert!( Range::from(3..5).contains(&3));
107 /// assert!( Range::from(3..5).contains(&4));
108 /// assert!(!Range::from(3..5).contains(&5));
109 ///
110 /// assert!(!Range::from(3..3).contains(&3));
111 /// assert!(!Range::from(3..2).contains(&3));
112 ///
113 /// assert!( Range::from(0.0..1.0).contains(&0.5));
114 /// assert!(!Range::from(0.0..1.0).contains(&f32::NAN));
115 /// assert!(!Range::from(0.0..f32::NAN).contains(&0.5));
116 /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5));
117 /// ```
118 #[inline]
119 #[unstable(feature = "new_range_api", issue = "125687")]
120 pub fn contains<U>(&self, item: &U) -> bool
121 where
122 Idx: PartialOrd<U>,
123 U: ?Sized + PartialOrd<Idx>,
124 {
125 <Self as RangeBounds<Idx>>::contains(self, item)
126 }
127
128 /// Returns `true` if the range contains no items.
129 ///
130 /// # Examples
131 ///
132 /// ```
133 /// #![feature(new_range_api)]
134 /// use core::range::Range;
135 ///
136 /// assert!(!Range::from(3..5).is_empty());
137 /// assert!( Range::from(3..3).is_empty());
138 /// assert!( Range::from(3..2).is_empty());
139 /// ```
140 ///
141 /// The range is empty if either side is incomparable:
142 ///
143 /// ```
144 /// #![feature(new_range_api)]
145 /// use core::range::Range;
146 ///
147 /// assert!(!Range::from(3.0..5.0).is_empty());
148 /// assert!( Range::from(3.0..f32::NAN).is_empty());
149 /// assert!( Range::from(f32::NAN..5.0).is_empty());
150 /// ```
151 #[inline]
152 #[unstable(feature = "new_range_api", issue = "125687")]
153 pub fn is_empty(&self) -> bool {
154 !(self.start < self.end)
155 }
156}
157
158#[unstable(feature = "new_range_api", issue = "125687")]
159impl<T> RangeBounds<T> for Range<T> {
160 fn start_bound(&self) -> Bound<&T> {
161 Included(&self.start)
162 }
163 fn end_bound(&self) -> Bound<&T> {
164 Excluded(&self.end)
165 }
166}
167
168// This impl intentionally does not have `T: ?Sized`;
169// see https://github.com/rust-lang/rust/pull/61584 for discussion of why.
170//
171/// If you need to use this implementation where `T` is unsized,
172/// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound],
173/// i.e. replace `start..end` with `(Bound::Included(start), Bound::Excluded(end))`.
174#[unstable(feature = "new_range_api", issue = "125687")]
175impl<T> RangeBounds<T> for Range<&T> {
176 fn start_bound(&self) -> Bound<&T> {
177 Included(self.start)
178 }
179 fn end_bound(&self) -> Bound<&T> {
180 Excluded(self.end)
181 }
182}
183
184// #[unstable(feature = "range_into_bounds", issue = "136903")]
185#[unstable(feature = "new_range_api", issue = "125687")]
186impl<T> IntoBounds<T> for Range<T> {
187 fn into_bounds(self) -> (Bound<T>, Bound<T>) {
188 (Included(self.start), Excluded(self.end))
189 }
190}
191
192#[unstable(feature = "new_range_api", issue = "125687")]
193#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
194impl<T> const From<Range<T>> for legacy::Range<T> {
195 #[inline]
196 fn from(value: Range<T>) -> Self {
197 Self { start: value.start, end: value.end }
198 }
199}
200
201#[unstable(feature = "new_range_api", issue = "125687")]
202#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
203impl<T> const From<legacy::Range<T>> for Range<T> {
204 #[inline]
205 fn from(value: legacy::Range<T>) -> Self {
206 Self { start: value.start, end: value.end }
207 }
208}
209
210/// A range bounded inclusively below and above (`start..=last`).
211///
212/// The `RangeInclusive` `start..=last` contains all values with `x >= start`
213/// and `x <= last`. It is empty unless `start <= last`.
214///
215/// # Examples
216///
217/// The `start..=last` syntax is a `RangeInclusive`:
218///
219/// ```
220/// #![feature(new_range_api)]
221/// use core::range::RangeInclusive;
222///
223/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last: 5 });
224/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
225/// ```
226#[lang = "RangeInclusiveCopy"]
227#[derive(Clone, Copy, PartialEq, Eq, Hash)]
228#[unstable(feature = "new_range_api", issue = "125687")]
229pub struct RangeInclusive<Idx> {
230 /// The lower bound of the range (inclusive).
231 #[unstable(feature = "new_range_api", issue = "125687")]
232 pub start: Idx,
233 /// The upper bound of the range (inclusive).
234 #[unstable(feature = "new_range_api", issue = "125687")]
235 pub last: Idx,
236}
237
238#[unstable(feature = "new_range_api", issue = "125687")]
239impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
240 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
241 self.start.fmt(fmt)?;
242 write!(fmt, "..=")?;
243 self.last.fmt(fmt)?;
244 Ok(())
245 }
246}
247
248impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
249 /// Returns `true` if `item` is contained in the range.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// #![feature(new_range_api)]
255 /// use core::range::RangeInclusive;
256 ///
257 /// assert!(!RangeInclusive::from(3..=5).contains(&2));
258 /// assert!( RangeInclusive::from(3..=5).contains(&3));
259 /// assert!( RangeInclusive::from(3..=5).contains(&4));
260 /// assert!( RangeInclusive::from(3..=5).contains(&5));
261 /// assert!(!RangeInclusive::from(3..=5).contains(&6));
262 ///
263 /// assert!( RangeInclusive::from(3..=3).contains(&3));
264 /// assert!(!RangeInclusive::from(3..=2).contains(&3));
265 ///
266 /// assert!( RangeInclusive::from(0.0..=1.0).contains(&1.0));
267 /// assert!(!RangeInclusive::from(0.0..=1.0).contains(&f32::NAN));
268 /// assert!(!RangeInclusive::from(0.0..=f32::NAN).contains(&0.0));
269 /// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0));
270 /// ```
271 #[inline]
272 #[unstable(feature = "new_range_api", issue = "125687")]
273 pub fn contains<U>(&self, item: &U) -> bool
274 where
275 Idx: PartialOrd<U>,
276 U: ?Sized + PartialOrd<Idx>,
277 {
278 <Self as RangeBounds<Idx>>::contains(self, item)
279 }
280
281 /// Returns `true` if the range contains no items.
282 ///
283 /// # Examples
284 ///
285 /// ```
286 /// #![feature(new_range_api)]
287 /// use core::range::RangeInclusive;
288 ///
289 /// assert!(!RangeInclusive::from(3..=5).is_empty());
290 /// assert!(!RangeInclusive::from(3..=3).is_empty());
291 /// assert!( RangeInclusive::from(3..=2).is_empty());
292 /// ```
293 ///
294 /// The range is empty if either side is incomparable:
295 ///
296 /// ```
297 /// #![feature(new_range_api)]
298 /// use core::range::RangeInclusive;
299 ///
300 /// assert!(!RangeInclusive::from(3.0..=5.0).is_empty());
301 /// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty());
302 /// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty());
303 /// ```
304 #[unstable(feature = "new_range_api", issue = "125687")]
305 #[inline]
306 pub fn is_empty(&self) -> bool {
307 !(self.start <= self.last)
308 }
309}
310
311impl<Idx: Step> RangeInclusive<Idx> {
312 /// Creates an iterator over the elements within this range.
313 ///
314 /// Shorthand for `.clone().into_iter()`
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// #![feature(new_range_api)]
320 /// use core::range::RangeInclusive;
321 ///
322 /// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n);
323 /// assert_eq!(i.next(), Some(9));
324 /// assert_eq!(i.next(), Some(16));
325 /// assert_eq!(i.next(), Some(25));
326 /// ```
327 #[unstable(feature = "new_range_api", issue = "125687")]
328 #[inline]
329 pub fn iter(&self) -> IterRangeInclusive<Idx> {
330 self.clone().into_iter()
331 }
332}
333
334impl RangeInclusive<usize> {
335 /// Converts to an exclusive `Range` for `SliceIndex` implementations.
336 /// The caller is responsible for dealing with `last == usize::MAX`.
337 #[inline]
338 pub(crate) const fn into_slice_range(self) -> Range<usize> {
339 Range { start: self.start, end: self.last + 1 }
340 }
341}
342
343#[unstable(feature = "new_range_api", issue = "125687")]
344impl<T> RangeBounds<T> for RangeInclusive<T> {
345 fn start_bound(&self) -> Bound<&T> {
346 Included(&self.start)
347 }
348 fn end_bound(&self) -> Bound<&T> {
349 Included(&self.last)
350 }
351}
352
353// This impl intentionally does not have `T: ?Sized`;
354// see https://github.com/rust-lang/rust/pull/61584 for discussion of why.
355//
356/// If you need to use this implementation where `T` is unsized,
357/// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound],
358/// i.e. replace `start..=end` with `(Bound::Included(start), Bound::Included(end))`.
359#[unstable(feature = "new_range_api", issue = "125687")]
360impl<T> RangeBounds<T> for RangeInclusive<&T> {
361 fn start_bound(&self) -> Bound<&T> {
362 Included(self.start)
363 }
364 fn end_bound(&self) -> Bound<&T> {
365 Included(self.last)
366 }
367}
368
369// #[unstable(feature = "range_into_bounds", issue = "136903")]
370#[unstable(feature = "new_range_api", issue = "125687")]
371impl<T> IntoBounds<T> for RangeInclusive<T> {
372 fn into_bounds(self) -> (Bound<T>, Bound<T>) {
373 (Included(self.start), Included(self.last))
374 }
375}
376
377#[unstable(feature = "new_range_api", issue = "125687")]
378#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
379impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
380 #[inline]
381 fn from(value: RangeInclusive<T>) -> Self {
382 Self::new(value.start, value.last)
383 }
384}
385#[unstable(feature = "new_range_api", issue = "125687")]
386#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
387impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
388 #[inline]
389 fn from(value: legacy::RangeInclusive<T>) -> Self {
390 assert!(
391 !value.exhausted,
392 "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
393 );
394
395 let (start, last) = value.into_inner();
396 RangeInclusive { start, last }
397 }
398}
399
400/// A range only bounded inclusively below (`start..`).
401///
402/// The `RangeFrom` `start..` contains all values with `x >= start`.
403///
404/// *Note*: Overflow in the [`Iterator`] implementation (when the contained
405/// data type reaches its numerical limit) is allowed to panic, wrap, or
406/// saturate. This behavior is defined by the implementation of the [`Step`]
407/// trait. For primitive integers, this follows the normal rules, and respects
408/// the overflow checks profile (panic in debug, wrap in release). Note also
409/// that overflow happens earlier than you might assume: the overflow happens
410/// in the call to `next` that yields the maximum value, as the range must be
411/// set to a state to yield the next value.
412///
413/// [`Step`]: crate::iter::Step
414///
415/// # Examples
416///
417/// The `start..` syntax is a `RangeFrom`:
418///
419/// ```
420/// #![feature(new_range_api)]
421/// use core::range::RangeFrom;
422///
423/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 });
424/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
425/// ```
426#[lang = "RangeFromCopy"]
427#[derive(Clone, Copy, PartialEq, Eq, Hash)]
428#[unstable(feature = "new_range_api", issue = "125687")]
429pub struct RangeFrom<Idx> {
430 /// The lower bound of the range (inclusive).
431 #[unstable(feature = "new_range_api", issue = "125687")]
432 pub start: Idx,
433}
434
435#[unstable(feature = "new_range_api", issue = "125687")]
436impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
437 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
438 self.start.fmt(fmt)?;
439 write!(fmt, "..")?;
440 Ok(())
441 }
442}
443
444impl<Idx: Step> RangeFrom<Idx> {
445 /// Creates an iterator over the elements within this range.
446 ///
447 /// Shorthand for `.clone().into_iter()`
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// #![feature(new_range_api)]
453 /// use core::range::RangeFrom;
454 ///
455 /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n);
456 /// assert_eq!(i.next(), Some(9));
457 /// assert_eq!(i.next(), Some(16));
458 /// assert_eq!(i.next(), Some(25));
459 /// ```
460 #[unstable(feature = "new_range_api", issue = "125687")]
461 #[inline]
462 pub fn iter(&self) -> IterRangeFrom<Idx> {
463 self.clone().into_iter()
464 }
465}
466
467impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
468 /// Returns `true` if `item` is contained in the range.
469 ///
470 /// # Examples
471 ///
472 /// ```
473 /// #![feature(new_range_api)]
474 /// use core::range::RangeFrom;
475 ///
476 /// assert!(!RangeFrom::from(3..).contains(&2));
477 /// assert!( RangeFrom::from(3..).contains(&3));
478 /// assert!( RangeFrom::from(3..).contains(&1_000_000_000));
479 ///
480 /// assert!( RangeFrom::from(0.0..).contains(&0.5));
481 /// assert!(!RangeFrom::from(0.0..).contains(&f32::NAN));
482 /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5));
483 /// ```
484 #[inline]
485 #[unstable(feature = "new_range_api", issue = "125687")]
486 pub fn contains<U>(&self, item: &U) -> bool
487 where
488 Idx: PartialOrd<U>,
489 U: ?Sized + PartialOrd<Idx>,
490 {
491 <Self as RangeBounds<Idx>>::contains(self, item)
492 }
493}
494
495#[unstable(feature = "new_range_api", issue = "125687")]
496impl<T> RangeBounds<T> for RangeFrom<T> {
497 fn start_bound(&self) -> Bound<&T> {
498 Included(&self.start)
499 }
500 fn end_bound(&self) -> Bound<&T> {
501 Unbounded
502 }
503}
504
505// This impl intentionally does not have `T: ?Sized`;
506// see https://github.com/rust-lang/rust/pull/61584 for discussion of why.
507//
508/// If you need to use this implementation where `T` is unsized,
509/// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound],
510/// i.e. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`.
511#[unstable(feature = "new_range_api", issue = "125687")]
512impl<T> RangeBounds<T> for RangeFrom<&T> {
513 fn start_bound(&self) -> Bound<&T> {
514 Included(self.start)
515 }
516 fn end_bound(&self) -> Bound<&T> {
517 Unbounded
518 }
519}
520
521// #[unstable(feature = "range_into_bounds", issue = "136903")]
522#[unstable(feature = "new_range_api", issue = "125687")]
523impl<T> IntoBounds<T> for RangeFrom<T> {
524 fn into_bounds(self) -> (Bound<T>, Bound<T>) {
525 (Included(self.start), Unbounded)
526 }
527}
528
529#[unstable(feature = "new_range_api", issue = "125687")]
530#[rustc_const_unstable(feature = "const_index", issue = "143775")]
531impl<T> const From<RangeFrom<T>> for legacy::RangeFrom<T> {
532 #[inline]
533 fn from(value: RangeFrom<T>) -> Self {
534 Self { start: value.start }
535 }
536}
537#[unstable(feature = "new_range_api", issue = "125687")]
538#[rustc_const_unstable(feature = "const_index", issue = "143775")]
539impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
540 #[inline]
541 fn from(value: legacy::RangeFrom<T>) -> Self {
542 Self { start: value.start }
543 }
544}
545
546/// A range only bounded inclusively above (`..=last`).
547///
548/// The `RangeToInclusive` `..=last` contains all values with `x <= last`.
549/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
550///
551/// # Examples
552///
553/// The `..=last` syntax is a `RangeToInclusive`:
554///
555/// ```
556/// #![feature(new_range_api)]
557/// #![feature(new_range)]
558/// assert_eq!((..=5), std::range::RangeToInclusive{ last: 5 });
559/// ```
560///
561/// It does not have an [`IntoIterator`] implementation, so you can't use it in a
562/// `for` loop directly. This won't compile:
563///
564/// ```compile_fail,E0277
565/// // error[E0277]: the trait bound `std::range::RangeToInclusive<{integer}>:
566/// // std::iter::Iterator` is not satisfied
567/// for i in ..=5 {
568/// // ...
569/// }
570/// ```
571///
572/// When used as a [slicing index], `RangeToInclusive` produces a slice of all
573/// array elements up to and including the index indicated by `last`.
574///
575/// ```
576/// let arr = [0, 1, 2, 3, 4];
577/// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]);
578/// assert_eq!(arr[ .. 3], [0, 1, 2 ]);
579/// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive`
580/// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]);
581/// assert_eq!(arr[1.. 3], [ 1, 2 ]);
582/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
583/// ```
584///
585/// [slicing index]: crate::slice::SliceIndex
586#[lang = "RangeToInclusiveCopy"]
587#[doc(alias = "..=")]
588#[derive(Copy, Clone, PartialEq, Eq, Hash)]
589#[unstable(feature = "new_range_api", issue = "125687")]
590pub struct RangeToInclusive<Idx> {
591 /// The upper bound of the range (inclusive)
592 #[unstable(feature = "new_range_api", issue = "125687")]
593 pub last: Idx,
594}
595
596#[unstable(feature = "new_range_api", issue = "125687")]
597impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
598 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
599 write!(fmt, "..=")?;
600 self.last.fmt(fmt)?;
601 Ok(())
602 }
603}
604
605impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
606 /// Returns `true` if `item` is contained in the range.
607 ///
608 /// # Examples
609 ///
610 /// ```
611 /// assert!( (..=5).contains(&-1_000_000_000));
612 /// assert!( (..=5).contains(&5));
613 /// assert!(!(..=5).contains(&6));
614 ///
615 /// assert!( (..=1.0).contains(&1.0));
616 /// assert!(!(..=1.0).contains(&f32::NAN));
617 /// assert!(!(..=f32::NAN).contains(&0.5));
618 /// ```
619 #[inline]
620 #[unstable(feature = "new_range_api", issue = "125687")]
621 pub fn contains<U>(&self, item: &U) -> bool
622 where
623 Idx: PartialOrd<U>,
624 U: ?Sized + PartialOrd<Idx>,
625 {
626 <Self as RangeBounds<Idx>>::contains(self, item)
627 }
628}
629
630// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
631// because underflow would be possible with (..0).into()
632
633#[unstable(feature = "new_range_api", issue = "125687")]
634impl<T> RangeBounds<T> for RangeToInclusive<T> {
635 fn start_bound(&self) -> Bound<&T> {
636 Unbounded
637 }
638 fn end_bound(&self) -> Bound<&T> {
639 Included(&self.last)
640 }
641}
642
643#[unstable(feature = "range_into_bounds", issue = "136903")]
644impl<T> IntoBounds<T> for RangeToInclusive<T> {
645 fn into_bounds(self) -> (Bound<T>, Bound<T>) {
646 (Unbounded, Included(self.last))
647 }
648}