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