@@ -151,6 +151,103 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
151151 }
152152}
153153
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+
154251/// A range only bounded inclusively below (`start..`).
155252///
156253/// The `RangeFrom` `start..` contains all values with `x >= start`.
@@ -764,101 +861,6 @@ pub trait RangeBounds<T: ?Sized> {
764861 #[ stable( feature = "collections_range" , since = "1.28.0" ) ]
765862 fn end_bound ( & self ) -> Bound < & T > ;
766863
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-
862864 /// Returns `true` if `item` is contained in the range.
863865 ///
864866 /// # Examples
0 commit comments