Reputation: 410
At the moment I have my own integer type which works like this:
let x = Integer::new(12);
Now I want to work with integers mod n (and be able to properly overload binary operations), so I would like something that works like this:
let X = IntegerMod<11>;
let x = X::new(12);
Then 12 is reduced mod 11 so x = 1.
I can do this using const generics but then the modulus needs to be known at compile time and I can't have a function output some IntegerMod<n>
where n is determined at runtime (which I would like to have).
What is the best way to get this behavior?
Upvotes: 0
Views: 613
Reputation: 5395
You could use a sort of factory function approach, where an IntegerMod
instance can be created giving it the modulus value, which acts as the factory for Integer
values. The underlying type can be generic.
Usage could look something like this:
fn main()
{
let im = IntegerMod::fact(5);
println!("{:?}", im.new(111)); // Prints `Integer { value: 1 }`.
}
IntegerMod as an Integer producer.
use std::ops::Rem;
struct IntegerMod<T>
{
modulus: T,
}
impl<T> IntegerMod<T>
where
T: Rem<Output = T> + Copy,
{
fn fact(modulus: T) -> Self
{
IntegerMod { modulus }
}
// Maybe name this something different. But keeping with the example...
fn new(&self, value: T) -> Integer<T>
{
Integer::new(value % self.modulus)
}
}
Integer:
#[derive(Debug)]
struct Integer<T>
{
value: T,
}
impl<T> Integer<T>
{
fn new(value: T) -> Self
{
Integer { value }
}
}
Upvotes: 1