Skip to content

Commit 14a5dc5

Browse files
authored
Rollup merge of #111081 - mattfbacon:master, r=workingjubilee
impl SliceIndex<str> for (Bound<usize>, Bound<usize>) This impl is conspicuously missing.
2 parents b484c87 + f189d00 commit 14a5dc5

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

library/core/src/slice/index.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ where
727727
}
728728

729729
/// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking
730-
fn into_range_unchecked(
730+
pub(crate) fn into_range_unchecked(
731731
len: usize,
732732
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
733733
) -> ops::Range<usize> {
@@ -747,7 +747,7 @@ fn into_range_unchecked(
747747

748748
/// Convert pair of `ops::Bound`s into `ops::Range`.
749749
/// Returns `None` on overflowing indices.
750-
fn into_range(
750+
pub(crate) fn into_range(
751751
len: usize,
752752
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
753753
) -> Option<ops::Range<usize>> {
@@ -772,7 +772,7 @@ fn into_range(
772772

773773
/// Convert pair of `ops::Bound`s into `ops::Range`.
774774
/// Panics on overflowing indices.
775-
fn into_slice_range(
775+
pub(crate) fn into_slice_range(
776776
len: usize,
777777
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
778778
) -> ops::Range<usize> {

library/core/src/slice/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub mod sort;
3838

3939
mod ascii;
4040
mod cmp;
41-
mod index;
41+
pub(crate) mod index;
4242
mod iter;
4343
mod raw;
4444
mod rotate;

library/core/src/str/traits.rs

+52
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,58 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
252252
}
253253
}
254254

255+
/// Implements substring slicing for arbitrary bounds.
256+
///
257+
/// Returns a slice of the given string bounded by the byte indices
258+
/// provided by each bound.
259+
///
260+
/// This operation is *O*(1).
261+
///
262+
/// # Panics
263+
///
264+
/// Panics if `begin` or `end` (if it exists and once adjusted for
265+
/// inclusion/exclusion) does not point to the starting byte offset of
266+
/// a character (as defined by `is_char_boundary`), if `begin > end`, or if
267+
/// `end > len`.
268+
#[stable(feature = "slice_index_str_with_ops_bound_pair", since = "CURRENT_RUSTC_VERSION")]
269+
unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) {
270+
type Output = str;
271+
272+
#[inline]
273+
fn get(self, slice: &str) -> Option<&str> {
274+
crate::slice::index::into_range(slice.len(), self)?.get(slice)
275+
}
276+
277+
#[inline]
278+
fn get_mut(self, slice: &mut str) -> Option<&mut str> {
279+
crate::slice::index::into_range(slice.len(), self)?.get_mut(slice)
280+
}
281+
282+
#[inline]
283+
unsafe fn get_unchecked(self, slice: *const str) -> *const str {
284+
let len = (slice as *const [u8]).len();
285+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
286+
unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) }
287+
}
288+
289+
#[inline]
290+
unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str {
291+
let len = (slice as *mut [u8]).len();
292+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
293+
unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) }
294+
}
295+
296+
#[inline]
297+
fn index(self, slice: &str) -> &str {
298+
crate::slice::index::into_slice_range(slice.len(), self).index(slice)
299+
}
300+
301+
#[inline]
302+
fn index_mut(self, slice: &mut str) -> &mut str {
303+
crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice)
304+
}
305+
}
306+
255307
/// Implements substring slicing with syntax `&self[.. end]` or `&mut
256308
/// self[.. end]`.
257309
///

0 commit comments

Comments
 (0)