wyoumans
wyoumans

Reputation: 410

How can I make a struct with a constant parameter that may be only known at runtime?

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

Answers (1)

Todd
Todd

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

Related Questions