1#![no_std]
26
27#[macro_use]
28extern crate dont_panic;
29
30pub struct DPSlice<T>([T]);
31
32impl<T> DPSlice<T> {
33 pub fn as_rust_slice(this: &Self) -> &[T] {
34 unsafe { ::core::mem::transmute(this) }
35 }
36
37 pub fn as_rust_slice_mut(this: &mut Self) -> &mut [T] {
38 unsafe { ::core::mem::transmute(this) }
39 }
40
41 pub fn len(&self) -> usize {
42 Self::as_rust_slice(self).len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 Self::as_rust_slice(self).is_empty()
47 }
48
49 pub fn first(&self) -> Option<&T> {
50 Self::as_rust_slice(self).first()
51 }
52
53 pub fn first_mut(&mut self) -> Option<&mut T> {
54 Self::as_rust_slice_mut(self).first_mut()
55 }
56
57 pub fn split_first(&self) -> Option<(&T, &[T])> {
58 Self::as_rust_slice(self).split_first()
59 }
60
61 pub fn split_first_mut(&self) -> Option<(&T, &[T])> {
62 Self::as_rust_slice(self).split_first()
63 }
64
65 pub fn split_last(&self) -> Option<(&T, &[T])> {
66 Self::as_rust_slice(self).split_last()
67 }
68
69 pub fn split_last_mut(&mut self) -> Option<(&T, &[T])> {
70 Self::as_rust_slice_mut(self).split_last()
71 }
72
73 pub fn swap(&mut self, a: usize, b: usize) {
74 if a > self.len() {
75 dont_panic!("index out of bounds: the len is {} but the index is {}", self.len(), a);
76 }
77
78 if b > self.len() {
79 dont_panic!("index out of bounds: the len is {} but the index is {}", self.len(), b);
80 }
81
82 Self::as_rust_slice_mut(self).swap(a, b);
83 }
84
85 pub fn windows(&self, size: usize) -> ::core::slice::Windows<T> {
86 dp_assert!(size != 0);
87
88 Self::as_rust_slice(self).windows(size)
89 }
90
91 pub fn chunks(&self, size: usize) -> ::core::slice::Chunks<T> {
92 dp_assert!(size != 0);
93
94 Self::as_rust_slice(self).chunks(size)
95 }
96
97 pub fn chunks_mut(&mut self, size: usize) -> ::core::slice::ChunksMut<T> {
98 dp_assert!(size != 0);
99
100 Self::as_rust_slice_mut(self).chunks_mut(size)
101 }
102
103 pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
104 if mid > self.len() {
105 dont_panic!("index {} out of range for slice of length {}", mid, self.len());
106 }
107
108 Self::as_rust_slice(self).split_at(mid)
109 }
110
111 pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
112 if mid > self.len() {
113 dont_panic!("index {} out of range for slice of length {}", mid, self.len());
114 }
115
116 Self::as_rust_slice_mut(self).split_at_mut(mid)
117 }
118}
119
120impl<'a, T> From<&'a [T]> for &'a DPSlice<T> {
121 fn from(slice: &[T]) -> Self {
122 unsafe { ::core::mem::transmute(slice) }
123 }
124}
125
126impl<'a, T> From<&'a mut [T]> for &'a mut DPSlice<T> {
135 fn from(slice: &mut [T]) -> Self {
136 unsafe { ::core::mem::transmute(slice) }
137 }
138}
139
140impl<T> ::core::ops::Index<usize> for DPSlice<T> {
149 type Output = T;
150
151 #[inline(always)]
152 fn index(&self, index: usize) -> &Self::Output {
153 Self::as_rust_slice(self).get(index).unwrap_or_else(|| dont_panic!("index out of bounds: the len is {} but the index is {}", self.len(), index))
154 }
155}
156
157impl<T> ::core::ops::IndexMut<usize> for DPSlice<T> {
158 #[inline(always)]
159 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
160 Self::as_rust_slice_mut(self).get_mut(index).unwrap_or_else(|| dont_panic!("index out of bounds: the len is {} but the index is {}", self.len(), index))
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use ::DPSlice;
167
168 #[test]
169 fn it_works() {
170 let arr = [0, 1, 2, 3];
171 let dps = <&DPSlice<_>>::from(&arr as &[_]);
172 assert_eq!(dps[0], 0);
173 assert_eq!(dps[3], 3);
174 }
175
176 #[cfg(feature = "panic")]
177 #[test]
178 #[should_panic]
179 fn panic() {
180 let arr = [0, 1, 2, 3];
181 let dps = <&DPSlice<_>>::from(&arr as &[_]);
182 assert_eq!(dps[42], 0);
183 assert_eq!(dps[3], 3);
184 }
185
186 #[cfg(feature = "panic")]
187 #[test]
188 fn no_panic() {
189 let arr = [0, 1, 2, 3];
190 let dps = <&DPSlice<_>>::from(&arr as &[_]);
191 assert_eq!(dps[0], 0);
192 assert_eq!(dps[3], 3);
193 }
194}