- Notifications
You must be signed in to change notification settings - Fork 13.8k
Open
Labels
C-feature-requestCategory: A feature request, i.e: not implemented / a PR.Category: A feature request, i.e: not implemented / a PR.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Description
To remove some unsafe "as" casts and keep the code safe (lossless) and nice, sometimes I'd like to use a rem+cast. So what do you think about adding this to the stdlib?
trait NarrowRem<Out> { fn narrowing_rem(&self, den: Out) -> Out; } impl NarrowRem<u8> for u16 { fn narrowing_rem(&self, den: u8) -> u8 { (*self % u16::from(den)) as u8 } } impl NarrowRem<u8> for u32 { fn narrowing_rem(&self, den: u8) -> u8 { (*self % u32::from(den)) as u8 } } impl NarrowRem<u16> for u32 { fn narrowing_rem(&self, den: u16) -> u16 { (*self % u32::from(den)) as u16 } } impl NarrowRem<u8> for u64 { fn narrowing_rem(&self, den: u8) -> u8 { (*self % u64::from(den)) as u8 } } impl NarrowRem<u16> for u64 { fn narrowing_rem(&self, den: u16) -> u16 { (*self % u64::from(den)) as u16 } } impl NarrowRem<u32> for u64 { fn narrowing_rem(&self, den: u32) -> u32 { (*self % u64::from(den)) as u32 } } impl NarrowRem<u8> for u128 { fn narrowing_rem(&self, den: u8) -> u8 { (*self % u128::from(den)) as u8 } } impl NarrowRem<u16> for u128 { fn narrowing_rem(&self, den: u16) -> u16 { (*self % u128::from(den)) as u16 } } impl NarrowRem<u32> for u128 { fn narrowing_rem(&self, den: u32) -> u32 { (*self % u128::from(den)) as u32 } } impl NarrowRem<u64> for u128 { fn narrowing_rem(&self, den: u64) -> u64 { (*self % u128::from(den)) as u64 } } impl NarrowRem<i8> for i16 { fn narrowing_rem(&self, den: i8) -> i8 { (*self % i16::from(den)) as i8 } } impl NarrowRem<i8> for i32 { fn narrowing_rem(&self, den: i8) -> i8 { (*self % i32::from(den)) as i8 } } impl NarrowRem<i16> for i32 { fn narrowing_rem(&self, den: i16) -> i16 { (*self % i32::from(den)) as i16 } } impl NarrowRem<i8> for i64 { fn narrowing_rem(&self, den: i8) -> i8 { (*self % i64::from(den)) as i8 } } impl NarrowRem<i16> for i64 { fn narrowing_rem(&self, den: i16) -> i16 { (*self % i64::from(den)) as i16 } } impl NarrowRem<i32> for i64 { fn narrowing_rem(&self, den: i32) -> i32 { (*self % i64::from(den)) as i32 } } impl NarrowRem<i8> for i128 { fn narrowing_rem(&self, den: i8) -> i8 { (*self % i128::from(den)) as i8 } } impl NarrowRem<i16> for i128 { fn narrowing_rem(&self, den: i16) -> i16 { (*self % i128::from(den)) as i16 } } impl NarrowRem<i32> for i128 { fn narrowing_rem(&self, den: i32) -> i32 { (*self % i128::from(den)) as i32 } } impl NarrowRem<i64> for i128 { fn narrowing_rem(&self, den: i64) -> i64 { (*self % i128::from(den)) as i64 } } impl NarrowRem<u8> for usize { fn narrowing_rem(&self, den: u8) -> u8 { (*self % usize::from(den)) as u8 } } impl NarrowRem<u16> for usize { fn narrowing_rem(&self, den: u16) -> u16 { (*self % usize::from(den)) as u16 } } impl NarrowRem<i8> for isize { fn narrowing_rem(&self, den: i8) -> i8 { (*self % isize::from(den)) as i8 } } impl NarrowRem<i16> for isize { fn narrowing_rem(&self, den: i16) -> i16 { (*self % isize::from(den)) as i16 } }
An example usage:
fn main() { let _x: u8 = 152_u64.narrowing_rem(51_u8); }
D language performs this lossless cast operation automatically and transparently (while it doesn't perform lossy casts silently):
uint foo(in ulong x) { // Error: cannot implicitly convert return x; } uint bar(in ulong x) { // OK return x % 1000; } void main() {}
jhpratt
Metadata
Metadata
Assignees
Labels
C-feature-requestCategory: A feature request, i.e: not implemented / a PR.Category: A feature request, i.e: not implemented / a PR.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.