1#![allow(unsafe_op_in_unsafe_fn)]
2use std::mem::MaybeUninit;
3
4use bytemuck::Pod;
5use num_traits::Zero;
6
7use crate::with_drop::WithDrop;
8
9pub trait IntoRawParts<T> {
10 fn into_raw_parts(self) -> (*mut T, usize, usize);
11
12 fn raw_parts(&self) -> (*mut T, usize, usize);
14}
15
16impl<T> IntoRawParts<T> for Vec<T> {
17 fn into_raw_parts(self) -> (*mut T, usize, usize) {
18 let mut me = std::mem::ManuallyDrop::new(self);
19 (me.as_mut_ptr(), me.len(), me.capacity())
20 }
21
22 fn raw_parts(&self) -> (*mut T, usize, usize) {
23 (self.as_ptr() as *mut T, self.len(), self.capacity())
24 }
25}
26
27pub trait ResizeFaster<T: Copy> {
30 fn fill_or_alloc(&mut self, new_len: usize, value: T);
31}
32
33impl<T: Copy + Zero + PartialEq> ResizeFaster<T> for Vec<T> {
34 fn fill_or_alloc(&mut self, new_len: usize, value: T) {
35 if self.capacity() == 0 {
36 *self = vec![value; new_len]
39 } else {
40 self.clear();
43 self.reserve(new_len);
44
45 let spare = &mut self.spare_capacity_mut()[..new_len];
47 let init_value = MaybeUninit::new(value);
48 spare.fill(init_value);
49 unsafe { self.set_len(new_len) }
50 }
51 }
52}
53pub trait PushUnchecked<T> {
54 unsafe fn push_unchecked(&mut self, value: T);
59}
60
61impl<T> PushUnchecked<T> for Vec<T> {
62 #[inline]
63 unsafe fn push_unchecked(&mut self, value: T) {
64 debug_assert!(self.capacity() > self.len());
65 let end = self.as_mut_ptr().add(self.len());
66 std::ptr::write(end, value);
67 self.set_len(self.len() + 1);
68 }
69}
70
71pub trait CapacityByFactor {
72 fn with_capacity_by_factor(original_len: usize, factor: f64) -> Self;
73}
74
75impl<T> CapacityByFactor for Vec<T> {
76 fn with_capacity_by_factor(original_len: usize, factor: f64) -> Self {
77 let cap = (original_len as f64 * factor) as usize;
78 Vec::with_capacity(cap)
79 }
80}
81
82pub trait ConvertVec<Out> {
86 type ItemIn;
87
88 fn convert_owned<F: FnMut(Self::ItemIn) -> Out>(self, f: F) -> Vec<Out>;
89
90 fn convert<F: FnMut(&Self::ItemIn) -> Out>(&self, f: F) -> Vec<Out>;
91}
92
93impl<T, Out> ConvertVec<Out> for Vec<T> {
94 type ItemIn = T;
95
96 fn convert_owned<F: FnMut(Self::ItemIn) -> Out>(self, f: F) -> Vec<Out> {
97 self.into_iter().map(f).collect()
98 }
99
100 fn convert<F: FnMut(&Self::ItemIn) -> Out>(&self, f: F) -> Vec<Out> {
101 self.iter().map(f).collect()
102 }
103}
104
105pub fn with_cast_mut_vec<T: Pod, U: Pod, R, F: FnOnce(&mut Vec<U>) -> R>(
106 v: &mut Vec<T>,
107 f: F,
108) -> R {
109 let mut vu = WithDrop::new(bytemuck::cast_vec::<T, U>(core::mem::take(v)), |vu| {
110 *v = bytemuck::cast_vec::<U, T>(vu)
111 });
112 f(&mut vu)
113}