1 2 //! This is a rather strange-looking workaround. The intention 3 //! is to keep GetUnchecked/Mut out of scope, so that we can use the 4 //! libcore SliceExt::get_unchecked/_mut methods. 5 6 use std::ops::{Range, RangeTo, RangeFrom, RangeFull}; 7 8 use super::CheckIndex; 9 10 type Output<T, I> = <[T] as ::std::ops::Index<I>>::Output; 11 12 macro_rules! impl_for_slice { 13 ($name:ident, $index_type:ty, $self_:ident, $index: ident, $assertion:expr) => { 14 15 mod $name { 16 use super::Output; 17 #[allow(unused)] 18 use std::ops::{Range, RangeTo, RangeFrom, RangeFull}; 19 20 #[inline] 21 pub unsafe fn get<T>(s: &[T], index: $index_type) -> &Output<T, $index_type> { 22 s.get_unchecked(index) 23 } 24 25 #[inline] 26 pub unsafe fn getm<T>(s: &mut [T], index: $index_type) -> &mut Output<T, $index_type> { 27 s.get_unchecked_mut(index) 28 } 29 } 30 31 impl<T> CheckIndex<$index_type> for [T] { 32 fn assert_indexable_with($self_: &Self, $index: &$index_type) { 33 $assertion 34 } 35 } 36 37 impl<T> super::GetUnchecked<$index_type> for [T] { 38 type Output = Output<T, $index_type>; 39 unsafe fn get_unchecked(&self, index: $index_type) -> &Self::Output { 40 $name::get(self, index) 41 } 42 } 43 44 impl<T> super::GetUncheckedMut<$index_type> for [T] { 45 unsafe fn get_unchecked_mut(&mut self, index: $index_type) -> &mut Self::Output { 46 $name::getm(self, index) 47 } 48 } 49 } 50 } 51 52 impl_for_slice!(index, usize, self, index, { 53 assert!(*index < self.len(), 54 "assertion index < len failed: index out of bounds: \ 55 index = {}, len = {}", 56 index, self.len()) 57 }); 58 59 impl_for_slice!(range, Range<usize>, self, index, { 60 assert!(index.start <= index.end, 61 "assertion start <= end failed: start = {}, end = {}, len = {}", 62 index.start, index.end, self.len()); 63 assert!(index.end <= self.len(), 64 "assertion end <= len failed: end = {}, len = {}", 65 index.end, self.len()); 66 }); 67 68 impl_for_slice!(rangeto, RangeTo<usize>, self, index, { 69 assert!(index.end <= self.len(), 70 "assertion end <= len failed: end = {}, len = {}", 71 index.end, self.len()); 72 }); 73 74 impl_for_slice!(rangefrom,RangeFrom<usize>, self, index, { 75 assert!(index.start <= self.len(), 76 "assertion start <= len failed: start = {}, len = {}", 77 index.start, self.len()); 78 }); 79 80 impl_for_slice!(rangefull, RangeFull, self, _index, { }); 81