Skip to content

Commit e5e93e8

Browse files
committed
More MinInt work
1 parent 85a83d1 commit e5e93e8

File tree

3 files changed

+106
-94
lines changed

3 files changed

+106
-94
lines changed

src/int/big.rs

+88-86
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Integers used for wide operations, larger than `u128`.
2+
13
#![allow(unused)]
24

35
use crate::int::{DInt, HInt, Int, MinInt};
@@ -208,93 +210,93 @@ impl MinInt for i256 {
208210
// }
209211
// }
210212

211-
// macro_rules! impl_common {
212-
// ($ty:ty) => {
213-
// impl ops::Add for $ty {
214-
// type Output = Self;
215-
216-
// fn add(self, rhs: Self) -> Self::Output {
217-
// let (val, wrapped) = self.overflowing_add(rhs);
218-
// debug_assert!(!wrapped, "attempted to add with overflow");
219-
// val
220-
// }
221-
// }
222-
223-
// impl ops::AddAssign for $ty {
224-
// fn add_assign(&mut self, rhs: Self) {
225-
// *self = *self + rhs
226-
// }
227-
// }
228-
229-
// impl ops::BitAnd for $ty {
230-
// type Output = Self;
231-
232-
// fn bitand(self, rhs: Self) -> Self::Output {
233-
// Self([
234-
// self.0[0] & rhs.0[0],
235-
// self.0[1] & rhs.0[1],
236-
// self.0[2] & rhs.0[2],
237-
// self.0[3] & rhs.0[3],
238-
// ])
239-
// }
240-
// }
241-
242-
// impl ops::BitAndAssign for $ty {
243-
// fn bitand_assign(&mut self, rhs: Self) {
244-
// *self = *self & rhs
245-
// }
246-
// }
247-
248-
// impl ops::BitOr for $ty {
249-
// type Output = Self;
250-
251-
// fn bitor(self, rhs: Self) -> Self::Output {
252-
// Self([
253-
// self.0[0] | rhs.0[0],
254-
// self.0[1] | rhs.0[1],
255-
// self.0[2] | rhs.0[2],
256-
// self.0[3] | rhs.0[3],
257-
// ])
258-
// }
259-
// }
260-
261-
// impl ops::BitOrAssign for $ty {
262-
// fn bitor_assign(&mut self, rhs: Self) {
263-
// *self = *self | rhs
264-
// }
265-
// }
266-
267-
// impl ops::BitXor for $ty {
268-
// type Output = Self;
269-
270-
// fn bitxor(self, rhs: Self) -> Self::Output {
271-
// Self([
272-
// self.0[0] ^ rhs.0[0],
273-
// self.0[1] ^ rhs.0[1],
274-
// self.0[2] ^ rhs.0[2],
275-
// self.0[3] ^ rhs.0[3],
276-
// ])
277-
// }
278-
// }
279-
280-
// impl ops::BitXorAssign for $ty {
281-
// fn bitxor_assign(&mut self, rhs: Self) {
282-
// *self = *self ^ rhs
283-
// }
284-
// }
285-
286-
// impl ops::Not for $ty {
287-
// type Output = Self;
288-
289-
// fn not(self) -> Self::Output {
290-
// Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]])
291-
// }
292-
// }
293-
// };
294-
// }
213+
macro_rules! impl_common {
214+
($ty:ty) => {
215+
// impl ops::Add for $ty {
216+
// type Output = Self;
217+
218+
// fn add(self, rhs: Self) -> Self::Output {
219+
// let (val, wrapped) = self.overflowing_add(rhs);
220+
// debug_assert!(!wrapped, "attempted to add with overflow");
221+
// val
222+
// }
223+
// }
224+
225+
// impl ops::AddAssign for $ty {
226+
// fn add_assign(&mut self, rhs: Self) {
227+
// *self = *self + rhs
228+
// }
229+
// }
230+
231+
// impl ops::BitAnd for $ty {
232+
// type Output = Self;
233+
234+
// fn bitand(self, rhs: Self) -> Self::Output {
235+
// Self([
236+
// self.0[0] & rhs.0[0],
237+
// self.0[1] & rhs.0[1],
238+
// self.0[2] & rhs.0[2],
239+
// self.0[3] & rhs.0[3],
240+
// ])
241+
// }
242+
// }
243+
244+
// impl ops::BitAndAssign for $ty {
245+
// fn bitand_assign(&mut self, rhs: Self) {
246+
// *self = *self & rhs
247+
// }
248+
// }
249+
250+
// impl ops::BitOr for $ty {
251+
// type Output = Self;
252+
253+
// fn bitor(self, rhs: Self) -> Self::Output {
254+
// Self([
255+
// self.0[0] | rhs.0[0],
256+
// self.0[1] | rhs.0[1],
257+
// self.0[2] | rhs.0[2],
258+
// self.0[3] | rhs.0[3],
259+
// ])
260+
// }
261+
// }
262+
263+
// impl ops::BitOrAssign for $ty {
264+
// fn bitor_assign(&mut self, rhs: Self) {
265+
// *self = *self | rhs
266+
// }
267+
// }
268+
269+
// impl ops::BitXor for $ty {
270+
// type Output = Self;
271+
272+
// fn bitxor(self, rhs: Self) -> Self::Output {
273+
// Self([
274+
// self.0[0] ^ rhs.0[0],
275+
// self.0[1] ^ rhs.0[1],
276+
// self.0[2] ^ rhs.0[2],
277+
// self.0[3] ^ rhs.0[3],
278+
// ])
279+
// }
280+
// }
281+
282+
// impl ops::BitXorAssign for $ty {
283+
// fn bitxor_assign(&mut self, rhs: Self) {
284+
// *self = *self ^ rhs
285+
// }
286+
// }
287+
288+
impl ops::Not for $ty {
289+
type Output = Self;
290+
291+
fn not(self) -> Self::Output {
292+
Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]])
293+
}
294+
}
295+
};
296+
}
295297

