1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::{Doubling, Linear, Recursive, SplitVec};
use alloc::vec::Vec;
impl<T> From<SplitVec<T, Doubling>> for SplitVec<T, Recursive> {
/// Converts a `SplitVec<T, Doubling>` into a `SplitVec<T, Recursive>` with no cost.
///
/// * The benefit of `Doubling` growth strategy is its constant random access time.
/// * On the other hand, the benefit of `Recursive` growth strategy is the constant time `expand` operation.
///
/// Note that this is a one-way conversion:
/// * it is possible to convert any split vec `SplitVec<T, Doubling>` into `SplitVec<T, Recursive>`;
/// * however, not the other way around, since constant random access time requirements of `Doubling` are not satisfied.
///
/// # Examples
///
/// ```
/// use orx_split_vec::*;
///
/// let mut split_vec_doubling = SplitVec::with_doubling_growth();
/// split_vec_doubling.extend_from_slice(&['a', 'b', 'c']);
/// assert_eq!(split_vec_doubling, &['a', 'b', 'c']);
///
/// let split_vec_recursive: SplitVec<_, Recursive> = split_vec_doubling.into();
/// assert_eq!(split_vec_recursive, &['a', 'b', 'c']);
/// ```
fn from(value: SplitVec<T, Doubling>) -> Self {
Self::from_raw_parts(value.len, value.fragments, Recursive)
}
}
impl<T> From<SplitVec<T, Linear>> for SplitVec<T, Recursive> {
/// Converts a `SplitVec<T, Doubling>` into a `SplitVec<T, Recursive>` with no cost.
///
/// * The benefit of `Doubling` growth strategy is its constant random access time.
/// * On the other hand, the benefit of `Recursive` growth strategy is the constant time `expand` operation.
///
/// Note that this is a one-way conversion:
/// * it is possible to convert any split vec `SplitVec<T, Doubling>` into `SplitVec<T, Recursive>`;
/// * however, not the other way around, since constant random access time requirements of `Doubling` are not satisfied.
///
/// # Examples
///
/// ```
/// use orx_split_vec::*;
///
/// let mut split_vec_linear = SplitVec::with_linear_growth(4);
/// split_vec_linear.extend_from_slice(&['a', 'b', 'c']);
/// assert_eq!(split_vec_linear, &['a', 'b', 'c']);
///
/// let split_vec_recursive: SplitVec<_, Recursive> = split_vec_linear.into();
/// assert_eq!(split_vec_recursive, &['a', 'b', 'c']);
/// ```
fn from(value: SplitVec<T, Linear>) -> Self {
Self::from_raw_parts(value.len, value.fragments, Recursive)
}
}
impl<T: Clone> From<Vec<T>> for SplitVec<T, Recursive> {
/// Converts a `Vec` into a `SplitVec`.
///
/// # Examples
///
/// ```
/// use orx_split_vec::*;
///
/// let vec = vec!['a', 'b', 'c'];
/// let vec_capacity = vec.capacity();
///
/// let split_vec: SplitVec<_, Recursive> = vec.into();
///
/// assert_eq!(split_vec, &['a', 'b', 'c']);
/// assert_eq!(1, split_vec.fragments().len());
/// assert!(vec_capacity <= split_vec.capacity());
/// ```
fn from(value: Vec<T>) -> Self {
SplitVec::from_raw_parts(value.len(), alloc::vec![value.into()], Recursive)
}
}
#[cfg(test)]
mod tests {
use crate::*;
fn validate<G: Growth>(split: SplitVec<usize, G>)
where
SplitVec<usize, G>: Into<SplitVec<usize, Recursive>>,
{
let recursive: SplitVec<_, Recursive> = split.clone().into();
assert_eq!(split.len(), recursive.len());
for i in 0..split.len() {
assert_eq!(split.get(i), recursive.get(i));
}
}
#[test]
fn into_recursive() {
let mut vec = alloc::vec![];
let mut linear = SplitVec::with_linear_growth(4);
let mut doubling = SplitVec::with_doubling_growth();
for i in 0..879 {
vec.push(i);
linear.push(i);
doubling.push(i);
}
let recursive: SplitVec<_, Recursive> = vec.into();
validate(recursive);
validate(linear);
validate(doubling);
}
}