@@ -831,6 +831,30 @@ pub trait RangeBounds<T: ?Sized> {
831831 }
832832}
833833
834+ /// Used to convert a range into start and end bounds, consuming the
835+ /// range by value.
836+ ///
837+ /// `IntoBounds` is implemented by Rust’s built-in range types, produced
838+ /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
839+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
840+ pub trait IntoBounds < T > : RangeBounds < T > {
841+ /// Convert this range into the start and end bounds.
842+ /// Returns `(start_bound, end_bound)`.
843+ ///
844+ /// # Examples
845+ ///
846+ /// ```
847+ /// #![feature(range_into_bounds)]
848+ ///
849+ /// use std::ops::Bound::*;
850+ /// use std::ops::IntoBounds;
851+ ///
852+ /// assert_eq!((0..5).into_bounds(), (Included(0), Excluded(5)));
853+ /// assert_eq!((..=7).into_bounds(), (Unbounded, Included(7)));
854+ /// ```
855+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) ;
856+ }
857+
834858use self :: Bound :: { Excluded , Included , Unbounded } ;
835859
836860#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
@@ -843,6 +867,13 @@ impl<T: ?Sized> RangeBounds<T> for RangeFull {
843867 }
844868}
845869
870+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
871+ impl < T > IntoBounds < T > for RangeFull {
872+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
873+ ( Unbounded , Unbounded )
874+ }
875+ }
876+
846877#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
847878impl < T > RangeBounds < T > for RangeFrom < T > {
848879 fn start_bound ( & self ) -> Bound < & T > {
@@ -853,6 +884,13 @@ impl<T> RangeBounds<T> for RangeFrom<T> {
853884 }
854885}
855886
887+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
888+ impl < T > IntoBounds < T > for RangeFrom < T > {
889+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
890+ ( Included ( self . start ) , Unbounded )
891+ }
892+ }
893+
856894#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
857895impl < T > RangeBounds < T > for RangeTo < T > {
858896 fn start_bound ( & self ) -> Bound < & T > {
@@ -863,6 +901,13 @@ impl<T> RangeBounds<T> for RangeTo<T> {
863901 }
864902}
865903
904+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
905+ impl < T > IntoBounds < T > for RangeTo < T > {
906+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
907+ ( Unbounded , Excluded ( self . end ) )
908+ }
909+ }
910+
866911#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
867912impl < T > RangeBounds < T > for Range < T > {
868913 fn start_bound ( & self ) -> Bound < & T > {
@@ -873,6 +918,13 @@ impl<T> RangeBounds<T> for Range<T> {
873918 }
874919}
875920
921+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
922+ impl < T > IntoBounds < T > for Range < T > {
923+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
924+ ( Included ( self . start ) , Excluded ( self . end ) )
925+ }
926+ }
927+
876928#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
877929impl < T > RangeBounds < T > for RangeInclusive < T > {
878930 fn start_bound ( & self ) -> Bound < & T > {
@@ -889,6 +941,22 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
889941 }
890942}
891943
944+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
945+ impl < T > IntoBounds < T > for RangeInclusive < T > {
946+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
947+ (
948+ Included ( self . start ) ,
949+ if self . exhausted {
950+ // When the iterator is exhausted, we usually have start == end,
951+ // but we want the range to appear empty, containing nothing.
952+ Excluded ( self . end )
953+ } else {
954+ Included ( self . end )
955+ } ,
956+ )
957+ }
958+ }
959+
892960#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
893961impl < T > RangeBounds < T > for RangeToInclusive < T > {
894962 fn start_bound ( & self ) -> Bound < & T > {
@@ -899,6 +967,13 @@ impl<T> RangeBounds<T> for RangeToInclusive<T> {
899967 }
900968}
901969
970+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
971+ impl < T > IntoBounds < T > for RangeToInclusive < T > {
972+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
973+ ( Unbounded , Included ( self . end ) )
974+ }
975+ }
976+
902977#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
903978impl < T > RangeBounds < T > for ( Bound < T > , Bound < T > ) {
904979 fn start_bound ( & self ) -> Bound < & T > {
@@ -918,6 +993,13 @@ impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
918993 }
919994}
920995
996+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
997+ impl < T > IntoBounds < T > for ( Bound < T > , Bound < T > ) {
998+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
999+ self
1000+ }
1001+ }
1002+
9211003#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
9221004impl < ' a , T : ?Sized + ' a > RangeBounds < T > for ( Bound < & ' a T > , Bound < & ' a T > ) {
9231005 fn start_bound ( & self ) -> Bound < & T > {
0 commit comments