Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trait for signed to unsigned conversion #391

Open
sffc opened this issue Jun 13, 2020 · 2 comments
Open

Add trait for signed to unsigned conversion #391

sffc opened this issue Jun 13, 2020 · 2 comments

Comments

@sffc
Copy link

sffc commented Jun 13, 2020

I would like a trait such as

pub trait ToUnsigned {
    type UnsignedType: Unsigned;

    fn abs_unsigned(&self) -> Self::UnsignedType;
}

// Example for i32
impl ToUnsigned for i32 {
    type UnsignedType = u32;

    fn abs_unsigned(&self) -> Self::UnsignedType {
        self.abs() as Self::UnsignedType
    }
}

// Example for u32
impl ToUnsigned for u32 {
    type UnsignedType = u32;

    fn abs_unsigned(&self) -> Self::UnsignedType {
        *self
    }
}

Ideally, I would like the traits to "bubble" across the UnsignedType. For example, if my function accepts a T: ToUnsigned + Integer, then I would ideally want to be able to call .abs_unsigned() on T and get back something implementing both Unsigned and Integer.

@cuviper
Copy link
Member

cuviper commented Jun 13, 2020

I'm open to it. There's a similar request in rust-num/num-traits#163.

Ideally, I would like the traits to "bubble" across the UnsignedType. For example, if my function accepts a T: ToUnsigned + Integer, then I would ideally want to be able to call .abs_unsigned() on T and get back something implementing both Unsigned and Integer.

The way you've written the trait will always get you Unsigned, but I don't think it's possible to express the conditional part in an automatic way. You can manually write that like:

where
    T: ToUnsigned + Integer,
    <T as ToUnsigned>::UnsignedType: Integer,

You might try to make a wrapper trait:

pub trait ToUnsignedInteger: ToUnsigned + Integer
where
    <Self as ToUnsigned>::UnsignedType: Integer
{}

But I think that added constraint will have limited use do to rust-lang/rust#20671.

@sffc
Copy link
Author

sffc commented Jun 20, 2020

One snag with the trait definitions in my OP: they panic when given std::i32::MIN since it is not possible to call .abs() on that value. The actual trait implementations should handle this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants