-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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.