@@ -979,6 +979,88 @@ impl<T> RangeBounds<T> for RangeToInclusive<&T> {
979
979
}
980
980
}
981
981
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
+
982
1064
/// An internal helper for `split_off` functions indicating
983
1065
/// which end a `OneSidedRange` is bounded on.
984
1066
#[ unstable( feature = "one_sided_range" , issue = "69780" ) ]
0 commit comments