offset_vec/
lib.rs

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/// Packer for [`Vec`] and [`String`] etc
30///
31/// For all methods index add a `offset`
32///
33/// Create from [`Offset::offset`] or [`create`]
34///
35/// # Examples
36///
37/// ```
38/// use offset_vec::Offset;
39///
40/// let mut vec = vec![0, 1, 2, 3, 4];
41/// let mut vec1 = vec.offset_mut(2);
42///
43/// assert_eq!(vec1, [2, 3, 4]);
44/// assert_eq!(vec1[1], 3);
45///
46/// vec1[1] += 2;
47/// assert_eq!(vec, [0, 1, 2, 5, 4]);
48/// ```
49#[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}