Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile-time arithmetic via generic types in Rust, similar to C++?

Tags:

c++

rust

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?

like image 791
NickFP Avatar asked Oct 23 '25 10:10

NickFP


1 Answers

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)

like image 134
mcarton Avatar answered Oct 25 '25 00:10

mcarton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!