Coverage Report

Created: 2026-08-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/num-bigint-0.4.4/src/biguint/iter.rs
Line
Count
Source
1
use core::iter::FusedIterator;
2
3
#[cfg(not(u64_digit))]
4
use super::u32_chunk_to_u64;
5
6
/// An iterator of `u32` digits representation of a `BigUint` or `BigInt`,
7
/// ordered least significant digit first.
8
pub struct U32Digits<'a> {
9
    #[cfg(u64_digit)]
10
    data: &'a [u64],
11
    #[cfg(u64_digit)]
12
    next_is_lo: bool,
13
    #[cfg(u64_digit)]
14
    last_hi_is_zero: bool,
15
16
    #[cfg(not(u64_digit))]
17
    it: core::slice::Iter<'a, u32>,
18
}
19
20
#[cfg(u64_digit)]
21
impl<'a> U32Digits<'a> {
22
    #[inline]
23
0
    pub(super) fn new(data: &'a [u64]) -> Self {
24
0
        let last_hi_is_zero = data
25
0
            .last()
26
0
            .map(|&last| {
27
0
                let last_hi = (last >> 32) as u32;
28
0
                last_hi == 0
29
0
            })
30
0
            .unwrap_or(false);
31
0
        U32Digits {
32
0
            data,
33
0
            next_is_lo: true,
34
0
            last_hi_is_zero,
35
0
        }
36
0
    }
37
}
38
39
#[cfg(u64_digit)]
40
impl Iterator for U32Digits<'_> {
41
    type Item = u32;
42
    #[inline]
43
0
    fn next(&mut self) -> Option<u32> {
44
0
        match self.data.split_first() {
45
0
            Some((&first, data)) => {
46
0
                let next_is_lo = self.next_is_lo;
47
0
                self.next_is_lo = !next_is_lo;
48
0
                if next_is_lo {
49
0
                    Some(first as u32)
50
                } else {
51
0
                    self.data = data;
52
0
                    if data.is_empty() && self.last_hi_is_zero {
53
0
                        self.last_hi_is_zero = false;
54
0
                        None
55
                    } else {
56
0
                        Some((first >> 32) as u32)
57
                    }
58
                }
59
            }
60
0
            None => None,
61
        }
62
0
    }
63
64
    #[inline]
65
0
    fn size_hint(&self) -> (usize, Option<usize>) {
66
0
        let len = self.len();
67
0
        (len, Some(len))
68
0
    }
69
70
    #[inline]
71
0
    fn last(self) -> Option<u32> {
72
0
        self.data.last().map(|&last| {
73
0
            if self.last_hi_is_zero {
74
0
                last as u32
75
            } else {
76
0
                (last >> 32) as u32
77
            }
78
0
        })
79
0
    }
80
81
    #[inline]
82
0
    fn count(self) -> usize {
83
0
        self.len()
84
0
    }
85
}
86
87
#[cfg(u64_digit)]
88
impl DoubleEndedIterator for U32Digits<'_> {
89
0
    fn next_back(&mut self) -> Option<Self::Item> {
90
0
        match self.data.split_last() {
91
0
            Some((&last, data)) => {
92
0
                let last_is_lo = self.last_hi_is_zero;
93
0
                self.last_hi_is_zero = !last_is_lo;
94
0
                if last_is_lo {
95
0
                    self.data = data;
96
0
                    if data.is_empty() && !self.next_is_lo {
97
0
                        self.next_is_lo = true;
98
0
                        None
99
                    } else {
100
0
                        Some(last as u32)
101
                    }
102
                } else {
103
0
                    Some((last >> 32) as u32)
104
                }
105
            }
106
0
            None => None,
107
        }
108
0
    }
109
}
110
111
#[cfg(u64_digit)]
112
impl ExactSizeIterator for U32Digits<'_> {
113
    #[inline]
114
0
    fn len(&self) -> usize {
115
0
        self.data.len() * 2 - usize::from(self.last_hi_is_zero) - usize::from(!self.next_is_lo)
116
0
    }
