offset_vec/
offset.rs

1use alloc::{boxed::Box, rc::Rc, string::String, sync::Arc, vec::Vec};
2
3mod check;
4
5pub use check::*;
6
7use crate::{VecLike, OffsetVec};
8
9#[track_caller]
10pub fn create<V: VecLike>(vec: V, offset: usize) -> OffsetVec<V> {
11    OffsetVec { vec, offset }.offset_check()
12}
13
14pub trait Offset {
15    type Output: VecLike;
16    type OutputMut: VecLike;
17
18    fn offset(self, i: usize) -> OffsetVec<Self::Output>;
19
20    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut>;
21}
22
23impl<'a, V: Offset + VecLike> Offset for &'a mut V {
24    type Output = &'a mut V::OutputMut;
25    type OutputMut = V::OutputMut;
26
27    #[track_caller]
28    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
29        (*self).offset_mut(i).offset_check()
30    }
31
32    #[track_caller]
33    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
34        (**self).offset_mut(i).offset_check()
35    }
36}
37
38impl<V: Offset<Output = V> + VecLike> Offset for Box<V> {
39    type Output = Self;
40    type OutputMut = V::OutputMut;
41
42    #[track_caller]
43    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
44        create(self, i)
45    }
46
47    #[track_caller]
48    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
49        (**self).offset_mut(i).offset_check()
50    }
51}
52
53impl<V: Offset<Output = V> + VecLike + Clone> Offset for Rc<V> {
54    type Output = Self;
55    type OutputMut = V::OutputMut;
56
57    #[track_caller]
58    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
59        create(self, i)
60    }
61
62    #[track_caller]
63    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
64        Self::make_mut(self).offset_mut(i).offset_check()
65    }
66}
67
68impl<V: Offset<Output = V> + VecLike + Clone> Offset for Arc<V> {
69    type Output = Self;
70    type OutputMut = V::OutputMut;
71
72    #[track_caller]
73    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
74        create(self, i)
75    }
76
77    #[track_caller]
78    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
79        Self::make_mut(self).offset_mut(i).offset_check()
80    }
81}
82
83
84impl<V: Offset + VecLike> Offset for OffsetVec<V> {
85    type Output = V::Output;
86    type OutputMut = V::OutputMut;
87
88    #[track_caller]
89    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
90        self.vec.offset(self.offset+i).offset_check()
91    }
92
93    #[track_caller]
94    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
95        self.vec.offset_mut(self.offset+i).offset_check()
96    }
97}
98
99impl<T> Offset for Vec<T> {
100    type Output = Vec<T>;
101    type OutputMut = Vec<T>;
102
103    #[track_caller]
104    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
105        create(self, i)
106    }
107
108    #[track_caller]
109    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
110        create(self, i)
111    }
112}
113
114impl Offset for String {
115    type Output = String;
116    type OutputMut = String;
117
118    #[track_caller]
119    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
120        let _ = &self[i..];
121        create(self, i)
122    }
123
124    #[track_caller]
125    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
126        let _ = &self[i..];
127        create(self, i)
128    }
129}
130
131#[cfg(feature = "smallvec")]
132#[cfg_attr(docsrs, doc(cfg(feature = "smallvec")))]
133impl<A: smallvec::Array> Offset for smallvec::SmallVec<A> {
134    type Output = Self;
135    type OutputMut = Self;
136
137    #[track_caller]
138    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
139        create(self, i)
140    }
141
142    #[track_caller]
143    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
144        create(self, i)
145    }
146}
147
148#[cfg(feature = "smallstr")]
149#[cfg_attr(docsrs, doc(cfg(feature = "smallstr")))]
150impl<A: smallvec::Array<Item = u8>> Offset for smallstr::SmallString<A> {
151    type Output = Self;
152    type OutputMut = Self;
153
154    #[track_caller]
155    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
156        let _ = &self[i..];
157        create(self, i)
158    }
159
160    #[track_caller]
161    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
162        let _ = &self[i..];
163        create(self, i)
164    }
165}
166
167#[cfg(feature = "rc-vec")]
168#[cfg_attr(docsrs, doc(cfg(feature = "rc-vec")))]
169impl<T> Offset for rc_vec::RcVec<T> {
170    type Output = Self;
171    type OutputMut = Self;
172
173    #[track_caller]
174    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
175        create(self, i)
176    }
177
178    #[track_caller]
179    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
180        create(self, i)
181    }
182}
183
184#[cfg(feature = "rc-vec")]
185#[cfg_attr(docsrs, doc(cfg(feature = "rc-vec")))]
186impl<T> Offset for rc_vec::ArcVec<T> {
187    type Output = Self;
188    type OutputMut = Self;
189
190    #[track_caller]
191    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
192        create(self, i)
193    }
194
195    #[track_caller]
196    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::Output> {
197        create(self, i)
198    }
199}
200
201#[cfg(feature = "unique-rc")]
202#[cfg_attr(docsrs, doc(cfg(feature = "unique-rc")))]
203impl<V: Offset<Output = V> + VecLike> Offset for unique_rc::UniqRc<V> {
204    type Output = Self;
205    type OutputMut = V::OutputMut;
206
207    #[track_caller]
208    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
209        create(self, i)
210    }
211
212    #[track_caller]
213    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
214        (**self).offset_mut(i).offset_check()
215    }
216}
217
218#[cfg(feature = "unique-rc")]
219#[cfg_attr(docsrs, doc(cfg(feature = "unique-rc")))]
220impl<V: Offset<Output = V> + VecLike> Offset for unique_rc::UniqArc<V> {
221    type Output = Self;
222    type OutputMut = V::OutputMut;
223
224    #[track_caller]
225    fn offset(self, i: usize) -> OffsetVec<Self::Output> {
226        create(self, i)
227    }
228
229    #[track_caller]
230    fn offset_mut(&mut self, i: usize) -> OffsetVec<&mut Self::OutputMut> {
231        (**self).offset_mut(i).offset_check()
232    }
233}
234
235#[cfg(test)]
236mod tests {
237    use super::*;
238    use alloc::vec;
239
240    #[test]
241    fn multiple_offset() {
242        let (vec, [o1, o2, o4]);
243        vec = vec![1, 2, 3, 4];
244        o1 = vec.offset(1);
245        assert_eq!(o1.offset, 1);
246        o2 = o1.offset(1);
247        assert_eq!(o2.offset, 2);
248        o4 = o2.offset(2);
249        assert_eq!(o4.offset, 4);
250    }
251
252    #[test]
253    fn multiple_offset_mut() {
254        let (mut vec, [mut o1, mut o2, o4]);
255
256        vec = vec![1, 2, 3, 4];
257        o1 = vec.offset_mut(1);
258        assert_eq!(o1.offset, 1);
259        o2 = o1.offset_mut(1);
260        assert_eq!(o2.offset, 2);
261        o4 = o2.offset_mut(2);
262        assert_eq!(o4.offset, 4);
263    }
264
265    #[test]
266    #[should_panic = "5 out of length (is 4)"]
267    fn checked_offset() {
268        let vec = vec![1, 2, 3, 4];
269        _ = vec.offset(5);
270    }
271
272    #[test]
273    #[should_panic = "5 out of length (is 4)"]
274    fn checked_multiple_offset() {
275        let vec = vec![1, 2, 3, 4];
276        _ = vec.offset(2).offset(3);
277    }
278
279    #[test]
280    #[should_panic = "5 out of length (is 4)"]
281    fn checked_offset_mut() {
282        let mut vec = vec![1, 2, 3, 4];
283        _ = vec.offset_mut(5);
284    }
285
286
287    #[test]
288    #[should_panic = "5 out of length (is 4)"]
289    fn checked_multiple_offset_mut() {
290        let mut vec = vec![1, 2, 3, 4];
291        _ = vec.offset_mut(2).offset_mut(3);
292    }
293}