blob: 12c2b6f8a7c98099e11296cb0171fa6d880a3c10 [file] [edit]
//@ run-pass
#![feature(step_trait)]
#![feature(ascii_char)]
use std::iter::Step;
use std::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
use std::ascii::Char as AsciiChar;
use std::net::{Ipv4Addr, Ipv6Addr};
// Pick various step sizes to exercise different overflow cases.
#[rustfmt::skip]
const STEPS: &[usize] = match usize::BITS {
64 => &[
1, 2, 5, 13, 29, 61, 127, 128, 255, 256, 511, 512,
1087, 4079, 17919, 32767, 32768, 65535, 65536,
(1 << 17) - 1, 1 << 17, (1 << 31) - 1, 1 << 31,
(1 << 32) - 1, 1 << 32, (1 << 63) - 1, 1 << 63,
usize::MAX,
],
32 => &[
1, 2, 5, 13, 29, 61, 127, 128, 255, 256, 511, 512,
1087, 4079, 17919, 32767, 32768, 65535, 65536,
(1 << 17) - 1, 1 << 17, (1 << 31) - 1, 1 << 31,
usize::MAX,
],
16 => &[
1, 2, 5, 13, 29, 61, 127, 128, 255, 256, 511, 512,
1087, 4079, 17919, 32767, 32768, usize::MAX
],
_ => &[
1, 2, 5, 13, 29, 61, 127, 128, usize::MAX
],
};
fn main() {
// Exhaustively test the smaller integers
for &step_size in STEPS {
let mut n = u8::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add(step_size as u8), true)
);
let mut n = u8::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub(step_size as u8), true)
);
}
for &step_size in STEPS {
let mut n = i8::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add_unsigned(step_size as u8), true)
);
let mut n = i8::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub_unsigned(step_size as u8), true)
);
}
for &step_size in STEPS {
let mut n = u16::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add(step_size as u16), true)
);
let mut n = u16::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub(step_size as u16), true)
);
}
for &step_size in STEPS {
let mut n = i16::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add_unsigned(step_size as u16), true)
);
let mut n = i16::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub_unsigned(step_size as u16), true)
);
}
for &step_size in STEPS {
let mut n = NonZeroU8::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (NonZeroU8::MAX, true));
let mut n = NonZeroU8::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (NonZeroU8::MIN, true));
}
for &step_size in STEPS {
let mut n = NonZeroU16::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (NonZeroU16::MAX, true));
let mut n = NonZeroU16::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (NonZeroU16::MIN, true));
}
// Test larger integers starting at MAX-2^16 and MIN+2^16
for &step_size in STEPS {
let mut n = u32::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add(step_size as u32), true)
);
let mut n = u32::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub(step_size as u32), true)
);
}
for &step_size in STEPS {
let mut n = i32::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add_unsigned(step_size as u32), true)
);
let mut n = i32::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub_unsigned(step_size as u32), true)
);
}
for &step_size in STEPS {
let mut n = u64::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add(step_size as u64), true)
);
let mut n = u64::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub(step_size as u64), true)
);
}
for &step_size in STEPS {
let mut n = i64::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add_unsigned(step_size as u64), true)
);
let mut n = i64::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub_unsigned(step_size as u64), true)
);
}
for &step_size in STEPS {
let mut n = u128::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add(step_size as u128), true)
);
let mut n = u128::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub(step_size as u128), true)
);
}
for &step_size in STEPS {
let mut n = i128::MAX - (1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(n.wrapping_add_unsigned(step_size as u128), true)
);
let mut n = i128::MIN + (1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(n.wrapping_sub_unsigned(step_size as u128), true)
);
}
for &step_size in STEPS {
let mut n = Step::backward(NonZeroU32::MAX, 1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (NonZeroU32::MAX, true));
let mut n = Step::forward(NonZeroU32::MIN, 1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (NonZeroU32::MIN, true));
}
for &step_size in STEPS {
let mut n = Step::backward(NonZeroU64::MAX, 1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (NonZeroU64::MAX, true));
let mut n = Step::forward(NonZeroU64::MIN, 1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (NonZeroU64::MIN, true));
}
for &step_size in STEPS {
let mut n = if usize::BITS > 16 {
usize::MAX - (1 << 16)
} else {
usize::MIN
};
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (n.wrapping_add(step_size), true));
let mut n = if usize::BITS > 16 {
usize::MIN + (1 << 16)
} else {
usize::MAX
};
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (n.wrapping_sub(step_size), true));
}
for &step_size in STEPS {
let mut n = if usize::BITS > 16 {
Step::backward(NonZeroUsize::MAX, 1 << 16)
} else {
NonZeroUsize::MIN
};
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (NonZeroUsize::MAX, true));
let mut n = if usize::BITS > 16 {
Step::forward(NonZeroUsize::MIN, 1 << 16)
} else {
NonZeroUsize::MAX
};
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (NonZeroUsize::MIN, true));
}
for &step_size in STEPS {
let mut n = Step::backward(char::MAX, 1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(Step::forward_overflowing(n, step_size), (char::MAX, true));
let mut n = Step::forward(char::MIN, 1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(Step::backward_overflowing(n, step_size), (char::MIN, true));
}
for &step_size in STEPS {
let mut n = AsciiChar::MIN;
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(AsciiChar::from_u8(
(n as u8).wrapping_add(step_size as u8) & (AsciiChar::MAX as u8)
).unwrap(), true)
);
let mut n = AsciiChar::MAX;
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(AsciiChar::from_u8(
(n as u8).wrapping_sub(step_size as u8) & (AsciiChar::MAX as u8)
).unwrap(), true)
);
}
for &step_size in STEPS {
let mut n = Step::backward(Ipv4Addr::from_bits(u32::MAX), 1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(Ipv4Addr::from_bits(n.to_bits().wrapping_add(step_size as u32)), true)
);
let mut n = Step::forward(Ipv4Addr::from_bits(u32::MIN), 1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(Ipv4Addr::from_bits(n.to_bits().wrapping_sub(step_size as u32)), true)
);
}
for &step_size in STEPS {
let mut n = Step::backward(Ipv6Addr::from_bits(u128::MAX), 1 << 16);
while let Some(p) = Step::forward_checked(n, step_size) {
assert_eq!(Step::forward_overflowing(n, step_size), (p, false));
n = p;
}
assert_eq!(
Step::forward_overflowing(n, step_size),
(Ipv6Addr::from_bits(n.to_bits().wrapping_add(step_size as u128)), true)
);
let mut n = Step::forward(Ipv6Addr::from_bits(u128::MIN), 1 << 16);
while let Some(m) = Step::backward_checked(n, step_size) {
assert_eq!(Step::backward_overflowing(n, step_size), (m, false));
n = m;
}
assert_eq!(
Step::backward_overflowing(n, step_size),
(Ipv6Addr::from_bits(n.to_bits().wrapping_sub(step_size as u128)), true)
);
}
}