use core::slice::SliceIndex;
use crate::string_base::StringBase;
unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeFull {
type Output = StringBase<[char]>;
#[inline]
fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
Some(slice)
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
Some(slice)
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
slice
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
slice
}
#[inline]
fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
slice
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
slice
}
}
unsafe impl SliceIndex<StringBase<[char]>> for core::ops::Range<usize> {
type Output = StringBase<[char]>;
#[inline]
fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
if self.start <= self.end && self.end <= slice.len() {
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
if self.start <= self.end && self.end <= slice.len() {
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
let slice = slice as *const [char];
let ptr = slice.as_ptr().add(self.start);
let len = self.end - self.start;
core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[char]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
let slice = slice as *mut [char];
let ptr = slice.as_mut_ptr().add(self.start);
let len = self.end - self.start;
core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[char]>
}
#[inline]
fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
let end = self.end;
match self.get(slice) {
Some(s) => s,
#[cfg(feature = "alloc")]
None => panic!("char index {} is out of bounds of `{}`", end, &*slice),
#[cfg(not(feature = "alloc"))]
None => panic!("char index {} is out of bounds", end),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
if self.start <= self.end && self.end <= slice.len() {
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
#[cfg(feature = "alloc")]
panic!("char index {} is out of bounds of `{}`", self.end, &*slice);
#[cfg(not(feature = "alloc"))]
panic!("char index {} is out of bounds", self.end);
}
}
}
unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeTo<usize> {
type Output = StringBase<[char]>;
#[inline]
fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
if self.end <= slice.len() {
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
if self.end <= slice.len() {
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
let slice = slice as *const [char];
let ptr = slice.as_ptr();
core::ptr::slice_from_raw_parts(ptr, self.end) as *const StringBase<[char]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
let slice = slice as *mut [char];
let ptr = slice.as_mut_ptr();
core::ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut StringBase<[char]>
}
#[inline]
fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
let end = self.end;
match self.get(slice) {
Some(s) => s,
#[cfg(feature = "alloc")]
None => panic!("char index {} is out of bounds of `{}`", end, &*slice),
#[cfg(not(feature = "alloc"))]
None => panic!("char index {} is out of bounds", end),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
if self.end <= slice.len() {
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
#[cfg(feature = "alloc")]
panic!("char index {} is out of bounds of `{}`", self.end, &*slice);
#[cfg(not(feature = "alloc"))]
panic!("char index {} is out of bounds", self.end);
}
}
}
unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeFrom<usize> {
type Output = StringBase<[char]>;
#[inline]
fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
if self.start <= slice.len() {
Some(unsafe { &*self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
if self.start <= slice.len() {
Some(unsafe { &mut *self.get_unchecked_mut(slice) })
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
let slice = slice as *const [char];
let ptr = slice.as_ptr().add(self.start);
let len = slice.len() - self.start;
core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[char]>
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
let slice = slice as *mut [char];
let ptr = slice.as_mut_ptr().add(self.start);
let len = slice.len() - self.start;
core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[char]>
}
#[inline]
fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
let start = self.start;
match self.get(slice) {
Some(s) => s,
#[cfg(feature = "alloc")]
None => panic!("char index {} is out of bounds of `{}`", start, &*slice),
#[cfg(not(feature = "alloc"))]
None => panic!("char index {} is out of bounds", start),
}
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
if self.start <= slice.len() {
unsafe { &mut *self.get_unchecked_mut(slice) }
} else {
#[cfg(feature = "alloc")]
panic!(
"char index {} is out of bounds of `{}`",
self.start, &*slice
);
#[cfg(not(feature = "alloc"))]
panic!("char index {} is out of bounds", self.start);
}
}
}
unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeToInclusive<usize> {
type Output = StringBase<[char]>;
#[inline]
fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
if self.end == usize::MAX {
None
} else {
(..self.end + 1).get(slice)
}
}
#[inline]
fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
if self.end == usize::MAX {
None
} else {
(..self.end + 1).get_mut(slice)
}
}
#[inline]
unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
(..self.end + 1).get_unchecked(slice)
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
(..self.end + 1).get_unchecked_mut(slice)
}
#[inline]
fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
if self.end == usize::MAX {
str_index_overflow_fail();
}
(..self.end + 1).index(slice)
}
#[inline]
fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
if self.end == usize::MAX {
str_index_overflow_fail();
}
(..self.end + 1).index_mut(slice)
}
}
#[inline(never)]
#[cold]
#[track_caller]
fn str_index_overflow_fail() -> ! {
panic!("attempted to index str up to maximum usize");
}