@@ -24,9 +24,11 @@ const fn lim_for_ty<T: Approx + Copy>(_x: T) -> T {
24
24
T :: LIM
25
25
}
26
26
27
+ // We have runtime ("rt") and const versions of these macros.
28
+
27
29
/// Verify that floats are within a tolerance of each other.
28
- macro_rules! assert_approx_eq_ {
29
- ( $a: expr, $b: expr) => { { assert_approx_eq !( $a, $b, $crate:: floats:: lim_for_ty( $a) ) } } ;
30
+ macro_rules! assert_approx_eq_rt {
31
+ ( $a: expr, $b: expr) => { { assert_approx_eq_rt !( $a, $b, $crate:: floats:: lim_for_ty( $a) ) } } ;
30
32
( $a: expr, $b: expr, $lim: expr) => { {
31
33
let ( a, b) = ( & $a, & $b) ;
32
34
let diff = ( * a - * b) . abs( ) ;
@@ -37,11 +39,18 @@ macro_rules! assert_approx_eq_ {
37
39
) ;
38
40
} } ;
39
41
}
40
- pub ( crate ) use assert_approx_eq_ as assert_approx_eq;
42
+ macro_rules! assert_approx_eq_const {
43
+ ( $a: expr, $b: expr) => { { assert_approx_eq_const!( $a, $b, $crate:: floats:: lim_for_ty( $a) ) } } ;
44
+ ( $a: expr, $b: expr, $lim: expr) => { {
45
+ let ( a, b) = ( & $a, & $b) ;
46
+ let diff = ( * a - * b) . abs( ) ;
47
+ assert!( diff <= $lim) ;
48
+ } } ;
49
+ }
41
50
42
51
/// Verify that floats have the same bitwise representation. Used to avoid the default `0.0 == -0.0`
43
52
/// behavior, as well as to ensure exact NaN bitpatterns.
44
- macro_rules! assert_biteq_ {
53
+ macro_rules! assert_biteq_rt {
45
54
( @inner $left: expr, $right: expr, $msg_sep: literal, $( $tt: tt) * ) => { {
46
55
let l = $left;
47
56
let r = $right;
@@ -69,54 +78,45 @@ macro_rules! assert_biteq_ {
69
78
}
70
79
} } ;
71
80
( $left: expr, $right: expr , $( $tt: tt) * ) => {
72
- assert_biteq_ !( @inner $left, $right, "\n " , $( $tt) * )
81
+ assert_biteq_rt !( @inner $left, $right, "\n " , $( $tt) * )
73
82
} ;
74
83
( $left: expr, $right: expr $( , ) ?) => {
75
- assert_biteq_ !( @inner $left, $right, "" , "" )
84
+ assert_biteq_rt !( @inner $left, $right, "" , "" )
76
85
} ;
77
86
}
78
- pub ( crate ) use assert_biteq_ as assert_biteq;
87
+ macro_rules! assert_biteq_const {
88
+ ( @inner $left: expr, $right: expr, $msg_sep: literal, $( $tt: tt) * ) => { {
89
+ let l = $left;
90
+ let r = $right;
79
91
80
- mod const_asserts {
81
- // Shadow some assert implementations that would otherwise not compile in a const-context.
82
- // Every macro added here also needs to be added in the `float_test!` macro below.
92
+ // Hack to coerce left and right to the same type
93
+ let mut _eq_ty = l ;
94
+ _eq_ty = r ;
83
95
84
- macro_rules! assert_biteq {
85
- ( @inner $left: expr, $right: expr, $msg_sep: literal, $( $tt: tt) * ) => { {
86
- let l = $left;
87
- let r = $right;
96
+ assert!( l. to_bits( ) == r. to_bits( ) ) ;
88
97
89
- // Hack to coerce left and right to the same type
90
- let mut _eq_ty = l;
91
- _eq_ty = r;
98
+ if !l. is_nan( ) && !r. is_nan( ) {
99
+ // Also check that standard equality holds, since most tests use `assert_biteq` rather
100
+ // than `assert_eq`.
101
+ assert!( l == r) ;
102
+ }
103
+ } } ;
104
+ ( $left: expr, $right: expr , $( $tt: tt) * ) => {
105
+ assert_biteq_const!( @inner $left, $right, "\n " , $( $tt) * )
106
+ } ;
107
+ ( $left: expr, $right: expr $( , ) ?) => {
108
+ assert_biteq_const!( @inner $left, $right, "" , "" )
109
+ } ;
110
+ }
92
111
93
- assert!( l. to_bits( ) == r. to_bits( ) ) ;
112
+ // Use the runtime version by default.
113
+ // This way, they can be shadowed by the const versions.
114
+ pub ( crate ) use { assert_approx_eq_rt as assert_approx_eq, assert_biteq_rt as assert_biteq} ;
94
115
95
- if !l. is_nan( ) && !r. is_nan( ) {
96
- // Also check that standard equality holds, since most tests use `assert_biteq` rather
97
- // than `assert_eq`.
98
- assert!( l == r) ;
99
- }
100
- } } ;
101
- ( $left: expr, $right: expr , $( $tt: tt) * ) => {
102
- assert_biteq!( @inner $left, $right, "\n " , $( $tt) * )
103
- } ;
104
- ( $left: expr, $right: expr $( , ) ?) => {
105
- assert_biteq!( @inner $left, $right, "" , "" )
106
- } ;
107
- }
108
- pub ( crate ) use assert_biteq;
109
-
110
- macro_rules! assert_approx_eq {
111
- ( $a: expr, $b: expr) => { { assert_approx_eq!( $a, $b, $crate:: floats:: lim_for_ty( $a) ) } } ;
112
- ( $a: expr, $b: expr, $lim: expr) => { {
113
- let ( a, b) = ( & $a, & $b) ;
114
- let diff = ( * a - * b) . abs( ) ;
115
- assert!( diff <= $lim) ;
116
- } } ;
117
- }
118
- pub ( crate ) use assert_approx_eq;
119
- }
116
+ // Also make the const version available for re-exports.
117
+ #[ rustfmt:: skip]
118
+ pub ( crate ) use assert_biteq_const;
119
+ pub ( crate ) use assert_approx_eq_const;
120
120
121
121
/// Generate float tests for all our float types, for compile-time and run-time behavior.
122
122
///
@@ -135,6 +135,7 @@ mod const_asserts {
135
135
/// /* write tests here, using `Float` as the type */
136
136
/// }
137
137
/// }
138
+ /// ```
138
139
macro_rules! float_test {
139
140
(
140
141
name: $name: ident,
@@ -186,8 +187,12 @@ macro_rules! float_test {
186
187
mod const_ {
187
188
#[ allow( unused) ]
188
189
use super :: Approx ;
190
+ // Shadow the runtime versions of the macro with const-compatible versions.
189
191
#[ allow( unused) ]
190
- use $crate:: floats:: const_asserts:: { assert_biteq, assert_approx_eq} ;
192
+ use $crate:: floats:: {
193
+ assert_approx_eq_const as assert_approx_eq,
194
+ assert_biteq_const as assert_biteq,
195
+ } ;
191
196
192
197
#[ test]
193
198
$( $( #[ $f16_const_meta] ) + ) ?
0 commit comments