mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Auto merge of #30523 - ubsan:wrapping_op_assign, r=eddyb
Add OpAssign to Wrapping<T>, plus fix some problems in core::num::wrapping including, but not limited to: * Testing Wrapping<T> * Pull out a lot of broken code that doesn't need to be there with the new stage0 compiler * Adding Rem and RemAssign to Wrapping<T> * Removed 3 (assumed accidental) re-exports, which is a minor [breaking-change]. * Change shl and shr to take all integer types, instead of a usize; this is a more major [breaking-change], because of values that were inferred before, but brings us in line with the integer shifts. Fixes #30524 and #30523
This commit is contained in:
commit
5e8cb3819b
@ -12,13 +12,13 @@
|
||||
#![unstable(feature = "wrapping", reason = "may be removed or relocated",
|
||||
issue = "27755")]
|
||||
|
||||
pub use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow};
|
||||
use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow};
|
||||
|
||||
use super::Wrapping;
|
||||
|
||||
use ops::*;
|
||||
|
||||
use ::{i8,i16,i32,i64};
|
||||
use ::{i8, i16, i32, i64, isize};
|
||||
|
||||
pub trait OverflowingOps {
|
||||
fn overflowing_add(self, rhs: Self) -> (Self, bool);
|
||||
@ -33,15 +33,27 @@ pub trait OverflowingOps {
|
||||
fn overflowing_shr(self, rhs: u32) -> (Self, bool);
|
||||
}
|
||||
|
||||
macro_rules! sh_impl {
|
||||
($t:ty, $f:ty) => (
|
||||
macro_rules! sh_impl_signed {
|
||||
($t:ident, $f:ident) => (
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shl<$f> for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
||||
#[inline(always)]
|
||||
fn shl(self, other: $f) -> Wrapping<$t> {
|
||||
Wrapping(self.0 << other)
|
||||
if other < 0 {
|
||||
Wrapping(self.0 >> (-other & self::shift_max::$t as $f))
|
||||
} else {
|
||||
Wrapping(self.0 << (other & self::shift_max::$t as $f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
|
||||
impl ShlAssign<$f> for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn shl_assign(&mut self, other: $f) {
|
||||
*self = *self << other;
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +63,59 @@ macro_rules! sh_impl {
|
||||
|
||||
#[inline(always)]
|
||||
fn shr(self, other: $f) -> Wrapping<$t> {
|
||||
Wrapping(self.0 >> other)
|
||||
if other < 0 {
|
||||
Wrapping(self.0 << (-other & self::shift_max::$t as $f))
|
||||
} else {
|
||||
Wrapping(self.0 >> (other & self::shift_max::$t as $f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
|
||||
impl ShrAssign<$f> for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn shr_assign(&mut self, other: $f) {
|
||||
*self = *self >> other;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! sh_impl_unsigned {
|
||||
($t:ident, $f:ident) => (
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shl<$f> for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
||||
#[inline(always)]
|
||||
fn shl(self, other: $f) -> Wrapping<$t> {
|
||||
Wrapping(self.0 << (other & self::shift_max::$t as $f))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
|
||||
impl ShlAssign<$f> for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn shl_assign(&mut self, other: $f) {
|
||||
*self = *self << other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shr<$f> for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
||||
#[inline(always)]
|
||||
fn shr(self, other: $f) -> Wrapping<$t> {
|
||||
Wrapping(self.0 >> (other & self::shift_max::$t as $f))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
|
||||
impl ShrAssign<$f> for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn shr_assign(&mut self, other: $f) {
|
||||
*self = *self >> other;
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -59,23 +123,24 @@ macro_rules! sh_impl {
|
||||
|
||||
// FIXME (#23545): uncomment the remaining impls
|
||||
macro_rules! sh_impl_all {
|
||||
($($t:ty)*) => ($(
|
||||
// sh_impl! { $t, u8 }
|
||||
// sh_impl! { $t, u16 }
|
||||
// sh_impl! { $t, u32 }
|
||||
// sh_impl! { $t, u64 }
|
||||
sh_impl! { $t, usize }
|
||||
($($t:ident)*) => ($(
|
||||
sh_impl_unsigned! { $t, u8 }
|
||||
sh_impl_unsigned! { $t, u16 }
|
||||
sh_impl_unsigned! { $t, u32 }
|
||||
sh_impl_unsigned! { $t, u64 }
|
||||
sh_impl_unsigned! { $t, usize }
|
||||
|
||||
// sh_impl! { $t, i8 }
|
||||
// sh_impl! { $t, i16 }
|
||||
// sh_impl! { $t, i32 }
|
||||
// sh_impl! { $t, i64 }
|
||||
// sh_impl! { $t, isize }
|
||||
sh_impl_signed! { $t, i8 }
|
||||
sh_impl_signed! { $t, i16 }
|
||||
sh_impl_signed! { $t, i32 }
|
||||
sh_impl_signed! { $t, i64 }
|
||||
sh_impl_signed! { $t, isize }
|
||||
)*)
|
||||
}
|
||||
|
||||
sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
|
||||
|
||||
// FIXME(30524): impl Op<T> for Wrapping<T>, impl OpAssign<T> for Wrapping<T>
|
||||
macro_rules! wrapping_impl {
|
||||
($($t:ty)*) => ($(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -88,6 +153,14 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl AddAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn add_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self + other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Sub for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -98,6 +171,14 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl SubAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn sub_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self - other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Mul for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -108,6 +189,14 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl MulAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn mul_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self * other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "wrapping_div", since = "1.3.0")]
|
||||
impl Div for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -118,6 +207,32 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl DivAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn div_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self / other;
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
|
||||
impl Rem for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
||||
#[inline(always)]
|
||||
fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> {
|
||||
Wrapping(self.0.wrapping_rem(other.0))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl RemAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn rem_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self % other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Not for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -138,6 +253,14 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl BitXorAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn bitxor_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self ^ other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl BitOr for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -148,6 +271,14 @@ macro_rules! wrapping_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl BitOrAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn bitor_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self | other;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl BitAnd for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
@ -157,6 +288,14 @@ macro_rules! wrapping_impl {
|
||||
Wrapping(self.0 & other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
|
||||
impl BitAndAssign for Wrapping<$t> {
|
||||
#[inline(always)]
|
||||
fn bitand_assign(&mut self, other: Wrapping<$t>) {
|
||||
*self = *self & other;
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
@ -165,15 +304,29 @@ wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
mod shift_max {
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
mod platform {
|
||||
pub const usize: u32 = super::u32;
|
||||
pub const isize: u32 = super::i32;
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod platform {
|
||||
pub const usize: u32 = super::u64;
|
||||
pub const isize: u32 = super::i64;
|
||||
}
|
||||
|
||||
pub const i8: u32 = (1 << 3) - 1;
|
||||
pub const i16: u32 = (1 << 4) - 1;
|
||||
pub const i32: u32 = (1 << 5) - 1;
|
||||
pub const i64: u32 = (1 << 6) - 1;
|
||||
pub use self::platform::isize;
|
||||
|
||||
pub const u8: u32 = i8;
|
||||
pub const u16: u32 = i16;
|
||||
pub const u32: u32 = i32;
|
||||
pub const u64: u32 = i64;
|
||||
pub use self::platform::usize;
|
||||
}
|
||||
|
||||
macro_rules! signed_overflowing_impl {
|
||||
@ -288,193 +441,5 @@ macro_rules! unsigned_overflowing_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
signed_overflowing_impl! { i8 i16 i32 i64 }
|
||||
unsigned_overflowing_impl! { u8 u16 u32 u64 }
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl OverflowingOps for usize {
|
||||
#[inline(always)]
|
||||
fn overflowing_add(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
add_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
sub_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
mul_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_div(self, rhs: usize) -> (usize, bool) {
|
||||
let (r, f) = (self as u64).overflowing_div(rhs as u64);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
|
||||
let (r, f) = (self as u64).overflowing_rem(rhs as u64);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_neg(self) -> (usize, bool) {
|
||||
let (r, f) = (self as u64).overflowing_neg();
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
|
||||
let (r, f) = (self as u64).overflowing_shl(rhs);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
|
||||
let (r, f) = (self as u64).overflowing_shr(rhs);
|
||||
(r as usize, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
impl OverflowingOps for usize {
|
||||
#[inline(always)]
|
||||
fn overflowing_add(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
add_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
sub_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
|
||||
unsafe {
|
||||
mul_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_div(self, rhs: usize) -> (usize, bool) {
|
||||
let (r, f) = (self as u32).overflowing_div(rhs as u32);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
|
||||
let (r, f) = (self as u32).overflowing_rem(rhs as u32);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_neg(self) -> (usize, bool) {
|
||||
let (r, f) = (self as u32).overflowing_neg();
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
|
||||
let (r, f) = (self as u32).overflowing_shl(rhs);
|
||||
(r as usize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
|
||||
let (r, f) = (self as u32).overflowing_shr(rhs);
|
||||
(r as usize, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl OverflowingOps for isize {
|
||||
#[inline(always)]
|
||||
fn overflowing_add(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
add_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
sub_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
mul_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_div(self, rhs: isize) -> (isize, bool) {
|
||||
let (r, f) = (self as i64).overflowing_div(rhs as i64);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
|
||||
let (r, f) = (self as i64).overflowing_rem(rhs as i64);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_neg(self) -> (isize, bool) {
|
||||
let (r, f) = (self as i64).overflowing_neg();
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
|
||||
let (r, f) = (self as i64).overflowing_shl(rhs);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
|
||||
let (r, f) = (self as i64).overflowing_shr(rhs);
|
||||
(r as isize, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
impl OverflowingOps for isize {
|
||||
#[inline(always)]
|
||||
fn overflowing_add(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
add_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
sub_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
|
||||
unsafe {
|
||||
mul_with_overflow(self, rhs)
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_div(self, rhs: isize) -> (isize, bool) {
|
||||
let (r, f) = (self as i32).overflowing_div(rhs as i32);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
|
||||
let (r, f) = (self as i32).overflowing_rem(rhs as i32);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_neg(self) -> (isize, bool) {
|
||||
let (r, f) = (self as i32).overflowing_neg();
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
|
||||
let (r, f) = (self as i32).overflowing_shl(rhs);
|
||||
(r as isize, f)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
|
||||
let (r, f) = (self as i32).overflowing_shr(rhs);
|
||||
(r as isize, f)
|
||||
}
|
||||
}
|
||||
signed_overflowing_impl! { i8 i16 i32 i64 isize }
|
||||
unsigned_overflowing_impl! { u8 u16 u32 u64 usize }
|
||||
|
@ -170,7 +170,7 @@ impl IsaacRng {
|
||||
const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
|
||||
|
||||
macro_rules! ind {
|
||||
($x:expr) => (self.mem[($x >> 2).0 as usize & (RAND_SIZE_USIZE - 1)] )
|
||||
($x:expr) => (self.mem[($x >> 2u32).0 as usize & (RAND_SIZE_USIZE - 1)] )
|
||||
}
|
||||
|
||||
let r = [(0, MIDPOINT), (MIDPOINT, 0)];
|
||||
@ -452,7 +452,7 @@ impl Isaac64Rng {
|
||||
const MP_VEC: [(usize, usize); 2] = [(0, MIDPOINT), (MIDPOINT, 0)];
|
||||
macro_rules! ind {
|
||||
($x:expr) => {
|
||||
*self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
|
||||
*self.mem.get_unchecked((($x >> 3u32).0 as usize) & (RAND_SIZE_64 - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,10 +495,10 @@ impl Isaac64Rng {
|
||||
}}
|
||||
}
|
||||
|
||||
rngstepp!(0, 21);
|
||||
rngstepn!(1, 5);
|
||||
rngstepp!(2, 12);
|
||||
rngstepn!(3, 33);
|
||||
rngstepp!(0, 21u32);
|
||||
rngstepn!(1, 5u32);
|
||||
rngstepp!(2, 12u32);
|
||||
rngstepn!(3, 33u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
412
src/test/run-pass/num-wrapping.rs
Normal file
412
src/test/run-pass/num-wrapping.rs
Normal file
@ -0,0 +1,412 @@
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// compile-flags: -C debug-assertions
|
||||
//
|
||||
// Test std::num::Wrapping<T> for {uN, iN, usize, isize}
|
||||
|
||||
#![feature(op_assign_traits, num_bits_bytes, test)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use std::num::Wrapping;
|
||||
use std::ops::{
|
||||
Add, Sub, Mul, Div, Rem, BitXor, BitOr, BitAnd,
|
||||
AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, BitXorAssign, BitOrAssign, BitAndAssign,
|
||||
Shl, Shr, ShlAssign, ShrAssign
|
||||
};
|
||||
use std::{i8, i16, i32, i64, isize, u8, u16, u32, u64, usize};
|
||||
use test::black_box;
|
||||
|
||||
fn main() {
|
||||
test_ops();
|
||||
test_op_assigns();
|
||||
test_sh_ops();
|
||||
test_sh_op_assigns();
|
||||
}
|
||||
|
||||
fn test_ops() {
|
||||
macro_rules! op_test {
|
||||
($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => {
|
||||
assert_eq!(black_box(Wrapping($lhs).$op(Wrapping($rhs))), Wrapping($ans));
|
||||
// FIXME(30524): uncomment this test when it's implemented
|
||||
// assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans));
|
||||
}
|
||||
}
|
||||
|
||||
op_test!(add(i8::MAX, 1) == i8::MIN);
|
||||
op_test!(add(i16::MAX, 1) == i16::MIN);
|
||||
op_test!(add(i32::MAX, 1) == i32::MIN);
|
||||
op_test!(add(i64::MAX, 1) == i64::MIN);
|
||||
op_test!(add(isize::MAX, 1) == isize::MIN);
|
||||
|
||||
op_test!(add(u8::MAX, 1) == 0);
|
||||
op_test!(add(u16::MAX, 1) == 0);
|
||||
op_test!(add(u32::MAX, 1) == 0);
|
||||
op_test!(add(u64::MAX, 1) == 0);
|
||||
op_test!(add(usize::MAX, 1) == 0);
|
||||
|
||||
|
||||
op_test!(sub(i8::MIN, 1) == i8::MAX);
|
||||
op_test!(sub(i16::MIN, 1) == i16::MAX);
|
||||
op_test!(sub(i32::MIN, 1) == i32::MAX);
|
||||
op_test!(sub(i64::MIN, 1) == i64::MAX);
|
||||
op_test!(sub(isize::MIN, 1) == isize::MAX);
|
||||
|
||||
op_test!(sub(0u8, 1) == u8::MAX);
|
||||
op_test!(sub(0u16, 1) == u16::MAX);
|
||||
op_test!(sub(0u32, 1) == u32::MAX);
|
||||
op_test!(sub(0u64, 1) == u64::MAX);
|
||||
op_test!(sub(0usize, 1) == usize::MAX);
|
||||
|
||||
|
||||
op_test!(mul(i8::MAX, 2) == -2);
|
||||
op_test!(mul(i16::MAX, 2) == -2);
|
||||
op_test!(mul(i32::MAX, 2) == -2);
|
||||
op_test!(mul(i64::MAX, 2) == -2);
|
||||
op_test!(mul(isize::MAX, 2) == -2);
|
||||
|
||||
op_test!(mul(u8::MAX, 2) == u8::MAX - 1);
|
||||
op_test!(mul(u16::MAX, 2) == u16::MAX - 1);
|
||||
op_test!(mul(u32::MAX, 2) == u32::MAX - 1);
|
||||
op_test!(mul(u64::MAX, 2) == u64::MAX - 1);
|
||||
op_test!(mul(usize::MAX, 2) == usize::MAX - 1);
|
||||
|
||||
|
||||
op_test!(div(i8::MIN, -1) == i8::MIN);
|
||||
op_test!(div(i16::MIN, -1) == i16::MIN);
|
||||
op_test!(div(i32::MIN, -1) == i32::MIN);
|
||||
op_test!(div(i64::MIN, -1) == i64::MIN);
|
||||
op_test!(div(isize::MIN, -1) == isize::MIN);
|
||||
|
||||
|
||||
op_test!(rem(i8::MIN, -1) == 0);
|
||||
op_test!(rem(i16::MIN, -1) == 0);
|
||||
op_test!(rem(i32::MIN, -1) == 0);
|
||||
op_test!(rem(i64::MIN, -1) == 0);
|
||||
op_test!(rem(isize::MIN, -1) == 0);
|
||||
|
||||
// these are not that interesting, just testing to make sure they are implemented correctly
|
||||
op_test!(bitxor(0b101010i8, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010i16, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010i32, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010i64, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010isize, 0b100110) == 0b001100);
|
||||
|
||||
op_test!(bitxor(0b101010u8, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010u16, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010u32, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010u64, 0b100110) == 0b001100);
|
||||
op_test!(bitxor(0b101010usize, 0b100110) == 0b001100);
|
||||
|
||||
|
||||
op_test!(bitor(0b101010i8, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010i16, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010i32, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010i64, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010isize, 0b100110) == 0b101110);
|
||||
|
||||
op_test!(bitor(0b101010u8, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010u16, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010u32, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010u64, 0b100110) == 0b101110);
|
||||
op_test!(bitor(0b101010usize, 0b100110) == 0b101110);
|
||||
|
||||
|
||||
op_test!(bitand(0b101010i8, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010i16, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010i32, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010i64, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010isize, 0b100110) == 0b100010);
|
||||
|
||||
op_test!(bitand(0b101010u8, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010u16, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010u32, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010u64, 0b100110) == 0b100010);
|
||||
op_test!(bitand(0b101010usize, 0b100110) == 0b100010);
|
||||
}
|
||||
|
||||
fn test_op_assigns() {
|
||||
macro_rules! op_assign_test {
|
||||
($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {
|
||||
{
|
||||
let mut tmp = Wrapping($initial);
|
||||
tmp = black_box(tmp);
|
||||
tmp.$op(Wrapping($rhs));
|
||||
assert_eq!(black_box(tmp), Wrapping($ans));
|
||||
}
|
||||
// FIXME(30524): Uncomment this test
|
||||
/*
|
||||
{
|
||||
let mut tmp = Wrapping($initial);
|
||||
tmp = black_box(tmp);
|
||||
tmp.$op($rhs);
|
||||
assert_eq!(black_box(tmp), Wrapping($ans));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
op_assign_test!(add_assign(i8::MAX, 1) == i8::MIN);
|
||||
op_assign_test!(add_assign(i16::MAX, 1) == i16::MIN);
|
||||
op_assign_test!(add_assign(i32::MAX, 1) == i32::MIN);
|
||||
op_assign_test!(add_assign(i64::MAX, 1) == i64::MIN);
|
||||
op_assign_test!(add_assign(isize::MAX, 1) == isize::MIN);
|
||||
|
||||
op_assign_test!(add_assign(u8::MAX, 1) == u8::MIN);
|
||||
op_assign_test!(add_assign(u16::MAX, 1) == u16::MIN);
|
||||
op_assign_test!(add_assign(u32::MAX, 1) == u32::MIN);
|
||||
op_assign_test!(add_assign(u64::MAX, 1) == u64::MIN);
|
||||
op_assign_test!(add_assign(usize::MAX, 1) == usize::MIN);
|
||||
|
||||
|
||||
op_assign_test!(sub_assign(i8::MIN, 1) == i8::MAX);
|
||||
op_assign_test!(sub_assign(i16::MIN, 1) == i16::MAX);
|
||||
op_assign_test!(sub_assign(i32::MIN, 1) == i32::MAX);
|
||||
op_assign_test!(sub_assign(i64::MIN, 1) == i64::MAX);
|
||||
op_assign_test!(sub_assign(isize::MIN, 1) == isize::MAX);
|
||||
|
||||
op_assign_test!(sub_assign(u8::MIN, 1) == u8::MAX);
|
||||
op_assign_test!(sub_assign(u16::MIN, 1) == u16::MAX);
|
||||
op_assign_test!(sub_assign(u32::MIN, 1) == u32::MAX);
|
||||
op_assign_test!(sub_assign(u64::MIN, 1) == u64::MAX);
|
||||
op_assign_test!(sub_assign(usize::MIN, 1) == usize::MAX);
|
||||
|
||||
|
||||
op_assign_test!(mul_assign(i8::MAX, 2) == -2);
|
||||
op_assign_test!(mul_assign(i16::MAX, 2) == -2);
|
||||
op_assign_test!(mul_assign(i32::MAX, 2) == -2);
|
||||
op_assign_test!(mul_assign(i64::MAX, 2) == -2);
|
||||
op_assign_test!(mul_assign(isize::MAX, 2) == -2);
|
||||
|
||||
op_assign_test!(mul_assign(u8::MAX, 2) == u8::MAX - 1);
|
||||
op_assign_test!(mul_assign(u16::MAX, 2) == u16::MAX - 1);
|
||||
op_assign_test!(mul_assign(u32::MAX, 2) == u32::MAX - 1);
|
||||
op_assign_test!(mul_assign(u64::MAX, 2) == u64::MAX - 1);
|
||||
op_assign_test!(mul_assign(usize::MAX, 2) == usize::MAX - 1);
|
||||
|
||||
|
||||
op_assign_test!(div_assign(i8::MIN, -1) == i8::MIN);
|
||||
op_assign_test!(div_assign(i16::MIN, -1) == i16::MIN);
|
||||
op_assign_test!(div_assign(i32::MIN, -1) == i32::MIN);
|
||||
op_assign_test!(div_assign(i64::MIN, -1) == i64::MIN);
|
||||
op_assign_test!(div_assign(isize::MIN, -1) == isize::MIN);
|
||||
|
||||
|
||||
op_assign_test!(rem_assign(i8::MIN, -1) == 0);
|
||||
op_assign_test!(rem_assign(i16::MIN, -1) == 0);
|
||||
op_assign_test!(rem_assign(i32::MIN, -1) == 0);
|
||||
op_assign_test!(rem_assign(i64::MIN, -1) == 0);
|
||||
op_assign_test!(rem_assign(isize::MIN, -1) == 0);
|
||||
|
||||
|
||||
// these are not that interesting, just testing to make sure they are implemented correctly
|
||||
op_assign_test!(bitxor_assign(0b101010i8, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010i16, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010i32, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010i64, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010isize, 0b100110) == 0b001100);
|
||||
|
||||
op_assign_test!(bitxor_assign(0b101010u8, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010u16, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010u32, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010u64, 0b100110) == 0b001100);
|
||||
op_assign_test!(bitxor_assign(0b101010usize, 0b100110) == 0b001100);
|
||||
|
||||
|
||||
op_assign_test!(bitor_assign(0b101010i8, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010i16, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010i32, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010i64, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010isize, 0b100110) == 0b101110);
|
||||
|
||||
op_assign_test!(bitor_assign(0b101010u8, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010u16, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010u32, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010u64, 0b100110) == 0b101110);
|
||||
op_assign_test!(bitor_assign(0b101010usize, 0b100110) == 0b101110);
|
||||
|
||||
|
||||
op_assign_test!(bitand_assign(0b101010i8, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010i16, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010i32, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010i64, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010isize, 0b100110) == 0b100010);
|
||||
|
||||
op_assign_test!(bitand_assign(0b101010u8, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010u16, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010u32, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010u64, 0b100110) == 0b100010);
|
||||
op_assign_test!(bitand_assign(0b101010usize, 0b100110) == 0b100010);
|
||||
}
|
||||
|
||||
fn test_sh_ops() {
|
||||
macro_rules! sh_test {
|
||||
($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => {
|
||||
assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans));
|
||||
}
|
||||
}
|
||||
// NOTE: This will break for i8 if we ever get i/u128
|
||||
macro_rules! sh_test_all {
|
||||
($t:ty) => {
|
||||
sh_test!(shl(i8::MAX, (i8::BITS + 1) as $t) == -2);
|
||||
sh_test!(shl(i16::MAX, (i16::BITS + 1) as $t) == -2);
|
||||
sh_test!(shl(i32::MAX, (i32::BITS + 1) as $t) == -2);
|
||||
sh_test!(shl(i64::MAX, (i64::BITS + 1) as $t) == -2);
|
||||
sh_test!(shl(isize::MAX, (isize::BITS + 1) as $t) == -2);
|
||||
|
||||
sh_test!(shl(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1);
|
||||
sh_test!(shl(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1);
|
||||
sh_test!(shl(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1);
|
||||
sh_test!(shl(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1);
|
||||
sh_test!(shl(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1);
|
||||
|
||||
|
||||
sh_test!(shr(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2);
|
||||
sh_test!(shr(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2);
|
||||
sh_test!(shr(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2);
|
||||
sh_test!(shr(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2);
|
||||
sh_test!(shr(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2);
|
||||
|
||||
sh_test!(shr(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2);
|
||||
sh_test!(shr(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2);
|
||||
sh_test!(shr(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2);
|
||||
sh_test!(shr(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2);
|
||||
sh_test!(shr(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2);
|
||||
}
|
||||
}
|
||||
macro_rules! sh_test_negative_all {
|
||||
($t:ty) => {
|
||||
sh_test!(shr(i8::MAX, -((i8::BITS + 1) as $t)) == -2);
|
||||
sh_test!(shr(i16::MAX, -((i16::BITS + 1) as $t)) == -2);
|
||||
sh_test!(shr(i32::MAX, -((i32::BITS + 1) as $t)) == -2);
|
||||
sh_test!(shr(i64::MAX, -((i64::BITS + 1) as $t)) == -2);
|
||||
sh_test!(shr(isize::MAX, -((isize::BITS + 1) as $t)) == -2);
|
||||
|
||||
sh_test!(shr(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1);
|
||||
sh_test!(shr(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1);
|
||||
sh_test!(shr(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1);
|
||||
sh_test!(shr(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1);
|
||||
sh_test!(shr(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1);
|
||||
|
||||
|
||||
sh_test!(shl(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2);
|
||||
sh_test!(shl(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2);
|
||||
sh_test!(shl(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2);
|
||||
sh_test!(shl(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2);
|
||||
sh_test!(shl(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2);
|
||||
|
||||
sh_test!(shl(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2);
|
||||
sh_test!(shl(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2);
|
||||
sh_test!(shl(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2);
|
||||
sh_test!(shl(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2);
|
||||
sh_test!(shl(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2);
|
||||
}
|
||||
}
|
||||
sh_test_all!(i8);
|
||||
sh_test_all!(u8);
|
||||
sh_test_all!(i16);
|
||||
sh_test_all!(u16);
|
||||
sh_test_all!(i32);
|
||||
sh_test_all!(u32);
|
||||
sh_test_all!(i64);
|
||||
sh_test_all!(u64);
|
||||
sh_test_all!(isize);
|
||||
sh_test_all!(usize);
|
||||
|
||||
sh_test_negative_all!(i8);
|
||||
sh_test_negative_all!(i16);
|
||||
sh_test_negative_all!(i32);
|
||||
sh_test_negative_all!(i64);
|
||||
sh_test_negative_all!(isize);
|
||||
}
|
||||
|
||||
fn test_sh_op_assigns() {
|
||||
macro_rules! sh_assign_test {
|
||||
($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {{
|
||||
let mut tmp = Wrapping($initial);
|
||||
tmp = black_box(tmp);
|
||||
tmp.$op($rhs);
|
||||
assert_eq!(black_box(tmp), Wrapping($ans));
|
||||
}}
|
||||
}
|
||||
macro_rules! sh_assign_test_all {
|
||||
($t:ty) => {
|
||||
sh_assign_test!(shl_assign(i8::MAX, (i8::BITS + 1) as $t) == -2);
|
||||
sh_assign_test!(shl_assign(i16::MAX, (i16::BITS + 1) as $t) == -2);
|
||||
sh_assign_test!(shl_assign(i32::MAX, (i32::BITS + 1) as $t) == -2);
|
||||
sh_assign_test!(shl_assign(i64::MAX, (i64::BITS + 1) as $t) == -2);
|
||||
sh_assign_test!(shl_assign(isize::MAX, (isize::BITS + 1) as $t) == -2);
|
||||
|
||||
sh_assign_test!(shl_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1);
|
||||
sh_assign_test!(shl_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1);
|
||||
sh_assign_test!(shl_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1);
|
||||
sh_assign_test!(shl_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1);
|
||||
sh_assign_test!(shl_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1);
|
||||
|
||||
|
||||
sh_assign_test!(shr_assign(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2);
|
||||
sh_assign_test!(shr_assign(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2);
|
||||
sh_assign_test!(shr_assign(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2);
|
||||
sh_assign_test!(shr_assign(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2);
|
||||
sh_assign_test!(shr_assign(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2);
|
||||
|
||||
sh_assign_test!(shr_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2);
|
||||
sh_assign_test!(shr_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2);
|
||||
sh_assign_test!(shr_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2);
|
||||
sh_assign_test!(shr_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2);
|
||||
sh_assign_test!(shr_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2);
|
||||
}
|
||||
}
|
||||
macro_rules! sh_assign_test_negative_all {
|
||||
($t:ty) => {
|
||||
sh_assign_test!(shr_assign(i8::MAX, -((i8::BITS + 1) as $t)) == -2);
|
||||
sh_assign_test!(shr_assign(i16::MAX, -((i16::BITS + 1) as $t)) == -2);
|
||||
sh_assign_test!(shr_assign(i32::MAX, -((i32::BITS + 1) as $t)) == -2);
|
||||
sh_assign_test!(shr_assign(i64::MAX, -((i64::BITS + 1) as $t)) == -2);
|
||||
sh_assign_test!(shr_assign(isize::MAX, -((isize::BITS + 1) as $t)) == -2);
|
||||
|
||||
sh_assign_test!(shr_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1);
|
||||
sh_assign_test!(shr_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1);
|
||||
sh_assign_test!(shr_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1);
|
||||
sh_assign_test!(shr_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1);
|
||||
sh_assign_test!(shr_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1);
|
||||
|
||||
|
||||
sh_assign_test!(shl_assign(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2);
|
||||
sh_assign_test!(shl_assign(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2);
|
||||
sh_assign_test!(shl_assign(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2);
|
||||
sh_assign_test!(shl_assign(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2);
|
||||
sh_assign_test!(shl_assign(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2);
|
||||
|
||||
sh_assign_test!(shl_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2);
|
||||
sh_assign_test!(shl_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2);
|
||||
sh_assign_test!(shl_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2);
|
||||
sh_assign_test!(shl_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2);
|
||||
sh_assign_test!(shl_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2);
|
||||
}
|
||||
}
|
||||
|
||||
sh_assign_test_all!(i8);
|
||||
sh_assign_test_all!(u8);
|
||||
sh_assign_test_all!(i16);
|
||||
sh_assign_test_all!(u16);
|
||||
sh_assign_test_all!(i32);
|
||||
sh_assign_test_all!(u32);
|
||||
sh_assign_test_all!(i64);
|
||||
sh_assign_test_all!(u64);
|
||||
sh_assign_test_all!(isize);
|
||||
sh_assign_test_all!(usize);
|
||||
|
||||
sh_assign_test_negative_all!(i8);
|
||||
sh_assign_test_negative_all!(i16);
|
||||
sh_assign_test_negative_all!(i32);
|
||||
sh_assign_test_negative_all!(i64);
|
||||
sh_assign_test_negative_all!(isize);
|
||||
}
|
Loading…
Reference in New Issue
Block a user