aldanor
aldanor

Reputation: 3481

How can I write a generic function that discriminates between signed and unsigned int?

I was wondering if it was possible to discriminate between a signed and unsigned int in Rust. In std::num we have Int, UnsignedInt : Int and SignedInt : Int + Neg, so those two are not mutually exclusive.

In the simplest case, would it be possible to write a simple function fn<T: Int>is_signed(value: T) -> bool that would return true when a signed value is passed (e.g. i32)? Is there a better way of doing this?

Edit in response to a comment below: a real-world example is wrapping a C FFI where functions that return signed integer types indicate an error by returning a -1 whereas functions returning uints indicate error by returning 0 (this, plus it got me interested in what's an idiomatic way of doing it in Rust).

Upvotes: 7

Views: 1725

Answers (1)

wingedsubmariner
wingedsubmariner

Reputation: 13667

You can take advantage of the methods on Int to implement is_signed:

fn is_signed<T: Int>(x: T) -> bool {
    let mv: T = Int::min_value();
    let z: T = Int::zero();
    mv < z
}

And then use it like:

is_signed(5i)

Or if you remove the unneeded parameter x from is_signed:

is_signed<i32>

However, this would not be very efficient or idiomatic. In your case of checking error codes, it would be better to define a trait with the behavior you want, and implement it for each possible type:

trait IsError {
    fn is_error(self) -> bool;
}

impl IsError for isize {
    fn is_error(self) -> bool { self < 0 }
}

impl IsError for usize {
    fn is_error(self) -> bool { self == 0 }
}

Upvotes: 6

Related Questions