Home > Back-end >  Compile-time arithmetic via generic types in Rust, similar to C ?
Compile-time arithmetic via generic types in Rust, similar to C ?

Time:04-06

I'm just learning Rust and would like to write code that uses generic types to perform compile-time arithmetic.

For example, in C I can write the following code (on Goldbolt):

#include <iostream>

template <int X>
struct Test {
    constexpr static int x = X;
};

template <int X1, int X2>
auto operator (const Test<X1>&, const Test<X2>&) {
    return Test<X1   X2>{};
}

int main() {
    const Test<4> a{};
    const Test<6> b{};
    const auto c = a   b;
    std::cout << c.x << '\n'; // prints 10
}

I try to write analogous code in Rust (on Playground):

use std::ops::Add;

pub struct Test<const X: u8>;

impl<const X: u8> Test<X> {
    pub fn x(&self) -> u8 { X }
}

impl<const X1: u8, const X2: u8> Add<Test<X2>> for Test<X1> {
    type Output = Test<{X1   X2}>;
    fn add(self, rhs: Test<X2>) -> Test<{X1   X2}> {
        Test::<{X1   X2}>{}
    }
}

fn main() {
    let a: Test<4> = Test{};
    let b: Test<6> = Test{};
    let c = a   b;
    println!("{}", c::x());
}

...but this won't compile, since generic parameters may not be used in const operations. Is this kind of thing simply impossible to do with Rust, or is there another strategy I can try?

CodePudding user response:

You can do it, but const generics aren't complete yet, so it currently requires a nightly compiler and an explicitly enabled feature:

#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

use std::ops::Add;

pub struct Test<const X: u8>;

impl<const X: u8> Test<X> {
    pub fn x(&self) -> u8 { X }
}

impl<const X1: u8, const X2: u8> Add<Test<X2>> for Test<X1> where [(); (X1   X2) as usize]: {
    type Output = Test<{X1   X2}>;
    fn add(self, _rhs: Test<X2>) -> Test<{X1   X2}> {
        Test::<{X1   X2}>{}
    }
}

fn main() {
    let a: Test<4> = Test{};
    let b: Test<6> = Test{};
    let c = a   b;
    let Test::<10> = c;
    println!("{}", c.x());
}

(Permalink to playground)

  • Related