-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Implement arithmetic overflow changes #20795
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
#![allow(missing_docs)] | ||
|
||
use ops::*; | ||
|
||
#[cfg(not(stage0))] | ||
use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul}; | ||
|
||
pub trait WrappingOps { | ||
fn wrapping_add(self, rhs: Self) -> Self; | ||
fn wrapping_sub(self, rhs: Self) -> Self; | ||
fn wrapping_mul(self, rhs: Self) -> Self; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two methods only make sense for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. floats don't panic on div by zero. they return inf. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Err, I surely meant that integers’ division panics and never overflows when dividing. |
||
} | ||
|
||
#[cfg(not(stage0))] | ||
macro_rules! wrapping_impl { | ||
($($t:ty)*) => ($( | ||
impl WrappingOps for $t { | ||
#[inline(always)] | ||
fn wrapping_add(self, rhs: $t) -> $t { | ||
unsafe { | ||
overflowing_add(self, rhs) | ||
} | ||
} | ||
#[inline(always)] | ||
fn wrapping_sub(self, rhs: $t) -> $t { | ||
unsafe { | ||
overflowing_sub(self, rhs) | ||
} | ||
} | ||
#[inline(always)] | ||
fn wrapping_mul(self, rhs: $t) -> $t { | ||
unsafe { | ||
overflowing_mul(self, rhs) | ||
} | ||
} | ||
} | ||
)*) | ||
} | ||
|
||
#[cfg(stage0)] | ||
macro_rules! wrapping_impl { | ||
($($t:ty)*) => ($( | ||
impl WrappingOps for $t { | ||
#[inline(always)] | ||
fn wrapping_add(self, rhs: $t) -> $t { | ||
self + rhs | ||
} | ||
#[inline(always)] | ||
fn wrapping_sub(self, rhs: $t) -> $t { | ||
self - rhs | ||
} | ||
#[inline(always)] | ||
fn wrapping_mul(self, rhs: $t) -> $t { | ||
self * rhs | ||
} | ||
} | ||
)*) | ||
} | ||
|
||
wrapping_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 } | ||
|
||
#[derive(PartialEq,Eq,PartialOrd,Ord,Clone,Copy)] | ||
pub struct Wrapping<T>(pub T); | ||
|
||
impl<T:WrappingOps> Add for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn add(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0.wrapping_add(other.0)) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps> Sub for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn sub(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0.wrapping_sub(other.0)) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps> Mul for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn mul(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0.wrapping_mul(other.0)) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps+Not<Output=T>> Not for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
fn not(self) -> Wrapping<T> { | ||
Wrapping(!self.0) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps+BitXor<Output=T>> BitXor for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn bitxor(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0 ^ other.0) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps+BitOr<Output=T>> BitOr for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn bitor(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0 | other.0) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps+BitAnd<Output=T>> BitAnd for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn bitand(self, other: Wrapping<T>) -> Wrapping<T> { | ||
Wrapping(self.0 & other.0) | ||
} | ||
} | ||
|
||
impl<T:WrappingOps+Shl<uint,Output=T>> Shl<uint> for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn shl(self, other: uint) -> Wrapping<T> { | ||
Wrapping(self.0 << other) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, shifts have extra overflow checks defined for them. |
||
} | ||
} | ||
|
||
impl<T:WrappingOps+Shr<uint,Output=T>> Shr<uint> for Wrapping<T> { | ||
type Output = Wrapping<T>; | ||
|
||
#[inline(always)] | ||
fn shr(self, other: uint) -> Wrapping<T> { | ||
Wrapping(self.0 >> other) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason these are overflowing_foo while the methods are wrapping_foo? I think wrapping_foo is a bit more descriptive, fwiw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we ought to give them consistent names.