117
}
118
119
#[cfg(not(u64_digit))]
120
impl<'a> U32Digits<'a> {
121
    #[inline]
122
    pub(super) fn new(data: &'a [u32]) -> Self {
123
        Self { it: data.iter() }
124
    }
125
}
126
127
#[cfg(not(u64_digit))]
128
impl Iterator for U32Digits<'_> {
129
    type Item = u32;
130
    #[inline]
131
    fn next(&mut self) -> Option<u32> {
132
        self.it.next().cloned()
133
    }
134
135
    #[inline]
136
    fn size_hint(&self) -> (usize, Option<usize>) {
137
        self.it.size_hint()
138
    }
139
140
    #[inline]
141
    fn nth(&mut self, n: usize) -> Option<u32> {
142
        self.it.nth(n).cloned()
143
    }
144
145
    #[inline]
146
    fn last(self) -> Option<u32> {
147
        self.it.last().cloned()
148
    }
149
150
    #[inline]
151
    fn count(self) -> usize {
152
        self.it.count()
153
    }
154
}
155
156
#[cfg(not(u64_digit))]
157
impl DoubleEndedIterator for U32Digits<'_> {
158
    fn next_back(&mut self) -> Option<Self::Item> {
159
        self.it.next_back().copied()
160
    }
161
}
162
163
#[cfg(not(u64_digit))]
164
impl ExactSizeIterator for U32Digits<'_> {
165
    #[inline]
166
    fn len(&self) -> usize {
167
        self.it.len()
168
    }
169
}
170
171
impl FusedIterator for U32Digits<'_> {}
172
173
/// An iterator of `u64` digits representation of a `BigUint` or `BigInt`,
174
/// ordered least significant digit first.
175
pub struct U64Digits<'a> {
176
    #[cfg(not(u64_digit))]
177
    it: core::slice::Chunks<'a, u32>,
178
179
    #[cfg(u64_digit)]
180
    it: core::slice::Iter<'a, u64>,
181
}
182
183
#[cfg(not(u64_digit))]
184
impl<'a> U64Digits<'a> {
185
    #[inline]
186
    pub(super) fn new(data: &'a [u32]) -> Self {
187
        U64Digits { it: data.chunks(2) }
188
    }
189
}
190
191
#[cfg(not(u64_digit))]
192
impl Iterator for U64Digits<'_> {
193
    type Item = u64;
194
    #[inline]
195
    fn next(&mut self) -> Option<u64> {
196
        self.it.next().map(u32_chunk_to_u64)
197
    }
198
199
    #[inline]
200
    fn size_hint(&self) -> (usize, Option<usize>) {
201
        let len = self.len();
202
        (len, Some(len))
203
    }
204
205
    #[inline]
206
    fn last(self) -> Option<u64> {
207
        self.it.last().map(u32_chunk_to_u64)
208
    }
209
210
    #[inline]
211
    fn count(self) -> usize {
212
        self.len()
213
    }
214
}
215
216
#[cfg(not(u64_digit))]
217
impl DoubleEndedIterator for U64Digits<'_> {
218
    fn next_back(&mut self) -> Option<Self::Item> {
219
        self.it.next_back().map(u32_chunk_to_u64)
220
    }
221
}
222
223
#[cfg(u64_digit)]
224
impl<'a> U64Digits<'a> {
225
    #[inline]
226
0
    pub(super) fn new(data: &'a [u64]) -> Self {
227
0
        Self { it: data.iter() }
228
0
    }
229
}
230
231
#[cfg(u64_digit)]
232
impl Iterator for U64Digits<'_> {
233
    type Item = u64;
234
    #[inline]
235
0
    fn next(&mut self) -> Option<u64> {
236
0
        self.it.next().cloned()
237
0
    }
238
239
    #[inline]
240
0
    fn size_hint(&self) -> (usize, Option<usize>) {
241
0
        self.it.size_hint()
242
0
    }
243
244
    #[inline]
245
0
    fn nth(&mut self, n: usize) -> Option<u64> {
246
0
        self.it.nth(n).cloned()
247
0
    }
248
249
    #[inline]
250
0
    fn last(self) -> Option<u64> {
251
0
        self.it.last().cloned()
252
0
    }
253
254
    #[inline]
