core_extensions/slices/extensions.rs
1//! Extension trait for \[T\] and [str].
2//!
3//!
4//!
5
6// use ranges::RangeBounds;
7use super::{BiasDirection, SliceBias,SplitSliceWhile,RSplitSliceWhile};
8
9use std_::borrow::Borrow;
10use std_::cmp;
11use std_::mem;
12use std_::ops::Range;
13
14
15/// Extension trait for `[T]`.
16pub trait ValSliceExt: SliceExt + Borrow<[<Self as SliceExt>::Elem]> {
17 /// Returns an iterator over subslices whose elements were mapped
18 /// to the same value by `mapper`.
19 ///
20 /// The returned type implements
21 /// `DoubleEndedIterator<Item =`[`KeySlice`](./struct.KeySlice.html)`<Self::Elem, U>>`.
22 ///
23 /// # Example
24 ///
25 /// ```
26 /// use core_extensions::ValSliceExt;
27 /// use core_extensions::slices::KeySlice;
28 ///
29 /// {
30 /// let list = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
31 ///
32 /// assert_eq!(
33 /// list.split_while(|x| x/4).collect::<Vec<_>>(),
34 /// vec![
35 /// KeySlice{key: 0, slice: &[0, 1, 2, 3]},
36 /// KeySlice{key: 1, slice: &[4, 5, 6, 7]},
37 /// KeySlice{key: 2, slice: &[8]},
38 /// ]
39 /// );
40 /// }
41 ///
42 /// {
43 /// let list = [0, 4, 1, 5, 9, 8, 7];
44 ///
45 /// assert_eq!(
46 /// list.split_while(|x| x%4).collect::<Vec<_>>(),
47 /// vec![
48 /// KeySlice{key: 0, slice: &[0, 4]},
49 /// KeySlice{key: 1, slice: &[1, 5, 9]},
50 /// KeySlice{key: 0, slice: &[8]},
51 /// KeySlice{key: 3, slice: &[7]},
52 /// ]
53 /// );
54 /// }
55 ///
56 ///
57 /// ```
58 ///
59 fn split_while<'a, P, U>(&'a self, mut mapper: P) -> SplitSliceWhile<'a, Self::Elem, P, U>
60 where
61 P: FnMut(&'a Self::Elem) -> U,
62 U: Eq + Clone,
63 {
64 let this:&'a [Self::Elem] = self.borrow();
65 SplitSliceWhile {
66 last_left: this.first().map(&mut mapper),
67 last_right: this.last().map(&mut mapper),
68 mapper,
69 s: this,
70 }
71 }
72
73 /// A variation of [`split_while`](#method.split_while) that iterates
74 /// from the right(the order of subslices is reversed).
75 ///
76 /// The returned type implements
77 /// `DoubleEndedIterator<Item =`[`KeySlice`](./struct.KeySlice.html)`<Self::Elem, U>>`.
78 ///
79 /// # Example
80 ///
81 /// ```
82 /// use core_extensions::ValSliceExt;
83 /// use core_extensions::slices::KeySlice;
84 ///
85 /// {
86 /// let list = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
87 ///
88 /// assert_eq!(
89 /// list.rsplit_while(|x| x/4 ).collect::<Vec<_>>(),
90 /// vec![
91 /// KeySlice{key: 2, slice: &[8]},
92 /// KeySlice{key: 1, slice: &[4, 5, 6, 7]},
93 /// KeySlice{key: 0, slice: &[0, 1, 2, 3]},
94 /// ]
95 /// );
96 /// }
97 ///
98 /// {
99 /// let list = [0, 4, 1, 5, 9, 8, 7];
100 ///
101 /// assert_eq!(
102 /// list.rsplit_while(|x| x%4 ).collect::<Vec<_>>(),
103 /// vec![
104 /// KeySlice{key: 3, slice: &[7]},
105 /// KeySlice{key: 0, slice: &[8]},
106 /// KeySlice{key: 1, slice: &[1, 5, 9]},
107 /// KeySlice{key: 0, slice: &[0, 4]},
108 /// ]
109 /// );
110 /// }
111 ///
112 ///
113 ///
114 /// ```
115 ///
116 fn rsplit_while<'a, P, U>(&'a self, mut mapper: P) -> RSplitSliceWhile<'a, Self::Elem, P, U>
117 where
118 P: FnMut(&'a Self::Elem) -> U,
119 U: Eq + Clone,
120 {
121 let this: &'a [Self::Elem] = self.borrow();
122 RSplitSliceWhile {
123 last_left: this.first().map(&mut mapper),
124 last_right: this.last().map(&mut mapper),
125 mapper,
126 s: this,
127 }
128 }
129}
130
131impl<This> ValSliceExt for This
132where
133 This: ?Sized + SliceExt,
134 This: Borrow<[Self::Elem]>,
135{}
136
137
138
139/// Extension trait for `[T]` and `str`.
140pub trait SliceExt {
141 /// The type of a slice element.
142 type Elem;
143
144 /// Checks whether self fully contains the `other` slice in memory.
145 ///
146 /// If `other` is a zero-length slice it is not contained inside `self`.
147 ///
148 /// # Example
149 ///
150 /// ### Called on slices
151 ///
152 /// ```
153 /// use core_extensions::SliceExt;
154 ///
155 /// let list = vec![0, 1, 2, 3, 4, 5];
156 ///
157 /// let another = [6, 7, 8];
158 ///
159 /// assert!(list.contains_slice(&list[..1]));
160 /// assert!(list.contains_slice(&list[3..]));
161 ///
162 /// // Empty slices aren't considered contained by any other slice
163 /// assert!(!list.contains_slice(&list[..0]));
164 /// assert!(!list.contains_slice(&another[..0]));
165 ///
166 /// assert!(!list.contains_slice(&another));
167 ///
168 /// ```
169 ///
170 /// ### Called on `str`s
171 ///
172 /// ```
173 /// use core_extensions::SliceExt;
174 ///
175 /// let string = "foo bar baz";
176 ///
177 /// let another = String::from(string);
178 ///
179 /// let foo = &string[..3];
180 /// let bar = &string[4..7];
181 /// let baz = &string[8..11];
182 ///
183 /// assert!(string.contains_slice(foo));
184 /// assert!(string.contains_slice(bar));
185 /// assert!(string.contains_slice(baz));
186 ///
187 /// // Empty slices aren't considered contained by any other slice
188 /// assert!(!string.contains_slice(&string[..0]));
189 ///
190 /// assert!(!string.contains_slice(&another));
191 ///
192 /// ```
193 fn contains_slice(&self, other: &Self) -> bool;
194
195 /// Checks whether `self` is exactly the `other` slice in memory.
196 ///
197 /// # Example
198 ///
199 /// ### Called on slices
200 ///
201 /// ```
202 /// use core_extensions::SliceExt;
203 ///
204 /// let list = [0, 1, 2, 3, 4, 5];
205 /// let slice_0 = &list[..0];
206 /// let slice_1 = &list[..];
207 ///
208 /// let other = [0, 1, 2, 3, 4, 5];
209 ///
210 /// assert!( slice_0.is_slice(slice_0));
211 /// assert!( slice_0.is_slice(&list[..0]));
212 /// assert!(!slice_0.is_slice(slice_1));
213 /// assert!(!slice_0.is_slice(&[]));
214 ///
215 /// assert!(!list.is_slice(&other));
216 ///
217 /// ```
218 ///
219 /// ### Called on `str`s
220 ///
221 /// ```
222 /// use core_extensions::SliceExt;
223 ///
224 /// let string = "foo bar baz";
225 ///
226 /// let another = String::from(string);
227 ///
228 /// let foo = &string[..3];
229 /// let bar = &string[4..7];
230 /// let baz = &string[8..11];
231 ///
232 /// assert!(!string.is_slice(foo));
233 /// assert!(!string.is_slice(bar));
234 /// assert!(!string.is_slice(baz));
235 /// assert!(string.is_slice(string));
236 ///
237 /// assert!(string[..0].is_slice(&string[..0]));
238 ///
239 /// assert!(!string.is_slice(&another));
240 ///
241 /// ```
242 fn is_slice(&self, other: &Self) -> bool;
243
244 /// Returns the index at which `other` starts.
245 ///
246 /// If `other` is not inside `self`, this returns `self.len()`
247 ///
248 /// # Example
249 ///
250 /// ### Called on slices
251 ///
252 /// ```
253 /// use core_extensions::SliceExt;
254 ///
255 /// let list = vec![0, 1, 2, 3, 4, 5];
256 ///
257 /// let other = [0, 1, 2, 3];
258 ///
259 /// assert_eq!(list.offset_of_slice(&list[..0]), 0);
260 /// assert_eq!(list.offset_of_slice(&list[3..]), 3);
261 /// assert_eq!(list.offset_of_slice(&list[5..]), 5);
262 /// assert_eq!(list.offset_of_slice(&list[6..]), list.len());
263 /// assert_eq!(list.offset_of_slice(&[]), list.len());
264 ///
265 /// assert_eq!(list.offset_of_slice(&other), list.len());
266 ///
267 /// ```
268 ///
269 /// ### Called on `str`s
270 ///
271 /// ```
272 /// use core_extensions::SliceExt;
273 ///
274 /// let string = "foo bar baz";
275 ///
276 /// let another = String::from(string);
277 ///
278 /// let foo = &string[..3];
279 /// let bar = &string[4..7];
280 /// let baz = &string[8..11];
281 ///
282 /// assert_eq!(string.offset_of_slice(string), 0);
283 /// assert_eq!(string.offset_of_slice(&string[..0]), 0);
284 /// assert_eq!(string.offset_of_slice(foo), 0);
285 /// assert_eq!(string.offset_of_slice(bar), 4);
286 /// assert_eq!(string.offset_of_slice(baz), 8);
287 /// assert_eq!(string.offset_of_slice(&string[11..]), 11);
288 ///
289 /// assert_eq!(string.offset_of_slice(&another), string.len());
290 ///
291 /// ```
292 fn offset_of_slice(&self, other: &Self) -> usize;
293
294 /// Returns the index at which `other` starts.
295 ///
296 /// If `other` is a zero-length slice, or is not inside `self`, this returns `None`.
297 ///
298 /// # Example
299 ///
300 /// ### Called on slices
301 ///
302 /// ```
303 /// use core_extensions::SliceExt;
304 ///
305 /// let list = [0, 1, 2, 3, 4, 5];
306 ///
307 /// let other = [0, 1, 2, 3];
308 ///
309 /// assert_eq!(list.get_offset_of_slice(&list[..0]), None);
310 /// assert_eq!(list.get_offset_of_slice(&list[1..]), Some(1));
311 /// assert_eq!(list.get_offset_of_slice(&list[3..]), Some(3));
312 /// assert_eq!(list.get_offset_of_slice(&list[5..]), Some(5));
313 /// assert_eq!(list.get_offset_of_slice(&list[6..]), None);
314 ///
315 /// assert_eq!(list.get_offset_of_slice(&other), None);
316 ///
317 /// ```
318 ///
319 /// ### Called on `str`s
320 ///
321 /// ```
322 /// use core_extensions::SliceExt;
323 ///
324 /// let string = "foo bar baz";
325 ///
326 /// let another = String::from(string);
327 ///
328 /// let foo = &string[..3];
329 /// let bar = &string[4..7];
330 /// let baz = &string[8..11];
331 ///
332 /// assert_eq!(string.get_offset_of_slice(&string[..0]), None);
333 /// assert_eq!(string.get_offset_of_slice(string), Some(0));
334 /// assert_eq!(string.get_offset_of_slice(foo), Some(0));
335 /// assert_eq!(string.get_offset_of_slice(bar), Some(4));
336 /// assert_eq!(string.get_offset_of_slice(baz), Some(8));
337 /// assert_eq!(string.get_offset_of_slice(&string[11..]), None);
338 ///
339 /// assert_eq!(string.get_offset_of_slice(&another), None);
340 ///
341 /// ```
342 fn get_offset_of_slice(&self, other: &Self) -> Option<usize>;
343
344 /// Returns the index of `other` if it's stored in the slice (if it points within the slice).
345 ///
346 /// If `other` is not inside `self`, this returns `self.len()`.
347 ///
348 /// # Example
349 ///
350 /// ### Called on slices
351 ///
352 /// ```
353 /// use core_extensions::SliceExt;
354 ///
355 /// let list = vec![0, 1, 2, 3, 4, 5];
356 ///
357 /// let other = [0, 1, 2, 3];
358 ///
359 /// assert_eq!(list.index_of(&list[0]), 0);
360 /// assert_eq!(list.index_of(&list[3]), 3);
361 /// assert_eq!(list.index_of(&list[5]), 5);
362 /// assert_eq!(list.index_of(list.as_ptr().wrapping_offset(6)), 6);
363 /// assert_eq!(list.index_of(list.as_ptr().wrapping_offset(7)), 6);
364 /// assert_eq!(list.index_of(&0), list.len());
365 ///
366 /// assert_eq!(list.index_of(&other[0]), list.len());
367 /// assert_eq!(list.index_of(&other[1]), list.len());
368 ///
369 /// ```
370 ///
371 /// ### Called on `str`s
372 ///
373 /// ```
374 /// use core_extensions::SliceExt;
375 ///
376 /// let string = String::from("abcdefgh");
377 /// let bytes = string.as_bytes();
378 ///
379 /// let other = b"abcdefgh";
380 ///
381 /// assert_eq!(string.index_of(&bytes[0]), 0);
382 /// assert_eq!(string.index_of(&bytes[3]), 3);
383 /// assert_eq!(string.index_of(&bytes[5]), 5);
384 /// assert_eq!(string.index_of(bytes.as_ptr().wrapping_offset(6)), 6);
385 /// assert_eq!(string.index_of(bytes.as_ptr().wrapping_offset(7)), 7);
386 /// assert_eq!(string.index_of(&0), string.len());
387 ///
388 /// assert_eq!(string.index_of(&other[0]), string.len());
389 /// assert_eq!(string.index_of(&other[1]), string.len());
390 /// ```
391 fn index_of(&self, other: *const Self::Elem) -> usize;
392
393 /// Returns the index of `other` if it's stored in the slice (if it points within the slice).
394 ///
395 /// If `other` is not inside `self`, this returns `None`.
396 ///
397 /// # Example
398 ///
399 /// ### Called on slices
400 ///
401 /// ```
402 /// use core_extensions::SliceExt;
403 ///
404 /// let list = vec![0, 1, 2, 3, 4, 5];
405 ///
406 /// let other = [0, 1, 2, 3];
407 ///
408 /// assert_eq!(list.get_index_of(&list[0]), Some(0));
409 /// assert_eq!(list.get_index_of(&list[3]), Some(3));
410 /// assert_eq!(list.get_index_of(&list[5]), Some(5));
411 /// assert_eq!(list.get_index_of(list.as_ptr().wrapping_offset(6)), None);
412 /// assert_eq!(list.get_index_of(list.as_ptr().wrapping_offset(7)), None);
413 /// assert_eq!(list.get_index_of(&0), None);
414 ///
415 /// assert_eq!(list.get_index_of(&other[0]), None);
416 /// assert_eq!(list.get_index_of(&other[1]), None);
417 ///
418 /// ```
419 ///
420 /// ### Called on `str`s
421 ///
422 /// ```
423 /// use core_extensions::SliceExt;
424 ///
425 /// let string = String::from("abcdefgh");
426 /// let bytes = string.as_bytes();
427 ///
428 /// let other = b"abcdefgh";
429 ///
430 /// assert_eq!(string.get_index_of(&bytes[0]), Some(0));
431 /// assert_eq!(string.get_index_of(&bytes[3]), Some(3));
432 /// assert_eq!(string.get_index_of(&bytes[5]), Some(5));
433 /// assert_eq!(string.get_index_of(bytes.as_ptr().wrapping_offset(6)), Some(6));
434 /// assert_eq!(string.get_index_of(bytes.as_ptr().wrapping_offset(7)), Some(7));
435 /// assert_eq!(string.get_index_of(&0), None);
436 ///
437 /// assert_eq!(string.get_index_of(&other[0]), None);
438 /// assert_eq!(string.get_index_of(&other[1]), None);
439 /// ```
440 fn get_index_of(&self, other: *const Self::Elem) -> Option<usize>;
441
442 /// Used for non-panicking slicing.
443 ///
444 /// If `range.end` is less than `range.start`, this returns an empty slice.
445 ///
446 /// # `bias` parameter
447 ///
448 /// The `bias` parameter, by being converted into a [`SliceBias`],
449 /// determines how this method handles invalid ranges.
450 ///
451 /// The impl for `[T]` ignores this parameter, saturating ranges at `self.len()`.
452 ///
453 /// For `str`, it grows the range in the directions determined by `bias` parameter.
454 ///
455 /// # Examples
456 ///
457 /// ### `[T]` slice
458 ///
459 /// ```
460 /// use core_extensions::SliceExt;
461 ///
462 /// let arr = [1, 2, 3, 4, 5, 6];
463 /// assert_eq!(arr.slice_lossy(0..3, ()), &arr[..3]);
464 /// assert_eq!(arr.slice_lossy(3..1000, ()), &arr[3..]);
465 /// assert_eq!(arr.slice_lossy(1000..1000, ()), &[]);
466 /// assert_eq!(arr.slice_lossy(1000..0, ()), &[]);
467 /// ```
468 ///
469 /// ### `str` slice
470 ///
471 /// ```
472 /// use core_extensions::SliceExt;
473 /// use core_extensions::slices::SliceBias;
474 ///
475 /// let word = "niño"; // 'ñ' is 2 bytes long , spanning the range 2..4
476 ///
477 /// assert_eq!(word.slice_lossy(0..3, SliceBias::LEFT ), "ni");
478 /// assert_eq!(word.slice_lossy(0..3, SliceBias::RIGHT), "niñ");
479 /// assert_eq!(word.slice_lossy(0..3, SliceBias::IN ), "ni");
480 /// assert_eq!(word.slice_lossy(0..3, SliceBias::OUT), "niñ");
481 ///
482 /// assert_eq!(word.slice_lossy(3..10000, ()), "ño");
483 /// assert_eq!(word.slice_lossy(3..10000, SliceBias::OUT), "ño");
484 ///
485 /// assert_eq!(word.slice_lossy(1000..1000, ()), "");
486 /// assert_eq!(word.slice_lossy(1000..1000, SliceBias::OUT), "");
487 /// assert_eq!(word.slice_lossy(1000..0, SliceBias::OUT), "");
488 /// ```
489 ///
490 /// [`SliceBias`]: struct.SliceBias.html
491 ///
492 fn slice_lossy<SB>(&self, range: Range<usize>, bias: SB) -> &Self
493 where
494 SB: Into<SliceBias>;
495
496 /// Used for non-panicking mutable slicing.
497 ///
498 /// Identical behavior to [`slice_lossy`](#tymethod.slice_lossy) with respect to ranges.
499 fn slice_lossy_mut<SB>(&mut self, range: Range<usize>, bias: SB) -> &mut Self
500 where
501 SB: Into<SliceBias>;
502}
503
504macro_rules! impl_common_slice_extensions {($T:ident) => {
505 type Elem = $T;
506
507 fn contains_slice(&self,other:&Self)->bool{
508 if other.is_empty() {
509 return false;
510 } else if mem::size_of::<$T>() == 0 {
511 return self.as_ptr() == other.as_ptr() && self.len() >= other.len();
512 }
513
514 let start_self = self.as_ptr() as usize;
515 let end_self = start_self + self.len() * mem::size_of::<$T>();
516 let start_other = other.as_ptr() as usize;
517 let end_other = start_other + other.len() * mem::size_of::<$T>();
518 start_self <= start_other && end_other <= end_self
519 }
520
521 fn is_slice(&self,other:&Self)->bool{
522 self.as_ptr() as usize == other.as_ptr() as usize &&
523 self.len() == other.len()
524 }
525
526 fn offset_of_slice(&self,other:&Self)->usize{
527 if mem::size_of::<$T>() == 0 {
528 return if self.as_ptr() == other.as_ptr() {
529 0
530 } else {
531 self.len()
532 }
533 }
534 let offset = (other.as_ptr() as usize).wrapping_sub(self.as_ptr() as usize);
535 cmp::min(self.len(),offset / mem::size_of::<$T>())
536 }
537
538 fn get_offset_of_slice(&self,other:&Self)->Option<usize>{
539 if mem::size_of::<$T>() == 0 {
540 if self.as_ptr() == other.as_ptr() {
541 Some(0)
542 } else {
543 None
544 }
545 } else if self.contains_slice(other) {
546 Some((other.as_ptr() as usize - self.as_ptr() as usize)/mem::size_of::<$T>())
547 }else{
548 None
549 }
550 }
551
552 fn index_of(&self,other:*const $T)->usize{
553 if mem::size_of::<$T>() == 0 {
554 return if self.as_ptr() == other {
555 0
556 } else {
557 self.len()
558 };
559 }
560 let offset = (other as *const $T as usize).wrapping_sub(self.as_ptr() as usize);
561 cmp::min(self.len(), offset / mem::size_of::<$T>())
562 }
563
564 fn get_index_of(&self,other:*const $T)->Option<usize>{
565 if mem::size_of::<$T>() == 0 {
566 return if self.as_ptr() == other {
567 Some(0)
568 } else {
569 None
570 };
571 }
572
573 let sub = (other as *const $T as usize)
574 .wrapping_sub(self.as_ptr() as usize)
575 /mem::size_of::<$T>();
576
577 if sub >= self.len() {
578 None
579 } else {
580 Some(sub)
581 }
582 }
583
584}}
585
586mod str_impls {
587 use super::*;
588
589 fn lossy_str_range(this: &str, mut range: Range<usize>, bias: SliceBias) -> Range<usize> {
590 #[inline]
591 fn bias_bound(this: &str, mut index: usize, bias: BiasDirection) -> usize {
592 if index > this.len() {
593 return this.len();
594 }
595
596 match bias {
597 BiasDirection::Left => {
598 while !this.is_char_boundary(index) {
599 index -= 1;
600 }
601 },
602 BiasDirection::Right => {
603 while !this.is_char_boundary(index) {
604 index += 1;
605 }
606 },
607 };
608
609 index
610 }
611 range.start = bias_bound(this, range.start, bias.start);
612 range.end = bias_bound(this, range.end, bias.end);
613 range.end = cmp::max(range.start, range.end);
614 range
615 }
616 impl SliceExt for str {
617 impl_common_slice_extensions! {u8}
618
619 fn slice_lossy<SB>(&self, range: Range<usize>, bias: SB) -> &Self
620 where
621 SB: Into<SliceBias>,
622 {
623 &self[lossy_str_range(self, range, bias.into())]
624 }
625
626 fn slice_lossy_mut<SB>(&mut self, range: Range<usize>, bias: SB) -> &mut Self
627 where
628 SB: Into<SliceBias>,
629 {
630 let r = lossy_str_range(self, range, bias.into());
631 &mut self[r]
632 }
633 }
634}
635
636mod slice_impls {
637 use super::*;
638
639 fn lossy_range<T>(this: &[T], mut range: Range<usize>) -> Range<usize> {
640 let len = this.len();
641 range.end = cmp::min(range.end, len);
642 range.start = cmp::min(range.start, range.end);
643 range
644 }
645
646 impl<T> SliceExt for [T] {
647 impl_common_slice_extensions! {T}
648
649 fn slice_lossy<SB>(&self, range: Range<usize>, _bias: SB) -> &Self {
650 &self[lossy_range(self, range)]
651 }
652
653 fn slice_lossy_mut<SB>(&mut self, range: Range<usize>, _bias: SB) -> &mut Self {
654 let r = lossy_range(self, range);
655 &mut self[r]
656 }
657 }
658}
659
660#[cfg(test)]
661mod tests {
662 use super::*;
663
664 #[cfg(feature = "alloc")]
665 use alloc::{
666 vec::Vec,
667 string::String,
668 };
669
670 struct Unpromoted<T> {
671 inner: T,
672 _dummy: std_::cell::Cell<u32>,
673 }
674 fn Unpromoted<T>(inner: T) -> Unpromoted<T> {
675 Unpromoted {
676 inner,
677 _dummy: std_::cell::Cell::new(10),
678 }
679 }
680 impl<T> std_::ops::Deref for Unpromoted<T> {
681 type Target = T;
682 fn deref(&self) -> &T {
683 &self.inner
684 }
685 }
686
687 #[test]
688 fn contains_slice() {
689 fn inner<T>(list: &[T; 12]){
690 let slice_a = &list[0..4];
691 let slice_b = &list[4..8];
692 let slice_c = &list[8..12];
693
694 assert_eq!(slice_b.contains_slice(&slice_a[3..]), false);
695 assert_eq!(slice_b.contains_slice(&slice_a[4..]), false);
696
697 assert_eq!(slice_b.contains_slice(&slice_b[0..]), true);
698 assert_eq!(slice_b.contains_slice(&slice_b[1..]), true);
699 assert_eq!(slice_b.contains_slice(&slice_b[2..]), true);
700 assert_eq!(slice_b.contains_slice(&slice_b[3..]), true);
701
702 assert_eq!(slice_b.contains_slice(&slice_c[0..0]), false);
703 assert_eq!(slice_b.contains_slice(&slice_c[0..]), false);
704 assert_eq!(slice_b.contains_slice(&slice_c[1..]), false);
705 }
706
707 inner(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
708 inner(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
709 inner(&[""; 12]);
710
711 {
712 let list = [(); 12];
713 let slice_a = &list[0..4];
714 let slice_b = &list[4..8];
715 let slice_c = &list[8..12];
716
717 let other = Unpromoted([(); 12]);
718
719 assert_eq!(slice_b.contains_slice(&slice_a[3..]), true);
720 assert_eq!(slice_b.contains_slice(&slice_a[4..]), false);
721
722 assert_eq!(slice_b.contains_slice(&slice_b[0..]), true);
723 assert_eq!(slice_b.contains_slice(&slice_b[1..]), true);
724 assert_eq!(slice_b.contains_slice(&slice_b[2..]), true);
725 assert_eq!(slice_b.contains_slice(&slice_b[3..]), true);
726
727 assert_eq!(slice_b.contains_slice(&slice_c[0..]), true);
728 assert_eq!(slice_b.contains_slice(&slice_c[1..]), true);
729
730 assert_eq!(list.contains_slice(&*other), false);
731 assert_eq!(slice_a.contains_slice(&*other), false);
732 assert_eq!(slice_b.contains_slice(&*other), false);
733 assert_eq!(slice_c.contains_slice(&*other), false);
734
735 assert_eq!(other.contains_slice(&list), false);
736 assert_eq!(other.contains_slice(&slice_a), false);
737 assert_eq!(other.contains_slice(&slice_b), false);
738 assert_eq!(other.contains_slice(&slice_c), false);
739 }
740 }
741 #[test]
742 fn offset_of_slice() {
743 fn inner<T>(list: &[T; 12]){
744 let slice_a = &list[0..4];
745 let slice_b = &list[4..8];
746 let slice_c = &list[8..12];
747
748 assert_eq!(slice_b.offset_of_slice(&slice_a[3..]), slice_b.len());
749
750 assert_eq!(slice_b.offset_of_slice(&slice_b[0..]), 0);
751 assert_eq!(slice_b.offset_of_slice(&slice_b[1..]), 1);
752 assert_eq!(slice_b.offset_of_slice(&slice_b[2..]), 2);
753 assert_eq!(slice_b.offset_of_slice(&slice_b[3..]), 3);
754
755 assert_eq!(slice_b.offset_of_slice(&slice_c[0..]), slice_b.len());
756 assert_eq!(slice_b.offset_of_slice(&slice_c[1..]), slice_b.len());
757 }
758
759 inner(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
760 inner(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
761 inner(&[""; 12]);
762
763 {
764 let list = [(); 12];
765 let slice_a = &list[0..4];
766 let slice_b = &list[4..8];
767 let slice_c = &list[8..12];
768
769 let other = Unpromoted([(); 12]);
770
771 assert_eq!(slice_b.offset_of_slice(&slice_a[3..]), 0);
772
773 assert_eq!(slice_b.offset_of_slice(&slice_b[0..]), 0);
774 assert_eq!(slice_b.offset_of_slice(&slice_b[1..]), 0);
775 assert_eq!(slice_b.offset_of_slice(&slice_b[2..]), 0);
776 assert_eq!(slice_b.offset_of_slice(&slice_b[3..]), 0);
777
778 assert_eq!(slice_b.offset_of_slice(&slice_c[0..]), 0);
779 assert_eq!(slice_b.offset_of_slice(&slice_c[1..]), 0);
780
781 assert_eq!(list.offset_of_slice(&*other), 12);
782 assert_eq!(slice_a.offset_of_slice(&*other), 4);
783 assert_eq!(slice_b.offset_of_slice(&*other), 4);
784 assert_eq!(slice_c.offset_of_slice(&*other), 4);
785
786 assert_eq!(other.offset_of_slice(&list), 12);
787 assert_eq!(other.offset_of_slice(&slice_a), 12);
788 assert_eq!(other.offset_of_slice(&slice_b), 12);
789 assert_eq!(other.offset_of_slice(&slice_c), 12);
790 }
791 }
792 #[test]
793 fn get_offset_of_slice() {
794 fn inner<T>(list: &[T; 12]){
795 let slice_a = &list[0..4];
796 let slice_b = &list[4..8];
797 let slice_c = &list[8..12];
798
799 assert_eq!(slice_b.get_offset_of_slice(&slice_a[3..]), None);
800
801 assert_eq!(slice_b.get_offset_of_slice(&slice_b[1..1]), None);
802 assert_eq!(slice_b.get_offset_of_slice(&slice_b[0..]), Some(0));
803 assert_eq!(slice_b.get_offset_of_slice(&slice_b[1..]), Some(1));
804 assert_eq!(slice_b.get_offset_of_slice(&slice_b[2..]), Some(2));
805 assert_eq!(slice_b.get_offset_of_slice(&slice_b[3..]), Some(3));
806
807 assert_eq!(slice_b.get_offset_of_slice(&slice_c[0..]), None);
808 assert_eq!(slice_b.get_offset_of_slice(&slice_c[1..]), None);
809 }
810
811 inner(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
812 inner(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
813 inner(&[""; 12]);
814
815 {
816 let list = [(); 12];
817 let slice_a = &list[0..4];
818 let slice_b = &list[4..8];
819 let slice_c = &list[8..12];
820
821 let other = Unpromoted([(); 12]);
822
823 assert_eq!(slice_b.get_offset_of_slice(&slice_a[3..]), Some(0));
824
825 assert_eq!(slice_b.get_offset_of_slice(&slice_b[0..]), Some(0));
826 assert_eq!(slice_b.get_offset_of_slice(&slice_b[1..]), Some(0));
827 assert_eq!(slice_b.get_offset_of_slice(&slice_b[2..]), Some(0));
828 assert_eq!(slice_b.get_offset_of_slice(&slice_b[3..]), Some(0));
829
830 assert_eq!(slice_b.get_offset_of_slice(&slice_c[0..]), Some(0));
831 assert_eq!(slice_b.get_offset_of_slice(&slice_c[1..]), Some(0));
832
833 assert_eq!(list.get_offset_of_slice(&*other), None);
834 assert_eq!(slice_a.get_offset_of_slice(&*other), None);
835 assert_eq!(slice_b.get_offset_of_slice(&*other), None);
836 assert_eq!(slice_c.get_offset_of_slice(&*other), None);
837
838 assert_eq!(other.get_offset_of_slice(&list), None);
839 assert_eq!(other.get_offset_of_slice(&slice_a), None);
840 assert_eq!(other.get_offset_of_slice(&slice_b), None);
841 assert_eq!(other.get_offset_of_slice(&slice_c), None);
842 }
843 }
844 #[test]
845 fn index_of() {
846 fn inner<T>(list: &[T; 12]){
847 let slice_a = &list[0..4];
848 let slice_b = &list[4..8];
849 let slice_c = &list[8..12];
850
851 assert_eq!(slice_b.index_of(&slice_a[3]), slice_b.len());
852
853 assert_eq!(slice_b.index_of(&slice_b[0]), 0);
854 assert_eq!(slice_b.index_of(&slice_b[1]), 1);
855 assert_eq!(slice_b.index_of(&slice_b[2]), 2);
856 assert_eq!(slice_b.index_of(&slice_b[3]), 3);
857
858 assert_eq!(slice_b.index_of(&slice_c[0]), slice_b.len());
859 assert_eq!(slice_b.index_of(&slice_c[1]), slice_b.len());
860 }
861
862 inner(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
863 inner(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
864 inner(&[""; 12]);
865
866 {
867 let list = [(); 12];
868 let slice_a = &list[0..4];
869 let slice_b = &list[4..8];
870 let slice_c = &list[8..12];
871
872 let other = Unpromoted([(); 12]);
873
874 assert_eq!(slice_b.index_of(&slice_a[3]), 0);
875
876 assert_eq!(slice_b.index_of(&slice_b[0]), 0);
877 assert_eq!(slice_b.index_of(&slice_b[1]), 0);
878 assert_eq!(slice_b.index_of(&slice_b[2]), 0);
879 assert_eq!(slice_b.index_of(&slice_b[3]), 0);
880
881 assert_eq!(slice_b.index_of(&slice_c[0]), 0);
882 assert_eq!(slice_b.index_of(&slice_c[1]), 0);
883
884 assert_eq!(list.index_of(&other[0]), 12);
885 assert_eq!(slice_a.index_of(&other[0]), 4);
886 assert_eq!(slice_b.index_of(&other[0]), 4);
887 assert_eq!(slice_c.index_of(&other[0]), 4);
888
889 assert_eq!(other.index_of(&list[0]), 12);
890 assert_eq!(other.index_of(&slice_a[0]), 12);
891 assert_eq!(other.index_of(&slice_b[0]), 12);
892 assert_eq!(other.index_of(&slice_c[0]), 12);
893 }
894 }
895 #[test]
896 fn get_index_of() {
897 fn inner<T>(list: &[T; 12]){
898 let slice_a = &list[0..4];
899 let slice_b = &list[4..8];
900 let slice_c = &list[8..12];
901
902 assert_eq!(slice_b.get_index_of(&slice_a[3]), None);
903
904 assert_eq!(slice_b.get_index_of(&slice_b[0]), Some(0));
905 assert_eq!(slice_b.get_index_of(&slice_b[1]), Some(1));
906 assert_eq!(slice_b.get_index_of(&slice_b[2]), Some(2));
907 assert_eq!(slice_b.get_index_of(&slice_b[3]), Some(3));
908
909 assert_eq!(slice_b.get_index_of(&slice_c[0]), None);
910 assert_eq!(slice_b.get_index_of(&slice_c[1]), None);
911 }
912
913 inner(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
914 inner(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
915 inner(&[""; 12]);
916
917 {
918 let list = [(); 12];
919 let slice_a = &list[0..4];
920 let slice_b = &list[4..8];
921 let slice_c = &list[8..12];
922
923 let other = Unpromoted([(); 12]);
924
925 assert_eq!(slice_b.get_index_of(&slice_a[3]), Some(0));
926
927 assert_eq!(slice_b.get_index_of(&slice_b[0]), Some(0));
928 assert_eq!(slice_b.get_index_of(&slice_b[1]), Some(0));
929 assert_eq!(slice_b.get_index_of(&slice_b[2]), Some(0));
930 assert_eq!(slice_b.get_index_of(&slice_b[3]), Some(0));
931
932 assert_eq!(slice_b.get_index_of(&slice_c[0]), Some(0));
933 assert_eq!(slice_b.get_index_of(&slice_c[1]), Some(0));
934
935 assert_eq!(list.get_index_of(&other[0]), None);
936 assert_eq!(slice_a.get_index_of(&other[0]), None);
937 assert_eq!(slice_b.get_index_of(&other[0]), None);
938 assert_eq!(slice_c.get_index_of(&other[0]), None);
939
940 assert_eq!(other.get_index_of(&list[0]), None);
941 assert_eq!(other.get_index_of(&slice_a[0]), None);
942 assert_eq!(other.get_index_of(&slice_b[0]), None);
943 assert_eq!(other.get_index_of(&slice_c[0]), None);
944 }
945 }
946 #[test]
947 #[cfg(feature = "alloc")]
948 fn slice_lossy_slice_examples() {
949 let list = vec![0, 1, 2, 3, 4, 5];
950 assert_eq!(list.slice_lossy(0..list.len(), ()), &list[..]);
951 assert_eq!(list.slice_lossy(0..1000, ()), &list[..]);
952 assert_eq!(list.slice_lossy(0..1000, ()), &list[..]);
953 assert_eq!(list.slice_lossy(10..10000, ()), &list[list.len()..]);
954 assert_eq!(list.slice_lossy(3..10000, ()), &list[3..]);
955 assert_eq!(list.slice_lossy(0..3, ()), &list[..3]);
956 assert_eq!(list.slice_lossy(0..2, ()), &list[..2]);
957 assert_eq!(list.slice_lossy(0..1, ()), &list[..1]);
958 assert_eq!(list.slice_lossy(0..0, ()), &list[..0]);
959 }
960 #[test]
961 fn slice_lossy_str_examples() {
962 let word = "niño";
963 assert_eq!(word.len(), 5);
964
965 assert!(word
966 .slice_lossy(0..word.len(), SliceBias::OUT)
967 .is_slice(&word[..]));
968 assert!(word
969 .slice_lossy(0..1000, SliceBias::OUT)
970 .is_slice(&word[..]));
971 assert!(word
972 .slice_lossy(0..1000, SliceBias::OUT)
973 .is_slice(&word[..]));
974 assert!(word
975 .slice_lossy(10..10000, SliceBias::OUT)
976 .is_slice(&word[word.len()..]));
977 assert!(word.slice_lossy(0..4, SliceBias::OUT).is_slice(&word[..4]));
978 assert!(word.slice_lossy(0..3, SliceBias::OUT).is_slice(&word[..4]));
979 assert!(word.slice_lossy(0..2, SliceBias::OUT).is_slice(&word[..2]));
980
981 assert!(word
982 .slice_lossy(10..10000, SliceBias::IN)
983 .is_slice(&word[word.len()..]));
984 assert!(word.slice_lossy(0..4, SliceBias::IN).is_slice(&word[0..4]));
985 assert!(word.slice_lossy(0..3, SliceBias::IN).is_slice(&word[0..2]));
986 assert!(word.slice_lossy(3..3, SliceBias::IN).is_slice(&word[4..4]));
987 assert!(word.slice_lossy(3..4, SliceBias::IN).is_slice(&word[4..4]));
988 assert!(word.slice_lossy(2..3, SliceBias::IN).is_slice(&word[2..2]));
989 assert!(word.slice_lossy(0..2, SliceBias::IN).is_slice(&word[0..2]));
990
991 assert!(word
992 .slice_lossy(10..10000, SliceBias::LEFT)
993 .is_slice(&word[word.len()..]));
994 assert!(word
995 .slice_lossy(0..4, SliceBias::LEFT)
996 .is_slice(&word[0..4]));
997 assert!(word
998 .slice_lossy(0..3, SliceBias::LEFT)
999 .is_slice(&word[0..2]));
1000 assert!(word
1001 .slice_lossy(3..3, SliceBias::LEFT)
1002 .is_slice(&word[2..2]));
1003 assert!(word
1004 .slice_lossy(3..4, SliceBias::LEFT)
1005 .is_slice(&word[2..4]));
1006 assert!(word
1007 .slice_lossy(2..3, SliceBias::LEFT)
1008 .is_slice(&word[2..2]));
1009 assert!(word
1010 .slice_lossy(0..2, SliceBias::LEFT)
1011 .is_slice(&word[0..2]));
1012
1013 assert!(word
1014 .slice_lossy(10..10000, SliceBias::RIGHT)
1015 .is_slice(&word[word.len()..]));
1016 assert!(word
1017 .slice_lossy(0..4, SliceBias::RIGHT)
1018 .is_slice(&word[0..4]));
1019 assert!(word
1020 .slice_lossy(0..3, SliceBias::RIGHT)
1021 .is_slice(&word[0..4]));
1022 assert!(word
1023 .slice_lossy(3..3, SliceBias::RIGHT)
1024 .is_slice(&word[4..4]));
1025 assert!(word
1026 .slice_lossy(3..4, SliceBias::RIGHT)
1027 .is_slice(&word[4..4]));
1028 assert!(word
1029 .slice_lossy(2..3, SliceBias::RIGHT)
1030 .is_slice(&word[2..4]));
1031 assert!(word
1032 .slice_lossy(0..2, SliceBias::RIGHT)
1033 .is_slice(&word[0..2]));
1034
1035 let sub_word = word.slice_lossy(3..10000, SliceBias::OUT);
1036 assert_eq!(sub_word, &word[2..]);
1037 assert_eq!(sub_word, "ño");
1038 }
1039
1040 #[test]
1041 #[cfg(feature = "alloc")]
1042 // Too slow to run in miri, and there's no unsafe code here.
1043 #[cfg(not(miri))]
1044 fn slice_lossy_slice_no_panic() {
1045 use rand::Rng;
1046
1047 let mut rng = ::rand::thread_rng();
1048 for _ in 0..50 {
1049 let slice_len = rng.gen_range(0, 100);
1050 let slice_ = rng.gen_iter::<usize>().take(slice_len).collect::<Vec<_>>();
1051 for _ in 0..500 {
1052 let start = if slice_len == 0 {
1053 0
1054 } else {
1055 rng.gen_range(0, slice_len * 2)
1056 };
1057 let end = if slice_len == 0 {
1058 0
1059 } else {
1060 rng.gen_range(0, slice_len * 2)
1061 };
1062 slice_.slice_lossy(start..end, rng.gen::<SliceBias>());
1063 }
1064 }
1065 }
1066
1067 #[test]
1068 #[cfg(feature = "alloc")]
1069 // Too slow to run in miri, and there's no unsafe code here.
1070 #[cfg(not(miri))]
1071 fn slice_lossy_str_no_panic() {
1072 use rand::Rng;
1073
1074 let mut rng = ::rand::thread_rng();
1075 for _ in 0..50 {
1076 let char_len = rng.gen_range(0, 100);
1077 let string = rng.gen_iter::<char>().take(char_len).collect::<String>();
1078 let slice_len = string.len();
1079 for _ in 0..500 {
1080 let start = if slice_len == 0 {
1081 0
1082 } else {
1083 rng.gen_range(0, slice_len * 2)
1084 };
1085 let end = if slice_len == 0 {
1086 0
1087 } else {
1088 rng.gen_range(0, slice_len * 2)
1089 };
1090 string.slice_lossy(start..end, rng.gen::<SliceBias>());
1091 }
1092 }
1093 }
1094}