generic_str/
slice_utf32_index.rs1use core::slice::SliceIndex;
2
3use crate::string_base::StringBase;
4
5unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeFull {
18 type Output = StringBase<[char]>;
19 #[inline]
20 fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
21 Some(slice)
22 }
23 #[inline]
24 fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
25 Some(slice)
26 }
27 #[inline]
28 unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
29 slice
30 }
31 #[inline]
32 unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
33 slice
34 }
35 #[inline]
36 fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
37 slice
38 }
39 #[inline]
40 fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
41 slice
42 }
43}
44
45unsafe impl SliceIndex<StringBase<[char]>> for core::ops::Range<usize> {
60 type Output = StringBase<[char]>;
61 #[inline]
62 fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
63 if self.start <= self.end && self.end <= slice.len() {
64 Some(unsafe { &*self.get_unchecked(slice) })
65 } else {
66 None
67 }
68 }
69 #[inline]
70 fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
71 if self.start <= self.end && self.end <= slice.len() {
72 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
75 } else {
76 None
77 }
78 }
79 #[inline]
80 unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
81 let slice = slice as *const [char];
82 let ptr = slice.as_ptr().add(self.start);
85 let len = self.end - self.start;
86 core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[char]>
87 }
88 #[inline]
89 unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
90 let slice = slice as *mut [char];
91 let ptr = slice.as_mut_ptr().add(self.start);
93 let len = self.end - self.start;
94 core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[char]>
95 }
96 #[inline]
97 fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
98 let end = self.end;
99 match self.get(slice) {
100 Some(s) => s,
101
102 #[cfg(feature = "alloc")]
103 None => panic!("char index {} is out of bounds of `{}`", end, &*slice),
104
105 #[cfg(not(feature = "alloc"))]
106 None => panic!("char index {} is out of bounds", end),
107 }
108 }
109 #[inline]
110 fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
111 if self.start <= self.end && self.end <= slice.len() {
112 unsafe { &mut *self.get_unchecked_mut(slice) }
115 } else {
116 #[cfg(feature = "alloc")]
117 panic!("char index {} is out of bounds of `{}`", self.end, &*slice);
118
119 #[cfg(not(feature = "alloc"))]
120 panic!("char index {} is out of bounds", self.end);
121 }
122 }
123}
124
125unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeTo<usize> {
140 type Output = StringBase<[char]>;
141 #[inline]
142 fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
143 if self.end <= slice.len() {
144 Some(unsafe { &*self.get_unchecked(slice) })
147 } else {
148 None
149 }
150 }
151 #[inline]
152 fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
153 if self.end <= slice.len() {
154 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
157 } else {
158 None
159 }
160 }
161 #[inline]
162 unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
163 let slice = slice as *const [char];
164 let ptr = slice.as_ptr();
165 core::ptr::slice_from_raw_parts(ptr, self.end) as *const StringBase<[char]>
166 }
167 #[inline]
168 unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
169 let slice = slice as *mut [char];
170 let ptr = slice.as_mut_ptr();
171 core::ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut StringBase<[char]>
172 }
173 #[inline]
174 fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
175 let end = self.end;
176 match self.get(slice) {
177 Some(s) => s,
178
179 #[cfg(feature = "alloc")]
180 None => panic!("char index {} is out of bounds of `{}`", end, &*slice),
181
182 #[cfg(not(feature = "alloc"))]
183 None => panic!("char index {} is out of bounds", end),
184 }
185 }
186 #[inline]
187 fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
188 if self.end <= slice.len() {
189 unsafe { &mut *self.get_unchecked_mut(slice) }
192 } else {
193 #[cfg(feature = "alloc")]
194 panic!("char index {} is out of bounds of `{}`", self.end, &*slice);
195
196 #[cfg(not(feature = "alloc"))]
197 panic!("char index {} is out of bounds", self.end);
198 }
199 }
200}
201
202unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeFrom<usize> {
218 type Output = StringBase<[char]>;
219 #[inline]
220 fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
221 if self.start <= slice.len() {
222 Some(unsafe { &*self.get_unchecked(slice) })
225 } else {
226 None
227 }
228 }
229 #[inline]
230 fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
231 if self.start <= slice.len() {
232 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
235 } else {
236 None
237 }
238 }
239 #[inline]
240 unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
241 let slice = slice as *const [char];
242 let ptr = slice.as_ptr().add(self.start);
245 let len = slice.len() - self.start;
246 core::ptr::slice_from_raw_parts(ptr, len) as *const StringBase<[char]>
247 }
248 #[inline]
249 unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
250 let slice = slice as *mut [char];
251 let ptr = slice.as_mut_ptr().add(self.start);
253 let len = slice.len() - self.start;
254 core::ptr::slice_from_raw_parts_mut(ptr, len) as *mut StringBase<[char]>
255 }
256 #[inline]
257 fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
258 let start = self.start;
259 match self.get(slice) {
260 Some(s) => s,
261
262 #[cfg(feature = "alloc")]
263 None => panic!("char index {} is out of bounds of `{}`", start, &*slice),
264
265 #[cfg(not(feature = "alloc"))]
266 None => panic!("char index {} is out of bounds", start),
267 }
268 }
269 #[inline]
270 fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
271 if self.start <= slice.len() {
272 unsafe { &mut *self.get_unchecked_mut(slice) }
275 } else {
276 #[cfg(feature = "alloc")]
277 panic!(
278 "char index {} is out of bounds of `{}`",
279 self.start, &*slice
280 );
281
282 #[cfg(not(feature = "alloc"))]
283 panic!("char index {} is out of bounds", self.start);
284 }
285 }
286}
287
288unsafe impl SliceIndex<StringBase<[char]>> for core::ops::RangeToInclusive<usize> {
303 type Output = StringBase<[char]>;
304 #[inline]
305 fn get(self, slice: &StringBase<[char]>) -> Option<&Self::Output> {
306 if self.end == usize::MAX {
307 None
308 } else {
309 (..self.end + 1).get(slice)
310 }
311 }
312 #[inline]
313 fn get_mut(self, slice: &mut StringBase<[char]>) -> Option<&mut Self::Output> {
314 if self.end == usize::MAX {
315 None
316 } else {
317 (..self.end + 1).get_mut(slice)
318 }
319 }
320 #[inline]
321 unsafe fn get_unchecked(self, slice: *const StringBase<[char]>) -> *const Self::Output {
322 (..self.end + 1).get_unchecked(slice)
324 }
325 #[inline]
326 unsafe fn get_unchecked_mut(self, slice: *mut StringBase<[char]>) -> *mut Self::Output {
327 (..self.end + 1).get_unchecked_mut(slice)
329 }
330 #[inline]
331 fn index(self, slice: &StringBase<[char]>) -> &Self::Output {
332 if self.end == usize::MAX {
333 str_index_overflow_fail();
334 }
335 (..self.end + 1).index(slice)
336 }
337 #[inline]
338 fn index_mut(self, slice: &mut StringBase<[char]>) -> &mut Self::Output {
339 if self.end == usize::MAX {
340 str_index_overflow_fail();
341 }
342 (..self.end + 1).index_mut(slice)
343 }
344}
345
346#[inline(never)]
347#[cold]
348#[track_caller]
349fn str_index_overflow_fail() -> ! {
350 panic!("attempted to index str up to maximum usize");
351}