use core::{cmp::min, mem::MaybeUninit, ptr::copy_nonoverlapping};
use super::constants::CUMULATIVE_CAPACITIES;
use crate::{Doubling, Fragment, SplitVec, growth::doubling::constants::CAPACITIES};
use alloc::vec::Vec;
impl<T> From<Vec<T>> for SplitVec<T, Doubling> {
fn from(mut value: Vec<T>) -> Self {
let len = value.len();
let f = CUMULATIVE_CAPACITIES
.iter()
.enumerate()
.find(|(_, cum_cap)| **cum_cap >= len)
.map(|(f, _)| f)
.expect("overflow");
let mut fragments = Vec::with_capacity(f + 1);
let fragments_init = fragments.spare_capacity_mut();
let mut remaining_len = len;
let mut curr_f = f;
while remaining_len > 0 {
curr_f -= 1;
let capacity = CAPACITIES[curr_f];
let copy_len = min(remaining_len - CUMULATIVE_CAPACITIES[curr_f], capacity);
remaining_len -= copy_len;
let mut fragment_data = Vec::with_capacity(capacity);
unsafe {
value.set_len(remaining_len);
fragment_data.set_len(copy_len);
copy_nonoverlapping(
value.as_ptr().add(remaining_len),
fragment_data.as_mut_ptr(),
copy_len,
);
}
fragments_init[curr_f] = MaybeUninit::new(Fragment::from(fragment_data));
}
debug_assert_eq!(curr_f, 0);
unsafe { fragments.set_len(f) };
Self::from_raw_parts(len, fragments, Doubling)
}
}