1pub trait RandomAccessSequence<T: Copy> {
7 fn len(&self) -> usize;
8
9 #[inline(always)]
10 fn is_empty(&self) -> bool {
11 self.len() == 0
12 }
13
14 #[inline(always)]
15 fn get(&self, index: usize) -> T {
16 assert!(index < self.len(), "Index out of bounds");
17 unsafe { self.get_unchecked(index) }
18 }
19
20 unsafe fn get_unchecked(&self, index: usize) -> T;
25}
26
27pub trait RandomAccessSequenceMut<T: Copy>: RandomAccessSequence<T> {
29 #[inline(always)]
30 fn set(&mut self, index: usize, value: T) {
31 assert!(index < self.len(), "Index out of bounds");
32 unsafe { self.set_unchecked(index, value) }
33 }
34
35 unsafe fn set_unchecked(&mut self, index: usize, value: T);
40}
41
42impl<T: Copy> RandomAccessSequence<T> for &[T] {
43 #[inline(always)]
44 fn len(&self) -> usize {
45 <[T]>::len(self)
46 }
47
48 #[inline(always)]
49 fn get(&self, index: usize) -> T {
50 self[index]
51 }
52
53 #[inline(always)]
54 unsafe fn get_unchecked(&self, index: usize) -> T {
55 unsafe { *<[T]>::get_unchecked(self, index) }
56 }
57}
58
59impl<T: Copy> RandomAccessSequence<T> for &mut [T] {
60 #[inline(always)]
61 fn len(&self) -> usize {
62 <[T]>::len(self)
63 }
64
65 #[inline(always)]
66 fn get(&self, index: usize) -> T {
67 self[index]
68 }
69
70 #[inline(always)]
71 unsafe fn get_unchecked(&self, index: usize) -> T {
72 unsafe { *<[T]>::get_unchecked(self, index) }
73 }
74}
75
76impl<T: Copy> RandomAccessSequenceMut<T> for &mut [T] {
77 #[inline(always)]
78 fn set(&mut self, index: usize, value: T) {
79 self[index] = value;
80 }
81
82 #[inline(always)]
83 unsafe fn set_unchecked(&mut self, index: usize, value: T) {
84 unsafe {
85 *<[T]>::get_unchecked_mut(self, index) = value;
86 }
87 }
88}
89
90#[derive(Clone)]
92pub struct SequenceSubrange<'a, T: Copy, Inner: RandomAccessSequence<T>> {
93 inner: &'a Inner,
94 offset: usize,
95 len: usize,
96 _marker: std::marker::PhantomData<T>,
97}
98
99impl<'a, T: Copy, Inner: RandomAccessSequence<T>> SequenceSubrange<'a, T, Inner> {
100 #[inline(always)]
101 pub fn new(inner: &'a Inner, offset: usize, len: usize) -> Self {
102 assert!(offset + len <= inner.len(), "subrange out of bounds");
103
104 Self {
105 inner,
106 offset,
107 len,
108 _marker: std::marker::PhantomData,
109 }
110 }
111}
112
113impl<T: Copy, Inner: RandomAccessSequence<T>> RandomAccessSequence<T>
114 for SequenceSubrange<'_, T, Inner>
115{
116 #[inline(always)]
117 fn len(&self) -> usize {
118 self.len
119 }
120
121 #[inline(always)]
122 unsafe fn get_unchecked(&self, index: usize) -> T {
123 unsafe { self.inner.get_unchecked(index + self.offset) }
124 }
125}
126
127pub struct SequenceSubrangeMut<'a, T: Copy, Inner: RandomAccessSequenceMut<T>> {
129 inner: &'a mut Inner,
130 offset: usize,
131 len: usize,
132 _marker: std::marker::PhantomData<&'a T>,
133}
134
135impl<'a, T: Copy, Inner: RandomAccessSequenceMut<T>> SequenceSubrangeMut<'a, T, Inner> {
136 #[inline(always)]
137 pub fn new(inner: &'a mut Inner, offset: usize, len: usize) -> Self {
138 assert!(offset + len <= inner.len(), "subrange out of bounds");
139
140 Self {
141 inner,
142 offset,
143 len,
144 _marker: std::marker::PhantomData,
145 }
146 }
147}
148impl<T: Copy, Inner: RandomAccessSequenceMut<T>> RandomAccessSequence<T>
149 for SequenceSubrangeMut<'_, T, Inner>
150{
151 #[inline(always)]
152 fn len(&self) -> usize {
153 self.len
154 }
155
156 #[inline(always)]
157 unsafe fn get_unchecked(&self, index: usize) -> T {
158 unsafe { self.inner.get_unchecked(index + self.offset) }
159 }
160}
161impl<T: Copy, Inner: RandomAccessSequenceMut<T>> RandomAccessSequenceMut<T>
162 for SequenceSubrangeMut<'_, T, Inner>
163{
164 #[inline(always)]
165 unsafe fn set_unchecked(&mut self, index: usize, value: T) {
166 unsafe {
167 self.inner.set_unchecked(index + self.offset, value);
168 }
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use std::fmt::Debug;
175
176 use rand::{Rng, SeedableRng, rngs::StdRng};
177
178 use super::*;
179
180 fn check_collection<T: Copy + Eq + Debug>(
181 collection: &impl RandomAccessSequence<T>,
182 expected: &[T],
183 ) {
184 assert_eq!(collection.len(), expected.len());
185
186 for (i, v) in expected.iter().enumerate() {
187 assert_eq!(&collection.get(i), v);
188 assert_eq!(&unsafe { collection.get_unchecked(i) }, v);
189 }
190 }
191
192 fn check_collection_get_set<T: Eq + Copy + Debug>(
193 collection: &mut impl RandomAccessSequenceMut<T>,
194 r#gen: &mut impl FnMut() -> T,
195 ) {
196 for i in 0..collection.len() {
197 let value = r#gen();
198 collection.set(i, value);
199 assert_eq!(collection.get(i), value);
200 assert_eq!(unsafe { collection.get_unchecked(i) }, value);
201 }
202 }
203
204 #[test]
205 fn check_slice() {
206 let slice: &[usize] = &[];
207 check_collection::<usize>(&slice, slice);
208
209 let slice: &[usize] = &[1usize, 2, 3];
210 check_collection(&slice, slice);
211 }
212
213 #[test]
214 fn check_slice_mut() {
215 let mut rng = StdRng::seed_from_u64(0);
216 let mut r#gen = || -> usize { rng.r#gen() };
217
218 let mut slice: &mut [usize] = &mut [];
219
220 check_collection(&slice, slice);
221 check_collection_get_set(&mut slice, &mut r#gen);
222
223 let mut slice: &mut [usize] = &mut [1, 2, 3];
224 check_collection(&slice, slice);
225 check_collection_get_set(&mut slice, &mut r#gen);
226 }
227
228 #[test]
229 fn test_subrange() {
230 let slice: &[usize] = &[1, 2, 3, 4, 5];
231 let subrange = SequenceSubrange::new(&slice, 1, 3);
232 check_collection(&subrange, &[2, 3, 4]);
233 }
234
235 #[test]
236 fn test_subrange_mut() {
237 let mut rng = StdRng::seed_from_u64(0);
238 let mut r#gen = || -> usize { rng.r#gen() };
239
240 let mut slice: &mut [usize] = &mut [1, 2, 3, 4, 5];
241 let values = slice[1..4].to_vec();
242 let mut subrange = SequenceSubrangeMut::new(&mut slice, 1, 3);
243 check_collection(&subrange, &values);
244 check_collection_get_set(&mut subrange, &mut r#gen);
245 }
246}