vortex_vector/bool/iter.rs
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Iterator implementations for [`BoolVectorMut`].
5
6use vortex_buffer::BitBufferMut;
7use vortex_mask::MaskMut;
8
9use crate::VectorMutOps;
10use crate::bool::BoolVectorMut;
11
12impl FromIterator<Option<bool>> for BoolVectorMut {
13 /// Creates a new [`BoolVectorMut`] from an iterator of `Option<bool>` values.
14 ///
15 /// `None` values will be marked as invalid in the validity mask.
16 ///
17 /// # Examples
18 ///
19 /// ```
20 /// use vortex_vector::bool::BoolVectorMut;
21 /// use vortex_vector::VectorMutOps;
22 ///
23 /// let mut vec = BoolVectorMut::from_iter([Some(true), None, Some(false)]);
24 /// assert_eq!(vec.len(), 3);
25 /// ```
26 fn from_iter<I>(iter: I) -> Self
27 where
28 I: IntoIterator<Item = Option<bool>>,
29 {
30 let iter = iter.into_iter();
31 // Since we do not know the length of the iterator, we can only guess how much memory we
32 // need to reserve. Note that these hints may be inaccurate.
33 let (lower_bound, _) = iter.size_hint();
34
35 // We choose not to use the optional upper bound size hint to match the standard library.
36
37 let mut bits = BitBufferMut::with_capacity(lower_bound);
38 let mut validity = MaskMut::with_capacity(lower_bound);
39
40 for opt_val in iter {
41 match opt_val {
42 Some(val) => {
43 bits.append(val);
44 validity.append_n(true, 1);
45 }
46 None => {
47 bits.append(false); // Value doesn't matter for invalid entries.
48 validity.append_n(false, 1);
49 }
50 }
51 }
52
53 BoolVectorMut { bits, validity }
54 }
55}
56
57impl FromIterator<bool> for BoolVectorMut {
58 /// Creates a new [`BoolVectorMut`] from an iterator of `bool` values.
59 ///
60 /// All values will be treated as non-null.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use vortex_vector::bool::BoolVectorMut;
66 /// use vortex_vector::VectorMutOps;
67 ///
68 /// let mut vec = BoolVectorMut::from_iter([true, false, false, true]);
69 /// assert_eq!(vec.len(), 4);
70 /// ```
71 fn from_iter<I>(iter: I) -> Self
72 where
73 I: IntoIterator<Item = bool>,
74 {
75 let buffer = BitBufferMut::from_iter(iter);
76 let validity = MaskMut::new_true(buffer.len());
77
78 BoolVectorMut {
79 bits: buffer,
80 validity,
81 }
82 }
83}
84
85/// Iterator over a [`BoolVectorMut`] that yields [`Option<bool>`] values.
86///
87/// This iterator is created by calling [`IntoIterator::into_iter`] on a [`BoolVectorMut`].
88///
89/// It consumes the mutable vector and iterates over the elements, yielding `None` for null values
90/// and `Some(value)` for valid values.
91#[derive(Debug)]
92pub struct BoolVectorMutIterator {
93 /// The vector being iterated over.
94 vector: BoolVectorMut,
95 /// The current index into the vector.
96 index: usize,
97}
98
99impl Iterator for BoolVectorMutIterator {
100 type Item = Option<bool>;
101
102 fn next(&mut self) -> Option<Self::Item> {
103 (self.index < self.vector.len()).then(|| {
104 let value = self
105 .vector
106 .validity
107 .value(self.index)
108 .then(|| self.vector.bits.value(self.index));
109 self.index += 1;
110 value
111 })
112 }
113
114 fn size_hint(&self) -> (usize, Option<usize>) {
115 let remaining = self.vector.len() - self.index;
116 (remaining, Some(remaining))
117 }
118}
119
120impl IntoIterator for BoolVectorMut {
121 type Item = Option<bool>;
122 type IntoIter = BoolVectorMutIterator;
123
124 /// Converts the mutable vector into an iterator over `Option<bool>` values.
125 ///
126 /// This method consumes the `BoolVectorMut` and returns an iterator that yields `None` for
127 /// null values and `Some(value)` for valid values.
128 ///
129 /// # Examples
130 ///
131 /// ```
132 /// use vortex_vector::bool::BoolVectorMut;
133 ///
134 /// let vec = BoolVectorMut::from_iter([Some(true), None, Some(false), Some(true)]);
135 /// let collected: Vec<_> = vec.into_iter().collect();
136 /// assert_eq!(collected, vec![Some(true), None, Some(false), Some(true)]);
137 /// ```
138 fn into_iter(self) -> Self::IntoIter {
139 BoolVectorMutIterator {
140 vector: self,
141 index: 0,
142 }
143 }
144}