const_primes/cache/
prime_factors.rs1use super::Underlying;
2
3use core::iter::FusedIterator;
4
5#[derive(Debug, Clone)]
10#[cfg_attr(
11 feature = "rkyv",
12 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
13)]
14#[must_use = "iterators are lazy and do nothing unless consumed"]
15pub struct PrimeFactorization<'a> {
16 primes_cache: &'a [Underlying],
17 cache_index: usize,
18 number: Underlying,
19}
20
21impl<'a> PrimeFactorization<'a> {
22 pub(crate) const fn new(primes_cache: &'a [Underlying], number: Underlying) -> Self {
23 Self {
24 primes_cache,
25 cache_index: 0,
26 number,
27 }
28 }
29
30 #[must_use = "`self` will be dropped if the result is not used"]
33 pub fn remainder(mut self) -> Option<Underlying> {
34 for _ in self.by_ref() {}
35 if self.number > 1 {
36 Some(self.number)
37 } else {
38 None
39 }
40 }
41}
42
43impl Iterator for PrimeFactorization<'_> {
44 type Item = (Underlying, u8);
45 fn next(&mut self) -> Option<Self::Item> {
46 if self.number == 1 {
47 return None;
48 }
49
50 while let Some(prime) = self.primes_cache.get(self.cache_index) {
51 let mut count = 0;
52 while self.number % prime == 0 {
53 count += 1;
54 self.number /= prime;
55 }
56
57 self.cache_index += 1;
58
59 if count > 0 {
60 return Some((*prime, count));
61 }
62 }
63
64 None
65 }
66
67 #[inline]
68 fn size_hint(&self) -> (usize, Option<usize>) {
69 (0, Some(self.primes_cache.len() - self.cache_index))
70 }
71}
72
73impl FusedIterator for PrimeFactorization<'_> {}
74
75#[derive(Debug, Clone)]
80#[must_use = "iterators are lazy and do nothing unless consumed"]
81pub struct PrimeFactors<'a> {
82 primes_cache: &'a [Underlying],
83 cache_index: usize,
84 number: Underlying,
85}
86
87impl<'a> PrimeFactors<'a> {
88 #[inline]
89 pub(crate) const fn new(primes_cache: &'a [Underlying], number: Underlying) -> Self {
90 Self {
91 primes_cache,
92 cache_index: 0,
93 number,
94 }
95 }
96
97 #[inline]
103 #[must_use = "`self` will be dropped if the result is not used"]
104 pub fn remainder(self) -> Option<Underlying> {
105 PrimeFactorization::new(self.primes_cache, self.number).remainder()
109 }
110}
111
112impl Iterator for PrimeFactors<'_> {
113 type Item = Underlying;
114 fn next(&mut self) -> Option<Self::Item> {
115 while let Some(prime) = self.primes_cache.get(self.cache_index) {
116 self.cache_index += 1;
117 if self.number % prime == 0 {
118 return Some(*prime);
119 }
120 }
121
122 None
123 }
124
125 #[inline]
126 fn size_hint(&self) -> (usize, Option<usize>) {
127 (0, Some(self.primes_cache.len() - self.cache_index))
128 }
129}
130
131impl FusedIterator for PrimeFactors<'_> {}