unchecked_index/
slice_impls.rs

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
6use std::ops::{Range, RangeTo, RangeFrom, RangeFull};
7
8use super::CheckIndex;
9
10type Output<T, I> = <[T] as ::std::ops::Index<I>>::Output;
11
12macro_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
52impl_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
59impl_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
68impl_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
74impl_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
80impl_for_slice!(rangefull, RangeFull, self, _index, { });