diff options
| -rw-r--r-- | library/core/src/ops/mod.rs | 2 | ||||
| -rw-r--r-- | library/core/src/ops/range.rs | 82 | ||||
| -rw-r--r-- | library/core/src/range.rs | 28 |
3 files changed, 111 insertions, 1 deletions
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 7b2ced2cc4b..627a875d9f7 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -182,6 +182,8 @@ pub use self::function::{Fn, FnMut, FnOnce}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::index::{Index, IndexMut}; pub(crate) use self::index_range::IndexRange; +#[unstable(feature = "range_into_bounds", issue = "136903")] +pub use self::range::IntoBounds; #[stable(feature = "inclusive_range", since = "1.26.0")] pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive}; #[unstable(feature = "one_sided_range", issue = "69780")] diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 42e07a0e51d..5580faefacc 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -831,6 +831,30 @@ pub trait RangeBounds<T: ?Sized> { } } +/// Used to convert a range into start and end bounds, consuming the +/// range by value. +/// +/// `IntoBounds` is implemented by Rust’s built-in range types, produced +/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. +#[unstable(feature = "range_into_bounds", issue = "136903")] +pub trait IntoBounds<T>: RangeBounds<T> { + /// Convert this range into the start and end bounds. + /// Returns `(start_bound, end_bound)`. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_into_bounds)] + /// + /// use std::ops::Bound::*; + /// use std::ops::IntoBounds; + /// + /// assert_eq!((0..5).into_bounds(), (Included(0), Excluded(5))); + /// assert_eq!((..=7).into_bounds(), (Unbounded, Included(7))); + /// ``` + fn into_bounds(self) -> (Bound<T>, Bound<T>); +} + use self::Bound::{Excluded, Included, Unbounded}; #[stable(feature = "collections_range", since = "1.28.0")] @@ -843,6 +867,13 @@ impl<T: ?Sized> RangeBounds<T> for RangeFull { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for RangeFull { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Unbounded, Unbounded) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for RangeFrom<T> { fn start_bound(&self) -> Bound<&T> { @@ -853,6 +884,13 @@ impl<T> RangeBounds<T> for RangeFrom<T> { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for RangeFrom<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Included(self.start), Unbounded) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for RangeTo<T> { fn start_bound(&self) -> Bound<&T> { @@ -863,6 +901,13 @@ impl<T> RangeBounds<T> for RangeTo<T> { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for RangeTo<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Unbounded, Excluded(self.end)) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for Range<T> { fn start_bound(&self) -> Bound<&T> { @@ -873,6 +918,13 @@ impl<T> RangeBounds<T> for Range<T> { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for Range<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Included(self.start), Excluded(self.end)) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for RangeInclusive<T> { fn start_bound(&self) -> Bound<&T> { @@ -889,6 +941,22 @@ impl<T> RangeBounds<T> for RangeInclusive<T> { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for RangeInclusive<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + ( + Included(self.start), + if self.exhausted { + // When the iterator is exhausted, we usually have start == end, + // but we want the range to appear empty, containing nothing. + Excluded(self.end) + } else { + Included(self.end) + }, + ) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for RangeToInclusive<T> { fn start_bound(&self) -> Bound<&T> { @@ -899,6 +967,13 @@ impl<T> RangeBounds<T> for RangeToInclusive<T> { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for RangeToInclusive<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Unbounded, Included(self.end)) + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) { fn start_bound(&self) -> Bound<&T> { @@ -918,6 +993,13 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) { } } +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl<T> IntoBounds<T> for (Bound<T>, Bound<T>) { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + self + } +} + #[stable(feature = "collections_range", since = "1.28.0")] impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { fn start_bound(&self) -> Bound<&T> { diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 6a62928873f..e94499065ac 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -31,7 +31,9 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive}; #[doc(inline)] pub use crate::iter::Step; #[doc(inline)] -pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive}; +pub use crate::ops::{ + Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive, +}; /// A (half-open) range bounded inclusively below and exclusively above /// (`start..end` in a future edition). @@ -175,6 +177,14 @@ impl<T> RangeBounds<T> for Range<&T> { } } +// #[unstable(feature = "range_into_bounds", issue = "136903")] +#[unstable(feature = "new_range_api", issue = "125687")] +impl<T> IntoBounds<T> for Range<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Included(self.start), Excluded(self.end)) + } +} + #[unstable(feature = "new_range_api", issue = "125687")] impl<T> From<Range<T>> for legacy::Range<T> { #[inline] @@ -343,6 +353,14 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> { } } +// #[unstable(feature = "range_into_bounds", issue = "136903")] +#[unstable(feature = "new_range_api", issue = "125687")] +impl<T> IntoBounds<T> for RangeInclusive<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Included(self.start), Included(self.end)) + } +} + #[unstable(feature = "new_range_api", issue = "125687")] impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> { #[inline] @@ -479,6 +497,14 @@ impl<T> RangeBounds<T> for RangeFrom<&T> { } } +// #[unstable(feature = "range_into_bounds", issue = "136903")] +#[unstable(feature = "new_range_api", issue = "125687")] +impl<T> IntoBounds<T> for RangeFrom<T> { + fn into_bounds(self) -> (Bound<T>, Bound<T>) { + (Included(self.start), Unbounded) + } +} + #[unstable(feature = "new_range_api", issue = "125687")] impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> { #[inline] |
