Skip to main content

tea_core/vec_core/
uninit.rs

1use tea_error::{TResult, tbail};
2
3use super::trusted::TrustedLen;
4use super::{GetLen, Vec1};
5/// Trait for uninitialized vectors that can be safely initialized.
6pub trait UninitVec<T>: GetLen {
7    /// The type of the initialized vector.
8    type Vec: Vec1<T>;
9
10    /// Assumes that all elements are initialized and returns the initialized vector.
11    ///
12    /// # Safety
13    ///
14    /// All elements must be initialized before calling this method.
15    unsafe fn assume_init(self) -> Self::Vec;
16
17    /// Sets the value at the given index in the uninitialized vector.
18    ///
19    /// # Safety
20    ///
21    /// The caller should ensure that the index is less than the length of the array.
22    unsafe fn uset(&mut self, _idx: usize, _v: T) {
23        unimplemented!(
24            "uset not implemented for {:?}",
25            std::any::type_name::<Self>()
26        );
27    }
28
29    /// Safely sets the value at the given index in the uninitialized vector.
30    ///
31    /// Returns an error if the index is out of bounds.
32    #[inline]
33    fn set(&mut self, idx: usize, v: T) -> TResult<()> {
34        if idx < self.len() {
35            unsafe { self.uset(idx, v) }
36            Ok(())
37        } else {
38            tbail!(oob(idx, self.len()))
39        }
40    }
41}
42
43/// Trait for mutable references to uninitialized vectors that can be written to.
44pub trait UninitRefMut<T>: GetLen {
45    /// Sets the value at the given index in the uninitialized vector.
46    ///
47    /// # Safety
48    ///
49    /// The caller should ensure that the index is less than the length of the array.
50    unsafe fn uset(&mut self, idx: usize, v: T);
51
52    /// Writes the contents of a trusted iterator to the uninitialized vector.
53    ///
54    /// This method handles three cases:
55    /// 1. If the iterator length matches the vector length, it writes each item.
56    /// 2. If the iterator has only one item, it clones and writes that item to all positions.
57    /// 3. If the lengths don't match and the iterator has more than one item, it returns an error.
58    fn write_trust_iter<I: TrustedLen<Item = T>>(&mut self, mut iter: I) -> TResult<()>
59    where
60        T: Clone,
61    {
62        let len = self.len();
63        let iter_len = iter.len();
64        if len == 0 {
65            return Ok(());
66        }
67        if len == iter_len {
68            (0..len).for_each(|i| unsafe { self.uset(i, iter.next().unwrap()) });
69        } else if iter_len == 1 {
70            let v = iter.next().unwrap();
71            (0..len).for_each(|i| unsafe { self.uset(i, v.clone()) });
72        } else {
73            tbail!(
74                "length of out and value to write are not equal, out: {}, iter: {}",
75                len,
76                iter_len
77            )
78        }
79        Ok(())
80    }
81}
82
83/// Trait for types that can be written to an uninitialized vector using a trusted iterator.
84pub trait WriteTrustIter<T: Clone> {
85    /// Writes the contents of this iterator to the given uninitialized vector.
86    fn write<O: UninitRefMut<T>>(self, out: &mut O) -> TResult<()>;
87}
88
89impl<I: TrustedLen> WriteTrustIter<I::Item> for I
90where
91    I::Item: Clone,
92{
93    fn write<O: UninitRefMut<I::Item>>(self, out: &mut O) -> TResult<()> {
94        out.write_trust_iter(self)
95    }
96}