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}