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