Skip to content

Commit 40d00c6

Browse files
committed
add IntoBounds trait
for `range_into_bounds` feature, #136903
1 parent 34a5ea9 commit 40d00c6

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

library/core/src/ops/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ pub use self::function::{Fn, FnMut, FnOnce};
182182
#[stable(feature = "rust1", since = "1.0.0")]
183183
pub use self::index::{Index, IndexMut};
184184
pub(crate) use self::index_range::IndexRange;
185+
#[unstable(feature = "range_into_bounds", issue = "136903")]
186+
pub use self::range::IntoBounds;
185187
#[stable(feature = "inclusive_range", since = "1.26.0")]
186188
pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
187189
#[unstable(feature = "one_sided_range", issue = "69780")]

library/core/src/ops/range.rs

+82
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,88 @@ impl<T> RangeBounds<T> for RangeToInclusive<&T> {
979979
}
980980
}
981981

982+
/// Used to convert a range into start and end bounds, consuming the
983+
/// range by value.
984+
///
985+
/// `IntoBounds` is implemented by Rust’s built-in range types, produced
986+
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
987+
#[unstable(feature = "range_into_bounds", issue = "136903")]
988+
pub trait IntoBounds<T: Sized>: RangeBounds<T> {
989+
/// Convert this range into the start and end bounds.
990+
/// Returns `(start_bound, end_bound)`.
991+
///
992+
/// # Examples
993+
///
994+
/// ```
995+
/// #![feature(range_into_bounds)]
996+
///
997+
/// use std::ops::Bound::*;
998+
/// use std::ops::IntoBounds;
999+
///
1000+
/// assert_eq!((0..5).into_bounds(), (Included(0), Excluded(5)));
1001+
/// assert_eq!((..=7).into_bounds(), (Unbounded, Included(7)));
1002+
/// ```
1003+
fn into_bounds(self) -> (Bound<T>, Bound<T>);
1004+
}
1005+
1006+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1007+
impl<T> IntoBounds<T> for Range<T> {
1008+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1009+
(Included(self.start), Excluded(self.end))
1010+
}
1011+
}
1012+
1013+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1014+
impl<T> IntoBounds<T> for RangeFrom<T> {
1015+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1016+
(Included(self.start), Unbounded)
1017+
}
1018+
}
1019+
1020+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1021+
impl<T> IntoBounds<T> for RangeFull {
1022+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1023+
(Unbounded, Unbounded)
1024+
}
1025+
}
1026+
1027+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1028+
impl<T> IntoBounds<T> for RangeInclusive<T> {
1029+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1030+
(
1031+
Included(self.start),
1032+
if self.exhausted {
1033+
// When the iterator is exhausted, we usually have start == end,
1034+
// but we want the range to appear empty, containing nothing.
1035+
Excluded(self.end)
1036+
} else {
1037+
Included(self.end)
1038+
},
1039+
)
1040+
}
1041+
}
1042+
1043+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1044+
impl<T> IntoBounds<T> for RangeTo<T> {
1045+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1046+
(Unbounded, Excluded(self.end))
1047+
}
1048+
}
1049+
1050+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1051+
impl<T> IntoBounds<T> for RangeToInclusive<T> {
1052+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1053+
(Unbounded, Included(self.end))
1054+
}
1055+
}
1056+
1057+
#[unstable(feature = "range_into_bounds", issue = "136903")]
1058+
impl<T> IntoBounds<T> for (Bound<T>, Bound<T>) {
1059+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
1060+
self
1061+
}
1062+
}
1063+
9821064
/// An internal helper for `split_off` functions indicating
9831065
/// which end a `OneSidedRange` is bounded on.
9841066
#[unstable(feature = "one_sided_range", issue = "69780")]

library/core/src/range.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
3131
#[doc(inline)]
3232
pub use crate::iter::Step;
3333
#[doc(inline)]
34-
pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive};
34+
pub use crate::ops::{
35+
Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive,
36+
};
3537

3638
/// A (half-open) range bounded inclusively below and exclusively above
3739
/// (`start..end` in a future edition).
@@ -175,6 +177,14 @@ impl<T> RangeBounds<T> for Range<&T> {
175177
}
176178
}
177179

180+
// #[unstable(feature = "range_into_bounds", issue = "136903")]
181+
#[unstable(feature = "new_range_api", issue = "125687")]
182+
impl<T> IntoBounds<T> for Range<T> {
183+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
184+
(Included(self.start), Excluded(self.end))
185+
}
186+
}
187+
178188
#[unstable(feature = "new_range_api", issue = "125687")]
179189
impl<T> From<Range<T>> for legacy::Range<T> {
180190
#[inline]
@@ -343,6 +353,14 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
343353
}
344354
}
345355

356+
// #[unstable(feature = "range_into_bounds", issue = "136903")]
357+
#[unstable(feature = "new_range_api", issue = "125687")]
358+
impl<T> IntoBounds<T> for RangeInclusive<T> {
359+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
360+
(Included(self.start), Included(self.end))
361+
}
362+
}
363+
346364
#[unstable(feature = "new_range_api", issue = "125687")]
347365
impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
348366
#[inline]
@@ -479,6 +497,14 @@ impl<T> RangeBounds<T> for RangeFrom<&T> {
479497
}
480498
}
481499

500+
// #[unstable(feature = "range_into_bounds", issue = "136903")]
501+
#[unstable(feature = "new_range_api", issue = "125687")]
502+
impl<T> IntoBounds<T> for RangeFrom<T> {
503+
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
504+
(Included(self.start), Unbounded)
505+
}
506+
}
507+
482508
#[unstable(feature = "new_range_api", issue = "125687")]
483509
impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> {
484510
#[inline]

0 commit comments

Comments
 (0)