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}