@@ -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" ) ]
0 commit comments