orx_split_vec/growth/doubling/
from.rs1use core::{cmp::min, mem::MaybeUninit, ptr::copy_nonoverlapping};
2
3use super::constants::CUMULATIVE_CAPACITIES;
4use crate::{Doubling, Fragment, SplitVec, growth::doubling::constants::CAPACITIES};
5use alloc::vec::Vec;
6
7impl<T> From<Vec<T>> for SplitVec<T, Doubling> {
8 fn from(mut value: Vec<T>) -> Self {
25 let len = value.len();
26 let f = CUMULATIVE_CAPACITIES
28 .iter()
29 .enumerate()
30 .find(|(_, cum_cap)| **cum_cap >= len)
31 .map(|(f, _)| f)
32 .expect("overflow");
33
34 let mut fragments = Vec::with_capacity(f + 1);
35 let fragments_init = fragments.spare_capacity_mut();
36 let mut remaining_len = len;
37 let mut curr_f = f;
38 while remaining_len > 0 {
39 curr_f -= 1;
40 let capacity = CAPACITIES[curr_f];
41 let copy_len = min(remaining_len - CUMULATIVE_CAPACITIES[curr_f], capacity);
44 remaining_len -= copy_len;
45
46 let mut fragment_data = Vec::with_capacity(capacity);
49 unsafe {
50 value.set_len(remaining_len);
51 fragment_data.set_len(copy_len);
52 copy_nonoverlapping(
53 value.as_ptr().add(remaining_len),
54 fragment_data.as_mut_ptr(),
55 copy_len,
56 );
57 }
58 fragments_init[curr_f] = MaybeUninit::new(Fragment::from(fragment_data));
59 }
60 debug_assert_eq!(curr_f, 0);
61 unsafe { fragments.set_len(f) };
62
63 Self::from_raw_parts(len, fragments, Doubling)
64 }
65}