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}