c_prime/
iterators.rs

1use crate::ptrait::Primality;
2/// Iterator over the set of primes
3///
4/// It may start at any point and iterate forwards or backwards 
5#[derive(Copy, Clone)]
6pub struct Primes<T: Primality>{
7    p: T,
8}
9
10impl<T: Primality> Primes<T>{
11   /// Initialise a new iterator over the Primes starting from 1
12   pub const fn new() -> Self{
13       Self{p: T::ONE}
14   }
15   
16   /// Initialise a new iterator over the Prime starting from p
17   pub const fn start(p: T) -> Self {
18        Self { p }
19    }
20    
21   /// Reset iterator to start at new point 
22   pub const fn jump_to(&self, p: T) -> Self{
23       Self{p}
24   } 
25   
26   /// Returns the last prime
27   pub const fn last() -> Self{
28      Self{p: T::LAST_PRIME}
29   }
30   
31    /// Syntatic sugar to make it look like a normal iterator
32    pub fn iter(&self) -> Self {
33        self.clone()
34    }
35    
36   /// Determine if  some x is within the defined set of Primes
37    pub fn contains(&self, x: T) -> bool{
38        x.is_prime()
39    }
40    
41    /// Returns the primes out of the given collection
42    pub fn intersection<F: IntoIterator<Item=T>>(&self, other: F) -> Vec<T>{
43        let mut veccy = vec![];
44        for i in other.into_iter(){
45          if i.is_prime(){
46             veccy.push(i)
47          }
48       }
49       veccy
50    }
51    
52    /// Elements in other set that are NOT primes
53    pub fn complement<F: IntoIterator<Item=T>>(&self, other: F) -> Vec<T>{
54        let mut veccy = vec![];
55       for i in other.into_iter(){
56          if !i.is_prime(){
57             veccy.push(i)
58          }
59       }
60       veccy
61    }
62  }  
63
64impl<T: Primality> Iterator for Primes<T>{
65    type Item = T;
66
67    fn next(&mut self) -> Option<Self::Item> {
68        loop {
69            
70            if self.p >= T::LAST_PRIME {
71                return None;
72            }
73             self.p += T::ONE;
74            if self.p.is_prime(){
75                return Some(self.p);
76            }
77        }
78    }
79
80    fn last(self) -> Option<Self::Item> {
81        Some(T::LAST_PRIME)
82    }
83}
84
85
86impl<T: Primality> DoubleEndedIterator for Primes<T> {
87    fn next_back(&mut self) -> Option<Self::Item> {
88        loop {
89            if self.p < T::FIRST_PRIME {
90                return None;
91            }
92            self.p -= T::ONE;
93           if self.p.is_prime(){
94                return Some(self.p);
95            }
96        }
97    }
98}
99
100/// Iterator of primes of the form X*RING + RESIDUE
101#[derive(Copy, Clone)]
102pub struct ResiduePrime<const RING: u128, const RESIDUE: u128> {
103    p: u128,
104}
105
106impl<const RING: u128, const RESIDUE: u128> ResiduePrime<RING,RESIDUE> {
107
108  pub  fn new(p: u128) -> Option<Self> {
109        // Checks that starting value is already a valid residue,
110        // but not necessarily prime
111        if p % RING == RESIDUE {
112            return Some(Self { p });
113        }
114        None
115    }  
116    
117}
118
119impl<const RING: u128, const RESIDUE: u128> Iterator for ResiduePrime<RING,RESIDUE> {
120    type Item = u128;
121
122    fn next(&mut self) -> Option<Self::Item> {
123        loop {
124            if self.p > u128::LAST_PRIME {
125                return None;
126            }
127            self.p += RING;
128            let x: u128 = self.p;
129            if machine_prime::is_prime_128(x) {
130                return Some(x);
131            }
132        }
133    }
134}
135