@@ -151,6 +151,103 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
151
151
}
152
152
}
153
153
154
+ impl Range < usize > {
155
+ /// Performs bounds-checking of a range.
156
+ ///
157
+ /// This method is similar to [`Index::index`] for slices, but it returns a
158
+ /// `Range` equivalent to `range`. You can use this method to turn any range
159
+ /// into `start` and `end` values.
160
+ ///
161
+ /// `bounds` is the range of the slice to use for bounds-checking. It should
162
+ /// be a [`RangeTo`] range that ends at the length of the slice.
163
+ ///
164
+ /// The returned `Range` is safe to pass to [`slice::get_unchecked`] and
165
+ /// [`slice::get_unchecked_mut`] for slices with the given range.
166
+ ///
167
+ /// [`slice::get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
168
+ /// [`slice::get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
169
+ ///
170
+ /// # Panics
171
+ ///
172
+ /// Panics if `range` would be out of bounds.
173
+ ///
174
+ /// # Examples
175
+ ///
176
+ /// ```
177
+ /// #![feature(range_ensure_subset_of)]
178
+ ///
179
+ /// use std::ops::Range;
180
+ ///
181
+ /// let v = [10, 40, 30];
182
+ /// assert_eq!(1..2, Range::ensure_subset_of(1..2, ..v.len()));
183
+ /// assert_eq!(0..2, Range::ensure_subset_of(..2, ..v.len()));
184
+ /// assert_eq!(1..3, Range::ensure_subset_of(1.., ..v.len()));
185
+ /// ```
186
+ ///
187
+ /// Panics when [`Index::index`] would panic:
188
+ ///
189
+ /// ```should_panic
190
+ /// #![feature(range_ensure_subset_of)]
191
+ ///
192
+ /// use std::ops::Range;
193
+ ///
194
+ /// Range::ensure_subset_of(2..1, ..3);
195
+ /// ```
196
+ ///
197
+ /// ```should_panic
198
+ /// #![feature(range_ensure_subset_of)]
199
+ ///
200
+ /// use std::ops::Range;
201
+ ///
202
+ /// Range::ensure_subset_of(1..4, ..3);
203
+ /// ```
204
+ ///
205
+ /// ```should_panic
206
+ /// #![feature(range_ensure_subset_of)]
207
+ ///
208
+ /// use std::ops::Range;
209
+ ///
210
+ /// Range::ensure_subset_of(1..=usize::MAX, ..3);
211
+ /// ```
212
+ ///
213
+ /// [`Index::index`]: crate::ops::Index::index
214
+ #[ track_caller]
215
+ #[ unstable( feature = "range_ensure_subset_of" , issue = "76393" ) ]
216
+ pub fn ensure_subset_of < R > ( range : R , bounds : RangeTo < usize > ) -> Self
217
+ where
218
+ R : RangeBounds < usize > ,
219
+ {
220
+ let len = bounds. end ;
221
+
222
+ let start: Bound < & usize > = range. start_bound ( ) ;
223
+ let start = match start {
224
+ Bound :: Included ( & start) => start,
225
+ Bound :: Excluded ( start) => {
226
+ start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
227
+ }
228
+ Bound :: Unbounded => 0 ,
229
+ } ;
230
+
231
+ let end: Bound < & usize > = range. end_bound ( ) ;
232
+ let end = match end {
233
+ Bound :: Included ( end) => {
234
+ end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
235
+ }
236
+ Bound :: Excluded ( & end) => end,
237
+ Bound :: Unbounded => len,
238
+ } ;
239
+
240
+ if start > end {
241
+ slice_index_order_fail ( start, end) ;
242
+ }
243
+ if end > len {
244
+ slice_end_index_len_fail ( end, len) ;
245
+ }
246
+
247
+ Self { start, end }
248
+ }
249
+ }
250
+
154
251
/// A range only bounded inclusively below (`start..`).
155
252
///
156
253
/// The `RangeFrom` `start..` contains all values with `x >= start`.
@@ -764,101 +861,6 @@ pub trait RangeBounds<T: ?Sized> {
764
861
#[ stable( feature = "collections_range" , since = "1.28.0" ) ]
765
862
fn end_bound ( & self ) -> Bound < & T > ;
766
863
767
- /// Performs bounds-checking of this range.
768
- ///
769
- /// This method is similar to [`Index::index`] for slices, but it returns a
770
- /// [`Range`] equivalent to this range. You can use this method to turn any
771
- /// range into `start` and `end` values.
772
- ///
773
- /// The given range is the range of the slice to use for bounds-checking. It
774
- /// should be a [`RangeTo`] range that ends at the length of the slice.
775
- ///
776
- /// The returned [`Range`] is safe to pass to [`slice::get_unchecked`] and
777
- /// [`slice::get_unchecked_mut`] for slices with the given range.
778
- ///
779
- /// [`slice::get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
780
- /// [`slice::get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
781
- ///
782
- /// # Panics
783
- ///
784
- /// Panics if the range would be out of bounds.
785
- ///
786
- /// # Examples
787
- ///
788
- /// ```
789
- /// #![feature(range_bounds_ensure_subset_of)]
790
- ///
791
- /// use std::ops::RangeBounds;
792
- ///
793
- /// let v = [10, 40, 30];
794
- /// assert_eq!(1..2, (1..2).ensure_subset_of(..v.len()));
795
- /// assert_eq!(0..2, (..2).ensure_subset_of(..v.len()));
796
- /// assert_eq!(1..3, (1..).ensure_subset_of(..v.len()));
797
- /// ```
798
- ///
799
- /// Panics when [`Index::index`] would panic:
800
- ///
801
- /// ```should_panic
802
- /// #![feature(range_bounds_ensure_subset_of)]
803
- ///
804
- /// use std::ops::RangeBounds;
805
- ///
806
- /// (2..1).ensure_subset_of(..3);
807
- /// ```
808
- ///
809
- /// ```should_panic
810
- /// #![feature(range_bounds_ensure_subset_of)]
811
- ///
812
- /// use std::ops::RangeBounds;
813
- ///
814
- /// (1..4).ensure_subset_of(..3);
815
- /// ```
816
- ///
817
- /// ```should_panic
818
- /// #![feature(range_bounds_ensure_subset_of)]
819
- ///
820
- /// use std::ops::RangeBounds;
821
- ///
822
- /// (1..=usize::MAX).ensure_subset_of(..3);
823
- /// ```
824
- ///
825
- /// [`Index::index`]: crate::ops::Index::index
826
- #[ track_caller]
827
- #[ unstable( feature = "range_bounds_ensure_subset_of" , issue = "76393" ) ]
828
- fn ensure_subset_of ( self , range : RangeTo < usize > ) -> Range < usize >
829
- where
830
- Self : RangeBounds < usize > ,
831
- {
832
- let len = range. end ;
833
-
834
- let start: Bound < & usize > = self . start_bound ( ) ;
835
- let start = match start {
836
- Bound :: Included ( & start) => start,
837
- Bound :: Excluded ( start) => {
838
- start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
839
- }
840
- Bound :: Unbounded => 0 ,
841
- } ;
842
-
843
- let end: Bound < & usize > = self . end_bound ( ) ;
844
- let end = match end {
845
- Bound :: Included ( end) => {
846
- end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
847
- }
848
- Bound :: Excluded ( & end) => end,
849
- Bound :: Unbounded => len,
850
- } ;
851
-
852
- if start > end {
853
- slice_index_order_fail ( start, end) ;
854
- }
855
- if end > len {
856
- slice_end_index_len_fail ( end, len) ;
857
- }
858
-
859
- Range { start, end }
860
- }
861
-
862
864
/// Returns `true` if `item` is contained in the range.
863
865
///
864
866
/// # Examples
0 commit comments