1#![doc = include_str!("../README.md")]
2#![no_std]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5extern crate alloc;
6
7#[cfg(doc)]
8use alloc::{vec::Vec, string::String};
9
10use core::{
11 iter::once,
12 ops::{Bound, Deref, DerefMut, Index, IndexMut, Range, RangeBounds},
13 slice::SliceIndex,
14};
15
16mod util;
17mod slice;
18mod offset;
19mod vec_like;
20
21pub use slice::*;
22pub use offset::*;
23pub use vec_like::*;
24
25mod externs {
26 mod core_impls;
27}
28
29#[derive(Debug, Clone, Default)]
50pub struct OffsetVec<V: VecLike> {
51 vec: V,
52 offset: usize,
53}
54
55impl<V: VecLike> Deref for OffsetVec<V> {
56 type Target = V::Slice;
57
58 #[inline]
59 fn deref(&self) -> &Self::Target {
60 let offset = self.offset;
61 let slice = self.vec.as_slice();
62 &slice[offset..]
63 }
64}
65
66impl<V: VecLike> DerefMut for OffsetVec<V> {
67 #[inline]
68 fn deref_mut(&mut self) -> &mut Self::Target {
69 let offset = self.offset;
70 let slice_mut = self.vec.as_mut_slice();
71 &mut slice_mut[offset..]
72 }
73}
74
75impl<V, I> Index<I> for OffsetVec<V>
76where V: VecLike,
77 I: SliceIndex<V::Slice>,
78 V::Slice: Index<I>,
79{
80 type Output = <V::Slice as Index<I>>::Output;
81
82 #[track_caller]
83 fn index(&self, index: I) -> &Self::Output {
84 let slice = &**self;
85 &slice[index]
86 }
87}
88
89impl<V, I> IndexMut<I> for OffsetVec<V>
90where V: VecLike,
91 I: SliceIndex<V::Slice>,
92 V::Slice: IndexMut<I>,
93{
94 #[track_caller]
95 fn index_mut(&mut self, index: I) -> &mut Self::Output {
96 let slice = &mut **self;
97 &mut slice[index]
98 }
99}
100
101impl<V: VecLike> OffsetVec<V> {
102 #[inline]
103 pub fn origin_vec(&self) -> &V {
104 &self.vec
105 }
106
107 #[inline]
108 pub fn origin_vec_mut(&mut self) -> &mut V {
109 &mut self.vec
110 }
111
112 #[inline]
113 pub fn into_origin_vec(self) -> V {
114 self.vec
115 }
116
117 #[inline]
118 pub fn as_slice(&self) -> &V::Slice {
119 self
120 }
121
122 #[inline]
123 pub fn as_mut_slice(&mut self) -> &mut V::Slice {
124 self
125 }
126
127 pub fn iter<'a>(&'a self) -> <&'a V::Slice as IntoIterator>::IntoIter
128 where &'a V::Slice: IntoIterator
129 {
130 self.as_slice().into_iter()
131 }
132
133 pub fn iter_mut<'a>(&'a mut self) -> <&'a V::Slice as IntoIterator>::IntoIter
134 where &'a V::Slice: IntoIterator
135 {
136 self.as_mut_slice().into_iter()
137 }
138
139 #[inline]
140 pub fn is_empty(&self) -> bool {
141 self.len() == 0
142 }
143
144 #[inline]
145 pub fn len(&self) -> usize {
146 self.vec.len() - self.offset
147 }
148
149 #[inline]
150 pub fn capacity(&self) -> usize {
151 self.vec.capacity() - self.offset
152 }
153
154 pub fn reserve(&mut self, additional: usize) {
155 self.vec.reserve(additional);
156 }
157
158 pub fn reserve_exact(&mut self, additional: usize) {
159 self.vec.reserve_exact(additional);
160 }
161
162 pub fn shrink_to_fit(&mut self) {
163 self.vec.shrink_to_fit();
164 }
165
166 pub fn shrink_to(&mut self, min_capacity: usize) {
167 self.vec.shrink_to(min_capacity);
168 }
169
170
171 pub fn offset(&self) -> usize {
172 self.offset
173 }
174
175 pub fn push(&mut self, value: V::Elem) {
176 self.vec.push(value);
177 }
178
179 pub fn pop(&mut self) -> Option<V::Elem> {
180 if self.is_empty() {
181 return None;
182 }
183
184 self.vec.pop()
185 }
186
187 #[track_caller]
188 pub fn remove(&mut self, index: usize) -> V::Elem {
189 let len = self.len();
190 if index > len {
191 index_out_of_range(index, self.offset, len)
192 }
193 self.vec.remove(index + self.offset)
194 }
195
196 #[track_caller]
197 pub fn insert(&mut self, index: usize, elem: V::Elem) {
198 let len = self.len();
199 if index > len {
200 index_out_of_range(index, self.offset, len)
201 }
202 self.vec.insert(index + self.offset, elem)
203 }
204
205 pub fn truncate(&mut self, len: usize) {
206 self.vec.truncate(len + self.offset);
207 }
208
209 pub fn append(&mut self, other: &mut V::Collection) {
210 self.vec.append(other);
211 }
212
213 pub fn clear(&mut self) {
214 self.truncate(self.offset);
215 }
216
217 #[track_caller]
218 fn map_range<R: RangeBounds<usize>>(&self, range: R) -> Range<usize> {
219 let start = match range.start_bound() {
220 Bound::Included(&n) => n,
221 Bound::Excluded(&n) => n.checked_add(1).expect("start range overflow"),
222 Bound::Unbounded => 0,
223 };
224 let end = match range.end_bound() {
225 Bound::Included(&n) => n.checked_add(1).expect("end range overflow"),
226 Bound::Excluded(&n) => n,
227 Bound::Unbounded => self.len(),
228 };
229 if start > end {
230 #[cold]
231 #[track_caller]
232 #[inline(never)]
233 fn fail(index: usize, end: usize) -> ! {
234 panic!("range index starts at {index} but ends at {end}");
235 }
236 fail(start, end)
237 }
238 if end > self.len() {
239 #[cold]
240 #[track_caller]
241 #[inline(never)]
242 fn fail(index: usize, len: usize) -> ! {
243 panic!("range end index {index} out of range for slice of length {len}");
244 }
245 fail(end, self.len())
246 }
247 let offset = self.offset;
248 Range { start: start+offset, end: end+offset }
249 }
250
251 #[track_caller]
252 pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> V::Drain<'_> {
253 self.vec.drain(self.map_range(range))
254 }
255
256 #[track_caller]
257 #[must_use = "use `.truncate()` if you don't need the other half"]
258 pub fn split_off(&mut self, at: usize) -> V::Collection {
259 let len = self.len();
260 if at > len {
261 index_out_of_range(at, self.offset, len)
262 }
263 self.vec.split_off(at + self.offset)
264 }
265
266 pub fn resize(&mut self, new_len: usize, value: V::Elem)
267 where V::Elem: Clone,
268 {
269 self.vec.resize(new_len+self.offset, value);
270 }
271
272 pub fn resize_with<F>(&mut self, new_len: usize, f: F)
273 where F: FnMut() -> V::Elem,
274 {
275 self.vec.resize_with(new_len+self.offset, f);
276 }
277
278 pub fn retain<F>(&mut self, mut f: F)
279 where F: FnMut(V::ElemRef<'_>) -> bool,
280 {
281 let i = self.vec.as_slice().transform_index(self.offset);
282
283 let mut i = 0..i;
284 self.vec.retain(|elem| {
285 i.next().is_some() || f(elem)
286 });
287 }
288}
289
290impl<V: VecLikeSolid> OffsetVec<V> {
291 pub fn retain_mut<F: FnMut(&mut V::Elem) -> bool>(&mut self, mut f: F) {
292 let mut i = 0..self.offset;
293 self.vec.retain_mut(|elem| {
294 i.next().is_some() || f(elem)
295 });
296 }
297
298 #[track_caller]
299 pub fn swap_remove(&mut self, index: usize) -> V::Elem {
300 let len = self.len();
301 if index > len {
302 index_out_of_range(index, self.offset, len)
303 }
304 self.vec.swap_remove(index + self.offset)
305 }
306
307 pub fn pop_if<F>(&mut self, predicate: F) -> Option<V::Elem>
308 where F: FnOnce(&mut V::Elem) -> bool,
309 {
310 if self.is_empty() {
311 return None;
312 }
313
314 self.vec.pop_if(predicate)
315 }
316}
317
318impl<V: VecLike<Slice = str>> OffsetVec<V> {
319 #[inline]
320 pub fn as_str(&self) -> &str {
321 self
322 }
323
324 #[inline]
325 pub fn as_mut_str(&mut self) -> &mut str {
326 self
327 }
328
329 pub fn push_str<'a>(&mut self, s: &'a str)
330 where V::Collection: Extend<&'a str>,
331 {
332 self.vec.as_mut_collection().extend(once(s));
333 }
334}
335
336#[cold]
337#[track_caller]
338#[inline(never)]
339fn index_out_of_range(index: usize, offset: usize, len: usize) -> ! {
340 panic!("offset index ({index} -> {}) out of length (is {len} -> {})",
341 index+offset,
342 len+offset);
343}