255
0
    fn count(self) -> usize {
256
0
        self.it.count()
257
0
    }
258
}
259
260
#[cfg(u64_digit)]
261
impl DoubleEndedIterator for U64Digits<'_> {
262
0
    fn next_back(&mut self) -> Option<Self::Item> {
263
0
        self.it.next_back().cloned()
264
0
    }
265
}
266
267
impl ExactSizeIterator for U64Digits<'_> {
268
    #[inline]
269
0
    fn len(&self) -> usize {
270
0
        self.it.len()
271
0
    }
272
}
273
274
impl FusedIterator for U64Digits<'_> {}
275
276
#[test]
277
fn test_iter_u32_digits() {
278
    let n = super::BigUint::from(5u8);
279
    let mut it = n.iter_u32_digits();
280
    assert_eq!(it.len(), 1);
281
    assert_eq!(it.next(), Some(5));
282
    assert_eq!(it.len(), 0);
283
    assert_eq!(it.next(), None);
284
    assert_eq!(it.len(), 0);
285
    assert_eq!(it.next(), None);
286
287
    let n = super::BigUint::from(112500000000u64);
288
    let mut it = n.iter_u32_digits();
289
    assert_eq!(it.len(), 2);
290
    assert_eq!(it.next(), Some(830850304));
291
    assert_eq!(it.len(), 1);
292
    assert_eq!(it.next(), Some(26));
293
    assert_eq!(it.len(), 0);
294
    assert_eq!(it.next(), None);
295
}
296
297
#[test]
298
fn test_iter_u64_digits() {
299
    let n = super::BigUint::from(5u8);
300
    let mut it = n.iter_u64_digits();
301
    assert_eq!(it.len(), 1);
302
    assert_eq!(it.next(), Some(5));
303
    assert_eq!(it.len(), 0);
304
    assert_eq!(it.next(), None);
305
    assert_eq!(it.len(), 0);
306
    assert_eq!(it.next(), None);
307
308
    let n = super::BigUint::from(18_446_744_073_709_551_616u128);
309
    let mut it = n.iter_u64_digits();
310
    assert_eq!(it.len(), 2);
311
    assert_eq!(it.next(), Some(0));
312
    assert_eq!(it.len(), 1);
313
    assert_eq!(it.next(), Some(1));
314
    assert_eq!(it.len(), 0);
315
    assert_eq!(it.next(), None);
316
}
317
318
#[test]
319
fn test_iter_u32_digits_be() {
320
    let n = super::BigUint::from(5u8);
321
    let mut it = n.iter_u32_digits();
322
    assert_eq!(it.len(), 1);
323
    assert_eq!(it.next(), Some(5));
324
    assert_eq!(it.len(), 0);
325
    assert_eq!(it.next(), None);
326
    assert_eq!(it.len(), 0);
327
    assert_eq!(it.next(), None);
328
329
    let n = super::BigUint::from(112500000000u64);
330
    let mut it = n.iter_u32_digits();
331
    assert_eq!(it.len(), 2);
332
    assert_eq!(it.next(), Some(830850304));
333
    assert_eq!(it.len(), 1);
334
    assert_eq!(it.next(), Some(26));
335
    assert_eq!(it.len(), 0);
336
    assert_eq!(it.next(), None);
337
}
338
339
#[test]
340
fn test_iter_u64_digits_be() {
341
    let n = super::BigUint::from(5u8);
342
    let mut it = n.iter_u64_digits();
343
    assert_eq!(it.len(), 1);
344
    assert_eq!(it.next_back(), Some(5));
345
    assert_eq!(it.len(), 0);
346
    assert_eq!(it.next(), None);
347
    assert_eq!(it.len(), 0);
348
    assert_eq!(it.next(), None);
349
350
    let n = super::BigUint::from(18_446_744_073_709_551_616u128);
351
    let mut it = n.iter_u64_digits();
352
    assert_eq!(it.len(), 2);
353
    assert_eq!(it.next_back(), Some(1));
354
    assert_eq!(it.len(), 1);
355
    assert_eq!(it.next_back(), Some(0));
356
    assert_eq!(it.len(), 0);
357
    assert_eq!(it.next(), None);
358
}