1use crate::ser::ScratchSpace;
2use core::{
3 alloc::Layout,
4 borrow::{Borrow, BorrowMut},
5 fmt,
6 mem::MaybeUninit,
7 ops,
8 ptr::NonNull,
9 slice,
10};
11
12pub struct ScratchVec<T> {
14 ptr: NonNull<T>,
15 cap: usize,
16 len: usize,
17}
18
19impl<T> Drop for ScratchVec<T> {
20 fn drop(&mut self) {
21 for i in 0..self.len {
22 unsafe {
23 core::ptr::drop_in_place(self.ptr.as_ptr().add(i));
24 }
25 }
26 }
27}
28
29unsafe impl<T: Send> Send for ScratchVec<T> {}
31
32unsafe impl<T: Sync> Sync for ScratchVec<T> {}
34
35impl<T> ScratchVec<T> {
36 #[inline]
46 pub unsafe fn new<S: ScratchSpace + ?Sized>(
47 scratch_space: &mut S,
48 capacity: usize,
49 ) -> Result<Self, S::Error> {
50 let layout = Layout::array::<T>(capacity).unwrap();
51 if layout.size() == 0 {
52 Ok(Self {
53 ptr: NonNull::dangling(),
54 cap: capacity,
55 len: 0,
56 })
57 } else {
58 let ptr = scratch_space.push_scratch(layout)?;
59 Ok(Self {
60 ptr: ptr.cast(),
61 cap: capacity,
62 len: 0,
63 })
64 }
65 }
66
67 #[inline]
78 pub unsafe fn free<S: ScratchSpace + ?Sized>(
79 self,
80 scratch_space: &mut S,
81 ) -> Result<(), S::Error> {
82 let layout = self.layout();
83 if layout.size() != 0 {
84 let ptr = self.ptr.cast();
85 core::mem::drop(self);
86 scratch_space.pop_scratch(ptr, layout)?;
87 }
88 Ok(())
89 }
90
91 #[inline]
92 fn layout(&self) -> Layout {
93 Layout::array::<T>(self.cap).unwrap()
94 }
95
96 #[inline]
100 pub fn clear(&mut self) {
101 self.len = 0;
102 }
103
104 #[inline]
109 pub fn as_mut_ptr(&mut self) -> *mut T {
110 self.ptr.as_ptr()
111 }
112
113 #[inline]
117 pub fn as_mut_slice(&mut self) -> &mut [T] {
118 unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
119 }
120
121 #[inline]
131 pub fn as_ptr(&self) -> *const T {
132 self.ptr.as_ptr()
133 }
134
135 #[inline]
139 pub fn as_slice(&self) -> &[T] {
140 unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
141 }
142
143 #[inline]
145 pub fn capacity(&self) -> usize {
146 self.cap
147 }
148
149 #[inline]
156 pub fn reserve(&mut self, additional: usize) {
157 if self.len + additional > self.cap {
158 panic!("reserve requested more capacity than the scratch vec has available");
159 }
160 }
161
162 #[inline]
164 pub fn is_empty(&self) -> bool {
165 self.len == 0
166 }
167
168 #[inline]
170 pub fn len(&self) -> usize {
171 self.len
172 }
173
174 #[inline]
178 pub fn extend_from_slice(&mut self, other: &[T]) {
179 if !other.is_empty() {
180 self.reserve(other.len());
181 unsafe {
182 core::ptr::copy_nonoverlapping(
183 other.as_ptr(),
184 self.as_mut_ptr().add(self.len()),
185 other.len(),
186 );
187 }
188 self.len += other.len();
189 }
190 }
191
192 #[inline]
194 pub fn pop(&mut self) -> Option<T> {
195 if self.len == 0 {
196 None
197 } else {
198 unsafe {
199 self.len -= 1;
200 Some(self.as_ptr().add(self.len()).read())
201 }
202 }
203 }
204
205 #[inline]
207 pub fn push(&mut self, value: T) {
208 unsafe {
209 self.reserve(1);
210 self.as_mut_ptr().add(self.len).write(value);
211 self.len += 1;
212 }
213 }
214
215 #[inline]
223 pub fn reserve_exact(&mut self, additional: usize) {
224 self.reserve(additional);
225 }
226
227 #[inline]
236 pub unsafe fn set_len(&mut self, new_len: usize) {
237 debug_assert!(new_len <= self.capacity());
238
239 self.len = new_len;
240 }
241
242 #[inline]
244 fn drain_range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
245 where
246 R: ops::RangeBounds<usize>,
247 {
248 let len = bounds.end;
249
250 let start: ops::Bound<&usize> = range.start_bound();
251 let start = match start {
252 ops::Bound::Included(&start) => start,
253 ops::Bound::Excluded(start) => start
254 .checked_add(1)
255 .unwrap_or_else(|| panic!("attempted to index slice from after maximum usize")),
256 ops::Bound::Unbounded => 0,
257 };
258
259 let end: ops::Bound<&usize> = range.end_bound();
260 let end = match end {
261 ops::Bound::Included(end) => end
262 .checked_add(1)
263 .unwrap_or_else(|| panic!("attempted to index slice up to maximum usize")),
264 ops::Bound::Excluded(&end) => end,
265 ops::Bound::Unbounded => len,
266 };
267
268 if start > end {
269 panic!("slice index starts at {} but ends at {}", start, end);
270 }
271 if end > len {
272 panic!(
273 "range start index {} out of range for slice of length {}",
274 end, len
275 );
276 }
277
278 ops::Range { start, end }
279 }
280
281 #[inline]
293 pub fn drain<R: ops::RangeBounds<usize>>(&mut self, range: R) -> Drain<'_, T> {
294 let len = self.len();
295 let ops::Range { start, end } = Self::drain_range(range, ..len);
296
297 unsafe {
298 self.set_len(start);
299 let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start);
300 Drain {
301 tail_start: end,
302 tail_len: len - end,
303 iter: range_slice.iter(),
304 vec: NonNull::from(self),
305 }
306 }
307 }
308}
309
310impl<T> ScratchVec<MaybeUninit<T>> {
311 #[inline]
320 pub fn assume_init(self) -> ScratchVec<T> {
321 ScratchVec {
322 ptr: self.ptr.cast(),
323 cap: self.cap,
324 len: self.len,
325 }
326 }
327}
328
329impl<T> AsMut<[T]> for ScratchVec<T> {
330 #[inline]
331 fn as_mut(&mut self) -> &mut [T] {
332 self.as_mut_slice()
333 }
334}
335
336impl<T> AsRef<[T]> for ScratchVec<T> {
337 #[inline]
338 fn as_ref(&self) -> &[T] {
339 self.as_slice()
340 }
341}
342
343impl<T> Borrow<[T]> for ScratchVec<T> {
344 #[inline]
345 fn borrow(&self) -> &[T] {
346 self.as_slice()
347 }
348}
349
350impl<T> BorrowMut<[T]> for ScratchVec<T> {
351 #[inline]
352 fn borrow_mut(&mut self) -> &mut [T] {
353 self.as_mut_slice()
354 }
355}
356
357impl<T: fmt::Debug> fmt::Debug for ScratchVec<T> {
358 #[inline]
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 self.as_slice().fmt(f)
361 }
362}
363
364impl<T> ops::Deref for ScratchVec<T> {
365 type Target = [T];
366
367 #[inline]
368 fn deref(&self) -> &Self::Target {
369 self.as_slice()
370 }
371}
372
373impl<T> ops::DerefMut for ScratchVec<T> {
374 #[inline]
375 fn deref_mut(&mut self) -> &mut Self::Target {
376 self.as_mut_slice()
377 }
378}
379
380impl<T, I: slice::SliceIndex<[T]>> ops::Index<I> for ScratchVec<T> {
381 type Output = <I as slice::SliceIndex<[T]>>::Output;
382
383 #[inline]
384 fn index(&self, index: I) -> &Self::Output {
385 &self.as_slice()[index]
386 }
387}
388
389impl<T, I: slice::SliceIndex<[T]>> ops::IndexMut<I> for ScratchVec<T> {
390 #[inline]
391 fn index_mut(&mut self, index: I) -> &mut Self::Output {
392 &mut self.as_mut_slice()[index]
393 }
394}
395
396pub struct Drain<'a, T: 'a> {
400 tail_start: usize,
401 tail_len: usize,
402 iter: slice::Iter<'a, T>,
403 vec: NonNull<ScratchVec<T>>,
404}
405
406impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
407 #[inline]
408 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409 f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
410 }
411}
412
413impl<T> Drain<'_, T> {
414 #[inline]
416 pub fn as_slice(&self) -> &[T] {
417 self.iter.as_slice()
418 }
419}
420
421impl<T> AsRef<[T]> for Drain<'_, T> {
422 fn as_ref(&self) -> &[T] {
423 self.as_slice()
424 }
425}
426
427impl<T> Iterator for Drain<'_, T> {
428 type Item = T;
429
430 #[inline]
431 fn next(&mut self) -> Option<T> {
432 self.iter
433 .next()
434 .map(|elt| unsafe { core::ptr::read(elt as *const _) })
435 }
436
437 #[inline]
438 fn size_hint(&self) -> (usize, Option<usize>) {
439 self.iter.size_hint()
440 }
441}
442
443impl<T> DoubleEndedIterator for Drain<'_, T> {
444 #[inline]
445 fn next_back(&mut self) -> Option<T> {
446 self.iter
447 .next_back()
448 .map(|elt| unsafe { core::ptr::read(elt as *const _) })
449 }
450}
451
452impl<T> Drop for Drain<'_, T> {
453 fn drop(&mut self) {
454 struct DropGuard<'r, 'a, T>(&'r mut Drain<'a, T>);
457
458 impl<'r, 'a, T> Drop for DropGuard<'r, 'a, T> {
459 fn drop(&mut self) {
460 self.0.for_each(drop);
463
464 if self.0.tail_len > 0 {
465 unsafe {
466 let source_vec = self.0.vec.as_mut();
467 let start = source_vec.len();
469 let tail = self.0.tail_start;
470 if tail != start {
471 let src = source_vec.as_ptr().add(tail);
472 let dst = source_vec.as_mut_ptr().add(start);
473 core::ptr::copy(src, dst, self.0.tail_len);
474 }
475 source_vec.set_len(start + self.0.tail_len);
476 }
477 }
478 }
479 }
480
481 while let Some(item) = self.next() {
483 let guard = DropGuard(self);
484 drop(item);
485 core::mem::forget(guard);
486 }
487
488 DropGuard(self);
490 }
491}
492
493impl<T> ExactSizeIterator for Drain<'_, T> {}
494
495impl<T> core::iter::FusedIterator for Drain<'_, T> {}