Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 5b32341

Browse files
committed
Add numeric traits
These traits are simplified versions of what we have in `compiler_builtins` and will be used for tests.
1 parent 2694ac6 commit 5b32341

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

crates/libm-test/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
mod num_traits;
2+
3+
pub use num_traits::{Float, Hex, Int};
14

25
// List of all files present in libm's source
36
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));

crates/libm-test/src/num_traits.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
use std::fmt;
2+
3+
/// Common types and methods for floating point numbers.
4+
pub trait Float: Copy + fmt::Display + fmt::Debug + PartialEq<Self> {
5+
type Int: Int<OtherSign = Self::SignedInt, Unsigned = Self::Int>;
6+
type SignedInt: Int + Int<OtherSign = Self::Int, Unsigned = Self::Int>;
7+
8+
const BITS: u32;
9+
fn is_nan(self) -> bool;
10+
fn to_bits(self) -> Self::Int;
11+
fn from_bits(bits: Self::Int) -> Self;
12+
fn signum(self) -> Self;
13+
}
14+
15+
macro_rules! impl_float {
16+
($($fty:ty, $ui:ty, $si:ty;)+) => {
17+
$(
18+
impl Float for $fty {
19+
type Int = $ui;
20+
type SignedInt = $si;
21+
const BITS: u32 = <$ui>::BITS;
22+
fn is_nan(self) -> bool {
23+
self.is_nan()
24+
}
25+
fn to_bits(self) -> Self::Int {
26+
self.to_bits()
27+
}
28+
fn from_bits(bits: Self::Int) -> Self {
29+
Self::from_bits(bits)
30+
}
31+
fn signum(self) -> Self {
32+
self.signum()
33+
}
34+
}
35+
36+
impl Hex for $fty {
37+
fn hex(self) -> String {
38+
self.to_bits().hex()
39+
}
40+
}
41+
)+
42+
}
43+
}
44+
45+
impl_float!(
46+
f32, u32, i32;
47+
f64, u64, i64;
48+
);
49+
50+
/// Common types and methods for integers.
51+
pub trait Int: Copy + fmt::Display + fmt::Debug + PartialEq<Self> {
52+
type OtherSign: Int;
53+
type Unsigned: Int;
54+
const BITS: u32;
55+
const SIGNED: bool;
56+
57+
fn signed(self) -> <Self::Unsigned as Int>::OtherSign;
58+
fn unsigned(self) -> Self::Unsigned;
59+
fn checked_sub(self, other: Self) -> Option<Self>;
60+
fn abs(self) -> Self;
61+
}
62+
63+
macro_rules! impl_int {
64+
($($ui:ty, $si:ty ;)+) => {
65+
$(
66+
impl Int for $ui {
67+
type OtherSign = $si;
68+
type Unsigned = Self;
69+
const BITS: u32 = <$ui>::BITS;
70+
const SIGNED: bool = false;
71+
fn signed(self) -> Self::OtherSign {
72+
self as $si
73+
}
74+
fn unsigned(self) -> Self {
75+
self
76+
}
77+
fn checked_sub(self, other: Self) -> Option<Self> {
78+
self.checked_sub(other)
79+
}
80+
fn abs(self) -> Self {
81+
unimplemented!()
82+
}
83+
}
84+
85+
impl Int for $si {
86+
type OtherSign = $ui;
87+
type Unsigned = $ui;
88+
const BITS: u32 = <$ui>::BITS;
89+
const SIGNED: bool = true;
90+
fn signed(self) -> Self {
91+
self
92+
}
93+
fn unsigned(self) -> $ui {
94+
self as $ui
95+
}
96+
fn checked_sub(self, other: Self) -> Option<Self> {
97+
self.checked_sub(other)
98+
}
99+
fn abs(self) -> Self {
100+
self.abs()
101+
}
102+
}
103+
104+
impl_int!(@for_both $si);
105+
impl_int!(@for_both $ui);
106+
107+
)+
108+
};
109+
110+
(@for_both $ty:ty) => {
111+
impl Hex for $ty {
112+
fn hex(self) -> String {
113+
format!("{self:#0width$x}", width = ((Self::BITS / 8) + 2) as usize)
114+
}
115+
}
116+
}
117+
}
118+
119+
impl_int!(
120+
u32, i32;
121+
u64, i64;
122+
);
123+
124+
/// A helper trait to print something as hex with the correct number of nibbles, e.g. a `u32`
125+
/// will always print with `0x` followed by 8 digits.
126+
///
127+
/// This is only used for printing errors so allocating is okay.
128+
pub trait Hex: Copy {
129+
fn hex(self) -> String;
130+
}
131+
132+
impl<T1> Hex for (T1,)
133+
where
134+
T1: Hex,
135+
{
136+
fn hex(self) -> String {
137+
format!("({},)", self.0.hex())
138+
}
139+
}
140+
141+
impl<T1, T2> Hex for (T1, T2)
142+
where
143+
T1: Hex,
144+
T2: Hex,
145+
{
146+
fn hex(self) -> String {
147+
format!("({}, {})", self.0.hex(), self.1.hex())
148+
}
149+
}
150+
151+
impl<T1, T2, T3> Hex for (T1, T2, T3)
152+
where
153+
T1: Hex,
154+
T2: Hex,
155+
T3: Hex,
156+
{
157+
fn hex(self) -> String {
158+
format!("({}, {}, {})", self.0.hex(), self.1.hex(), self.2.hex())
159+
}
160+
}

0 commit comments

Comments
 (0)