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}