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 *<[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 *<[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 *<[T]>::get_unchecked_mut(self, index) = value;
85 }
86}
87
88#[derive(Clone)]
90pub struct SequenceSubrange<'a, T: Copy, Inner: RandomAccessSequence<T>> {
91 inner: &'a Inner,
92 offset: usize,
93 len: usize,
94 _marker: std::marker::PhantomData<T>,
95}
96
97impl<'a, T: Copy, Inner: RandomAccessSequence<T>> SequenceSubrange<'a, T, Inner> {
98 #[inline(always)]
99 pub fn new(inner: &'a Inner, offset: usize, len: usize) -> Self {
100 assert!(offset + len <= inner.len(), "subrange out of bounds");
101
102 Self {
103 inner,
104 offset,
105 len,
106 _marker: std::marker::PhantomData,
107 }
108 }
109}
110
111impl<T: Copy, Inner: RandomAccessSequence<T>> RandomAccessSequence<T>
112 for SequenceSubrange<'_, T, Inner>
113{
114 #[inline(always)]
115 fn len(&self) -> usize {
116 self.len
117 }
118
119 #[inline(always)]
120 unsafe fn get_unchecked(&self, index: usize) -> T {
121 self.inner.get_unchecked(index + self.offset)
122 }
123}
124
125pub struct SequenceSubrangeMut<'a, T: Copy, Inner: RandomAccessSequenceMut<T>> {
127 inner: &'a mut Inner,
128 offset: usize,
129 len: usize,
130 _marker: std::marker::PhantomData<&'a T>,
131}
132
133impl<'a, T: Copy, Inner: RandomAccessSequenceMut<T>> SequenceSubrangeMut<'a, T, Inner> {
134 #[inline(always)]
135 pub fn new(inner: &'a mut Inner, offset: usize, len: usize) -> Self {
136 assert!(offset + len <= inner.len(), "subrange out of bounds");
137
138 Self {
139 inner,
140 offset,
141 len,
142 _marker: std::marker::PhantomData,
143 }
144 }
145}
146impl<T: Copy, Inner: RandomAccessSequenceMut<T>> RandomAccessSequence<T>
147 for SequenceSubrangeMut<'_, T, Inner>
148{
149 #[inline(always)]
150 fn len(&self) -> usize {
151 self.len
152 }
153
154 #[inline(always)]
155 unsafe fn get_unchecked(&self, index: usize) -> T {
156 self.inner.get_unchecked(index + self.offset)
157 }
158}
159impl<T: Copy, Inner: RandomAccessSequenceMut<T>> RandomAccessSequenceMut<T>
160 for SequenceSubrangeMut<'_, T, Inner>
161{
162 #[inline(always)]
163 unsafe fn set_unchecked(&mut self, index: usize, value: T) {
164 self.inner.set_unchecked(index + self.offset, value);
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use std::fmt::Debug;
171
172 use rand::{rngs::StdRng, Rng, SeedableRng};
173
174 use super::*;
175
176 fn check_collection<T: Copy + Eq + Debug>(
177 collection: &impl RandomAccessSequence<T>,
178 expected: &[T],
179 ) {
180 assert_eq!(collection.len(), expected.len());
181
182 for (i, v) in expected.iter().enumerate() {
183 assert_eq!(&collection.get(i), v);
184 assert_eq!(&unsafe { collection.get_unchecked(i) }, v);
185 }
186 }
187
188 fn check_collection_get_set<T: Eq + Copy + Debug>(
189 collection: &mut impl RandomAccessSequenceMut<T>,
190 gen: &mut impl FnMut() -> T,
191 ) {
192 for i in 0..collection.len() {
193 let value = gen();
194 collection.set(i, value);
195 assert_eq!(collection.get(i), value);
196 assert_eq!(unsafe { collection.get_unchecked(i) }, value);
197 }
198 }
199
200 #[test]
201 fn check_slice() {
202 let slice: &[usize] = &[];
203 check_collection::<usize>(&slice, slice);
204
205 let slice: &[usize] = &[1usize, 2, 3];
206 check_collection(&slice, slice);
207 }
208
209 #[test]
210 fn check_slice_mut() {
211 let mut rng = StdRng::seed_from_u64(0);
212 let mut gen = || -> usize { rng.gen() };
213
214 let mut slice: &mut [usize] = &mut [];
215
216 check_collection(&slice, slice);
217 check_collection_get_set(&mut slice, &mut gen);
218
219 let mut slice: &mut [usize] = &mut [1, 2, 3];
220 check_collection(&slice, slice);
221 check_collection_get_set(&mut slice, &mut gen);
222 }
223
224 #[test]
225 fn test_subrange() {
226 let slice: &[usize] = &[1, 2, 3, 4, 5];
227 let subrange = SequenceSubrange::new(&slice, 1, 3);
228 check_collection(&subrange, &[2, 3, 4]);
229 }
230
231 #[test]
232 fn test_subrange_mut() {
233 let mut rng = StdRng::seed_from_u64(0);
234 let mut gen = || -> usize { rng.gen() };
235
236 let mut slice: &mut [usize] = &mut [1, 2, 3, 4, 5];
237 let values = slice[1..4].to_vec();
238 let mut subrange = SequenceSubrangeMut::new(&mut slice, 1, 3);
239 check_collection(&subrange, &values);
240 check_collection_get_set(&mut subrange, &mut gen);
241 }
242}