296-
// impl_common!(i256);
297-
// impl_common!(u256);
298+
impl_common!(i256);
299+
impl_common!(u256);
298300

299301
// impl ops::Sub for u256 {
300302
// type Output = Self;

src/int/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ pub use self::leading_zeros::__clzsi2;
1414

1515
public_test_dep! {
1616
/// Minimal integer implementations needed on wide integers`
17-
pub(crate) trait MinInt: Copy + core::fmt::Debug {
17+
pub(crate) trait MinInt: Copy
18+
+ core::fmt::Debug
19+
+ ops::Not<Output = Self>
20+
{
1821

1922
/// Type with the same width but other signedness
2023
type OtherSign: MinInt;
@@ -54,7 +57,6 @@ pub(crate) trait Int: MinInt
5457
+ ops::BitOr<Output = Self>
5558
+ ops::BitXor<Output = Self>
5659
+ ops::BitAnd<Output = Self>
57-
+ ops::Not<Output = Self>
5860
{
5961
/// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing
6062
/// in `testcrate`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,111,

testcrate/src/lib.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
//! correct rounding.
1515
#![no_std]
1616

17+
use core::ops;
18+
1719
use compiler_builtins::float::Float;
18-
use compiler_builtins::int::Int;
20+
use compiler_builtins::int::{Int, MinInt};
1921

2022
use rand_xoshiro::rand_core::{RngCore, SeedableRng};
2123
use rand_xoshiro::Xoshiro128StarStar;
@@ -101,7 +103,10 @@ macro_rules! edge_cases {
101103

102104
/// Feeds a series of fuzzing inputs to `f`. The fuzzer first uses an algorithm designed to find
103105
/// edge cases, followed by a more random fuzzer that runs `n` times.
104-
pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F) {
106+
pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F)
107+
where
108+
<I as MinInt>::UnsignedInt: Int,
109+
{
105110
// edge case tester. Calls `f` 210 times for u128.
106111
// zero gets skipped by the loop
107112
f(I::ZERO);
@@ -111,15 +116,18 @@ pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F) {
111116

112117
// random fuzzer
113118
let mut rng = Xoshiro128StarStar::seed_from_u64(0);
114-
let mut x: I = Int::ZERO;
119+
let mut x: I = MinInt::ZERO;
115120
for _ in 0..n {
116121
fuzz_step(&mut rng, &mut x);
117122
f(x)
118123
}
119124
}
120125

121126
/// The same as `fuzz`, except `f` has two inputs.
122-
pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F) {
127+
pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F)
128+
where
129+
<I as MinInt>::UnsignedInt: Int,
130+
{
123131
// Check cases where the first and second inputs are zero. Both call `f` 210 times for `u128`.
124132
edge_cases!(I, case, {
125133
f(I::ZERO, case);
@@ -150,10 +158,10 @@ pub fn fuzz_shift<I: Int, F: Fn(I, u32)>(f: F) {
150158
// Shift functions are very simple and do not need anything other than shifting a small
151159
// set of random patterns for every fuzz length.
152160
let mut rng = Xoshiro128StarStar::seed_from_u64(0);
153-
let mut x: I = Int::ZERO;
161+
let mut x: I = MinInt::ZERO;
154162
for i in 0..I::FUZZ_NUM {
155163
fuzz_step(&mut rng, &mut x);
156-
f(x, Int::ZERO);
164+
f(x, MinInt::ZERO);
157165
f(x, I::FUZZ_LENGTHS[i] as u32);
158166
}
159167
}

0 commit comments

Comments
 (0)